Skip to content

Commit e55236e

Browse files
committed
add ColumnFromCadCommand
1 parent bf013e0 commit e55236e

File tree

60 files changed

+2526
-81
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+2526
-81
lines changed
39.5 MB
Binary file not shown.

source/Sonny.Application.Core/Bases/BaseViewModel.cs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,23 +33,26 @@ protected BaseViewModel(ICommonServices commonServices)
3333
/// <summary>
3434
/// Handle display unit changed event
3535
/// </summary>
36-
private void OnDisplayUnitChanged(object? sender, ForgeTypeId newUnit)
36+
private void OnDisplayUnitChanged(object? sender,
37+
ForgeTypeId newUnit)
3738
{
3839
var oldUnit = DisplayUnit ;
3940
DisplayUnit = newUnit ;
40-
OnPropertyChanged(nameof(DisplayUnit)) ;
41-
OnPropertyChanged(nameof(DisplayUnitName)) ;
42-
41+
OnPropertyChanged(nameof( DisplayUnit )) ;
42+
OnPropertyChanged(nameof( DisplayUnitName )) ;
43+
4344
// Allow derived classes to handle unit conversion
44-
OnDisplayUnitChanged(oldUnit, newUnit) ;
45+
OnDisplayUnitChanged(oldUnit,
46+
newUnit) ;
4547
}
4648

4749
/// <summary>
4850
/// Called when display unit changes, allowing derived classes to convert values
4951
/// </summary>
5052
/// <param name="oldUnit">Previous display unit</param>
5153
/// <param name="newUnit">New display unit</param>
52-
protected virtual void OnDisplayUnitChanged(ForgeTypeId oldUnit, ForgeTypeId newUnit)
54+
protected virtual void OnDisplayUnitChanged(ForgeTypeId oldUnit,
55+
ForgeTypeId newUnit)
5356
{
5457
// Override in derived classes to convert values when unit changes
5558
}
@@ -148,5 +151,10 @@ protected void LogError(string message,
148151
/// </summary>
149152
protected void ShowInfo(string message) => MessageService.ShowInfo(message) ;
150153

154+
/// <summary>
155+
/// Show warning message to user
156+
/// </summary>
157+
protected void ShowWarning(string message) => MessageService.ShowWarning(message) ;
158+
151159
#endregion
152160
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
using Sonny.Application.Core.Interfaces ;
2+
3+
namespace Sonny.Application.Core.Bases ;
4+
5+
/// <summary>
6+
/// Base class for ViewModels that need settings management
7+
/// </summary>
8+
/// <typeparam name="TSettings">Settings model type</typeparam>
9+
public abstract class BaseViewModelWithSettings<TSettings> : BaseViewModel where TSettings : class, new()
10+
{
11+
/// <summary>
12+
/// Settings service for loading and saving settings
13+
/// </summary>
14+
private readonly IViewModelSettingsService<TSettings> _settingsService ;
15+
16+
private bool _isLoadingSettings ;
17+
18+
/// <summary>
19+
/// Initializes a new instance of BaseViewModelWithSettings
20+
/// </summary>
21+
/// <param name="commonServices">Common services</param>
22+
/// <param name="settingsService">Settings service</param>
23+
protected BaseViewModelWithSettings(ICommonServices commonServices,
24+
IViewModelSettingsService<TSettings> settingsService) : base(commonServices)
25+
{
26+
_settingsService = settingsService ;
27+
}
28+
29+
/// <summary>
30+
/// Called after all data is initialized, before loading settings.
31+
/// Override this method to initialize ViewModel data (load collections, set defaults, etc.)
32+
/// </summary>
33+
protected abstract void OnDataInitialized() ;
34+
35+
/// <summary>
36+
/// Called to apply loaded settings to ViewModel properties.
37+
/// Override this method to map settings properties to ViewModel properties.
38+
/// </summary>
39+
/// <param name="settings">Settings loaded from storage</param>
40+
protected abstract void ApplySettings(TSettings settings) ;
41+
42+
/// <summary>
43+
/// Called to create settings object from current ViewModel state.
44+
/// Override this method to map ViewModel properties to settings object.
45+
/// </summary>
46+
/// <returns>Settings object with current ViewModel state</returns>
47+
protected abstract TSettings CreateSettings() ;
48+
49+
/// <summary>
50+
/// Initialize data and load settings.
51+
/// Call this method in constructor after setting up dependencies.
52+
/// </summary>
53+
protected void InitializeWithSettings()
54+
{
55+
OnDataInitialized() ;
56+
LoadSettings() ;
57+
}
58+
59+
/// <summary>
60+
/// Loads settings from storage and applies them to the view model
61+
/// </summary>
62+
private void LoadSettings()
63+
{
64+
var settings = _settingsService.LoadSettings() ;
65+
if (settings == null)
66+
{
67+
return ;
68+
}
69+
70+
_isLoadingSettings = true ;
71+
try
72+
{
73+
ApplySettings(settings) ;
74+
}
75+
finally
76+
{
77+
_isLoadingSettings = false ;
78+
}
79+
}
80+
81+
/// <summary>
82+
/// Saves current settings to storage.
83+
/// This method checks if settings are currently being loaded to avoid saving during load.
84+
/// </summary>
85+
protected void SaveSettings()
86+
{
87+
if (_isLoadingSettings)
88+
{
89+
return ; // Don't save while loading
90+
}
91+
92+
var settings = CreateSettings() ;
93+
_settingsService.SaveSettings(settings) ;
94+
}
95+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
namespace Sonny.Application.Core.FailuresPreprocessors ;
2+
3+
/// <summary>
4+
/// Failure preprocessor to delete warnings
5+
/// </summary>
6+
public class SuppressWarningsPreprocessor : IFailuresPreprocessor
7+
{
8+
/// <summary>
9+
/// Preprocesses failures and deletes warnings
10+
/// </summary>
11+
/// <param name="failuresAccessor">The failures accessor</param>
12+
/// <returns>Continue processing result</returns>
13+
public FailureProcessingResult PreprocessFailures(FailuresAccessor failuresAccessor)
14+
{
15+
var failures = failuresAccessor.GetFailureMessages() ;
16+
foreach (var failure in failures)
17+
{
18+
var severity = failure.GetSeverity() ;
19+
if (severity == FailureSeverity.Warning)
20+
{
21+
failuresAccessor.DeleteWarning(failure) ;
22+
}
23+
}
24+
25+
return FailureProcessingResult.Continue ;
26+
}
27+
}

source/Sonny.Application.Core/Interfaces/IRevitDocument.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ public interface IRevitDocument
1212
/// </summary>
1313
Document Document { get ; }
1414

15+
/// <summary>
16+
/// Gets the Revit UIDocument
17+
/// </summary>
18+
UIDocument UIDocument { get ; }
19+
1520
/// <summary>
1621
/// Gets the active view
1722
/// </summary>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
namespace Sonny.Application.Core.Interfaces ;
2+
3+
/// <summary>
4+
/// Generic interface for ViewModel-specific settings management
5+
/// </summary>
6+
/// <typeparam name="TSettings">Settings model type</typeparam>
7+
public interface IViewModelSettingsService<TSettings> where TSettings : class, new()
8+
{
9+
/// <summary>
10+
/// Loads settings from storage
11+
/// </summary>
12+
/// <returns>Settings instance, or new instance if not found</returns>
13+
TSettings? LoadSettings() ;
14+
15+
/// <summary>
16+
/// Saves settings to storage
17+
/// </summary>
18+
/// <param name="settings">Settings to save</param>
19+
void SaveSettings(TSettings settings) ;
20+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Licensed to the.NET Foundation under one or more agreements.
2+
// The.NET Foundation licenses this file to you under the MIT license.
3+
4+
using Autodesk.Revit.UI.Selection ;
5+
6+
namespace Sonny.Application.Core.SelectionFilters ;
7+
8+
public class TypeSelectionFilter : ISelectionFilter
9+
{
10+
private readonly List<Guid> _typeGuid = [] ;
11+
12+
public TypeSelectionFilter(Type type) => _typeGuid.Add(type.GUID) ;
13+
14+
public TypeSelectionFilter(List<Type> types) =>
15+
_typeGuid = types.Select(category => category.GUID)
16+
.ToList() ;
17+
18+
public bool AllowElement(Element elem) =>
19+
_typeGuid.Contains(elem.GetType()
20+
.GUID) ;
21+
22+
public bool AllowReference(Reference reference,
23+
XYZ position) =>
24+
false ;
25+
}

source/Sonny.Application.Core/Services/RevitDocumentService.cs

Lines changed: 5 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,41 +4,16 @@
44

55
namespace Sonny.Application.Core.Services ;
66

7-
/// <summary>
8-
/// Implementation of IRevitDocument using Revit API
9-
/// </summary>
10-
public class RevitDocumentService : IRevitDocument
7+
public class RevitDocumentService(IUIDocumentProvider uiDocumentProvider) : IRevitDocument
118
{
12-
private readonly UIDocument _uiDocument ;
9+
public Document Document => UIDocument.Document ;
1310

14-
/// <summary>
15-
/// Initializes a new instance of RevitDocumentService
16-
/// </summary>
17-
/// <param name="uiDocumentProvider">The UIDocument provider</param>
18-
public RevitDocumentService(IUIDocumentProvider uiDocumentProvider)
19-
{
20-
_uiDocument = uiDocumentProvider.GetUIDocument() ;
21-
}
11+
public UIDocument UIDocument { get ; } = uiDocumentProvider.GetUIDocument() ;
2212

23-
/// <summary>
24-
/// Gets the Revit Document
25-
/// </summary>
26-
public Document Document => _uiDocument.Document ;
13+
public View ActiveView => UIDocument.ActiveView ;
2714

28-
/// <summary>
29-
/// Gets the active view
30-
/// </summary>
31-
public View ActiveView => _uiDocument.ActiveView ;
15+
public UIApplication Application => UIDocument.Application ;
3216

33-
/// <summary>
34-
/// Gets the UIApplication
35-
/// </summary>
36-
public UIApplication Application => _uiDocument.Application ;
37-
38-
/// <summary>
39-
/// Gets dimension types from the document
40-
/// </summary>
41-
/// <returns>List of DimensionType</returns>
4217
public List<DimensionType> GetDimensionTypes() =>
4318
Document.GetAllElements<DimensionType>()
4419
.Where(x => x.StyleType == DimensionStyleType.Linear)

source/Sonny.Application.Core/Services/UIDocumentProvider.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ namespace Sonny.Application.Core.Services ;
88
/// </summary>
99
public class UIDocumentProvider : IUIDocumentProvider
1010
{
11-
private UIDocument? _uiDocument ;
1211
private readonly object _lock = new() ;
12+
private UIDocument? _uiDocument ;
1313

1414
/// <summary>
1515
/// Gets the current active UIDocument
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#if NETCOREAPP
2+
using System.Text.Json ;
3+
#else
4+
using Newtonsoft.Json ;
5+
#endif
6+
using Sonny.Application.Core.Interfaces ;
7+
8+
namespace Sonny.Application.Core.Services ;
9+
10+
public class ViewModelSettingsService<TSettings> : IViewModelSettingsService<TSettings> where TSettings : class, new()
11+
{
12+
private readonly string _settingsFilePath ;
13+
14+
public ViewModelSettingsService(string settingsFileName)
15+
{
16+
var appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) ;
17+
var sonnyFolder = Path.Combine(appDataPath,
18+
"Sonny") ;
19+
Directory.CreateDirectory(sonnyFolder) ;
20+
_settingsFilePath = Path.Combine(sonnyFolder,
21+
settingsFileName) ;
22+
}
23+
24+
public TSettings? LoadSettings()
25+
{
26+
if (! File.Exists(_settingsFilePath))
27+
{
28+
return null ;
29+
}
30+
31+
try
32+
{
33+
var json = File.ReadAllText(_settingsFilePath) ;
34+
#if NETCOREAPP
35+
return JsonSerializer.Deserialize<TSettings>(json) ?? new TSettings() ;
36+
#else
37+
return JsonConvert.DeserializeObject<TSettings>(json) ?? new TSettings() ;
38+
#endif
39+
}
40+
catch
41+
{
42+
// If deserialization fails, return new instance
43+
return null ;
44+
}
45+
}
46+
47+
public void SaveSettings(TSettings settings)
48+
{
49+
try
50+
{
51+
#if NETCOREAPP
52+
var json = JsonSerializer.Serialize(settings,
53+
new JsonSerializerOptions { WriteIndented = true }) ;
54+
#else
55+
var json = JsonConvert.SerializeObject(settings, Formatting.Indented) ;
56+
#endif
57+
File.WriteAllText(_settingsFilePath,
58+
json) ;
59+
}
60+
catch
61+
{
62+
// Log error but don't throw - settings are not critical
63+
}
64+
}
65+
}

0 commit comments

Comments
 (0)