/// <summary> /// This function should be called when you want to load more files after the loading of the library is finished. /// This function is mainly called when the user save a new group in the library. This function will not delete any /// part, but will update the existing part if you reload the same part. /// </summary> /// <param name="xmlFiles">The list of group xml to load</param> public void loadAdditionnalGroups(List<FileInfo> xmlFiles, List<string> groupNames) { // use a default display setting that won't be used to change the setting of the Custom tab page // unless this tab page doesn't exist, in which case the default setting is suitable PartLibDisplaySetting displaySetting = new PartLibDisplaySetting(); CategoryBuildingInfo buildingInfo = new CategoryBuildingInfo(displaySetting.mRespectProportion); // first check if the Custom tab exits. If not we need to create it. if (this.TabPages.ContainsKey(PartLibraryPanel.sFolderNameForCustomParts)) { // the tabe page exist, so get it TabPage tabPage = this.TabPages[this.TabPages.IndexOfKey(PartLibraryPanel.sFolderNameForCustomParts)]; // patch the building info with the correct listview buildingInfo.mListView = tabPage.Controls[0] as PartListView; // patch also the image list buildingInfo.mImageList = buildingInfo.mListView.reconstructImageListFromBrickLibrary(); // patch the respect proportion buildingInfo.mRespectProportion = (tabPage.ContextMenuStrip.Items[(int)ContextMenuIndex.RESPECT_PROPORTION] as ToolStripMenuItem).Checked; // now check if the part is already in, and remove it in order to replace it foreach (string name in groupNames) foreach (ListViewItem item in buildingInfo.mListView.Items) if (item.Tag.Equals(name)) { int removedImageIndex = item.ImageIndex; buildingInfo.mImageList.RemoveAt(removedImageIndex); buildingInfo.mListView.Items.Remove(item); // then iterate again on all the item to shift all the image index that are after the item removed of -1 foreach (ListViewItem itemToShift in buildingInfo.mListView.Items) if (itemToShift.ImageIndex > removedImageIndex) itemToShift.ImageIndex = itemToShift.ImageIndex - 1; // break the list view search since we found the item to remove break; } } else { // The custom page doesn't exist we need to create a new one addOneTabPageWithItsListView(buildingInfo, PartLibraryPanel.sFolderNameForCustomParts, displaySetting); } // now load the xml files List<FileNameWithException> imageFileUnloadable = new List<FileNameWithException>(); List<FileNameWithException> xmlFileUnloadable = new List<FileNameWithException>(); fillListViewWithPartsWithoutImage(buildingInfo, xmlFiles, xmlFileUnloadable, true); // the fill the list view with the new groups fillListViewWithGroupAndImageToFinalize(buildingInfo, imageFileUnloadable, xmlFileUnloadable); // after the loading is finished eventually display the error messages displayErrorMessage(imageFileUnloadable, xmlFileUnloadable); // Select the Custom Tab page int cutsomTabIndex = this.TabPages.IndexOfKey(PartLibraryPanel.sFolderNameForCustomParts); if (cutsomTabIndex >= 0) { // select the Custom tab this.SelectTab(cutsomTabIndex); // find the first item created and scroll it in view foreach (ListViewItem item in buildingInfo.mListView.Items) if (item.Tag.Equals(groupNames[0])) { buildingInfo.mListView.EnsureVisible(item.Index); break; } } }
/// <summary> /// This method create a new TabPage into the tab control of the library panel, and also create the ListView /// that holds the brick items, which is the only child of the TabPage /// </summary> /// <param name="buildingInfo">The building info that can be used to create the tab</param> /// <param name="tabPageName">The name of the tab page (which should be the name of the folder)</param> /// <param name="displaySetting">a display setting to correctly init the tab properties</param> private void addOneTabPageWithItsListView(CategoryBuildingInfo buildingInfo, string tabPageName, PartLibDisplaySetting displaySetting) { // add the tab in the tab control, based on the name of the folder TabPage newTabPage = new TabPage(tabPageName); newTabPage.Name = tabPageName; newTabPage.ContextMenuStrip = createContextMenuItemForATabPage(displaySetting.mLargeIcons, displaySetting.mRespectProportion); this.TabPages.Add(newTabPage); // then for the new tab added, we add a list control to // fill it with the pictures found in that folder // but we don't need to create it, we use the one created in the building info PartListView newListView = buildingInfo.mListView; // get a shortcut on the list view // filter the view (at this point it will be useless since there's no item in the view, but the goal is to save the filter sentence, it will be refilter later) newListView.filter(displaySetting.mFilterSentence, true); // set the tile size if (displaySetting.mLargeIcons) newListView.TileSize = PART_ITEM_LARGE_SIZE_WITH_MARGIN; else newListView.TileSize = PART_ITEM_SMALL_SIZE_WITH_MARGIN; // set the event handler newListView.MouseMove += new System.Windows.Forms.MouseEventHandler(this.listView_MouseMove); // add the list view to the tab page newTabPage.Controls.Add(newListView); }
/// <summary> /// parse the part folder to find all the part in the library /// </summary> public void initPartsTabControl() { // suspend layout when rebuilding the library this.SuspendLayout(); // init the part tab control based on the folders found on the drive // first clear the tab control this.TabPages.Clear(); // then search the "parts" folder, if not here maybe we should display // an error message (something wrong with the installation of the application?) DirectoryInfo partsFolder = new DirectoryInfo(PartLibraryPanel.sFullPathForLibrary); if (partsFolder.Exists) { // create two list to record the exception thrown by some files List<FileNameWithException> imageFileUnloadable = new List<FileNameWithException>(); List<FileNameWithException> xmlFileUnloadable = new List<FileNameWithException>(); // create from the Settings a dictionary to store the display status of each tab Dictionary<string, PartLibDisplaySetting> tabDisplayStatus = new Dictionary<string,PartLibDisplaySetting>(); foreach (string tabConfig in Settings.Default.UIPartLibDisplayConfig) { // the format of the tabConfig string is: tabName00?filterSentence // we will split it in the middle at the '?' char string filterSentence = string.Empty; // get the index of the ? character which is the separator between the tab name and the filter keywords // because the ? char cannot be used in filename (and tab name comes from filename) int separatorIndex = tabConfig.IndexOf('?'); if (separatorIndex < 0) separatorIndex = tabConfig.Length; // check the case of old config file without "?" char separator // get the first part before the keyword string tabNameAndDisplayConfig = tabConfig.Substring(0, separatorIndex); // maybe we have some keywords, so try to get them if (tabConfig.Length > separatorIndex + 1) filterSentence = tabConfig.Substring(separatorIndex + 1); tabDisplayStatus.Add(tabNameAndDisplayConfig.Remove(separatorIndex - 2), new PartLibDisplaySetting(tabNameAndDisplayConfig[separatorIndex - 2] == '1', tabNameAndDisplayConfig[separatorIndex - 1] == '1', filterSentence)); } // get all the folders in the parts folder to create a tab for each folder found DirectoryInfo[] categoryFolder = partsFolder.GetDirectories(); // create a list to store all the info necessary for the library building for each category List<CategoryBuildingInfo> categoryList = new List<CategoryBuildingInfo>(categoryFolder.Length); // iterate on each folder foreach (DirectoryInfo category in categoryFolder) { // try to get the display setting or construct a default one PartLibDisplaySetting displaySetting = null; if (!tabDisplayStatus.TryGetValue(category.Name, out displaySetting)) displaySetting = new PartLibDisplaySetting(); // create a building info and add it to the list CategoryBuildingInfo buildingInfo = new CategoryBuildingInfo(displaySetting.mRespectProportion); categoryList.Add(buildingInfo); // create the tab page corresponding to the folder addOneTabPageWithItsListView(buildingInfo, category.Name, displaySetting); // fill the list view with the parts loaded from the files fillListViewWithParts(buildingInfo, category, imageFileUnloadable, xmlFileUnloadable); } // reiterate on a second pass on all the list view, because we need to add the group parts foreach (CategoryBuildingInfo buildingInfo in categoryList) { fillListViewWithGroupAndImageToFinalize(buildingInfo, imageFileUnloadable, xmlFileUnloadable); } // after the loading is finished eventually display the error messages displayErrorMessage(imageFileUnloadable, xmlFileUnloadable); // after creating all the tabs, sort them according to the settings updateAppearanceAccordingToSettings(true, false, false, false, true, true); // call the index event handler manually cause, it is not called on Mono PartLibraryPanel_SelectedIndexChanged(null, null); } // suspend layout when rebuilding the library this.ResumeLayout(); }