Пример #1
0
 public static void OnTemplateFilePreviewDrag(DragEventArgs dragEvent)
 {
     // Check the arguments for null
     ThrowIf.IsNullArgument(dragEvent, nameof(dragEvent));
     if (DragDropFile.IsTemplateFileDragging(dragEvent, out _))
     {
         dragEvent.Effects = DragDropEffects.All;
     }
     else
     {
         dragEvent.Effects = DragDropEffects.None;
     }
     dragEvent.Handled = true;
 }
Пример #2
0
        /// <summary>
        /// Given two dictionaries, return a dictionary that contains only those key / value pairs in dictionary1 that are not in dictionary2
        /// </summary>
        /// <param name="dictionary1"></param>
        /// <param name="dictionary2"></param>
        /// <returns></returns>
        public static Dictionary <string, string> Dictionary1ExceptDictionary2(Dictionary <string, string> dictionary1, Dictionary <string, string> dictionary2)
        {
            // Check the arguments for null
            ThrowIf.IsNullArgument(dictionary1, nameof(dictionary1));
            ThrowIf.IsNullArgument(dictionary2, nameof(dictionary2));

            Dictionary <string, string> dictionaryDifferences = new Dictionary <string, string>();
            List <string> differencesByKeys = dictionary1.Keys.Except(dictionary2.Keys).ToList();

            foreach (string key in differencesByKeys)
            {
                dictionaryDifferences.Add(key, dictionary1[key]);
            }
            return(dictionaryDifferences);
        }
Пример #3
0
        /// <summary>
        /// Get a RecencyOrderedList from the registry
        /// </summary>
        public static RecencyOrderedList <string> GetRecencyOrderedList(this RegistryKey registryKey, string subKeyPath)
        {
            // Check the arguments for null
            ThrowIf.IsNullArgument(registryKey, nameof(registryKey));

            RegistryKey subKey = registryKey.OpenSubKey(subKeyPath);
            RecencyOrderedList <string> values = new RecencyOrderedList <string>(Constant.Defaults.NumberOfMostRecentDatabasesToTrack);

            if (subKey != null)
            {
                for (int index = subKey.ValueCount - 1; index >= 0; --index)
                {
                    string listItem = (string)subKey.GetValue(index.ToString());
                    if (listItem != null)
                    {
                        values.SetMostRecent(listItem);
                    }
                }
            }
            return(values);
        }
        // Try to load a layout from the given resourceFilePath
        private static bool AvalonLayout_TryLoadFromResource(this TimelapseWindow timelapse, string resourceFilePath)
        {
            // Check the arguments for null
            ThrowIf.IsNullArgument(timelapse, nameof(timelapse));

            XmlLayoutSerializer serializer = new XmlLayoutSerializer(timelapse.DockingManager);
            Uri uri = new Uri(resourceFilePath);

            try
            {
                using (Stream stream = System.Windows.Application.GetResourceStream(uri).Stream)
                {
                    serializer.Deserialize(stream);
                }
            }
            catch
            {
                // Should only happen if there is something wrong with the uri address, e.g., if the resource doesn't exist
                return(false);
            }
            return(true);
        }
Пример #5
0
        /// <summary>
        /// If any dependency files are missing, return false else true
        /// </summary>
        public static bool AreRequiredBinariesPresent(string applicationName, Assembly executingAssembly)
        {
            // Check the arguments for null
            ThrowIf.IsNullArgument(executingAssembly, nameof(executingAssembly));

            string directoryContainingCurrentExecutable = Path.GetDirectoryName(executingAssembly.Location);

            foreach (string binaryName in Dependencies.CommonRequiredBinaries)
            {
                if (File.Exists(Path.Combine(directoryContainingCurrentExecutable, binaryName)) == false)
                {
                    return(false);
                }
            }

            if (applicationName == Constant.VersionUpdates.ApplicationName)
            {
                foreach (string binaryName in Dependencies.TimelapseRequiredBinaries)
                {
                    if (File.Exists(Path.Combine(directoryContainingCurrentExecutable, binaryName)) == false)
                    {
                        return(false);
                    }
                }
            }
            else
            {
                foreach (string binaryName in Dependencies.EditorRequiredBinaries)
                {
                    if (File.Exists(Path.Combine(directoryContainingCurrentExecutable, binaryName)) == false)
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
Пример #6
0
        /// <summary>
        /// Sort the given data grid by the given column number in ascending order
        /// </summary>
        public static void SortByColumnAscending(this DataGrid dataGrid, int columnNumber)
        {
            // Check the arguments for null
            ThrowIf.IsNullArgument(dataGrid, nameof(dataGrid));

            // Clear current sort descriptions
            dataGrid.Items.SortDescriptions.Clear();

            // Add the new sort description
            DataGridColumn    firstColumn   = dataGrid.Columns[columnNumber];
            ListSortDirection sortDirection = ListSortDirection.Ascending;

            dataGrid.Items.SortDescriptions.Add(new SortDescription(firstColumn.SortMemberPath, sortDirection));

            // Apply sort
            foreach (DataGridColumn column in dataGrid.Columns)
            {
                column.SortDirection = null;
            }
            firstColumn.SortDirection = sortDirection;

            // Refresh items to display sort
            dataGrid.Items.Refresh();
        }
Пример #7
0
 /// <summary>
 /// Write a TimeSpan value as Seconds to registry
 /// </summary>
 public static void Write(this RegistryKey registryKey, string subKeyPath, TimeSpan value)
 {
     // Check the arguments for null
     ThrowIf.IsNullArgument(registryKey, nameof(registryKey));
     registryKey.SetValue(subKeyPath, value.TotalSeconds.ToString(), RegistryValueKind.String);
 }
Пример #8
0
 /// <summary>
 /// Write a string value to registry
 /// </summary>
 public static void Write(this RegistryKey registryKey, string subKeyPath, string value)
 {
     // Check the arguments for null
     ThrowIf.IsNullArgument(registryKey, nameof(registryKey));
     registryKey.SetValue(subKeyPath, value, RegistryValueKind.String);
 }
        /// <summary>
        /// Try to load the layout identified by the layoutKey, which, depending on the key, is stored in the resource file or the registry
        /// This includes various adjustments, as detailed in the comments below.
        /// </summary>
        /// <param name="timelapse"></param>
        /// <param name="layoutKey"></param>
        /// <returns></returns>
        public static bool AvalonLayout_TryLoad(this TimelapseWindow timelapse, string layoutKey)
        {
            // Check the arguments for null
            ThrowIf.IsNullArgument(timelapse, nameof(timelapse));

            bool   isResourceFile = false;
            string layoutName     = String.Empty;

            // Layouts are loaded from either the registry or from a resource file
            // If from the registry, then the registry lookup key is the the layoutKey
            // If from the resource file, then we have to use the path of the resource file
            switch (layoutKey)
            {
            case Constant.AvalonLayoutTags.DataEntryOnTop:
                layoutName     = Constant.AvalonLayoutResourcePaths.DataEntryOnTop;
                isResourceFile = true;
                break;

            case Constant.AvalonLayoutTags.DataEntryOnSide:
                layoutName     = Constant.AvalonLayoutResourcePaths.DataEntryOnSide;
                isResourceFile = true;
                break;

            case Constant.AvalonLayoutTags.DataEntryFloating:
                layoutName     = Constant.AvalonLayoutResourcePaths.DataEntryFloating;
                isResourceFile = true;
                break;

            default:
                layoutName = layoutKey;
                break;
            }

            bool result;

            try
            {
                if (isResourceFile)
                {
                    // Load thelayout from the resource file
                    result = timelapse.AvalonLayout_TryLoadFromResource(layoutName);
                }
                else
                {
                    // Load both the layout and the window position/size from the registry
                    result = timelapse.AvalonLayout_TryLoadFromRegistry(layoutName);
                    if (result)
                    {
                        timelapse.AvalonLayout_LoadWindowPositionAndSizeFromRegistry(layoutName + Constant.AvalonDockValues.WindowRegistryKeySuffix);
                        timelapse.AvalonLayout_LoadWindowMaximizeStateFromRegistry(layoutName + Constant.AvalonDockValues.WindowMaximizeStateRegistryKeySuffix);
                    }
                }
            }
            catch
            {
                // If for some reason loading the avalon layout fails, catch that and then reload from scratch.
                // Note that if this is the result of a corrupt registry entry,
                // that will self-correct as that entry will be over-written with new values after we load and image set and exit.
                result = false;
            }
            if (result == false)
            {
                // We are trying to load the last-used layout, but there isn't one. As a fallback,
                // we use the default configuration as specified in the XAML: - all tiled with the data entry on top.
                // Eve so, we check to see if the window position and size were saved; if they aren't there, it defaults to a reasonable size and position.
                timelapse.AvalonLayout_LoadWindowPositionAndSizeFromRegistry(layoutName + Constant.AvalonDockValues.WindowRegistryKeySuffix);
                timelapse.AvalonLayout_LoadWindowMaximizeStateFromRegistry(layoutName + Constant.AvalonDockValues.WindowMaximizeStateRegistryKeySuffix);
                return(result);
            }

            // After deserializing, a completely new LayoutRoot object is created.
            // This means we have to reset various things so the documents in the new object behave correctly.
            // This includes resetting the callbacks to the DataGrid.IsActiveChanged
            timelapse.DataEntryControlPanel.PropertyChanging -= timelapse.LayoutAnchorable_PropertyChanging;
            timelapse.DataGridPane.IsActiveChanged           -= timelapse.DataGridPane_IsActiveChanged;
            timelapse.AvalonDock_ResetAfterDeserialize();
            timelapse.DataGridPane.IsActiveChanged           += timelapse.DataGridPane_IsActiveChanged;
            timelapse.DataEntryControlPanel.PropertyChanging += timelapse.LayoutAnchorable_PropertyChanging;

            // Force an update to the DataGridPane if its visible, as the above doesn't trigger it
            if (timelapse.DataGridPane.IsVisible)
            {
                timelapse.DataGridPane_IsActiveChanged(true);
            }

            // Force an update to the DataEntryControlPanel if its visible, as the above doesn't trigger it
            timelapse.DataEntryControlPanel.IsVisible = true;

            // Special case for DataEntryFloating:
            // Reposition the floating window in the middle of the main window, but just below the top
            // Note that this assumes there is just a single floating window (which should be the case for this configuration)
            if (layoutKey == Constant.AvalonLayoutTags.DataEntryFloating)
            {
                if (timelapse.DockingManager.FloatingWindows.Any())
                {
                    // BUG. This doesn't work, although it used to in older versions of AvalonDock.
                    // It seems we need to call Float() to get these positions to 'stick', as otherwise the positions are done
                    // relative to the primary screen. But if we call Float, it crashes as PreviousParent is null (in Float)
                    foreach (var floatingWindow in timelapse.DockingManager.FloatingWindows)
                    {
                        // We set the DataEntry Control Panel top / left as it remembers the values (i.e. so the layout will be saved correctly later)
                        // If we set the floating window top/left directly, it won't remember those values as its just the view.
                        timelapse.DataEntryControlPanel.FloatingTop  = timelapse.Top + 100;
                        timelapse.DataEntryControlPanel.FloatingLeft = timelapse.Left + ((timelapse.Width - floatingWindow.Width) / 2.0);
                    }
                    // This used to cause the above values to 'stick', but it no longer works.
                    //timelapse.DataEntryControlPanel.Float();
                }
            }
            return(true);
        }
Пример #10
0
 /// <summary>
 /// Get a REG_SZ key's value from the registry
 /// </summary>
 public static string GetString(this RegistryKey registryKey, string subKeyPath)
 {
     // Check the arguments for null
     ThrowIf.IsNullArgument(registryKey, nameof(registryKey));
     return((string)registryKey.GetValue(subKeyPath));
 }