Persisted library view state
This commit is contained in:
parent
8193319188
commit
202f3f8ee2
5 changed files with 197 additions and 54 deletions
|
|
@ -682,7 +682,7 @@ namespace MatterHackers.MatterControl
|
|||
{
|
||||
UiThread.RunOnIdle(() =>
|
||||
{
|
||||
// we need to ask for a destination
|
||||
// we need to ask for a destination
|
||||
DialogWindow.Show(
|
||||
new SaveAsPage(
|
||||
(container, newName) =>
|
||||
|
|
|
|||
|
|
@ -30,13 +30,18 @@ either expressed or implied, of the FreeBSD Project.
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using MatterHackers.Agg;
|
||||
using MatterHackers.DataConverters3D;
|
||||
using MatterHackers.Localizations;
|
||||
using MatterHackers.MatterControl.CustomWidgets;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace MatterHackers.MatterControl.Library
|
||||
{
|
||||
public static class LibraryExtensionMethods
|
||||
public static class LibraryExtensionMethods
|
||||
{
|
||||
public static async Task<IObject3D> CreateContent(this ILibraryItem libraryItem, Action<double, string> progressReporter)
|
||||
{
|
||||
|
|
@ -126,6 +131,52 @@ namespace MatterHackers.MatterControl.Library
|
|||
}
|
||||
}
|
||||
|
||||
public static string GetPath(this ILibraryContainer currentContainer)
|
||||
{
|
||||
return string.Join("/", currentContainer.AncestorsAndSelf().Reverse().Select(c => c.Name));
|
||||
}
|
||||
|
||||
private static string GetDBKey(ILibraryContainer activeContainer)
|
||||
{
|
||||
var idFromPath = activeContainer.GetPath();
|
||||
|
||||
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(idFromPath)))
|
||||
{
|
||||
var sha1 = HashGenerator.ComputeSHA1(stream);
|
||||
return $"library-{sha1}";
|
||||
}
|
||||
}
|
||||
|
||||
public static LibraryViewState GetUserView(this ILibraryContainer currentContainer)
|
||||
{
|
||||
string dbKey = GetDBKey(currentContainer);
|
||||
|
||||
try
|
||||
{
|
||||
string storedJson = UserSettings.Instance.get(dbKey);
|
||||
if (!string.IsNullOrWhiteSpace(storedJson))
|
||||
{
|
||||
return JsonConvert.DeserializeObject<LibraryViewState>(storedJson);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Error loading view {currentContainer.Name}: {ex.Message}");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void PersistUserView(this ILibraryContainer currentContainer, LibraryViewState userView)
|
||||
{
|
||||
string dbKey = GetDBKey(currentContainer);
|
||||
|
||||
// Store
|
||||
string json = JsonConvert.SerializeObject(userView);
|
||||
|
||||
UserSettings.Instance.set(dbKey, json);
|
||||
}
|
||||
|
||||
public static void Add(this Dictionary<string, IContentProvider> list, IEnumerable<string> extensions, IContentProvider provider)
|
||||
{
|
||||
foreach (var extension in extensions)
|
||||
|
|
|
|||
40
MatterControlLib/Library/Interfaces/LibraryViewState.cs
Normal file
40
MatterControlLib/Library/Interfaces/LibraryViewState.cs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
Copyright (c) 2017, John Lewin
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The views and conclusions contained in the software and documentation are those
|
||||
of the authors and should not be interpreted as representing official policies,
|
||||
either expressed or implied, of the FreeBSD Project.
|
||||
*/
|
||||
|
||||
using MatterHackers.MatterControl.Library.Widgets;
|
||||
|
||||
namespace MatterHackers.MatterControl.Library
|
||||
{
|
||||
public class LibraryViewState
|
||||
{
|
||||
public PrintLibraryWidget.ListViewModes ViewMode { get; set; }
|
||||
|
||||
public LibrarySortBehavior SortBehavior { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -248,21 +248,21 @@ namespace MatterHackers.MatterControl.Library.Widgets
|
|||
popupMenu.CreateBoolMenuItem(
|
||||
"Date Created".Localize(),
|
||||
() => libraryView.ActiveSort.HasFlag(SortKey.CreatedDate),
|
||||
(v) => libraryView.ActiveSort = SortKey.CreatedDate,
|
||||
(v) => libraryView.SetUserSort(SortKey.CreatedDate),
|
||||
useRadioStyle: false,
|
||||
siblingRadioButtonList: siblingList);
|
||||
|
||||
popupMenu.CreateBoolMenuItem(
|
||||
"Date Modified".Localize(),
|
||||
() => libraryView.ActiveSort.HasFlag(SortKey.ModifiedDate),
|
||||
(v) => libraryView.ActiveSort = SortKey.ModifiedDate,
|
||||
(v) => libraryView.SetUserSort(SortKey.ModifiedDate),
|
||||
useRadioStyle: false,
|
||||
siblingRadioButtonList: siblingList);
|
||||
|
||||
popupMenu.CreateBoolMenuItem(
|
||||
"Name".Localize(),
|
||||
() => libraryView.ActiveSort.HasFlag(SortKey.Name),
|
||||
(v) => libraryView.ActiveSort = SortKey.Name,
|
||||
(v) => libraryView.SetUserSort(SortKey.Name),
|
||||
useRadioStyle: false,
|
||||
siblingRadioButtonList: siblingList);
|
||||
|
||||
|
|
@ -273,14 +273,14 @@ namespace MatterHackers.MatterControl.Library.Widgets
|
|||
popupMenu.CreateBoolMenuItem(
|
||||
"Ascending".Localize(),
|
||||
() => libraryView.Ascending,
|
||||
(v) => libraryView.Ascending = true,
|
||||
(v) => libraryView.SetUserSort(ascending: true),
|
||||
useRadioStyle: false,
|
||||
siblingRadioButtonList: siblingList);
|
||||
|
||||
popupMenu.CreateBoolMenuItem(
|
||||
"Descending".Localize(),
|
||||
() => !libraryView.Ascending,
|
||||
(v) => libraryView.Ascending = false,
|
||||
(v) => libraryView.SetUserSort(ascending: false),
|
||||
useRadioStyle: false,
|
||||
siblingRadioButtonList: siblingList);
|
||||
|
||||
|
|
@ -325,11 +325,8 @@ namespace MatterHackers.MatterControl.Library.Widgets
|
|||
popupMenu.CreateBoolMenuItem(
|
||||
"View List".Localize(),
|
||||
() => ApplicationController.Instance.ViewState.LibraryViewMode == ListViewModes.RowListView,
|
||||
(isChecked) =>
|
||||
{
|
||||
ApplicationController.Instance.ViewState.LibraryViewMode = ListViewModes.RowListView;
|
||||
listView.ListContentView = new RowListView(theme);
|
||||
listView.Reload().ConfigureAwait(false);
|
||||
(isChecked) => {
|
||||
listView.SetContentView(ListViewModes.RowListView);
|
||||
},
|
||||
useRadioStyle: false,
|
||||
siblingRadioButtonList: siblingList);
|
||||
|
|
@ -339,9 +336,7 @@ namespace MatterHackers.MatterControl.Library.Widgets
|
|||
() => ApplicationController.Instance.ViewState.LibraryViewMode == ListViewModes.IconListView18,
|
||||
(isChecked) =>
|
||||
{
|
||||
ApplicationController.Instance.ViewState.LibraryViewMode = ListViewModes.IconListView18;
|
||||
listView.ListContentView = new IconListView(theme, 18);
|
||||
listView.Reload().ConfigureAwait(false);
|
||||
listView.SetContentView(ListViewModes.IconListView18);
|
||||
},
|
||||
useRadioStyle: false,
|
||||
siblingRadioButtonList: siblingList);
|
||||
|
|
@ -351,9 +346,7 @@ namespace MatterHackers.MatterControl.Library.Widgets
|
|||
() => ApplicationController.Instance.ViewState.LibraryViewMode == ListViewModes.IconListView70,
|
||||
(isChecked) =>
|
||||
{
|
||||
ApplicationController.Instance.ViewState.LibraryViewMode = ListViewModes.IconListView70;
|
||||
listView.ListContentView = new IconListView(theme, 70);
|
||||
listView.Reload().ConfigureAwait(false);
|
||||
listView.SetContentView(ListViewModes.IconListView70);
|
||||
},
|
||||
useRadioStyle: false,
|
||||
siblingRadioButtonList: siblingList);
|
||||
|
|
@ -363,9 +356,7 @@ namespace MatterHackers.MatterControl.Library.Widgets
|
|||
() => ApplicationController.Instance.ViewState.LibraryViewMode == ListViewModes.IconListView,
|
||||
(isChecked) =>
|
||||
{
|
||||
ApplicationController.Instance.ViewState.LibraryViewMode = ListViewModes.IconListView;
|
||||
listView.ListContentView = new IconListView(theme);
|
||||
listView.Reload().ConfigureAwait(false);
|
||||
listView.SetContentView(ListViewModes.IconListView);
|
||||
},
|
||||
useRadioStyle: false,
|
||||
siblingRadioButtonList: siblingList);
|
||||
|
|
@ -375,9 +366,7 @@ namespace MatterHackers.MatterControl.Library.Widgets
|
|||
() => ApplicationController.Instance.ViewState.LibraryViewMode == ListViewModes.IconListView256,
|
||||
(isChecked) =>
|
||||
{
|
||||
ApplicationController.Instance.ViewState.LibraryViewMode = ListViewModes.IconListView256;
|
||||
listView.ListContentView = new IconListView(theme, 256);
|
||||
listView.Reload().ConfigureAwait(false);
|
||||
listView.SetContentView(ListViewModes.IconListView256);
|
||||
},
|
||||
useRadioStyle: false,
|
||||
siblingRadioButtonList: siblingList);
|
||||
|
|
|
|||
|
|
@ -30,8 +30,10 @@ either expressed or implied, of the FreeBSD Project.
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Markdig.Agg;
|
||||
using MatterHackers.Agg;
|
||||
|
|
@ -39,9 +41,12 @@ using MatterHackers.Agg.Image;
|
|||
using MatterHackers.Agg.UI;
|
||||
using MatterHackers.Localizations;
|
||||
using MatterHackers.MatterControl.Library;
|
||||
using MatterHackers.MatterControl.Library.Widgets;
|
||||
using MatterHackers.MatterControl.PartPreviewWindow;
|
||||
using MatterHackers.MatterControl.PrintQueue;
|
||||
using MatterHackers.VectorMath;
|
||||
using static MatterHackers.MatterControl.CustomWidgets.LibraryListView;
|
||||
using static MatterHackers.MatterControl.Library.Widgets.PrintLibraryWidget;
|
||||
|
||||
namespace MatterHackers.MatterControl.CustomWidgets
|
||||
{
|
||||
|
|
@ -126,12 +131,26 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
{
|
||||
var activeContainer = e.ActiveContainer;
|
||||
|
||||
// Anytime the container changes,
|
||||
Type targetType = activeContainer?.DefaultView;
|
||||
if (targetType != null
|
||||
if (activeContainer.DefaultSort != null)
|
||||
{
|
||||
this.ActiveSort = activeContainer.DefaultSort.SortKey;
|
||||
this.Ascending = activeContainer.DefaultSort.Ascending;
|
||||
}
|
||||
|
||||
// If a container level view override is active, but the container is not, restore the original view
|
||||
if (stashedContentView != null
|
||||
&& activeContainer.ViewOverride == null)
|
||||
{
|
||||
// Switch back to the original view
|
||||
stashedContentView.ClearRemovedFlag();
|
||||
this.ListContentView = stashedContentView;
|
||||
stashedContentView = null;
|
||||
}
|
||||
|
||||
if (activeContainer?.ViewOverride is Type targetType
|
||||
&& targetType != this.ListContentView.GetType())
|
||||
{
|
||||
// If no original view is stored in stashedContentView then store a reference before the switch
|
||||
// Stash the active view while the container level override is in place
|
||||
if (stashedContentView == null)
|
||||
{
|
||||
stashedContentView = this.ListContentView;
|
||||
|
|
@ -143,35 +162,15 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
this.ListContentView = targetView;
|
||||
}
|
||||
}
|
||||
else if (stashedContentView != null)
|
||||
else if (activeContainer.GetUserView() is LibraryViewState userView)
|
||||
{
|
||||
// Switch back to the original view
|
||||
stashedContentView.ClearRemovedFlag();
|
||||
this.ListContentView = stashedContentView;
|
||||
stashedContentView = null;
|
||||
}
|
||||
|
||||
if (activeContainer.DefaultSort != null)
|
||||
{
|
||||
if (stashedSortOrder == null)
|
||||
if (userView.ViewMode != ApplicationController.Instance.ViewState.LibraryViewMode)
|
||||
{
|
||||
stashedSortOrder = new LibrarySortBehavior()
|
||||
{
|
||||
SortKey = this.ActiveSort,
|
||||
Ascending = this.Ascending
|
||||
};
|
||||
this.SetContentView(userView.ViewMode, userDriven: false);
|
||||
}
|
||||
|
||||
this.ActiveSort = activeContainer.DefaultSort.SortKey;
|
||||
this.Ascending = activeContainer.DefaultSort.Ascending;
|
||||
}
|
||||
else if (stashedSortOrder != null
|
||||
&& (stashedSortOrder.SortKey != this.ActiveSort
|
||||
|| stashedSortOrder.Ascending != this.Ascending))
|
||||
{
|
||||
this.ActiveSort = stashedSortOrder.SortKey;
|
||||
this.Ascending = stashedSortOrder.Ascending;
|
||||
stashedSortOrder = null;
|
||||
this.ActiveSort = userView.SortBehavior.SortKey;
|
||||
this.Ascending = userView.SortBehavior.Ascending;
|
||||
}
|
||||
|
||||
await DisplayContainerContent(activeContainer);
|
||||
|
|
@ -192,7 +191,6 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
public IEnumerable<ListViewItem> Items => items;
|
||||
|
||||
private SortKey _activeSort = SortKey.Name;
|
||||
private LibrarySortBehavior stashedSortOrder;
|
||||
|
||||
public SortKey ActiveSort
|
||||
{
|
||||
|
|
@ -225,6 +223,71 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
}
|
||||
}
|
||||
|
||||
public void SetUserSort(SortKey sortKey)
|
||||
{
|
||||
this.ActiveSort = sortKey;
|
||||
this.PersistUserView();
|
||||
}
|
||||
|
||||
public void SetUserSort(bool ascending)
|
||||
{
|
||||
this.Ascending = true;
|
||||
this.PersistUserView();
|
||||
}
|
||||
|
||||
public void SetContentView(PrintLibraryWidget.ListViewModes viewMode, bool userDriven = true)
|
||||
{
|
||||
ApplicationController.Instance.ViewState.LibraryViewMode = viewMode;
|
||||
|
||||
switch (viewMode)
|
||||
{
|
||||
case PrintLibraryWidget.ListViewModes.RowListView:
|
||||
this.ListContentView = new RowListView(theme);
|
||||
break;
|
||||
|
||||
case PrintLibraryWidget.ListViewModes.IconListView18:
|
||||
this.ListContentView = new IconListView(theme, 18);
|
||||
break;
|
||||
|
||||
case PrintLibraryWidget.ListViewModes.IconListView70:
|
||||
this.ListContentView = new IconListView(theme, 70);
|
||||
break;
|
||||
|
||||
case PrintLibraryWidget.ListViewModes.IconListView256:
|
||||
this.ListContentView = new IconListView(theme, 256);
|
||||
break;
|
||||
|
||||
case PrintLibraryWidget.ListViewModes.IconListView:
|
||||
default:
|
||||
if (viewMode != PrintLibraryWidget.ListViewModes.IconListView)
|
||||
{
|
||||
Debugger.Break(); // Unknown/unexpected value
|
||||
}
|
||||
|
||||
this.ListContentView = new IconListView(theme);
|
||||
break;
|
||||
}
|
||||
|
||||
if (userDriven)
|
||||
{
|
||||
this.PersistUserView();
|
||||
this.Reload().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void PersistUserView()
|
||||
{
|
||||
this.ActiveContainer.PersistUserView(new LibraryViewState()
|
||||
{
|
||||
ViewMode = ApplicationController.Instance.ViewState.LibraryViewMode,
|
||||
SortBehavior = new LibrarySortBehavior()
|
||||
{
|
||||
SortKey = _activeSort,
|
||||
Ascending = _ascending,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void ApplySort()
|
||||
{
|
||||
this.Reload().ConfigureAwait(false);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue