public override int Execute(params string[] parameters) { try { Document doc = Application.ActiveDocument; if (DataStorage == null) { string initialPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); string docFileName = doc.FileName; if (!String.IsNullOrEmpty(docFileName)) { initialPath = Path.GetDirectoryName(docFileName); } //выбрать два файла st.xml и cl.xml WinForms.OpenFileDialog ofd1 = new WinForms.OpenFileDialog(); ofd1.InitialDirectory = initialPath; ofd1.Filter = ".st.xml files (*.st.xml)|*.st.xml"; ofd1.FilterIndex = 1; ofd1.RestoreDirectory = true; ofd1.Title = "Выберите файл структуры модели " + S1NF0_APP_NAME; if (ofd1.ShowDialog() == WinForms.DialogResult.OK) { string stFilename = ofd1.FileName; initialPath = Path.GetDirectoryName(stFilename); WinForms.OpenFileDialog ofd2 = new WinForms.OpenFileDialog(); ofd2.InitialDirectory = initialPath; ofd2.Filter = ".cl.xml files (*.cl.xml)|*.cl.xml"; ofd2.FilterIndex = 1; ofd2.RestoreDirectory = true; ofd2.Title = "Выберите файл классификатора модели " + S1NF0_APP_NAME; if (ofd2.ShowDialog() == WinForms.DialogResult.OK) { string clFilename = ofd2.FileName; //Десериализовать Structure structure = null; using (StreamReader sr = new StreamReader(stFilename)) { string serializedData = Common.Utils.RemoveInvalidXmlSubstrs(sr.ReadToEnd()); XmlSerializer xmlSerializer = new XmlSerializer(typeof(Structure)); StringReader stringReader = new StringReader(serializedData); structure = (Structure)xmlSerializer.Deserialize(stringReader); } Classifier classifier = null; using (StreamReader sr = new StreamReader(clFilename)) { string serializedData = Common.Utils.RemoveInvalidXmlSubstrs(sr.ReadToEnd()); XmlSerializer xmlSerializer = new XmlSerializer(typeof(Classifier)); StringReader stringReader = new StringReader(serializedData); classifier = (Classifier)xmlSerializer.Deserialize(stringReader); classifier.ClassName = classifier.Name; classifier.DefaultClasses[0] = classifier.Name + "_DefaultFolder"; classifier.DefaultClasses[1] = classifier.Name + "_DefaultGeometry"; } DataStorage = new StructureDataStorage(doc, stFilename, clFilename, structure, classifier); startEditXML = true; } } } if (DataStorage != null) { //StructureWindow structureWindow = new StructureWindow(DataStorage); StructureWindow structureWindow = DataStorage.StructureWindow; //Изучается набор выбора на наличие объектов геометрии //Объекты геометрии передаются в свойство StructureWindow.SelectedGeometryModelItems IEnumerable <ModelItem> geometryItems = null; if (startEditXML) { //Для того, чтобы не увеличивать время ожидания при начале редактирования XML //Принудительно настроить выбор объектов на те объекты, которые были не скрыты в начале редактирования //doc.CurrentSelection.CopyFrom(DataStorage.AllItemsLookup.Values);//выглядит не очень красиво doc.CurrentSelection.Clear();//Просто сбросить текущий выбор geometryItems = DataStorage.AllItemsLookup.Values; startEditXML = false; } else { ModelItemCollection currSelectionColl = doc.CurrentSelection.SelectedItems; int n = 50000; //Проверит, что выбрано не более n конечных геометрических элементов Search searchForAllIDs = new Search(); searchForAllIDs.Selection.CopyFrom(currSelectionColl); searchForAllIDs.Locations = SearchLocations.DescendantsAndSelf; StructureDataStorage.ConfigureSearchForAllGeometryItemsWithIds(searchForAllIDs); ModelItemCollection selectedGeometry = searchForAllIDs.FindAll(doc, false); int nSel = selectedGeometry.Count; if (nSel > n) { doc.CurrentSelection.CopyFrom(selectedGeometry); WinForms.DialogResult dialogResult = WinForms.MessageBox.Show("Вы выбрали очень большое количество конечных геометрических элементов - " + nSel + ". Это приведет к большой задержке в работе программы. Продолжить?", "Предупреждение", WinForms.MessageBoxButtons.YesNo, WinForms.MessageBoxIcon.Warning); if (dialogResult == WinForms.DialogResult.No) { return(0); } } #region Найти все конечные геометрические элементы с id с помощью Search API. Нельзя настроить на поиск только не скрытых элементов /* * Search searchForAllIDs = new Search(); * searchForAllIDs.Selection.CopyFrom(currSelectionColl); * searchForAllIDs.Locations = SearchLocations.DescendantsAndSelf; * * DataStorage.ConfigureSearchForAllNotHiddenGeometryItemsWithIds(searchForAllIDs); * ModelItemCollection selectedGeometry = searchForAllIDs.FindAll(doc, false); * * * if (!DataStorage.AllNotHiddenGeometryModelItems.IsSelected(selectedGeometry)) * { * WinForms.MessageBox.Show("Выбраны объекты, которые были скрыты при начале редактирования XML"); * return 0; * } * * * List<ModelItem> geometryItems = new List<ModelItem>(); * selectedGeometry.CopyTo(geometryItems);//ЗДЕСЬ БУДЕТ ЗАДЕРЖКА * //foreach (ModelItem item in selectedGeometry) * //{ * // geometryItems.Add(item); * //} */ #endregion //Начать поиск элементов с id currSelectionColl = new ModelItemCollection(currSelectionColl); currSelectionColl.MakeDisjoint();//Убрать все вложенные объекты geometryItems = new List <ModelItem>(); RecurseSearchForAllNotHiddenGeometryItemsWithIdsContainedInBaseLookup (currSelectionColl, (List <ModelItem>)geometryItems, DataStorage.AllItemsLookup); } structureWindow.SelectedGeometryModelItems = geometryItems; //Открывается окно StructureWindow structureWindow.BeforeShow(); structureWindow.ShowDialog(); } } catch (Exception ex) { CommonException(ex, "Ошибка при задании файла структуры " + S1NF0_APP_NAME); } return(0); }
public StructureDataStorage(Document doc, string stPath, string clPath, Structure structure, Classifier classifier, bool newStructureCreationBySelSets = false, List <string> propCategories = null) { this.doc = doc; this.stPath = stPath; this.clPath = clPath; this.oState = ComApiBridge.ComApiBridge.State; this.Structure = structure; this.Classifier = classifier; if (propCategories != null) { this.propCategories = propCategories; } //Все новые классы будут создаваться на 2 DetailLevel. 1 - папки, 2 - конечные элементы //(это относится только к вновь создаваемым объектам) //Значит должно быть 2 класса без свойств. 1 - для папок, второй для конечных элементов! //если уровней меньше, чем должно быть, то нужно добавить недостающие for (int i = classifier.DetailLevels.Count; i < DefDetailLevels.Length; i++) { classifier.DetailLevels.Add(DefDetailLevels[i]); } DefDetailLevels[0] = classifier.DetailLevels[0]; DefDetailLevels[1] = classifier.DetailLevels[1]; foreach (string lvlName in DefDetailLevels) { if (String.IsNullOrWhiteSpace(lvlName)) { throw new Exception("DetailLevel должен быть не пустой строкой"); } } //Построить словари для быстрого поиска классов foreach (Class c in classifier.NestedClasses) { SurveyClass(c); } //Всегда должны быть заданы все необходимые DefaultClass (сейчас их 2 - для папок и для конечных элементов) for (int i = 0; i < DefClassesWithNoProps.Length; i++) { if (DefClassesWithNoProps[i] == null) { DefClassesWithNoProps[i] = CreateNewClass(Classifier.DefaultClasses[i] /*DEFAULT_CLASS_NAME[i]*/, Classifier.DefaultClasses[i] /*DEFAULT_CLASS_NAME_IN_PLURAL[i]*/, i); } } #region Поиск всех объектов геометрии с id с помощью Search API. Нельзя настроить на поиск только не скрытых элементов /* * //Все объекты модели геометрии с id * Search searchForAllIDs = new Search(); * searchForAllIDs.Selection.SelectAll(); * //searchForIDs.PruneBelowMatch = false; * * ConfigureSearchForAllNotHiddenGeometryItemsWithIds(searchForAllIDs); * * //ModelItemCollection allModelItemCollection; * AllNotHiddenGeometryModelItems = searchForAllIDs.FindAll(doc, false); * * int n = AllNotHiddenGeometryModelItems.Count; * * * //Сформировать объект Search для поиска конкретного значения Id. МНОГОКРАТНЫЙ ПОИСК РАБОТАЕТ МЕДЛЕННО * //searchForCertainID = new Search(); * //searchForCertainID.Selection.CopyFrom(allModelItemCollection); * //searchForCertainIDCondition = new SearchCondition(tabCN, idCN, SearchConditionOptions.None, SearchConditionComparison.Equal, new VariantData()); * * //ПОЧЕМУ-ТО ОБХОД ОБЪЕКТОВ ПРОИСХОДИТ ОЧЕНЬ МЕДЛЕННО НА БОЛЬЩИХ МОДЕЛЯХ * //Поэтому у пользователя есть возможность скрыть часть модели, чтобы не загружать ее всю в словарь за один раз * allItemsLookup = new Dictionary<string, ModelItem>(); * foreach (ModelItem item in AllNotHiddenGeometryModelItems) * { * DataProperty idProp = item.PropertyCategories * .FindPropertyByDisplayName(S1NF0_DATA_TAB_DISPLAY_NAME, * ID_PROP_DISPLAY_NAME); * string key = Utils.GetDisplayValue(idProp.Value); * allItemsLookup[key] = item; * } */ #endregion //Обход всей модели через рекурсию НЕ БЫСТРЕЕ. Но можно искать только не скрытые элементы if (!newStructureCreationBySelSets)//если структура создается с нуля, то этот шаг не нужен! { AllItemsLookup = new Dictionary <string, ModelItem>(); RecurseSearchForAllNotHiddenGeometryItemsWithIds(doc.Models.RootItems, AllItemsLookup); //Обход всех объектов //Просмотреть все объекты, не имеющие вложенных. Какие из них уже присутствуют в документе? //Построить словарь для быстрого поиска объектов, уже добавленных в дерево List <XML.St.Object> nestedObjectsValid; List <XML.St.Object> geometryObjectsCurrDoc; List <XML.St.Object> geometryObjectsOtherDoc; List <XML.St.Object> displayObjects; List <XML.St.Object> resetObjects; SurveyNestedObjects(structure.NestedObjects, out nestedObjectsValid, out geometryObjectsCurrDoc, out geometryObjectsOtherDoc, out displayObjects, out resetObjects); structure.NestedObjects = nestedObjectsValid; //Если какие-то объекты уже присутствуют в дереве, то уточнить набор свойств и класс для них согласно модели Navis foreach (XML.St.Object o in AddedGeometryItemsLookUp.Values) { PropertyCategoryCollection categories = o.NavisItem.PropertyCategories; SetObjectProps(o, categories, 1, 1); } //Создать окно и заполнить TreeView. StructureWindow = new StructureWindow(this); } }