Index: Core/Common/src/Core.Common.Controls/Views/IView.cs
===================================================================
diff -u -r4512af7782ee31b36941bb280b54d9da2953dd71 -r6c6c9b6eb17d92348c51b05a7e862c860c3d018a
--- Core/Common/src/Core.Common.Controls/Views/IView.cs (.../IView.cs) (revision 4512af7782ee31b36941bb280b54d9da2953dd71)
+++ Core/Common/src/Core.Common.Controls/Views/IView.cs (.../IView.cs) (revision 6c6c9b6eb17d92348c51b05a7e862c860c3d018a)
@@ -24,7 +24,7 @@
namespace Core.Common.Controls.Views
{
///
- /// Interface for graphical user interface views.
+ /// Interface for graphical user interface views. Class should have a default constructor.
///
public interface IView : IDisposable
{
Index: Core/Common/src/Core.Common.Gui/Forms/ViewManager/IViewResolver.cs
===================================================================
diff -u -r4512af7782ee31b36941bb280b54d9da2953dd71 -r6c6c9b6eb17d92348c51b05a7e862c860c3d018a
--- Core/Common/src/Core.Common.Gui/Forms/ViewManager/IViewResolver.cs (.../IViewResolver.cs) (revision 4512af7782ee31b36941bb280b54d9da2953dd71)
+++ Core/Common/src/Core.Common.Gui/Forms/ViewManager/IViewResolver.cs (.../IViewResolver.cs) (revision 6c6c9b6eb17d92348c51b05a7e862c860c3d018a)
@@ -27,71 +27,45 @@
namespace Core.Common.Gui.Forms.ViewManager
{
+ ///
+ /// Interface for an object capable of finding a view for a given data object.
+ ///
public interface IViewResolver
{
///
- /// Default view types registered for data object types.
+ /// Default view types registered for data object types, that can be used to automatically
+ /// resolve to a particular view when multiple candidates are available.
///
/// The keys in this dictionary are the object types and the values the
- /// corresponding view object types.
+ /// corresponding view types.
IDictionary DefaultViewTypes { get; }
///
- /// List of view info objects used for resolving views
+ /// Opens a view for specified data.
///
- IList ViewInfos { get; }
-
- ///
- /// Opens a view for specified data. Using viewprovider to resolve the correct view.
- ///
- /// Data to open a view for
- /// Always present the user with a dialog to choose from
+ /// Data to open a view for.
+ /// Always present the user with a dialog to choose
+ /// the view that has to be opened.
bool OpenViewForData(object data, bool alwaysShowDialog = false);
///
- /// Creates a view for the
- ///
- /// The data to create a view for
- /// Function to filter the view infos to use
- /// A view for data
- IView CreateViewForData(object data, Func selectViewInfo = null);
-
- ///
- /// Check if a view can be created for the .
- ///
- /// The data to check for
- ///
- bool CanOpenViewFor(object data);
-
- ///
- /// Returns all currently opened views for the same data.
- ///
- ///
- ///
- IList GetViewsForData(object data);
-
- ///
/// Closes all views for .
///
- ///
- ///
+ /// The data object to close all views for.
void CloseAllViewsFor(object data);
///
- /// Gives the default viewtype for the given data object.
+ /// Gets the view info objects for the .
///
- ///
- ///
- Type GetDefaultViewType(object dataObject);
+ /// Data used for finding matches.
+ /// The matching view info object.
+ IEnumerable GetViewInfosFor(object data);
///
- /// Gets the view info objects for the
+ /// Gets the name of the view.
///
- /// Data used for searching the view infos
- /// The viewType of the view info
- /// The matching view infos for data and view type
- IEnumerable GetViewInfosFor(object data, Type viewType = null);
-
+ /// The view.
+ /// The name of the view.
string GetViewName(IView view);
}
}
\ No newline at end of file
Index: Core/Common/src/Core.Common.Gui/Forms/ViewManager/ViewList.cs
===================================================================
diff -u -r4512af7782ee31b36941bb280b54d9da2953dd71 -r6c6c9b6eb17d92348c51b05a7e862c860c3d018a
--- Core/Common/src/Core.Common.Gui/Forms/ViewManager/ViewList.cs (.../ViewList.cs) (revision 4512af7782ee31b36941bb280b54d9da2953dd71)
+++ Core/Common/src/Core.Common.Gui/Forms/ViewManager/ViewList.cs (.../ViewList.cs) (revision 6c6c9b6eb17d92348c51b05a7e862c860c3d018a)
@@ -103,7 +103,7 @@
private bool Close(IView view, bool removeTabFromDockingManager, bool activateNextView)
{
- if (ViewResolver.IsViewOpening)
+ if (ViewResolver.IsOpeningView)
{
throw new InvalidOperationException(Resources.ViewList_Close_View_is_being_closed_while_it_is_being_opened);
}
Index: Core/Common/src/Core.Common.Gui/Forms/ViewManager/ViewResolver.cs
===================================================================
diff -u -r4512af7782ee31b36941bb280b54d9da2953dd71 -r6c6c9b6eb17d92348c51b05a7e862c860c3d018a
--- Core/Common/src/Core.Common.Gui/Forms/ViewManager/ViewResolver.cs (.../ViewResolver.cs) (revision 4512af7782ee31b36941bb280b54d9da2953dd71)
+++ Core/Common/src/Core.Common.Gui/Forms/ViewManager/ViewResolver.cs (.../ViewResolver.cs) (revision 6c6c9b6eb17d92348c51b05a7e862c860c3d018a)
@@ -23,28 +23,40 @@
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
+
using Core.Common.Controls.Views;
using Core.Common.Gui.Plugin;
using Core.Common.Gui.Properties;
using Core.Common.Utils.Reflection;
+
using log4net;
namespace Core.Common.Gui.Forms.ViewManager
{
+ ///
+ /// Object responsible for finding a view given some data-object.
+ ///
public class ViewResolver : IViewResolver
{
- private static readonly ILog Log = LogManager.GetLogger(typeof(ViewResolver));
+ private static readonly ILog log = LogManager.GetLogger(typeof(ViewResolver));
+
private readonly IDictionary defaultViewTypes = new Dictionary();
private readonly ViewList viewList;
- private readonly IList viewInfos;
- private readonly IWin32Window owner;
+ private readonly ViewInfo[] viewInfos;
+ private readonly IWin32Window dialogParent;
- public ViewResolver(ViewList viewList, IEnumerable viewInfos, IWin32Window owner)
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The view list.
+ /// The sequence of available view info objects.
+ /// The parent object for which dialogs should be shown on top.
+ public ViewResolver(ViewList viewList, IEnumerable viewInfos, IWin32Window dialogParent)
{
this.viewList = viewList;
- this.viewInfos = viewInfos.ToList();
- this.owner = owner;
+ this.viewInfos = viewInfos.ToArray();
+ this.dialogParent = dialogParent;
}
public IDictionary DefaultViewTypes
@@ -55,38 +67,30 @@
}
}
- public IList ViewInfos
- {
- get
- {
- return viewInfos;
- }
- }
-
public bool OpenViewForData(object data, bool alwaysShowDialog = false)
{
try
{
- IsViewOpening = true;
+ IsOpeningView = true;
if (data == null)
{
return false;
}
- var viewInfoList = FilterOnInheritance(GetViewInfosFor(data)).ToList();
-
- if (viewInfoList.Count == 0)
+ var viewInfoList = FilterOnInheritance(GetViewInfosFor(data)).ToArray();
+ if (viewInfoList.Length == 0)
{
- Log.DebugFormat(Resources.ViewResolver_OpenViewForData_No_view_registered_for_0_, data);
+ log.DebugFormat(Resources.ViewResolver_OpenViewForData_No_view_registered_for_0_, data);
return false;
}
if (!alwaysShowDialog)
{
- if (viewInfoList.Count == 1)
+ if (viewInfoList.Length == 1)
{
- return CreateViewFromViewInfo(data, viewInfoList[0]);
+ CreateViewFromViewInfo(data, viewInfoList[0]);
+ return true;
}
// Create default view
@@ -95,100 +99,50 @@
if (defaultViewInfo != null)
{
- if (CreateViewFromViewInfo(data, defaultViewInfo))
- {
- return true;
- }
-
- viewInfoList.Remove(defaultViewInfo);
+ CreateViewFromViewInfo(data, defaultViewInfo);
+ return true;
}
}
- if (viewInfoList.Count == 0)
+ // Create chosen view
+ var chosenViewInfo = GetViewInfoUsingDialog(data, viewInfoList);
+ if (chosenViewInfo == null)
{
return false;
}
-
- // Create chosen view
- var chosenViewInfo = GetViewInfoUsingDialog(data, viewInfoList);
-
- return chosenViewInfo != null && CreateViewFromViewInfo(data, chosenViewInfo);
+ else
+ {
+ CreateViewFromViewInfo(data, chosenViewInfo);
+ return true;
+ }
}
finally
{
- IsViewOpening = false;
+ IsOpeningView = false;
}
}
- public IView CreateViewForData(object data, Func selectViewInfo = null)
+ public void CloseAllViewsFor(object data)
{
- var viewInfoList = ((selectViewInfo == null)
- ? GetViewInfosFor(data)
- : GetViewInfosFor(data).Where(selectViewInfo))
- .ToList();
-
- if (viewInfoList.Count == 0)
+ if (data == null)
{
- return null;
+ return;
}
- if (viewInfoList.Count > 1)
+ foreach (var view in viewList.ToArray())
{
- throw new Exception(Resources.ViewResolver_CreateViewForData_More_than_one_view_for_data);
+ if (ShouldRemoveViewForData(view, data))
+ {
+ viewList.Remove(view);
+ }
}
-
- return CreateViewForData(data, viewInfoList[0]);
}
- public bool CanOpenViewFor(object data)
+ public IEnumerable GetViewInfosFor(object data)
{
- return data != null && GetViewInfosFor(data).Any();
+ return viewInfos.Where(vi => data.GetType().Implements(vi.DataType) && vi.AdditionalDataCheck(data));
}
- public IList GetViewsForData(object data)
- {
- return GetViewsForData(viewList, data).ToList();
- }
-
- public void CloseAllViewsFor(object data)
- {
- DoWithMatchingViews(data, viewList,
- v => viewList.Remove(v),
- (v, o) =>
- {
- var viewInfo = GetViewInfoForView(v);
- if (viewInfo != null)
- {
- return viewInfo.CloseForData(v, o);
- }
-
- return false;
- });
- }
-
- public Type GetDefaultViewType(object dataObject)
- {
- if (dataObject == null)
- {
- return null;
- }
-
- var selectionType = dataObject.GetType();
-
- return defaultViewTypes.Keys.Contains(selectionType)
- ? defaultViewTypes[selectionType]
- : null;
- }
-
- public IEnumerable GetViewInfosFor(object data, Type viewType = null)
- {
- var infos = ViewInfos.Where(vi => data.GetType().Implements(vi.DataType) && vi.AdditionalDataCheck(data));
-
- return viewType != null
- ? infos.Where(vi => viewType.Implements(vi.ViewType))
- : infos;
- }
-
public string GetViewName(IView view)
{
var viewInfo = GetViewInfoForView(view);
@@ -201,39 +155,42 @@
}
///
- /// Checks consistency of ViewList / ViewResolver logic. Sometimes views are closed while being opened.
+ /// Indicates if the view resolver is opening a view. Can be used to ensure consistency
+ /// of / logic. Sometimes views
+ /// are closed while being opened.
///
- internal static bool IsViewOpening { get; private set; }
+ internal static bool IsOpeningView { get; private set; }
- private void DoWithMatchingViews(object data, IEnumerable views, Action viewAction, Func extraCheck = null)
+ private bool ShouldRemoveViewForData(IView view, object data)
{
- var viewsToCheck = views.ToList();
- foreach (var view in viewsToCheck)
+ if (IsViewData(view, data))
{
- if (IsViewData(view, data) || (extraCheck != null && extraCheck(view, data)))
- {
- viewAction(view);
- }
+ return true;
}
+
+ var viewInfo = GetViewInfoForView(view);
+ return viewInfo != null && viewInfo.CloseForData(view, data);
}
- private IEnumerable GetViewsForData(IEnumerable viewsToCheck, object data)
+ private Type GetDefaultViewType(object dataObject)
{
- return data != null
- ? GetOpenViewsFor(viewsToCheck, data)
- : Enumerable.Empty();
+ var selectionType = dataObject.GetType();
+
+ return defaultViewTypes.ContainsKey(selectionType)
+ ? defaultViewTypes[selectionType]
+ : null;
}
private static IEnumerable FilterOnInheritance(IEnumerable compatibleStandaloneViewInfos)
{
- var viewInfos = compatibleStandaloneViewInfos.ToList();
+ var viewInfos = compatibleStandaloneViewInfos.ToArray();
// filter on inheritance
- var dataTypes = viewInfos.Select(i => i.DataType).ToList();
+ var dataTypes = viewInfos.Select(i => i.DataType).ToArray();
return viewInfos.Where(i => !dataTypes.Any(t => t != i.DataType && t.Implements(i.DataType)));
}
- private bool CreateViewFromViewInfo(object data, ViewInfo viewInfo)
+ private void CreateViewFromViewInfo(object data, ViewInfo viewInfo)
{
var viewData = viewInfo.GetViewData(data);
var view = (viewInfo.DataType == viewInfo.ViewDataType
@@ -246,20 +203,18 @@
viewInfo.OnActivateView(view, data);
viewList.ActiveView = view;
- return true;
+ return;
}
var newView = CreateViewForData(data, viewInfo);
viewList.Add(newView);
viewList.SetImage(newView, viewInfo.Image);
-
- return true;
}
private static IView CreateViewForData(object data, ViewInfo viewInfo)
{
- var view = (IView) Activator.CreateInstance(viewInfo.ViewType);
+ var view = (IView)Activator.CreateInstance(viewInfo.ViewType);
view.Data = viewInfo.GetViewData(data);
@@ -280,7 +235,7 @@
: null;
var viewTypeDictionary = viewInfoList.ToDictionary(vi => vi.Description ?? vi.ViewType.Name);
- using (var viewSelector = new SelectViewDialog(owner)
+ using (var viewSelector = new SelectViewDialog(dialogParent)
{
DefaultViewName = defaultViewName,
Items = viewTypeDictionary.Keys.ToList()
@@ -306,39 +261,20 @@
}
}
- private IEnumerable GetOpenViewsFor(IEnumerable viewsToCheck, object data, Func extraCheck = null)
+ private IEnumerable GetOpenViewsFor(IEnumerable viewsToCheck, object data)
{
- if (data == null)
- {
- yield break;
- }
-
- foreach (var view in viewsToCheck)
- {
- var viewInfo = GetViewInfoForView(view);
-
- if (IsViewData(view, data) && (extraCheck == null || extraCheck(view, viewInfo)))
- {
- yield return view;
- }
- }
+ return viewsToCheck.Where(view => IsViewData(view, data));
}
private bool IsViewData(IView view, object data)
{
var viewInfo = GetViewInfoForView(view);
- return data.Equals(view.Data) || (IsDataForView(view, data) && Equals(viewInfo.GetViewData(data), view.Data));
+ return data.Equals(view.Data) || (IsDataForView(data, GetViewInfoForView(view)) && Equals(viewInfo.GetViewData(data), view.Data));
}
- private bool IsDataForView(IView view, object data)
+ private bool IsDataForView(object data, ViewInfo info)
{
- if (data == null)
- {
- return false;
- }
-
- var viewInfo = GetViewInfoForView(view);
- return viewInfo != null && data.GetType().Implements(viewInfo.DataType) && viewInfo.AdditionalDataCheck(data);
+ return info != null && data.GetType().Implements(info.DataType) && info.AdditionalDataCheck(data);
}
private ViewInfo GetViewInfoForView(IView view)
@@ -350,7 +286,7 @@
{
var selectedItemType = data.GetType();
- if (defaultViewTypes.Keys.Contains(selectedItemType))
+ if (defaultViewTypes.ContainsKey(selectedItemType))
{
defaultViewTypes.Remove(selectedItemType);
}
@@ -360,7 +296,7 @@
{
var selectedItemType = data.GetType();
- if (defaultViewTypes.Keys.Contains(selectedItemType))
+ if (defaultViewTypes.ContainsKey(selectedItemType))
{
defaultViewTypes[selectedItemType] = selectedViewType;
}
@@ -374,7 +310,7 @@
{
var selectionType = dataObject.GetType();
- return defaultViewTypes.Keys.Contains(selectionType) ? defaultViewTypes[selectionType] : null;
+ return defaultViewTypes.ContainsKey(selectionType) ? defaultViewTypes[selectionType] : null;
}
}
}
\ No newline at end of file
Index: Core/Common/test/Core.Common.Gui.Test/Forms/ViewManager/TestView.Designer.cs
===================================================================
diff -u -r1e9f415cb615bf84526faeecb51f9a70498f9ffc -r6c6c9b6eb17d92348c51b05a7e862c860c3d018a
--- Core/Common/test/Core.Common.Gui.Test/Forms/ViewManager/TestView.Designer.cs (.../TestView.Designer.cs) (revision 1e9f415cb615bf84526faeecb51f9a70498f9ffc)
+++ Core/Common/test/Core.Common.Gui.Test/Forms/ViewManager/TestView.Designer.cs (.../TestView.Designer.cs) (revision 6c6c9b6eb17d92348c51b05a7e862c860c3d018a)
@@ -1,4 +1,4 @@
-namespace Core.Common.Test.TestObjects
+namespace Core.Common.Gui.Test.Forms.ViewManager
{
partial class TestView
{
Index: Core/Common/test/Core.Common.Gui.Test/Forms/ViewManager/TestView.cs
===================================================================
diff -u -r1e9f415cb615bf84526faeecb51f9a70498f9ffc -r6c6c9b6eb17d92348c51b05a7e862c860c3d018a
--- Core/Common/test/Core.Common.Gui.Test/Forms/ViewManager/TestView.cs (.../TestView.cs) (revision 1e9f415cb615bf84526faeecb51f9a70498f9ffc)
+++ Core/Common/test/Core.Common.Gui.Test/Forms/ViewManager/TestView.cs (.../TestView.cs) (revision 6c6c9b6eb17d92348c51b05a7e862c860c3d018a)
@@ -1,7 +1,8 @@
using System.Windows.Forms;
+
using Core.Common.Controls.Views;
-namespace Core.Common.Test.TestObjects
+namespace Core.Common.Gui.Test.Forms.ViewManager
{
public partial class TestView : UserControl, IView
{
Index: Core/Common/test/Core.Common.Gui.Test/Forms/ViewManager/ViewResolverTest.cs
===================================================================
diff -u -r1e9f415cb615bf84526faeecb51f9a70498f9ffc -r6c6c9b6eb17d92348c51b05a7e862c860c3d018a
--- Core/Common/test/Core.Common.Gui.Test/Forms/ViewManager/ViewResolverTest.cs (.../ViewResolverTest.cs) (revision 1e9f415cb615bf84526faeecb51f9a70498f9ffc)
+++ Core/Common/test/Core.Common.Gui.Test/Forms/ViewManager/ViewResolverTest.cs (.../ViewResolverTest.cs) (revision 6c6c9b6eb17d92348c51b05a7e862c860c3d018a)
@@ -1,10 +1,10 @@
using System;
using System.Linq;
+using System.Windows.Forms;
using Core.Common.Controls.Views;
using Core.Common.Gui.Forms.ViewManager;
using Core.Common.Gui.Plugin;
-using Core.Common.Test.TestObjects;
using Core.Common.Utils;
using NUnit.Framework;
@@ -13,134 +13,830 @@
namespace Core.Common.Gui.Test.Forms.ViewManager
{
+ [TestFixture]
public class ViewResolverTest
{
[Test]
- public void OpeningAViewForAObjectShouldUseNewView()
+ public void ParameteredConstructor_ExpectedValues()
{
// Setup
var mocks = new MockRepository();
var dockingManager = mocks.Stub();
+ var dialogParent = mocks.Stub();
mocks.ReplayAll();
- var viewList = new ViewList(dockingManager, ViewLocation.Left);
- var viewResolver = new ViewResolver(viewList, new ViewInfo[]
+ using (var viewList = new ViewList(dockingManager, ViewLocation.Bottom))
{
+ // Call
+ var viewResolver = new ViewResolver(viewList, Enumerable.Empty(), dialogParent);
+
+ // Assert
+ Assert.IsInstanceOf(viewResolver);
+ CollectionAssert.IsEmpty(viewResolver.DefaultViewTypes);
+
+ mocks.VerifyAll();
+ }
+ }
+
+ [Test]
+ [TestCase(true)]
+ [TestCase(false)]
+ public void OpenViewForData_DataIsNull_ReturnFalse(bool forceShowDialog)
+ {
+ // Setup
+ var mocks = new MockRepository();
+ var dockingManager = mocks.Stub();
+ var dialogParent = mocks.Stub();
+ mocks.ReplayAll();
+
+ var viewInfos = new ViewInfo[]
+ {
new ViewInfo