/// <summary>
        /// 根据收藏夹完整路径获取收藏夹
        /// </summary>
        /// <param name="path">收藏夹完整路径</param>
        public static FavoriteFolder GetFavoritesByPath(string path)
        {
            FavoriteFolder folder = new FavoriteFolder();
            folder.Title = Path.GetFileNameWithoutExtension(path);

            List<FavoriteFolder> childFolders = new List<FavoriteFolder>();
            foreach (string dir in Directory.GetDirectories(path))
            {
                FavoriteFolder childFolder = GetFavoritesByPath(dir);
                childFolders.Add(childFolder);
            }

            List<FavoriteItem> items = new List<FavoriteItem>();
            foreach (string file in Directory.GetFiles(path))
            {
                if ((File.GetAttributes(file) & FileAttributes.System) != FileAttributes.Hidden
                    && (File.GetAttributes(file) & FileAttributes.System) != FileAttributes.System)
                {
                    FavoriteItem item = new FavoriteItem();
                    item.Title = Path.GetFileNameWithoutExtension(file);
                    item.URL = GetUrl(file);
                    items.Add(item);
                }
            }

            folder.FavoriteFolders = childFolders;
            folder.FavoritesItems = items;
            return folder;
        }
 public FavoriteFolderViewModel(FavoriteFolder model)
 {
     if (model == null)
     {
         throw new ArgumentNullException("model");
     }
     _model = model;
 }
        /// <summary>
        /// Create FavoriteFolder
        /// </summary>
        /// <example>
        /// {
        /// "Folder": { "Id":"fo96aec5-d637-4124-bcc9-c86fd7301e4d" },
        /// "FolderAlias" : "alias"
        /// }
        /// </example>
        /// <remarks>
        /// Adds an existing folder to the list of favorites of a given user.
        /// </remarks>
        /// <param name="url"></param>
        /// <param name="folder"></param>
        /// <returns>
        /// A new FavoriteFolder record
        /// </returns>
        public IQuery <FavoriteFolder> CreateByUser(Uri url, FavoriteFolder folder)
        {
            var sfApiQuery = new ShareFile.Api.Client.Requests.Query <FavoriteFolder>(Client);

            sfApiQuery.Action("FavoriteFolders");
            sfApiQuery.Uri(url);
            sfApiQuery.Body       = folder;
            sfApiQuery.HttpMethod = "POST";
            return(sfApiQuery);
        }
        private void Settings_SettingsLoaded(object?sender, SettingsLoadedEventArgs e)
        {
            if (Settings.Default.UpgradeRequired)
            {
                LOG.Debug("Upgrading settings");
                Settings.Default.Upgrade();
                Settings.Default.UpgradeRequired = false;

                if (Settings.Default.LastVersion is null or "")
                {
                    try
                    {
                        LOG.Debug("Triggering automatic settings restore");
                        Settings.Restore();
                        LOG.Debug("Successfully restored settings");
                    }
                    catch (Exception ex)
                    {
                        LOG.Error("Failed to restore settings:", ex);
                    }
                }

                Settings.Default.LastVersion = Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? "Unknown";

                bool upgradedFavoriteReposString = false;
                try
                {
                    if (Settings.Default.GetPreviousVersion("FavoriteReposString") is String reposString)
                    {
                        Dictionary <String, String> favoritedRepos = JsonConvert.DeserializeObject <Dictionary <String, String> >(reposString);

                        FavoriteFolder root = Settings.Default.DefaultFavoriteRepos;

                        if (favoritedRepos != null)
                        {
                            foreach (KeyValuePair <String, String> favorite in favoritedRepos)
                            {
                                root.Children.Add(new FavoriteRepo(favorite.Key, favorite.Value, true, Color.Black, null));
                            }
                        }

                        Settings.Default.FavoriteRepos = root;

                        upgradedFavoriteReposString = true;
                    }
                }
                catch (SettingsPropertyNotFoundException ex)
                {
                    LOG.Error("Failed to upgrade FavoriteReposString setting", ex);
                }
                catch (JsonException ex)
                {
                    LOG.Error("Failed to upgrade FavoriteReposString setting", ex);
                }

                if (!upgradedFavoriteReposString)
                {
                    try
                    {
                        if (Settings.Default.GetPreviousVersion("FavoritedRepos") is String reposString)
                        {
                            Dictionary <String, String> favoritedRepos = JsonConvert.DeserializeObject <Dictionary <String, String> >(reposString);

                            FavoriteFolder root = Settings.Default.DefaultFavoriteRepos;

                            if (favoritedRepos != null)
                            {
                                foreach (KeyValuePair <String, String> favorite in favoritedRepos)
                                {
                                    root.Children.Add(new FavoriteRepo(favorite.Key, favorite.Value, true, Color.Black, null));
                                }
                            }

                            Settings.Default.FavoriteRepos = root;

                            upgradedFavoriteReposString = true;
                        }
                    }
                    catch (SettingsPropertyNotFoundException ex)
                    {
                        LOG.Error("Failed to upgrade FavoritedRepos setting", ex);
                    }
                }

                if (!upgradedFavoriteReposString)
                {
                    String favoriteReposString = Settings.Default.FavoriteReposJsonString;
                    if (!String.IsNullOrEmpty(favoriteReposString) &&
                        !favoriteReposString.Contains("\"Type\":"))
                    {
                        try
                        {
                            TreeNode <OldFavoriteRepo>?favoriteRepos = JsonConvert.DeserializeObject <TreeNode <OldFavoriteRepo> >(Settings.Default.FavoriteReposJsonString, OldFavoriteReposContractResolver.Settings);
                            if (favoriteRepos != null)
                            {
                                Favorite favorites = OldTreeNodeFavoriteToFavorite(favoriteRepos);
                                if (favorites is FavoriteFolder folder)
                                {
                                    Settings.Default.FavoriteRepos = folder;
                                    upgradedFavoriteReposString    = true;
                                    LOG.Debug("Upgraded tree-based FavoriteRepos to new Favorites");
                                }
                                else
                                {
                                    FavoriteFolder f = Settings.Default.DefaultFavoriteRepos;
                                    f.Children.Add(favorites);

                                    Settings.Default.FavoriteRepos = f;
                                    upgradedFavoriteReposString    = true;
                                    LOG.Debug("Upgraded tree-based FavoriteRepos to new Favorites");
                                }
                            }
                        }
                        catch (JsonException ex)
                        {
                            LOG.Error($"Failed to upgrade FavoriteReposJsonString setting to new subclassed FavoriteRepos - Favorite Repos Json String:\n{favoriteReposString}", ex);
                        }
                    }
                }

                try
                {
                    Object oldValue = Settings.Default.GetPreviousVersion("DefaultRepos");
                    if (oldValue != null && oldValue is List <String> )
                    {
                        Settings.Default.StartupRepos = (List <String>)oldValue;
                        LOG.Debug("Upgraded DefaultRepos to StartupRepos");
                    }
                }
                catch (SettingsPropertyNotFoundException ex)
                {
                    LOG.Error("Failed to upgrade DefaultRepos setting", ex);
                }

                if (Settings.Default.KeyboardShortcutsString == "")
                {
                    Dictionary <String, KeyboardShortcuts> shortcutsMapping = new Dictionary <String, KeyboardShortcuts>()
                    {
                        { "NewTabShortcut", TabbedTortoiseGit.KeyboardShortcuts.NewTab },
                        { "NextTabShortcut", TabbedTortoiseGit.KeyboardShortcuts.NextTab },
                        { "PreviousTabShortcut", TabbedTortoiseGit.KeyboardShortcuts.PreviousTab },
                        { "CloseTabShortcut", TabbedTortoiseGit.KeyboardShortcuts.CloseTab },
                        { "ReopenClosedTabShortcut", TabbedTortoiseGit.KeyboardShortcuts.ReopenClosedTab }
                    };

                    Dictionary <KeyboardShortcuts, Shortcut> shortcuts = new Dictionary <KeyboardShortcuts, Shortcut>();

                    foreach (KeyValuePair <String, KeyboardShortcuts> pair in shortcutsMapping)
                    {
                        try
                        {
                            if (Settings.Default.GetPreviousVersion(pair.Key) is Shortcut oldShortcut)
                            {
                                shortcuts[pair.Value] = oldShortcut;
                            }
                        }
                        catch (SettingsPropertyNotFoundException ex)
                        {
                            LOG.Error($"Failed to upgrade {pair.Key}.", ex);
                        }
                    }

                    Settings.Default.KeyboardShortcuts = shortcuts;
                }
            }

            if (Settings.Default.StartupRepos == null)
            {
                Settings.Default.StartupRepos = new List <String>();
            }

            if (Settings.Default.FavoriteReposJsonString == null)
            {
                Settings.Default.FavoriteReposJsonString = "";
            }

            if (Settings.Default.RecentRepos == null)
            {
                Settings.Default.RecentRepos = new List <String>();
            }

            if (Settings.Default.TabContextMenuGitActions == null)
            {
                Settings.Default.TabContextMenuGitActions = new List <String>(GitAction.ACTIONS.Keys);
            }

            if (Settings.Default.MaxRecentRepos <= 0)
            {
                LOG.Debug($"{nameof( Settings_SettingsLoaded )} - Invalid Max Recent Repos: {Settings.Default.MaxRecentRepos}");
                Settings.Default.MaxRecentRepos = 10;
            }

            if (Settings.Default.FastSubmoduleUpdateMaxProcesses <= 0)
            {
                LOG.Debug($"{nameof( Settings_SettingsLoaded )} - Invalid Max Fast Submodule Update Processes: {Settings.Default.FastSubmoduleUpdateMaxProcesses} -> {TTG.DefaultMaxProcesses}");
                Settings.Default.FastSubmoduleUpdateMaxProcesses = TTG.DefaultMaxProcesses;
            }

            if (Settings.Default.FasterSubmoduleUpdateMaxProcesses <= 0)
            {
                LOG.Debug($"{nameof( Settings_SettingsLoaded )} - Invalid Max Faster Submodule Update Processes: {Settings.Default.FasterSubmoduleUpdateMaxProcesses} -> {TTG.DefaultMaxProcesses}");
                Settings.Default.FasterSubmoduleUpdateMaxProcesses = TTG.DefaultMaxProcesses;
            }

            if (Settings.Default.FastFetchMaxProcesses <= 0)
            {
                LOG.Debug($"{nameof( Settings_SettingsLoaded )} - Invalid Max Fast Fetch Processes: {Settings.Default.FastFetchMaxProcesses} -> {TTG.DefaultMaxProcesses}");
                Settings.Default.FastFetchMaxProcesses = TTG.DefaultMaxProcesses;
            }

            if (Settings.Default.NormalTabFont == null)
            {
                Settings.Default.NormalTabFont = SystemFonts.DefaultFont;
            }

            if (Settings.Default.NormalTabFontColor.IsEmpty)
            {
                Settings.Default.NormalTabFontColor = SystemColors.ControlText;
            }

            if (Settings.Default.CheckForModifiedTabsInterval < 1000)
            {
                LOG.Debug($"{nameof( Settings_SettingsLoaded )} - Invalid Check for Modified Tabs Interval: {Settings.Default.CheckForModifiedTabsInterval}");
                Settings.Default.CheckForModifiedTabsInterval = 1000;
            }

            if (Settings.Default.ModifiedTabFont == null)
            {
                Settings.Default.ModifiedTabFont = Settings.Default.DefaultModifiedTabFont;
            }

            if (Settings.Default.ModifiedTabFontColor.IsEmpty)
            {
                Settings.Default.ModifiedTabFontColor = Settings.Default.DefaultModifiedTabFontColor;
            }

            if (Settings.Default.KeyboardShortcutsString == null)
            {
                Settings.Default.KeyboardShortcutsString = "";
            }

            if (String.IsNullOrEmpty(Settings.Default.CustomActionsString))
            {
                Settings.Default.CustomActions = new List <CustomAction>()
                {
                    new CustomAction("Open Console Here", "cmd.exe", "", "%r", false, false, false)
                };
            }

            Settings.Default.Save();
        }