Skip to content

Commit 861357e

Browse files
committed
Merge pull request #911 from Hosch250/AutoSave
Auto save
2 parents b8968c6 + 89a9fd9 commit 861357e

File tree

8 files changed

+180
-8
lines changed

8 files changed

+180
-8
lines changed

RetailCoder.VBE/App.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
using System;
2-
using System.Collections.Concurrent;
32
using System.Globalization;
43
using System.Linq;
5-
using System.Threading;
64
using System.Threading.Tasks;
75
using System.Windows.Forms;
86
using Microsoft.Vbe.Interop;
97
using NLog;
8+
using Rubberduck.AutoSave;
109
using Rubberduck.Common;
1110
using Rubberduck.Inspections;
1211
using Rubberduck.Parsing;
@@ -26,6 +25,7 @@ public class App : IDisposable
2625
private readonly IParserErrorsPresenterFactory _parserErrorsPresenterFactory;
2726
private readonly IRubberduckParser _parser;
2827
private readonly IInspectorFactory _inspectorFactory;
28+
private readonly AutoSave.AutoSave _autoSave;
2929
private readonly IGeneralConfigService _configService;
3030
private readonly IAppMenu _appMenus;
3131
private readonly ParserStateCommandBar _stateBar;
@@ -39,7 +39,7 @@ public class App : IDisposable
3939
public App(VBE vbe, IMessageBox messageBox,
4040
IParserErrorsPresenterFactory parserErrorsPresenterFactory,
4141
IRubberduckParser parser,
42-
IInspectorFactory inspectorFactory,
42+
IInspectorFactory inspectorFactory,
4343
IGeneralConfigService configService,
4444
IAppMenu appMenus,
4545
ParserStateCommandBar stateBar,
@@ -51,6 +51,7 @@ public App(VBE vbe, IMessageBox messageBox,
5151
_parserErrorsPresenterFactory = parserErrorsPresenterFactory;
5252
_parser = parser;
5353
_inspectorFactory = inspectorFactory;
54+
_autoSave = new AutoSave.AutoSave(_vbe, new AutoSaveSettings());
5455
_configService = configService;
5556
_appMenus = appMenus;
5657
_stateBar = stateBar;
@@ -208,6 +209,7 @@ public void Dispose()
208209
_hooks.MessageReceived -= hooks_MessageReceived;
209210
_configService.SettingsChanged -= _configService_SettingsChanged;
210211
_parser.State.StateChanged -= Parser_StateChanged;
212+
_autoSave.Dispose();
211213

212214
_hooks.Dispose();
213215
}

RetailCoder.VBE/AutoSave/AutoSave.cs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
using System;
2+
using System.IO;
3+
using System.Linq;
4+
using System.Timers;
5+
using Microsoft.Vbe.Interop;
6+
7+
namespace Rubberduck.AutoSave
8+
{
9+
public class AutoSave : IDisposable
10+
{
11+
private readonly VBE _vbe;
12+
private readonly IAutoSaveSettings _settings;
13+
// ReSharper disable once InconsistentNaming
14+
private readonly Timer _timer = new Timer();
15+
16+
public bool IsEnabled
17+
{
18+
get { return _timer.Enabled; }
19+
set { _timer.Enabled = value; }
20+
}
21+
22+
public double TimerDelay
23+
{
24+
get { return _timer.Interval; }
25+
set { _timer.Interval = value; }
26+
}
27+
28+
public AutoSave(VBE vbe, IAutoSaveSettings settings)
29+
{
30+
_vbe = vbe;
31+
_settings = settings;
32+
33+
_settings.PropertyChanged += _settings_PropertyChanged;
34+
35+
_timer.Enabled = _settings.IsEnabled;
36+
_timer.Interval = _settings.TimerDelay;
37+
38+
_timer.Elapsed += _timer_Elapsed;
39+
}
40+
41+
void _settings_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
42+
{
43+
if (e.PropertyName == "IsEnabled")
44+
{
45+
_timer.Enabled = _settings.IsEnabled;
46+
}
47+
if (e.PropertyName == "TimerDelay")
48+
{
49+
_timer.Interval = _settings.TimerDelay;
50+
}
51+
}
52+
53+
private void _timer_Elapsed(object sender, ElapsedEventArgs e)
54+
{
55+
if (_vbe.VBProjects.OfType<VBProject>().Any(p => !p.Saved))
56+
{
57+
try
58+
{
59+
// iterate to find if a file exists for each open project
60+
// I do hope the compiler doesn't optimize this out
61+
_vbe.VBProjects.OfType<VBProject>().Select(p => p.FileName).ToList();
62+
}
63+
catch (DirectoryNotFoundException)
64+
{
65+
return;
66+
}
67+
68+
_vbe.CommandBars.FindControl(Id: 3).Execute();
69+
}
70+
}
71+
72+
public void Dispose()
73+
{
74+
_settings.PropertyChanged -= _settings_PropertyChanged;
75+
_timer.Elapsed -= _timer_Elapsed;
76+
77+
_timer.Dispose();
78+
}
79+
}
80+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
using System;
2+
using System.ComponentModel;
3+
using System.Runtime.CompilerServices;
4+
5+
namespace Rubberduck.AutoSave
6+
{
7+
public interface IAutoSaveSettings : INotifyPropertyChanged
8+
{
9+
bool IsEnabled { get; set; }
10+
double TimerDelay { get; set; }
11+
}
12+
13+
public class AutoSaveSettings : IAutoSaveSettings
14+
{
15+
public AutoSaveSettings(bool isEnabled = true, int timerDelay = 600000)
16+
{
17+
IsEnabled = isEnabled;
18+
TimerDelay = timerDelay;
19+
}
20+
21+
private bool _isEnabled;
22+
public bool IsEnabled
23+
{
24+
get { return _isEnabled; }
25+
set
26+
{
27+
if (_isEnabled != value)
28+
{
29+
_isEnabled = value;
30+
OnPropertyChanged();
31+
}
32+
}
33+
}
34+
35+
private double _timerDelay;
36+
public double TimerDelay
37+
{
38+
get { return _timerDelay; }
39+
set
40+
{
41+
if (Math.Abs(_timerDelay - value) > .1)
42+
{
43+
_timerDelay = value;
44+
OnPropertyChanged();
45+
}
46+
}
47+
}
48+
49+
public event PropertyChangedEventHandler PropertyChanged;
50+
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
51+
{
52+
var handler = PropertyChanged;
53+
if (handler != null)
54+
{
55+
handler(this, new PropertyChangedEventArgs(propertyName));
56+
}
57+
}
58+
}
59+
}

RetailCoder.VBE/Rubberduck.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,8 @@
268268
</ItemGroup>
269269
<ItemGroup>
270270
<Compile Include="AppMenu.cs" />
271+
<Compile Include="AutoSave\AutoSave.cs" />
272+
<Compile Include="AutoSave\AutoSaveSettings.cs" />
271273
<Compile Include="Common\ClipboardWriter.cs" />
272274
<Compile Include="Common\DeclarationExtensions.cs" />
273275
<Compile Include="Common\HookEventArgs.cs" />

Rubberduck.VBEEditor/Rubberduck.VBEditor.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
<WarningLevel>4</WarningLevel>
3131
</PropertyGroup>
3232
<ItemGroup>
33+
<Reference Include="Microsoft.CSharp" />
3334
<Reference Include="Microsoft.Office.Interop.Access, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c">
3435
<SpecificVersion>False</SpecificVersion>
3536
<EmbedInteropTypes>True</EmbedInteropTypes>

Rubberduck.VBEEditor/VBEHost/AccessApp.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Reflection;
12
using Microsoft.Office.Interop.Access;
23

34
namespace Rubberduck.VBEditor.VBEHost

Rubberduck.VBEEditor/VBEHost/HostApplicationBase.cs

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,7 @@ protected HostApplicationBase(string applicationName)
2626

2727
~HostApplicationBase()
2828
{
29-
if (Application != null)
30-
{
31-
Marshal.ReleaseComObject(Application);
32-
}
29+
Dispose(false);
3330
}
3431

3532
public string ApplicationName
@@ -41,12 +38,42 @@ public string ApplicationName
4138

4239
public TimeSpan TimedMethodCall(QualifiedMemberName qualifiedMemberName)
4340
{
41+
if (_disposed)
42+
{
43+
throw new ObjectDisposedException(GetType().Name);
44+
}
45+
4446
var stopwatch = Stopwatch.StartNew();
4547

4648
Run(qualifiedMemberName);
4749

4850
stopwatch.Stop();
4951
return stopwatch.Elapsed;
5052
}
53+
54+
public void Dispose()
55+
{
56+
Dispose(true);
57+
GC.SuppressFinalize(this);
58+
}
59+
60+
private bool _disposed;
61+
protected virtual void Dispose(bool disposing)
62+
{
63+
if (_disposed) { return; }
64+
65+
// clean up managed resources
66+
if (Application != null)
67+
{
68+
Marshal.ReleaseComObject(Application);
69+
}
70+
71+
if (disposing)
72+
{
73+
// we don't have any managed resources to clean up right now.
74+
}
75+
76+
_disposed = true;
77+
}
5178
}
5279
}

Rubberduck.VBEEditor/VBEHost/IHostApplication.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace Rubberduck.VBEditor.VBEHost
44
{
5-
public interface IHostApplication
5+
public interface IHostApplication : IDisposable
66
{
77
/// <summary>
88
/// Runs VBA procedure specified by name.

0 commit comments

Comments
 (0)