• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

HicServices / RDMP / 20057586828

09 Dec 2025 08:56AM UTC coverage: 57.193% (-0.2%) from 57.422%
20057586828

Pull #2182

github

JFriel
Merge branch 'develop' of https://github.com/HicServices/RDMP into task/RDMP-33-dataset-integration-interface
Pull Request #2182: [Datasets] Task/rdmp 33 dataset integration interface

11510 of 21615 branches covered (53.25%)

Branch coverage included in aggregate %.

1226 of 2024 new or added lines in 85 files covered. (60.57%)

35 existing lines in 15 files now uncovered.

32654 of 55604 relevant lines covered (58.73%)

8854.02 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

34.54
/Rdmp.Core/ReusableLibraryCode/Settings/UserSettings.cs
1
// Copyright (c) The University of Dundee 2018-2024
2
// This file is part of the Research Data Management Platform (RDMP).
3
// RDMP is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
4
// RDMP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
5
// You should have received a copy of the GNU General Public License along with RDMP. If not, see <https://www.gnu.org/licenses/>.
6

7
using System;
8
using System.Collections.Generic;
9
using System.IO;
10
using System.Linq;
11
using FAnsi.Discovery;
12
using Rdmp.Core.ReusableLibraryCode.Checks;
13

14
namespace Rdmp.Core.ReusableLibraryCode.Settings;
15

16
/// <summary>
17
/// This is the Settings static class that can be used in your Core solution or in any
18
/// of your client applications. All settings are laid out the same exact way with getters
19
/// and setters.
20
/// </summary>
21
public static class UserSettings
22
{
23
    private static readonly Lazy<RDMPApplicationSettings> Implementation =
2✔
24
        new(static () => new RDMPApplicationSettings(), System.Threading.LazyThreadSafetyMode.ExecutionAndPublication);
4✔
25

26
    private static RDMPApplicationSettings AppSettings => Implementation.Value ??
30,244!
27
                                                          throw new NotImplementedException(
30,244✔
28
                                                              "Isolated Storage does not work in this environment...");
30,244✔
29

30
    public static bool ShowFlatLists
31
    {
NEW
32
        get => AppSettings.GetValueOrDefault("ShowFlatLists", false);
×
NEW
33
        set => AppSettings.AddOrUpdateValue("ShowFlatLists", value);
×
34
    }
35
    public static bool UseLocalFileSystem
36
    {
37
        get => AppSettings.GetValueOrDefault("UseLocalFileSystem", false);
×
38
        set => AppSettings.AddOrUpdateValue("UseLocalFileSystem", value);
×
39
    }
40

41
    public static string LocalFileSystemLocation 
42
    {
43
        get => AppSettings.GetValueOrDefault("LocalFileSystemLocation", Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "rdmp")); 
×
44
        set => AppSettings.AddOrUpdateValue("LocalFileSystemLocation", value);
×
45
    }
46

47
    /// <summary>
48
    /// Show a Yes/No confirmation dialog box when closing RDMP
49
    /// </summary>
50
    public static bool ConfirmApplicationExiting
51
    {
52
        get => AppSettings.GetValueOrDefault("ConfirmExit", true);
×
53
        set => AppSettings.AddOrUpdateValue("ConfirmExit", value);
×
54
    }
55

56
    /// <summary>
57
    /// True if the user has accepted the open source license agreements for RDMP and
58
    /// dependencies used in the software (i.e. MIT and GNU licenses).
59
    /// </summary>
60
    public static string LicenseAccepted
61
    {
62
        get => AppSettings.GetValueOrDefault("LicenseAccepted", null);
×
63
        set => AppSettings.AddOrUpdateValue("LicenseAccepted", value);
×
64
    }
65

66
    /// <summary>
67
    /// Automatically launch the RDMP Home Screen on launch of the RDMP application, regardless of the last window you viewed.
68
    /// </summary>
69
    public static bool ShowHomeOnStartup
70
    {
71
        get => AppSettings.GetValueOrDefault("ShowHomeOnStartup", false);
×
72
        set => AppSettings.AddOrUpdateValue("ShowHomeOnStartup", value);
×
73
    }
74

75
    /// <summary>
76
    /// If checked series included in graphs that have no values will not be displayed
77
    /// </summary>
78
    public static bool IncludeZeroSeriesInGraphs
79
    {
80
        get => AppSettings.GetValueOrDefault("IncludeZeroSeriesInGraphs", true);
2✔
81
        set => AppSettings.AddOrUpdateValue("IncludeZeroSeriesInGraphs", value);
3✔
82
    }
83

84
    /// <summary>
85
    /// Adds an additional behaviour when changing tabs that highlights the tree view
86
    /// collection that has that object visible in it.
87
    /// </summary>
88
    public static bool EmphasiseOnTabChanged
89
    {
90
        get => AppSettings.GetValueOrDefault("EmphasiseOnTabChanged", false);
×
91
        set => AppSettings.AddOrUpdateValue("EmphasiseOnTabChanged", value);
×
92
    }
93

94
    /// <summary>
95
    /// True to disable any auto starting tutorials
96
    /// </summary>
97
    public static bool DisableTutorials
98
    {
99
        get => AppSettings.GetValueOrDefault("DisableTutorials", false);
×
100
        set => AppSettings.AddOrUpdateValue("DisableTutorials", value);
×
101
    }
102

103
    /// <summary>
104
    /// The connection string to the main RDMP platform database
105
    /// </summary>
106
    public static string CatalogueConnectionString
107
    {
108
        get => AppSettings.GetValueOrDefault("CatalogueConnectionString", "");
×
109
        set => AppSettings.AddOrUpdateValue("CatalogueConnectionString", value);
×
110
    }
111

112
    /// <summary>
113
    /// The connection string to the data export RDMP platform database.  This database will contain
114
    /// references to objects in the <see cref="CatalogueConnectionString"/> database
115
    /// </summary>
116
    public static string DataExportConnectionString
117
    {
118
        get => AppSettings.GetValueOrDefault("DataExportConnectionString", "");
×
119
        set => AppSettings.AddOrUpdateValue("DataExportConnectionString", value);
×
120
    }
121

122
    /// <summary>
123
    /// The colour scheme and format for the RDMP gui client application
124
    /// </summary>
125
    public static string Theme
126
    {
127
        get => AppSettings.GetValueOrDefault("Theme", "ResearchDataManagementPlatform.Theme.MyVS2015BlueTheme");
×
128
        set => AppSettings.AddOrUpdateValue("Theme", value);
×
129
    }
130

131
    /// <summary>
132
    /// When selecting a result from the Find dialog the selected item is pinned in the corresponding view.
133
    /// </summary>
134
    public static bool FindShouldPin
135
    {
136
        get => AppSettings.GetValueOrDefault("FindShouldPin", true);
×
137
        set => AppSettings.AddOrUpdateValue("FindShouldPin", value);
×
138
    }
139

140
    /// <summary>
141
    /// Set the amount of time (in seconds) that the Create Database processes should wait before timing out.
142
    /// </summary>
143
    public static int CreateDatabaseTimeout
144
    {
145
        get => AppSettings.GetValueOrDefault("CreateDatabaseTimeout", 30);
8✔
146
        set => AppSettings.AddOrUpdateValue("CreateDatabaseTimeout",
×
147
            DiscoveredServerHelper.CreateDatabaseTimeoutInSeconds = Math.Max(value, 30));
×
148
    }
149

150
    /// <summary>
151
    /// Set the amount of time (in milliseconds) that tooltips should take to appear in the tree collection views (e.g. list of Catalogues etc)
152
    /// </summary>
153
    public static int TooltipAppearDelay
154
    {
155
        get => AppSettings.GetValueOrDefault("TooltipAppearDelay", 750);
10✔
156
        set => AppSettings.AddOrUpdateValue("TooltipAppearDelay", Math.Max(10, value));
×
157
    }
158

159
    /// <summary>
160
    /// When using the Find feature this option will automatically filter out any cohort set containers (i.e. UNION / INTERSECT / EXCEPT containers)
161
    /// </summary>
162
    public static bool ScoreZeroForCohortAggregateContainers
163
    {
164
        get => AppSettings.GetValueOrDefault("ScoreZeroForCohortAggregateContainers", false);
17✔
165
        set => AppSettings.AddOrUpdateValue("ScoreZeroForCohortAggregateContainers", value);
4✔
166
    }
167

168
    /// <summary>
169
    /// Create audit objects for specific objects/changes (e.g. changes to Catalogue Deprecated status).
170
    /// </summary>
171
    public static bool EnableCommits
172
    {
173
        get => AppSettings.GetValueOrDefault("EnableCommits", true);
19✔
174
        set => AppSettings.AddOrUpdateValue("EnableCommits", value);
×
175
    }
176

177

178
    public static bool PromptRenameOnCohortFilterChange
179
    {
180
        get => AppSettings.GetValueOrDefault("PromptRenameOnCohortFilterChange", true);
×
181
        set => AppSettings.AddOrUpdateValue("PromptRenameOnCohortFilterChange", value);
×
182
    }
183

184
    public static bool NewFindAndReplace
185
    {
186
        get => AppSettings.GetValueOrDefault("NewFindAndReplace", false);
×
187
        set => AppSettings.AddOrUpdateValue("NewFindAndReplace", value);
×
188
    }
189

190

191
    public static string ExtractionWebhookUsername
192
    {
193
        get => AppSettings.GetValueOrDefault("ExtractionWebhookUsername", null);
×
194
        set => AppSettings.AddOrUpdateValue("ExtractionWebhookUsername", value);
×
195
    }
196
    public static string ExtractionWebhookUrl
197
    {
198
        get => AppSettings.GetValueOrDefault("ExtractionWebhookUrl", null);
20✔
199
        set => AppSettings.AddOrUpdateValue("ExtractionWebhookUrl", value);
×
200
    }
201

202
    public static bool DefaultLogViewFlat
203
    {
NEW
204
        get => AppSettings.GetValueOrDefault("DefaultLogViewFlat", false);
×
NEW
205
        set => AppSettings.AddOrUpdateValue("DefaultLogViewFlat", value);
×
206
    }
207

208
    #region Catalogue flag visibility settings
209

210
    public static bool ShowInternalCatalogues
211
    {
212
        get => AppSettings.GetValueOrDefault("ShowInternalCatalogues", true);
12✔
213
        set => AppSettings.AddOrUpdateValue("ShowInternalCatalogues", value);
16✔
214
    }
215

216
    public static bool ShowDeprecatedCatalogues
217
    {
218
        get => AppSettings.GetValueOrDefault("ShowDeprecatedCatalogues", true);
12✔
219
        set => AppSettings.AddOrUpdateValue("ShowDeprecatedCatalogues", value);
16✔
220
    }
221

222
    public static bool ShowProjectSpecificCatalogues
223
    {
224
        get => AppSettings.GetValueOrDefault("ShowProjectSpecificCatalogues", true);
12✔
225
        set => AppSettings.AddOrUpdateValue("ShowProjectSpecificCatalogues", value);
16✔
226
    }
227

228
    /// <summary>
229
    /// True to apply theme changes to context menus and tool strips.
230
    /// </summary>
231
    public static bool ApplyThemeToMenus
232
    {
233
        get => AppSettings.GetValueOrDefault("ApplyThemeToMenus", true);
×
234
        set => AppSettings.AddOrUpdateValue("ApplyThemeToMenus", value);
×
235
    }
236

237
    /// <summary>
238
    /// Determines line wrapping in multi line editor controls when lines stretch off the control client area
239
    /// </summary>
240
    public static int WrapMode
241
    {
242
        get => AppSettings.GetValueOrDefault("WrapMode", 0);
20✔
243
        set => AppSettings.AddOrUpdateValue("WrapMode", value);
×
244
    }
245

246
    /// <summary>
247
    /// <para>Base colours used for generating heatmaps in HEX format.  Colour intensity will vary
248
    /// from the first color to the second.</para>
249
    /// 
250
    /// <para>The first colour represents the lowest values and should
251
    /// typically be darker than the second which represents high values.</para>
252
    /// </summary>
253
    public static string HeatMapColours
254
    {
255
        get => AppSettings.GetValueOrDefault("HeatMapColours", null);
×
256
        set => AppSettings.AddOrUpdateValue("HeatMapColours", value);
×
257
    }
258

259
    /// <summary>
260
    /// <para>Adds a 5 second delay after startup</para>
261
    /// <para>Use this option to add a delay that can be helpful for troubleshooting issues on RDMP startup. </para>
262
    /// </summary>
263
    public static bool Wait5SecondsAfterStartupUI
264
    {
265
        get => AppSettings.GetValueOrDefault("Wait5SecondsAfterStartupUI", true);
5✔
266
        set => AppSettings.AddOrUpdateValue("Wait5SecondsAfterStartupUI", value);
6✔
267
    }
268

269
    /// <summary>
270
    /// True to show the cohort creation wizard when creating new cohorts.  False to create
271
    /// a default empty configuration.
272
    /// </summary>
273
    public static bool ShowCohortWizard
274
    {
275
        get => AppSettings.GetValueOrDefault("ShowCohortWizard", false);
×
276
        set => AppSettings.AddOrUpdateValue("ShowCohortWizard", value);
×
277
    }
278

279
    /// <summary>
280
    /// <para>True to enable "stirct validation" for containers in Cohort Builder Queries.</para>
281
    ///
282
    /// <para>Will not allow empty sets, or sets that only have one item.</para>
283
    /// </summary>
284
    public static bool StrictValidationForCohortBuilderContainers
285
    {
286
        get => AppSettings.GetValueOrDefault("StrictValidationForCohortBuilderContainers", true);
19✔
287
        set => AppSettings.AddOrUpdateValue("StrictValidationForCohortBuilderContainers", value);
×
288
    }
289

290
    /// <summary>
291
    /// Changes the behaviour of mouse double clicks in tree views.  When enabled double
292
    /// click expands nodes instead of opening the double clicked object (the default behaviour).
293
    /// </summary>
294
    public static bool DoubleClickToExpand
295
    {
296
        get => AppSettings.GetValueOrDefault("DoubleClickToExpand", false);
×
297
        set => AppSettings.AddOrUpdateValue("DoubleClickToExpand", value);
×
298
    }
299

300
    public static string RecentHistory
301
    {
302
        get => AppSettings.GetValueOrDefault("RecentHistory", "");
30✔
303
        set => AppSettings.AddOrUpdateValue("RecentHistory", value);
9✔
304
    }
305

306
    /// <summary>
307
    /// <para>When enabled RDMP will record certain performance related metrics (how long refresh takes etc).</para>
308
    /// <para>These figures are completely internal to the application and are not transmitted anywhere.You can view the results in the toolbar.</para>
309
    /// </summary>
310
    public static bool DebugPerformance
311
    {
312
        get => AppSettings.GetValueOrDefault("DebugPerformance", false);
26,709✔
313
        set => AppSettings.AddOrUpdateValue("DebugPerformance", value);
×
314
    }
315

316
    /// <summary>
317
    /// <para>Automatically resize columns in the RDMP user interface with fit contents.</para>
318
    /// <para>Can be disabled if problems arise with column content or header visibility</para>
319
    /// </summary>
320
    public static bool AutoResizeColumns
321
    {
322
        get => AppSettings.GetValueOrDefault("AutoResizeColumns", true);
15✔
323
        set => AppSettings.AddOrUpdateValue("AutoResizeColumns", value);
×
324
    }
325

326

327
    /// <summary>
328
    /// Show a popup confirmation dialog at the end of a pipeline completing execution
329
    /// </summary>
330
    public static bool ShowPipelineCompletedPopup
331
    {
332
        get => AppSettings.GetValueOrDefault("ShowPipelineCompletedPopup", true);
×
333
        set => AppSettings.AddOrUpdateValue("ShowPipelineCompletedPopup", value);
×
334
    }
335

336
    /// <summary>
337
    /// <para>Enable to skip the checking stage of pipeline source component CohortIdentificationConfigurationSource.</para>
338
    /// <para>In slow computer, or contesest databases this can take a while to compile. This option lets you disable it.</para>
339
    /// </summary>
340
    public static bool SkipCohortBuilderValidationOnCommit
341
    {
342
        get => AppSettings.GetValueOrDefault("SkipCohortBuilderValidationOnCommit", false);
×
343
        set => AppSettings.AddOrUpdateValue("SkipCohortBuilderValidationOnCommit", value);
×
344
    }
345

346
    public static string ConsoleColorScheme
347
    {
348
        get => AppSettings.GetValueOrDefault("ConsoleColorScheme", "default");
×
349
        set => AppSettings.AddOrUpdateValue("ConsoleColorScheme", value);
×
350
    }
351

352
    /// <summary>
353
    /// <para>When true RDMP log viewer will hide table load audits where no inserts/updates/deletes were applied.</para>
354
    /// <para>This is helpful if a load targets many tables not all of which will be updated in a given run</para>
355
    /// </summary>
356
    public static bool HideEmptyTableLoadRunAudits
357
    {
358
        get => AppSettings.GetValueOrDefault("HideEmptyTableLoadRunAudits", false);
×
359
        set => AppSettings.AddOrUpdateValue("HideEmptyTableLoadRunAudits", value);
×
360
    }
361

362
    /// <summary>
363
    /// <para>Enables additional Find filters for objects that are in:</para>
364
    /// <para>Cold Storage, Internal, Deprecated, Project Specific and Non Extractable</para>
365
    /// </summary>
366
    public static bool AdvancedFindFilters
367
    {
368
        get => AppSettings.GetValueOrDefault("AdvancedFindFilters", false);
×
369
        set => AppSettings.AddOrUpdateValue("AdvancedFindFilters", value);
×
370
    }
371

372
    /// <summary>
373
    /// Timeout in seconds to allow for creating archive trigger, index etc
374
    /// </summary>
375
    public static int ArchiveTriggerTimeout
376
    {
377
        get => AppSettings.GetValueOrDefault("ArchiveTriggerTimeout", 30);
673✔
378
        set => AppSettings.AddOrUpdateValue("ArchiveTriggerTimeout", value);
×
379
    }
380

381
    public static int FindWindowWidth
382
    {
383
        get => AppSettings.GetValueOrDefault("FindWindowWidth", 730);
×
384
        set => AppSettings.AddOrUpdateValue("FindWindowWidth", value);
×
385
    }
386

387
    public static int FindWindowHeight
388
    {
389
        get => AppSettings.GetValueOrDefault("FindWindowHeight", 400);
×
390
        set => AppSettings.AddOrUpdateValue("FindWindowHeight", value);
×
391
    }
392

393
    /// <summary>
394
    /// Enable to refresh only objects which you make changes to instead of
395
    /// fetching all database changes since your last edit.  This improves
396
    /// performance in large RDMP deployments with thousands of Projects configured.
397
    /// </summary>
398
    public static bool SelectiveRefresh
399
    {
400
        get => AppSettings.GetValueOrDefault("SelectiveRefresh", false);
253✔
401
        set => AppSettings.AddOrUpdateValue("SelectiveRefresh", value);
×
402
    }
403

404
    /// <summary>
405
    /// Set to true to always attempt to force joins on all tables under a Catalogue
406
    /// when building queries (in Cohort Builder).  This makes it impossible to untick
407
    /// force joins.
408
    /// </summary>
409
    public static bool AlwaysJoinEverything
410
    {
411
        get => AppSettings.GetValueOrDefault("AlwaysJoinEverything", false);
341✔
412
        set => AppSettings.AddOrUpdateValue("AlwaysJoinEverything", value);
×
413
    }
414

415
    /// <summary>
416
    /// <para>
417
    /// Determines whether queries are automatically sent and results displayed in
418
    /// data tabs in RDMP (e.g. View top 100 etc).  Enable to automatically send the
419
    /// queries.  Disable to show the SQL but require the user to press F5 or click Run
420
    /// to execute.
421
    /// </para>
422
    /// </summary>
423
    public static bool AutoRunSqlQueries
424
    {
425
        get => AppSettings.GetValueOrDefault("AutoRunSqlQueries", false);
×
426
        set => AppSettings.AddOrUpdateValue("AutoRunSqlQueries", value);
×
427
    }
428

429
    /// <summary>
430
    /// Enable to automatically expand the tree when opening or creating cohorts in
431
    /// Cohort Builder
432
    /// </summary>
433
    public static bool ExpandAllInCohortBuilder
434
    {
435
        get => AppSettings.GetValueOrDefault("ExpandAllInCohortBuilder", true);
1✔
436
        set => AppSettings.AddOrUpdateValue("ExpandAllInCohortBuilder", value);
×
437
    }
438

439
    /// <summary>
440
    /// True to show ProjectSpecific Catalogues' columns in extraction configuration user interface
441
    /// </summary>
442
    public static bool ShowProjectSpecificColumns
443
    {
444
        get => AppSettings.GetValueOrDefault("ShowProjectSpecificColumns", true);
9✔
445
        set => AppSettings.AddOrUpdateValue("ShowProjectSpecificColumns", value);
×
446
    }
447

448
    /// <summary>
449
    /// <para>When generating an aggregate graph, use the column alias instead of the select sql.  For example
450
    /// when you have the select column 'SELECT YEAR(dt) as myYear' then the GROUP BY will default to
451
    /// 'GROUP BY YEAR(dt)'.  Setting this property to true will instead use 'GROUP BY myYear'.  Typically
452
    /// this only works in MySql but it is not universally supported by all MySql versions and server settings
453
    /// </para>
454
    /// <para>Defaults to false.</para>
455
    /// </summary>
456
    public static bool UseAliasInsteadOfTransformInGroupByAggregateGraphs
457
    {
458
        get => AppSettings.GetValueOrDefault("ShowProjectSpecificColumns", false);
149✔
459
        set => AppSettings.AddOrUpdateValue("ShowProjectSpecificColumns", value);
4✔
460
    }
461

462
    #endregion
463

464
    /// <summary>
465
    /// Returns the error level the user wants for <paramref name="errorCode"/> or <see cref="ErrorCode.DefaultTreatment"/> (if no custom
466
    /// reporting level has been set up for this error code).
467
    /// </summary>
468
    /// <param name="errorCode"></param>
469
    /// <returns></returns>
470
    public static CheckResult GetErrorReportingLevelFor(ErrorCode errorCode)
471
    {
472
        var result = AppSettings.GetValueOrDefault($"EC_{errorCode.Code}", errorCode.DefaultTreatment.ToString());
16✔
473

474
        return Enum.Parse<CheckResult>(result);
16✔
475
    }
476

477
    /// <summary>
478
    /// Changes the reporting level of the given error to <paramref name="value"/> instead of its <see cref="ErrorCode.DefaultTreatment"/>
479
    /// </summary>
480
    /// <param name="errorCode"></param>
481
    /// <param name="value"></param>
482
    public static void SetErrorReportingLevelFor(ErrorCode errorCode, CheckResult value)
483
    {
484
        AppSettings.AddOrUpdateValue($"EC_{errorCode.Code}", value.ToString());
8✔
485
    }
8✔
486

487
    public static bool GetTutorialDone(Guid tutorialGuid) =>
488
        tutorialGuid != Guid.Empty && AppSettings.GetValueOrDefault($"T_{tutorialGuid:N}", false);
×
489

490
    public static void SetTutorialDone(Guid tutorialGuid, bool value)
491
    {
492
        if (tutorialGuid == Guid.Empty)
×
493
            return;
×
494

495
        AppSettings.AddOrUpdateValue($"T_{tutorialGuid:N}", value);
×
496
    }
×
497

498
    public static void SetColumnWidth(Guid columnGuid, int width)
499
    {
500
        if (columnGuid == Guid.Empty)
1,566!
501
            return;
×
502
        SetColumnWidth(columnGuid.ToString("N"), width);
1,566✔
503
    }
1,566✔
504

505
    public static void SetColumnWidth(string colIdentifier, int width)
506
    {
507
        AppSettings.AddOrUpdateValue($"ColW_{colIdentifier}", width);
1,566✔
508
    }
1,566✔
509

510
    public static void SetColumnVisible(Guid columnGuid, bool visible)
511
    {
512
        if (columnGuid == Guid.Empty)
×
513
            return;
×
514

515
        SetColumnVisible(columnGuid.ToString("N"), visible);
×
516
    }
×
517

518
    public static void SetColumnVisible(string colIdentifier, bool visible)
519
    {
520
        AppSettings.AddOrUpdateValue($"ColV_{colIdentifier}", visible);
×
521
    }
×
522

523
    public static int GetColumnWidth(Guid columnGuid) =>
524
        columnGuid == Guid.Empty ? 100 : GetColumnWidth(columnGuid.ToString("N"));
64!
525

526
    public static int GetColumnWidth(string colIdentifier) =>
527
        AppSettings.GetValueOrDefault($"ColW_{colIdentifier}", 100);
64✔
528

529
    public static bool GetColumnVisible(Guid columnGuid) =>
530
        columnGuid == Guid.Empty || GetColumnVisible(columnGuid.ToString("N"));
64!
531

532
    public static bool GetColumnVisible(string colIdentifier) =>
533
        AppSettings.GetValueOrDefault($"ColV_{colIdentifier}", true);
64✔
534

535
    public static string[] GetHistoryForControl(Guid controlGuid)
536
    {
537
        return AppSettings.GetValueOrDefault($"A_{controlGuid:N}", "").Split(new[] { "#!#" }, StringSplitOptions.None);
11✔
538
    }
539

540
    public static void SetHistoryForControl(Guid controlGuid, IEnumerable<string> history)
541
    {
542
        AppSettings.AddOrUpdateValue($"A_{controlGuid:N}", string.Join("#!#", history));
102✔
543
    }
102✔
544

545
    public static void AddHistoryForControl(Guid guid, string v)
546
    {
547
        if (string.IsNullOrWhiteSpace(v))
×
548
            return;
×
549

550
        var l = GetHistoryForControl(guid).ToList();
×
551

552
        if (l.Contains(v))
×
553
            return;
×
554

555
        l.Add(v);
×
556

557
        SetHistoryForControl(guid, l.Distinct().ToList());
×
558
    }
×
559

560
    public static Tuple<string, bool> GetLastColumnSortForCollection(Guid controlGuid)
561
    {
562
        lock (_oLockUserSettings)
1✔
563
        {
564
            var value = AppSettings.GetValueOrDefault($"LastColumnSort_{controlGuid:N}", null);
1✔
565

566
            //if we don't have a value
567
            if (string.IsNullOrWhiteSpace(value))
1!
568
                return null;
1✔
569

570
            var args = value.Split(new[] { "#!#" }, StringSplitOptions.RemoveEmptyEntries);
×
571

572
            //or it doesn't split properly
573
            if (args.Length != 2)
×
574
                return null;
×
575

576
            //or either element is null
577
            if (string.IsNullOrWhiteSpace(args[0]) || string.IsNullOrWhiteSpace(args[1]))
×
578
                return null;
×
579

580
            if (bool.TryParse(args[1], out var ascending))
×
581
                return Tuple.Create(args[0], ascending);
×
582
        }
×
583

584
        return null;
×
585
    }
1✔
586

587
    private static object _oLockUserSettings = new();
2✔
588

589
    public static void SetLastColumnSortForCollection(Guid controlGuid, string columnName, bool ascending)
590
    {
591
        lock (_oLockUserSettings)
1✔
592
        {
593
            AppSettings.AddOrUpdateValue($"LastColumnSort_{controlGuid:N}", $"{columnName}#!#{ascending}");
1✔
594
        }
1✔
595
    }
1✔
596

597

598
    /// <summary>
599
    /// Returns the last known manually set splitter distance for the Control who is
600
    /// identified by <paramref name="controlGuid"/> or -1 if none set yet
601
    /// </summary>
602
    /// <param name="controlGuid"></param>
603
    /// <returns></returns>
604
    public static int GetSplitterDistance(Guid controlGuid) =>
605
        AppSettings.GetValueOrDefault($"SplitterDistance_{controlGuid:N}", -1);
×
606

607
    /// <summary>
608
    /// Records that the user has manually changed the splitter distance of the Control
609
    /// who is identified by <paramref name="controlGuid"/>
610
    /// </summary>
611
    /// <param name="controlGuid"></param>
612
    /// <param name="splitterDistance"></param>
613
    public static void SetSplitterDistance(Guid controlGuid, int splitterDistance)
614
    {
615
        lock (_oLockUserSettings)
×
616
        {
617
            AppSettings.AddOrUpdateValue($"SplitterDistance_{controlGuid:N}", splitterDistance);
×
618
        }
×
619
    }
×
620

621
    public static void ClearUserSettings()
622
    {
623
        AppSettings.Clear();
1✔
624
    }
1✔
625
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc