Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Finished recent repositories feature.

  • Loading branch information...
commit 62042fe668ec899c6818d4d873a39a7e30b3853c 1 parent ddce7d3
@kaisellgren authored
View
41 Libraries/Configuration.cs
@@ -1,5 +1,5 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
+using System.IO;
using System.Xml.Serialization;
namespace GG.Libraries
@@ -10,6 +10,43 @@ public class Configuration
[XmlArrayItem("Repository")]
[XmlArray("RecentRepositories")]
public List<RecentRepositoryConfiguration> RecentRepositories { get; set; }
+
+ /// <summary>
+ /// Loads the configuration from the Configuration.xml file.
+ /// </summary>
+ /// <returns></returns>
+ public static Configuration LoadConfiguration()
+ {
+ if (File.Exists("./Configuration.xml"))
+ {
+ using (var fileStream = new FileStream("./Configuration.xml", FileMode.Open))
+ {
+ return (Configuration) new XmlSerializer(typeof(Configuration)).Deserialize(fileStream);
+ }
+ }
+
+ // If the configuration file was not found, create a new empty configuration and save it.
+ var configuration = new Configuration();
+ configuration.Save();
+
+ return configuration;
+ }
+
+ /// <summary>
+ /// Saves the configuration to the Configuration.xml file.
+ /// </summary>
+ public void Save()
+ {
+ using (var fileStream = new FileStream("./Configuration.xml", FileMode.Create))
+ {
+ new XmlSerializer(typeof(Configuration)).Serialize(fileStream, this);
+ }
+ }
+
+ public Configuration()
+ {
+ RecentRepositories = new List<RecentRepositoryConfiguration>();
+ }
}
public class RecentRepositoryConfiguration
View
3  UserControls/NewTabPage.xaml
@@ -3,7 +3,8 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- mc:Ignorable="d" HorizontalAlignment="Center" VerticalAlignment="Center">
+ mc:Ignorable="d" HorizontalAlignment="Center" VerticalAlignment="Center"
+ Loaded="NewTabPageLoaded">
<DockPanel>
<StackPanel DockPanel.Dock="Top">
View
94 UserControls/NewTabPage.xaml.cs
@@ -1,17 +1,9 @@
using System;
-using System.Collections.Generic;
using System.Linq;
-using System.Text;
using System.Windows;
using System.Windows.Controls;
-using System.Windows.Data;
-using System.Windows.Documents;
using WinForms = System.Windows.Forms;
using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Imaging;
-using System.Windows.Navigation;
-using System.Windows.Shapes;
using GG.Libraries;
using GG.UserControls.Dialogs;
@@ -34,27 +26,31 @@ public NewTabPage()
/// <param name="e"></param>
void OnMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
- var item = ((FrameworkElement) e.OriginalSource).DataContext as RepositoryViewModel;
+ var item = (RepositoryViewModel) ((FrameworkElement) e.OriginalSource).DataContext;
- // The user double clicked one of the recent repositories.
- if (item != null)
- {
- var mainWindowViewModel = Application.Current.MainWindow.DataContext as MainWindowViewModel;
+ if (item == null)
+ return;
- // Skip if the repository is already opened.
- if (mainWindowViewModel.RepositoryViewModels.Contains(item) == false)
- {
- // Load the repository.
- item.NotOpened = false;
- item.Init();
+ // Find the tab contrl.
+ var repositoryTabs = UIHelper.FindChild<TabControl>(Application.Current.MainWindow, "RepositoryTabs");
- // Open the tab.
- mainWindowViewModel.RepositoryViewModels.Add(item);
+ // The user double clicked one of the recent repositories.
+ var mainWindowViewModel = (MainWindowViewModel) Application.Current.MainWindow.DataContext;
- var repositoryTabs = UIHelper.FindChild<TabControl>(Application.Current.MainWindow, "RepositoryTabs");
- repositoryTabs.SelectedItem = item;
- }
+ // Skip if the repository is already opened.
+ if (mainWindowViewModel.RepositoryViewModels.Contains(item))
+ {
+ repositoryTabs.SelectedItem = item;
+ return;
}
+
+ // Load the repository.
+ item.NotOpened = false;
+ item.Init();
+
+ // Open the tab.
+ mainWindowViewModel.RepositoryViewModels.Add(item);
+ repositoryTabs.SelectedItem = item;
}
/// <summary>
@@ -64,12 +60,15 @@ void OnMouseDoubleClick(object sender, MouseButtonEventArgs e)
/// <param name="e"></param>
private void OnOpenLocalRepository(object sender, RoutedEventArgs e)
{
- var dialog = new WinForms.FolderBrowserDialog();
- dialog.ShowNewFolderButton = false;
+ var dialog = new WinForms.FolderBrowserDialog
+ {
+ ShowNewFolderButton = false
+ };
+
dialog.ShowDialog();
// Open the selected repository, if possible.
- if (dialog.SelectedPath != null && dialog.SelectedPath.Length > 0)
+ if (!string.IsNullOrEmpty(dialog.SelectedPath))
{
if (OpenNewRepository(dialog.SelectedPath) == false)
MessageBox.Show(String.Format("Could not open \"{0}\". Are you sure it is an existing Git repository?", dialog.SelectedPath));
@@ -85,8 +84,11 @@ private void OnOpenLocalRepository(object sender, RoutedEventArgs e)
/// <param name="e"></param>
private void OnCreateLocalRepository(object sender, RoutedEventArgs e)
{
- var dialog = new WinForms.FolderBrowserDialog();
- dialog.Description = "Create and choose the folder for your new repository.";
+ var dialog = new WinForms.FolderBrowserDialog
+ {
+ Description = "Create and choose the folder for your new repository."
+ };
+
dialog.ShowDialog();
// Open the selected folder if possible.
@@ -95,7 +97,7 @@ private void OnCreateLocalRepository(object sender, RoutedEventArgs e)
LibGit2Sharp.Repository.Init(dialog.SelectedPath).Dispose();
if (OpenNewRepository(dialog.SelectedPath) == false)
- MessageBox.Show(String.Format("Something went wrong with the creation of the new repository. Try again.", dialog.SelectedPath));
+ MessageBox.Show(String.Format("Something went wrong with the creation of the new repository. Try again."));
}
dialog.Dispose();
@@ -110,26 +112,27 @@ private void OnCreateLocalRepository(object sender, RoutedEventArgs e)
/// <returns></returns>
private bool OpenNewRepository(string path)
{
- var repository = new RepositoryViewModel();
- repository.NotOpened = false;
- repository.RepositoryFullPath = path;
+ var repository = new RepositoryViewModel
+ {
+ NotOpened = false,
+ RepositoryFullPath = path
+ };
// Try loading the repository information and see if it worked.
var result = repository.Init();
- if (result == true)
+ if (result)
{
- var mainWindowViewModel = Application.Current.MainWindow.DataContext as MainWindowViewModel;
+ var mainWindowViewModel = (MainWindowViewModel) Application.Current.MainWindow.DataContext;
// Ask the user for the Name.
- var nameDialog = new PromptDialog();
- nameDialog.ResponseText = repository.RepositoryFullPath.Split(System.IO.Path.DirectorySeparatorChar).Last(); // Default to the folder name.
- nameDialog.Message = "Give a name for this repository:";
- nameDialog.Title = "Information needed";
+ var nameDialog = new PromptDialog
+ {
+ ResponseText = repository.RepositoryFullPath.Split(System.IO.Path.DirectorySeparatorChar).Last(),
+ Message = "Give a name for this repository:",
+ Title = "Information needed"
+ };
- if (nameDialog.ShowDialog() == true)
- repository.Name = nameDialog.ResponseText;
- else
- repository.Name = repository.RepositoryFullPath;
+ repository.Name = nameDialog.ShowDialog() == true ? nameDialog.ResponseText : repository.RepositoryFullPath;
// Open the repository and display it visually.
mainWindowViewModel.RepositoryViewModels.Add(repository);
@@ -144,5 +147,10 @@ private bool OpenNewRepository(string path)
return true;
}
+
+ private void NewTabPageLoaded(object sender, RoutedEventArgs e)
+ {
+ RecentRepositoriesList.Focus();
+ }
}
}
View
101 ViewModels/MainWindowViewModel.cs
@@ -1,35 +1,34 @@
using System;
-using System.Collections.Generic;
+using System.Linq;
using System.Collections.ObjectModel;
+using System.Collections.Specialized;
using System.ComponentModel;
-using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
-using System.Windows.Input;
-using System.Xml.Serialization;
using GG.Libraries;
-using GG.UserControls;
using GG.ViewModels;
namespace GG
{
class MainWindowViewModel : BaseViewModel
{
+ public Configuration Config { get; private set; }
+
public ObservableCollection<RepositoryViewModel> RecentRepositories { get; set; }
- ObservableCollection<RepositoryViewModel> _repositoryViewModels;
+ private ObservableCollection<RepositoryViewModel> repositoryViewModels;
public ObservableCollection<RepositoryViewModel> RepositoryViewModels
{
get
{
- if (_repositoryViewModels == null)
+ if (repositoryViewModels == null)
{
- _repositoryViewModels = new ObservableCollection<RepositoryViewModel>();
- var itemsView = (IEditableCollectionView)CollectionViewSource.GetDefaultView(_repositoryViewModels);
+ repositoryViewModels = new ObservableCollection<RepositoryViewModel>();
+ var itemsView = (IEditableCollectionView) CollectionViewSource.GetDefaultView(repositoryViewModels);
itemsView.NewItemPlaceholderPosition = NewItemPlaceholderPosition.AtEnd;
}
- return _repositoryViewModels;
+ return repositoryViewModels;
}
}
@@ -37,47 +36,68 @@ public MainWindowViewModel()
{
RecentRepositories = new ObservableCollection<RepositoryViewModel>() { };
+ RepositoryViewModels.CollectionChanged += RepositoryViewModelsOnCollectionChanged;
+
CreateTabCommand = new DelegateCommand(CreateTab);
CloseTabCommand = new DelegateCommand(CloseTab);
}
+ private void RepositoryViewModelsOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs)
+ {
+ if (notifyCollectionChangedEventArgs.NewItems == null)
+ return;
+
+ // Update the configuration "recent repositories".
+ // Basically, remove existing and prepend again, to make sure they appear on "top".
+ foreach (RepositoryViewModel item in notifyCollectionChangedEventArgs.NewItems)
+ {
+ if (item.RepositoryFullPath == null)
+ continue;
+
+ Config.RecentRepositories.RemoveAll(r => r.RepositoryFullPath == item.RepositoryFullPath);
+
+ Config.RecentRepositories.Add(new RecentRepositoryConfiguration
+ {
+ Name = item.Name,
+ RepositoryFullPath = item.RepositoryFullPath
+ });
+ }
+
+ if (Config.RecentRepositories.Count > 20)
+ Config.RecentRepositories.RemoveRange(20, Config.RecentRepositories.Count - 20);
+
+ Config.Save();
+ }
+
/// <summary>
/// Loads the initial configuration.
/// </summary>
public void Load()
{
- if (File.Exists("./Configuration.xml"))
- {
- XmlSerializer serializer = new XmlSerializer(typeof(Configuration));
- using (FileStream fileStream = new FileStream("./Configuration.xml", FileMode.Open))
- {
- Configuration configuration = (Configuration) serializer.Deserialize(fileStream);
+ var tabControl = UIHelper.FindChild<TabControl>(Application.Current.MainWindow, "RepositoryTabs");
- var alreadyOpenedOneRepo = false;
+ Config = Configuration.LoadConfiguration();
- // Fill the "RecentRepositories" collection and load them.
- foreach (RecentRepositoryConfiguration recent in configuration.RecentRepositories)
- {
- RepositoryViewModel repo = new RepositoryViewModel { Name = recent.Name, RepositoryFullPath = recent.RepositoryFullPath };
-
- RecentRepositories.Add(repo);
+ // Fill the "RecentRepositories" collection and load them.
+ foreach (var recent in Config.RecentRepositories)
+ {
+ var repo = new RepositoryViewModel { Name = recent.Name, RepositoryFullPath = recent.RepositoryFullPath };
- // Only open the most recent one.
- if (alreadyOpenedOneRepo == false)
- {
- repo.Init();
- RepositoryViewModels.Add(repo);
- }
+ RecentRepositories.Add(repo);
- alreadyOpenedOneRepo = true;
- }
- }
+ // Only open the most recent one.
+ /*if (recent.IsOpened)
+ {
+ repo.Init();
+ RepositoryViewModels.Add(repo);
+ }*/
}
- CreateTab(new object()); // Create "New Tab".
+ // Create the dashboard tab if there are no tabs opened.
+ if (tabControl.Items.Count == 1) // The "+" tab is counted as one.
+ CreateTab(new object()); // Create "Dashboard".
// Select the first tab.
- TabControl tabControl = UIHelper.FindChild<TabControl>(Application.Current.MainWindow, "RepositoryTabs");
tabControl.SelectedIndex = 0;
}
@@ -92,8 +112,8 @@ public void Load()
/// <param name="action"></param>
private void CloseTab(object action)
{
- TabControl tabControl = UIHelper.FindChild<TabControl>(Application.Current.MainWindow, "RepositoryTabs");
- ObservableCollection<RepositoryViewModel> repositories = tabControl.ItemsSource as ObservableCollection<RepositoryViewModel>;
+ var tabControl = UIHelper.FindChild<TabControl>(Application.Current.MainWindow, "RepositoryTabs");
+ var repositories = (ObservableCollection<RepositoryViewModel>) tabControl.ItemsSource;
if (action == null)
repositories.Remove((RepositoryViewModel) tabControl.SelectedContent);
@@ -115,10 +135,10 @@ private void CloseTab(object action)
/// <param name="action"></param>
private void CreateTab(object action)
{
- TabControl tabControl = UIHelper.FindChild<TabControl>(Application.Current.MainWindow, "RepositoryTabs");
- MainWindowViewModel mainWindowViewModel = Application.Current.MainWindow.DataContext as MainWindowViewModel;
+ var tabControl = UIHelper.FindChild<TabControl>(Application.Current.MainWindow, "RepositoryTabs");
+ var mainWindowViewModel = (MainWindowViewModel) Application.Current.MainWindow.DataContext;
- RepositoryViewModel repository = new RepositoryViewModel
+ var repository = new RepositoryViewModel
{
Name = "Dashboard",
NotOpened = true,
@@ -128,9 +148,6 @@ private void CreateTab(object action)
mainWindowViewModel.RepositoryViewModels.Add(repository);
tabControl.SelectedItem = repository;
-
- // TODO: Automatically give focus to the ListView's first item.
- //ListView recentRepositoriesList = UIHelper.FindChild<ListView>(tabControl.ItemContainerGenerator.ContainerFromIndex(0), "RecentRepositoriesList");
}
#endregion
View
10 ViewModels/RepositoryViewModel.cs
@@ -25,7 +25,6 @@ public class RepositoryViewModel : BaseViewModel
public string Name { get; set; }
public string RepositoryFullPath { get; set; }
public bool NotOpened { get; set; }
- private bool alreadyLoaded;
public EnhancedObservableCollection<Commit> Commits { get; set; }
public EnhancedObservableCollection<StatusItem> StatusItemsStaged { get; set; }
@@ -469,14 +468,9 @@ private void OpenAbout(object action)
/// </summary>
public bool Init()
{
- if (alreadyLoaded)
- throw new Exception("You may not load the repository more than once.");
-
// The "New Tab" page should not load data, i.e., the repository is not yet opened.
if (NotOpened == false)
{
- alreadyLoaded = true;
-
try
{
LoadEntireRepository();
@@ -591,7 +585,9 @@ private void LoadBranchesAndCommits(LibGit2Sharp.Repository repo = null)
var tabControl = UIHelper.FindChild<TabControl>(Application.Current.MainWindow, "RepositoryTabs");
var changesetHistory = UIHelper.FindChild<ChangesetHistory>(tabControl);
- changesetHistory.RedrawGraph();
+
+ if (changesetHistory != null)
+ changesetHistory.RedrawGraph();
})
);
View
27 Views/MainWindow.xaml.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using GG.Libraries;
@@ -18,7 +19,8 @@ public MainWindow()
void OnLoad(object sender, RoutedEventArgs e)
{
- MainWindowViewModel vm = this.DataContext as MainWindowViewModel;
+ var vm = DataContext as MainWindowViewModel;
+ Debug.Assert(vm != null, "vm != null");
vm.Load();
if (Application.Current.MainWindow.WindowState == WindowState.Maximized)
@@ -36,8 +38,8 @@ void OnLoad(object sender, RoutedEventArgs e)
/// <param name="hideRestore"></param>
private void HideMaximizeRestoreApplicationButton(bool hideMaximize, bool hideRestore)
{
- Button maximize = UIHelper.FindChild<Button>(Application.Current.MainWindow, "MaximizeApplicationButton");
- Button restore = UIHelper.FindChild<Button>(Application.Current.MainWindow, "RestoreApplicationButton");
+ var maximize = UIHelper.FindChild<Button>(Application.Current.MainWindow, "MaximizeApplicationButton");
+ var restore = UIHelper.FindChild<Button>(Application.Current.MainWindow, "RestoreApplicationButton");
maximize.Visibility = hideMaximize ? Visibility.Collapsed : Visibility.Visible;
restore.Visibility = hideRestore ? Visibility.Collapsed : Visibility.Visible;
@@ -75,16 +77,25 @@ private void WindowStateChanged(object sender, EventArgs e)
HideMaximizeRestoreApplicationButton(false, true);
}
+ private int lastRepositoryIndex;
+
private void RepositoryTabs_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
- if (e.Source is TabControl)
- {
- // Make sure the repository tabs never goes to the last item (because it is the + tab).
- var tabControl = (TabControl) e.Source;
+ var tabControl = (TabControl) e.Source;
+
+ if (tabControl == null)
+ return;
- if (tabControl.SelectedIndex == tabControl.Items.Count - 1)
+ // When the user switches the tab via ctrl+tab, make sure we never end up in the "+" tab page.
+ if (tabControl.SelectedIndex == tabControl.Items.Count - 1)
+ {
+ if (lastRepositoryIndex == tabControl.SelectedIndex - 1)
tabControl.SelectedIndex = 0;
+ else
+ tabControl.SelectedIndex = tabControl.Items.Count - 2;
}
+
+ lastRepositoryIndex = tabControl.SelectedIndex;
}
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.