/// <summary> /// Get an Int from the registry /// </summary> public static int GetInteger(this RegistryKey registryKey, string subKeyPath, int defaultValue) { // Check the arguments for null if (registryKey == null) { // this should not happen TracePrint.PrintStackTrace(1); // throw new ArgumentNullException(nameof(registryKey)); return(defaultValue); } object value = registryKey.GetValue(subKeyPath); if (value == null) { return(defaultValue); } if (value is Int32) { return((int)value); } if (value is string) { return(Int32.Parse((string)value)); } throw new NotSupportedException(String.Format("Registry key {0}\\{1} has unhandled type {2}.", registryKey.Name, subKeyPath, value.GetType().FullName)); }
/// <summary> /// Given size units in normal pixels, translate them into device independent pixels (the out parameters) /// </summary> /// <param name="widthInPixels"></param> /// <param name="heightInPixels"></param> /// <param name="widthInDeviceIndependentPixels"></param> /// <param name="heightInDeviceIndependentPixels"></param> public static void TransformPixelsToDeviceIndependentPixels(int widthInPixels, int heightInPixels, out double widthInDeviceIndependentPixels, out double heightInDeviceIndependentPixels) { IntPtr hDc = GetDC(IntPtr.Zero); if (hDc != IntPtr.Zero) { int dpiX = GetDeviceCaps(hDc, LOGPIXELSX); int dpiY = GetDeviceCaps(hDc, LOGPIXELSY); _ = ReleaseDC(IntPtr.Zero, hDc); widthInDeviceIndependentPixels = 96 * widthInPixels / (double)dpiX; heightInDeviceIndependentPixels = 96 * heightInPixels / (double)dpiY; } else { // This is very unlikely. // As a workaround, we just return the original pixel size. While this may not be the correct size (depending on the actual dpi), // it will not crash the program and at least maintains the correct aspect ration widthInDeviceIndependentPixels = widthInPixels; heightInDeviceIndependentPixels = heightInPixels; TracePrint.PrintMessage("In TransformPixelsToDeviceIndependentPixels: Failed to get DC."); } }
/// <summary> /// Get an Int from the registry /// </summary> public static int GetInteger(this RegistryKey registryKey, string subKeyPath, int defaultValue) { // Check the arguments for null if (registryKey == null) { // this should not happen TracePrint.PrintStackTrace(1); // throw new ArgumentNullException(nameof(registryKey)); return(defaultValue); } object value = registryKey.GetValue(subKeyPath); if (value == null) { return(defaultValue); } if (value is Int32) { return((int)value); } if (value is string @string) { return(Int32.Parse(@string)); } return(defaultValue); }
private static void GetAllImageAndVideoFilesInFolderAndSubfolders(string rootFolderPath, List <FileInfo> fileInfoList, int recursionLevel) { // Check the arguments for null if (fileInfoList == null) { // this should not happen TracePrint.PrintStackTrace(1); // Not show what happens if we return with a null fileInfoList, but its worth a shot // throw new ArgumentNullException(nameof(control)); return; } int nextRecursionLevel = recursionLevel + 1; if (!Directory.Exists(rootFolderPath)) { return; } DirectoryInfo directoryInfo = new DirectoryInfo(rootFolderPath); foreach (string extension in new List <string>() { Constant.File.JpgFileExtension, Constant.File.AviFileExtension, Constant.File.Mp4FileExtension, Constant.File.ASFFileExtension }) { // GetFiles has a 'bug', where it can match an extension even if there are more letters after the extension. // That is, if we are looking for *.jpg, it will not only return *.jpg files, but files such as *.jpgXXX fileInfoList.AddRange(directoryInfo.GetFiles("*" + extension)); } // Recursively descend subfolders DirectoryInfo dirInfo = new DirectoryInfo(rootFolderPath); DirectoryInfo[] subDirs = dirInfo.GetDirectories(); foreach (DirectoryInfo subDir in subDirs) { // Skip the following folders if (subDir.Name == Constant.File.BackupFolder || subDir.Name == Constant.File.DeletedFilesFolder || subDir.Name == Constant.File.VideoThumbnailFolderName) { continue; } GetAllImageAndVideoFilesInFolderAndSubfolders(subDir.FullName, fileInfoList, nextRecursionLevel); } if (recursionLevel == 0) { // After all recursion is complete, do the following (but only on the initial recursion level) // Because of that bug, we need to check for, and remove, any files that don't exactly match the desired extension // At the same time, we also remove MacOSX hidden files, if any FilesRemoveAllButImagesAndVideos(fileInfoList); if (fileInfoList.Count != 0) { fileInfoList.OrderBy(file => file.FullName).ToList(); } } }
// Checks the length of the backup path public static bool IsBackupPathLengthTooLong(string str) { // Check the arguments for null if (str == null) { // this should not happen TracePrint.PrintStackTrace(1); return(false); } return(str.Length + Constant.File.MaxAdditionalLengthOfBackupFiles > Constant.File.MaxPathLength); }
/// <summary> /// Populate folderPaths with all the folders and subfolders (from the root folder) that contains at least one video or image file /// If prefixPath is provided, it is stripped from the beginning of the matching folder paths, otherwise the full path is returned /// </summary> /// <param name="folderRoot"></param> /// <param name="folderPaths"></param> public static void GetAllFoldersContainingAnImageOrVideo(string folderRoot, List <string> folderPaths, string prefixPath) { // Check the arguments for null if (folderPaths == null || folderRoot == null) { // this should not happen TracePrint.PrintStackTrace(1); // throw new ArgumentNullException(nameof(folderPaths)); // Not sure what happens if we have a null folderPaths, but we may as well try it. return; } if (!Directory.Exists(folderRoot)) { return; } // Add a folder only if it contains one of the desired extensions if (CheckFolderForAtLeastOneImageOrVideoFiles(folderRoot) == true) { if (String.IsNullOrEmpty(prefixPath) == false) { int index = folderRoot.Length > prefixPath.Length + 1 ? prefixPath.Length + 1 : prefixPath.Length; folderPaths.Add(folderRoot.Substring(index)); } else { folderPaths.Add(folderRoot); } } DirectoryInfo[] subDirs; // Recursively descend subfolders, collecting directory info on the way // Note that while folders without images are also collected, these will eventually be skipped when it is later scanned for images to load try { DirectoryInfo dirInfo = new DirectoryInfo(folderRoot); subDirs = dirInfo.GetDirectories(); } catch { // It may fail if there is a permissions issue return; } foreach (DirectoryInfo subDir in subDirs) { // Skip the following folders if (subDir.Name == Constant.File.BackupFolder || subDir.Name == Constant.File.DeletedFilesFolder || subDir.Name == Constant.File.VideoThumbnailFolderName) { continue; } GetAllFoldersContainingAnImageOrVideo(subDir.FullName, folderPaths, prefixPath); } }
/// <summary> /// Returns true only if every character in the string is a letter or a digit /// </summary> public static bool IsLetterOrDigit(string str) { // Check the arguments for null if (str == null) { // this should not happen TracePrint.PrintStackTrace(1); return(false); } foreach (char c in str) { if (!Char.IsLetterOrDigit(c)) { return(false); } } return(true); }
/// <summary> /// Returns true only if every character in the string is a digit /// </summary> public static bool IsDigits(string value) { // Check the arguments for null if (value == null) { // this should not happen TracePrint.PrintStackTrace(1); // throw new ArgumentNullException(nameof(value)); return(false); } foreach (char character in value) { if (!Char.IsDigit(character)) { return(false); } } return(true); }
public static Dictionary <string, ImageMetadata> LoadMetadata(string filePath) { Dictionary <string, ImageMetadata> metadataDictionary = new Dictionary <string, ImageMetadata>(); try { foreach (Directory metadataDirectory in ImageMetadataReader.ReadMetadata(filePath)) { // TraceDebug.PrintMessage(String.Format("metadataDirectory is: {0}", metadataDirectory.Name)); foreach (Tag metadataTag in metadataDirectory.Tags) { ImageMetadata metadata = new ImageMetadata(metadataTag.DirectoryName, metadataTag.Name, metadataTag.Description); // Check if the metadata name is already in the dictionary. // If so, just skip it as its not clear what else to do with it // Note that Quicktime mp4s appear to have multiple directories called Quicktime Track Headers. // Exiftool seems to handle this properly but MetadataDetector generates duplicates. // So only the first Quicktime track header is added to the dictionary. if (!metadataDictionary.ContainsKey(metadata.Key)) { metadataDictionary.Add(metadata.Key, metadata); } else { TracePrint.PrintMessage(String.Format("ImageMetadata Dictionary: Duplicate metadata key: {0}:{1} (Note that Quicktime may have multiple Track Headers)", metadataDirectory.Name, metadata.Key)); } } } } catch { // Likely a corrupt file, Just return the empty dictionary metadataDictionary.Clear(); } return(metadataDictionary); }
/// <summary> /// Select the rows with the given IDs, discover its rowIndexes, and then scroll the topmost row into view /// This method is provided with a list of tuples, each containing /// - a File ID, /// - a possible row index into the data table containing that File ID /// </summary> public static void SelectAndScrollIntoView(this DataGrid dataGrid, List <Tuple <long, int> > idRowIndexes) { // We want to select (highlight) each row in the data table matching those IDs. // Typically, the file record identified by the ID will be found in the datagrid row specified by RowIndex, // which will occur *unless* the the user has resorted the datagrid by clicking a column header // For efficiency, we check each tuple to see if the ID provided matches the ID in the row specified by rowIndex. If so, // we can quickly highlight those rows. Otherwise we need to search the datagrid for each ID // Check the arguments for null if (dataGrid == null || idRowIndexes == null) { // this should not happen TracePrint.PrintStackTrace(1); // throw new ArgumentNullException(nameof(idRowIndexes) + " or " nameof(dataGrid)); // Not sure what the consequences of this empty return is, but ... return; } // If there are no selections, just unselect everything if (idRowIndexes.Count.Equals(0)) { dataGrid.UnselectAll(); return; } int topmostRowIndex = int.MaxValue; // Keeps track of the topmost row index, as this is the one we will want to scroll too DataRowView currentRow; // The current row being examined List <int> rowIndexesToSelect = new List <int>(); long currentID; int currentRowIndexThatMayContainID; foreach (Tuple <long, int> idRowIndex in idRowIndexes) { currentID = (int)idRowIndex.Item1; currentRowIndexThatMayContainID = idRowIndex.Item2; // Get the row indicated by rowIndex (after first checking that such a row exists) if (dataGrid.Items.Count < currentRowIndexThatMayContainID) { // System.Diagnostics.Debug.Print("row index " + currentRowIndexThatMayContainID + " is not in array sized " + dataGrid.Items.Count); return; } currentRow = dataGrid.Items[currentRowIndexThatMayContainID] as DataRowView; if ((long)currentRow.Row.ItemArray[0] == currentID) { // The ID is in the row indicated by rowIndex. Add that rowIndex as one of the rows we should select rowIndexesToSelect.Add(currentRowIndexThatMayContainID); if (topmostRowIndex > currentRowIndexThatMayContainID) { topmostRowIndex = currentRowIndexThatMayContainID; } } else { // The ID is not in the row indicated by rowIndex. Search the datagrid for that ID, and then add it as one of the rows we should select bool idFound = false; int dataGridItemsCount = dataGrid.Items.Count; for (int index = 0; index < dataGridItemsCount; index++) { currentRow = dataGrid.Items[index] as DataRowView; if ((long)currentRow.Row.ItemArray[0] == currentID) { idFound = true; rowIndexesToSelect.Add(index); if (topmostRowIndex > index) { topmostRowIndex = index; } break; } } if (idFound == false) { // The id should always be found. But just in case we ignore IDS that aren't found // System.Diagnostics.Debug.Print("could not find ID: " + currentID + " in array sized " + dataGrid.Items.Count); } } } // Select the items (which highlights those rows) bool indexIncreasing = topmostRowIndex > dataGrid.SelectedIndex; SelectRowByIndexes(dataGrid, rowIndexesToSelect); // Depending on our selection direction, we scroll to expose the previous or next 2 rows to ensure they are visible beyond the selected row); int scrollIndex = indexIncreasing ? Math.Min(topmostRowIndex + 3, dataGrid.Items.Count - 1) : Math.Max(topmostRowIndex - 3, 0); dataGrid.ScrollIntoView(dataGrid.Items[scrollIndex]); }