KiCad PCB EDA Suite
Loading...
Searching...
No Matches
panel_common_settings.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2018-2022 KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
25
26#include <advanced_config.h>
27#include <bitmaps.h>
28#include <dialog_shim.h>
29#include <dpi_scaling_common.h>
30#include <kiface_base.h>
31#include <kiplatform/ui.h>
32#include <pgm_base.h>
33#include <id.h>
38#include <wx/filedlg.h>
39
40/*
41 * What follows is a whole lot of ugly to handle various platform GUI deficiences with respect
42 * to light/dark mode, DPI scaling, and other foibles.
43 *
44 * Ugly as it all is, it does improve our usability on various platforms.
45 */
46
48 : PANEL_COMMON_SETTINGS_BASE( aParent ),
49 m_iconScaleLabel( nullptr ),
50 m_iconScaleSlider( nullptr ),
51 m_iconScaleAuto( nullptr ),
52 m_last_scale( -1 )
53{
54 /*
55 * Cairo canvas doesn't work on Mac, so no need for fallback anti-aliasing options
56 */
57#ifdef __WXMAC__
58 m_antialiasingFallback->Show( false );
59 m_antialiasingFallbackLabel->Show( false );
60#endif
61
62 m_textEditorBtn->SetBitmap( KiBitmap( BITMAPS::small_folder ) );
63 m_pdfViewerBtn->SetBitmap( KiBitmap( BITMAPS::small_folder ) );
64
65 /*
66 * Automatic dark mode detection works fine on Mac, so no need for the explicit options.
67 */
68#ifdef __WXMAC__
69 m_stIconTheme->Show( false );
70 m_rbIconThemeLight->Show( false );
71 m_rbIconThemeDark->Show( false );
72 m_rbIconThemeAuto->Show( false );
73#endif
74
75 /*
76 * Automatic icon scaling works fine on Mac. It works mostly fine on MSW, but perhaps not
77 * uniformly enough to exclude the explicit controls there.
78 */
79#if defined( __WXGTK__ ) || defined( __WXMSW__ )
80 // Sadly wxSlider is poorly implemented and adds its legends as sibling windows (so that
81 // showing/hiding the control doesn't work). So we have to create it conditionally.
82 wxGridBagSizer* gb = m_gbUserInterface;
83
84 const int row_num = 0;
85 m_iconScaleLabel = new wxStaticText( this, wxID_ANY, _( "Icon scale:" ) );
86 m_iconScaleLabel->Wrap( -1 );
87 gb->Add( m_iconScaleLabel, wxGBPosition( row_num, 0 ),
88 wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
89
90 m_iconScaleSlider = new STEPPED_SLIDER( this, wxID_ANY, 100, 50, 275, wxDefaultPosition,
91 wxDefaultSize, wxSL_HORIZONTAL|wxSL_VALUE_LABEL );
93 gb->Add( m_iconScaleSlider, wxGBPosition( row_num, 1 ), wxGBSpan( 1, 1 ), wxEXPAND|wxBOTTOM, 5 );
94
95 m_iconScaleAuto = new wxCheckBox( this, wxID_ANY, _( "Automatic" ) );
96 gb->Add( m_iconScaleAuto, wxGBPosition( row_num, 2 ),
97 wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxLEFT, 15 );
98#endif
99
100 /*
101 * Automatic canvas scaling works fine on all supported platforms, so manual scaling is disabled
102 */
103 if( ADVANCED_CFG::GetCfg().m_AllowManualCanvasScale )
104 {
105 static constexpr int dpi_scaling_precision = 1;
106 static constexpr double dpi_scaling_increment = 0.5;
107
110 m_canvasScaleCtrl->SetDigits( dpi_scaling_precision );
111 m_canvasScaleCtrl->SetIncrement( dpi_scaling_increment );
113
114 m_canvasScaleCtrl->SetToolTip(
115 _( "Set the scale for the canvas."
116 "\n\n"
117 "On high-DPI displays on some platforms, KiCad cannot determine the "
118 "scaling factor. In this case you may need to set this to a value to "
119 "match your system's DPI scaling. 2.0 is a common value. "
120 "\n\n"
121 "If this does not match the system DPI scaling, the canvas will "
122 "not match the window size and cursor position." ) );
123
124 m_canvasScaleAuto->SetToolTip(
125 _( "Use an automatic value for the canvas scale."
126 "\n\n"
127 "On some platforms, the automatic value is incorrect and should be "
128 "set manually." ) );
129 }
130 else
131 {
132 m_staticTextCanvasScale->Show( false );
133 m_canvasScaleCtrl->Show( false );
134 m_canvasScaleCtrl = nullptr;
135 m_canvasScaleAuto->Show( false );
136 }
137
138 // Hide the option of icons in menus for platforms that do not support them
140
141 m_scaleFonts->Show( false );
142 m_fontScalingHelp->Show( false );
143
145 {
146 m_iconScaleSlider->Connect( wxEVT_SCROLL_TOP,
147 wxScrollEventHandler( PANEL_COMMON_SETTINGS::OnScaleSlider ),
148 nullptr, this );
149 m_iconScaleSlider->Connect( wxEVT_SCROLL_BOTTOM,
150 wxScrollEventHandler( PANEL_COMMON_SETTINGS::OnScaleSlider ),
151 nullptr, this );
152 m_iconScaleSlider->Connect( wxEVT_SCROLL_LINEUP,
153 wxScrollEventHandler( PANEL_COMMON_SETTINGS::OnScaleSlider ),
154 nullptr, this );
155 m_iconScaleSlider->Connect( wxEVT_SCROLL_LINEDOWN,
156 wxScrollEventHandler( PANEL_COMMON_SETTINGS::OnScaleSlider ),
157 nullptr, this );
158 m_iconScaleSlider->Connect( wxEVT_SCROLL_PAGEUP,
159 wxScrollEventHandler( PANEL_COMMON_SETTINGS::OnScaleSlider ),
160 nullptr, this );
161 m_iconScaleSlider->Connect( wxEVT_SCROLL_PAGEDOWN,
162 wxScrollEventHandler( PANEL_COMMON_SETTINGS::OnScaleSlider ),
163 nullptr, this );
164 m_iconScaleSlider->Connect( wxEVT_SCROLL_THUMBTRACK,
165 wxScrollEventHandler( PANEL_COMMON_SETTINGS::OnScaleSlider ),
166 nullptr, this );
167 m_iconScaleSlider->Connect( wxEVT_SCROLL_THUMBRELEASE,
168 wxScrollEventHandler( PANEL_COMMON_SETTINGS::OnScaleSlider ),
169 nullptr, this );
170 m_iconScaleSlider->Connect( wxEVT_SCROLL_CHANGED,
171 wxScrollEventHandler( PANEL_COMMON_SETTINGS::OnScaleSlider ),
172 nullptr, this );
173 m_iconScaleAuto->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED,
174 wxCommandEventHandler( PANEL_COMMON_SETTINGS::OnIconScaleAuto ),
175 nullptr, this );
176 }
177
179 {
180 m_canvasScaleCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED,
181 wxCommandEventHandler( PANEL_COMMON_SETTINGS::OnCanvasScaleChange ),
182 nullptr, this );
183 }
184
185 wxSize minSize = m_highContrastCtrl->GetMinSize();
186 int minWidth = m_highContrastCtrl->GetTextExtent( wxT( "XXX.XXX" ) ).GetWidth();
187
188 m_highContrastCtrl->SetMinSize( wxSize( minWidth, minSize.GetHeight() ) );
189}
190
191
193{
195 {
196 m_iconScaleSlider->Disconnect( wxEVT_SCROLL_TOP,
197 wxScrollEventHandler( PANEL_COMMON_SETTINGS::OnScaleSlider ),
198 nullptr, this );
199 m_iconScaleSlider->Disconnect( wxEVT_SCROLL_BOTTOM,
200 wxScrollEventHandler( PANEL_COMMON_SETTINGS::OnScaleSlider ),
201 nullptr, this );
202 m_iconScaleSlider->Disconnect( wxEVT_SCROLL_LINEUP,
203 wxScrollEventHandler( PANEL_COMMON_SETTINGS::OnScaleSlider ),
204 nullptr, this );
205 m_iconScaleSlider->Disconnect( wxEVT_SCROLL_LINEDOWN,
206 wxScrollEventHandler( PANEL_COMMON_SETTINGS::OnScaleSlider ),
207 nullptr, this );
208 m_iconScaleSlider->Disconnect( wxEVT_SCROLL_PAGEUP,
209 wxScrollEventHandler( PANEL_COMMON_SETTINGS::OnScaleSlider ),
210 nullptr, this );
211 m_iconScaleSlider->Disconnect( wxEVT_SCROLL_PAGEDOWN,
212 wxScrollEventHandler( PANEL_COMMON_SETTINGS::OnScaleSlider ),
213 nullptr, this );
214 m_iconScaleSlider->Disconnect( wxEVT_SCROLL_THUMBTRACK,
215 wxScrollEventHandler( PANEL_COMMON_SETTINGS::OnScaleSlider ),
216 nullptr, this );
217 m_iconScaleSlider->Disconnect( wxEVT_SCROLL_THUMBRELEASE,
218 wxScrollEventHandler( PANEL_COMMON_SETTINGS::OnScaleSlider ),
219 nullptr, this );
220 m_iconScaleSlider->Disconnect( wxEVT_SCROLL_CHANGED,
221 wxScrollEventHandler( PANEL_COMMON_SETTINGS::OnScaleSlider ),
222 nullptr, this );
223 m_iconScaleAuto->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED,
224 wxCommandEventHandler( PANEL_COMMON_SETTINGS::OnIconScaleAuto ),
225 nullptr, this );
226 }
227
229 {
230 m_canvasScaleCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED,
231 wxCommandEventHandler( PANEL_COMMON_SETTINGS::OnCanvasScaleChange ),
232 nullptr, this );
233 }
234}
235
236
238{
239 COMMON_SETTINGS* commonSettings = Pgm().GetCommonSettings();
240
241 applySettingsToPanel( *commonSettings );
242
243 // TODO(JE) Move these into COMMON_SETTINGS probably
244 m_textEditorPath->SetValue( Pgm().GetTextEditor( false ) );
245 m_defaultPDFViewer->SetValue( Pgm().UseSystemPdfBrowser() );
246 m_otherPDFViewer->SetValue( !Pgm().UseSystemPdfBrowser() );
247 m_PDFViewerPath->SetValue( Pgm().GetPdfBrowserName() );
249
250 return true;
251}
252
253
255{
256 COMMON_SETTINGS* commonSettings = Pgm().GetCommonSettings();
257
258 commonSettings->m_System.autosave_interval = m_SaveTime->GetValue() * 60;
259 commonSettings->m_System.file_history_size = m_fileHistorySize->GetValue();
260 commonSettings->m_System.clear_3d_cache_interval = m_Clear3DCacheFilesOlder->GetValue();
261
262 commonSettings->m_Graphics.opengl_aa_mode = m_antialiasing->GetSelection();
263 commonSettings->m_Graphics.cairo_aa_mode = m_antialiasingFallback->GetSelection();
264
266 {
267 int scale_fourths = m_iconScaleAuto->GetValue() ? -1 : m_iconScaleSlider->GetValue() / 25;
268 commonSettings->m_Appearance.icon_scale = scale_fourths;
269 }
270
272 {
273 DPI_SCALING_COMMON dpi( commonSettings, this );
274 dpi.SetDpiConfig( m_canvasScaleAuto->GetValue(), m_canvasScaleCtrl->GetValue() );
275 }
276
277 if( m_rbIconThemeLight->GetValue() )
278 commonSettings->m_Appearance.icon_theme = ICON_THEME::LIGHT;
279 else if( m_rbIconThemeDark->GetValue() )
280 commonSettings->m_Appearance.icon_theme = ICON_THEME::DARK;
281 else if( m_rbIconThemeAuto->GetValue() )
282 commonSettings->m_Appearance.icon_theme = ICON_THEME::AUTO;
283
284 commonSettings->m_Appearance.use_icons_in_menus = m_checkBoxIconsInMenus->GetValue();
285 commonSettings->m_Appearance.apply_icon_scale_to_fonts = m_scaleFonts->GetValue();
286
287 commonSettings->m_Appearance.show_scrollbars = m_showScrollbars->GetValue();
288
289 double dimmingPercent = 80;
290 m_highContrastCtrl->GetValue().ToDouble( &dimmingPercent );
291 commonSettings->m_Appearance.hicontrast_dimming_factor = dimmingPercent / 100.0f;
292
293 commonSettings->m_Input.focus_follow_sch_pcb = m_focusFollowSchPcb->GetValue();
294 commonSettings->m_Input.hotkey_feedback = m_hotkeyFeedback->GetValue();
295 commonSettings->m_Input.immediate_actions = !m_NonImmediateActions->GetValue();
296 commonSettings->m_Input.warp_mouse_on_move = m_warpMouseOnMove->GetValue();
297
298 commonSettings->m_Backup.enabled = m_cbBackupEnabled->GetValue();
299 commonSettings->m_Backup.backup_on_autosave = m_cbBackupAutosave->GetValue();
300 commonSettings->m_Backup.limit_total_files = m_backupLimitTotalFiles->GetValue();
301 commonSettings->m_Backup.limit_daily_files = m_backupLimitDailyFiles->GetValue();
302 commonSettings->m_Backup.min_interval = m_backupMinInterval->GetValue() * 60;
303 commonSettings->m_Backup.limit_total_size = m_backupLimitTotalSize->GetValue() * 1024 * 1024;
304
305 commonSettings->m_Session.remember_open_files = m_cbRememberOpenFiles->GetValue();
306
307 Pgm().SetTextEditor( m_textEditorPath->GetValue());
308
309 Pgm().SetPdfBrowserName( m_PDFViewerPath->GetValue() );
310 Pgm().ForceSystemPdfBrowser( m_defaultPDFViewer->GetValue() );
311 Pgm().WritePdfBrowserInfos();
312
313 Pgm().GetSettingsManager().Save( commonSettings );
314
315 return true;
316}
317
318
320{
321 COMMON_SETTINGS defaultSettings;
322
323 defaultSettings.ResetToDefaults();
324
325 applySettingsToPanel( defaultSettings );
326
327 // TODO(JE) Move these into COMMON_SETTINGS probably
328 m_textEditorPath->SetValue( defaultSettings.m_System.text_editor );
329 m_defaultPDFViewer->SetValue( defaultSettings.m_System.use_system_pdf_viewer );
330 m_otherPDFViewer->SetValue( !defaultSettings.m_System.use_system_pdf_viewer );
331 m_PDFViewerPath->SetValue( defaultSettings.m_System.pdf_viewer_name );
333}
334
335
337{
338 int timevalue = aSettings.m_System.autosave_interval;
339 wxString msg;
340
341 msg << timevalue / 60;
342 m_SaveTime->SetValue( msg );
343
344 m_fileHistorySize->SetValue( aSettings.m_System.file_history_size );
345
346 m_antialiasing->SetSelection( aSettings.m_Graphics.opengl_aa_mode );
347 m_antialiasingFallback->SetSelection( aSettings.m_Graphics.cairo_aa_mode );
348
350
352 {
353 int icon_scale_fourths = aSettings.m_Appearance.icon_scale;
354
355 if( icon_scale_fourths <= 0 )
356 {
357 m_iconScaleAuto->SetValue( true );
358 m_iconScaleSlider->SetValue( 25 * KiIconScale( GetParent() ) );
359 }
360 else
361 {
362 m_iconScaleAuto->SetValue( false );
363 m_iconScaleSlider->SetValue( icon_scale_fourths * 25 );
364 }
365 }
366
368 {
369 const DPI_SCALING_COMMON dpi( &aSettings, this );
370 m_canvasScaleCtrl->SetValue( dpi.GetScaleFactor() );
371 m_canvasScaleAuto->SetValue( dpi.GetCanvasIsAutoScaled() );
372 }
373
374 switch( aSettings.m_Appearance.icon_theme )
375 {
376 case ICON_THEME::LIGHT: m_rbIconThemeLight->SetValue( true ); break;
377 case ICON_THEME::DARK: m_rbIconThemeDark->SetValue( true ); break;
378 case ICON_THEME::AUTO: m_rbIconThemeAuto->SetValue( true ); break;
379 }
380
383
384 double dimmingPercent = aSettings.m_Appearance.hicontrast_dimming_factor * 100.0f;
385 m_highContrastCtrl->SetValue( wxString::Format( "%.0f", dimmingPercent ) );
386
387 m_focusFollowSchPcb->SetValue( aSettings.m_Input.focus_follow_sch_pcb );
388 m_hotkeyFeedback->SetValue( aSettings.m_Input.hotkey_feedback );
389 m_warpMouseOnMove->SetValue( aSettings.m_Input.warp_mouse_on_move );
390 m_NonImmediateActions->SetValue( !aSettings.m_Input.immediate_actions );
391
393
394 m_cbBackupEnabled->SetValue( aSettings.m_Backup.enabled );
395 m_cbBackupAutosave->SetValue( aSettings.m_Backup.backup_on_autosave );
398 m_backupMinInterval->SetValue( aSettings.m_Backup.min_interval / 60 );
399 m_backupLimitTotalSize->SetValue( aSettings.m_Backup.limit_total_size / ( 1024 * 1024 ) );
400
401 m_showScrollbars->SetValue( aSettings.m_Appearance.show_scrollbars );
402}
403
404
405void PANEL_COMMON_SETTINGS::OnScaleSlider( wxScrollEvent& aEvent )
406{
407 m_iconScaleAuto->SetValue( false );
408 aEvent.Skip();
409}
410
411
412void PANEL_COMMON_SETTINGS::OnIconScaleAuto( wxCommandEvent& aEvent )
413{
415 {
416 if( m_iconScaleAuto->GetValue() )
417 {
418 m_last_scale = m_iconScaleAuto->GetValue();
419 m_iconScaleSlider->SetValue( 25 * KiIconScale( GetParent() ) );
420 }
421 else
422 {
423 if( m_last_scale >= 0 )
424 m_iconScaleSlider->SetValue( m_last_scale );
425 }
426 }
427}
428
429
430void PANEL_COMMON_SETTINGS::OnCanvasScaleChange( wxCommandEvent& aEvent )
431{
432 m_canvasScaleAuto->SetValue( false );
433}
434
435
436void PANEL_COMMON_SETTINGS::OnCanvasScaleAuto( wxCommandEvent& aEvent )
437{
438 const bool automatic = m_canvasScaleAuto->GetValue();
439
440 if( automatic && m_canvasScaleCtrl )
441 {
442 // set the scale to the auto value, without consulting the config
443 DPI_SCALING_COMMON dpi( nullptr, this );
444
445 // update the field (no events sent)
446 m_canvasScaleCtrl->SetValue( dpi.GetScaleFactor() );
447 }
448}
449
450
451void PANEL_COMMON_SETTINGS::OnTextEditorClick( wxCommandEvent& event )
452{
453 // Ask the user to select a new editor, but suggest the current one as the default.
454 wxString editorname = Pgm().AskUserForPreferredEditor( m_textEditorPath->GetValue() );
455
456 // If we have a new editor name request it to be copied to m_text_editor and saved
457 // to the preferences file. If the user cancelled the dialog then the previous
458 // value will be retained.
459 if( !editorname.IsEmpty() )
460 m_textEditorPath->SetValue( editorname );
461}
462
463
464void PANEL_COMMON_SETTINGS::OnPDFViewerClick( wxCommandEvent& event )
465{
466 wxString mask( wxT( "*" ) );
467
468#ifdef __WINDOWS__
469 mask += wxT( ".exe" );
470#endif
471
472 wxString wildcard = _( "Executable files (" ) + mask + wxT( ")|" ) + mask;
473
474 Pgm().ReadPdfBrowserInfos();
475 wxFileName fn = Pgm().GetPdfBrowserName();
476
477 wxFileDialog dlg( this, _( "Select Preferred PDF Viewer" ), fn.GetPath(), fn.GetFullPath(),
478 wildcard, wxFD_OPEN | wxFD_FILE_MUST_EXIST );
479
480 if( dlg.ShowModal() == wxID_CANCEL )
481 return;
482
483 m_otherPDFViewer->SetValue( true );
484 m_PDFViewerPath->SetValue( dlg.GetPath() );
485}
486
487
489{
491}
492
493
495{
496 m_PDFViewerPath->Enable( m_otherPDFViewer->GetValue() );
497 m_pdfViewerBtn->Enable( m_otherPDFViewer->GetValue() );
498}
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition: bitmap.cpp:106
int KiIconScale(wxWindow *aWindow)
Return the automatic scale factor that would be used for a given window by KiScaledBitmap and KiScale...
Definition: bitmap.cpp:123
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
APPEARANCE m_Appearance
AUTO_BACKUP m_Backup
Class to handle configuration and automatic determination of the DPI scale to use for canvases.
bool GetCanvasIsAutoScaled() const override
Is the current value auto scaled, or is it user-set in the config.
double GetScaleFactor() const override
Get the DPI scale from all known sources in order:
void SetDpiConfig(bool aAuto, double aValue) override
Set the common DPI config in a given config object.
static double GetDefaultScaleFactor()
Get the "default" scaling factor to use if not other config is available.
Definition: dpi_scaling.cpp:40
static double GetMaxScaleFactor()
Definition: dpi_scaling.cpp:26
static double GetMinScaleFactor()
Definition: dpi_scaling.cpp:34
void ResetToDefaults()
Resets all parameters to default values.
Class PANEL_COMMON_SETTINGS_BASE.
STEPPED_SLIDER * m_iconScaleSlider
void OnTextEditorClick(wxCommandEvent &event) override
bool TransferDataFromWindow() override
bool TransferDataToWindow() override
void OnCanvasScaleChange(wxCommandEvent &aEvent)
Event fired when the canvas scale field is modified.
PANEL_COMMON_SETTINGS(wxWindow *aParent)
void applySettingsToPanel(COMMON_SETTINGS &aSettings)
void OnScaleSlider(wxScrollEvent &aEvent)
int m_last_scale
saved icon scale when Auto selected
void OnPDFViewerClick(wxCommandEvent &event) override
void OnIconScaleAuto(wxCommandEvent &aEvent)
void OnCanvasScaleAuto(wxCommandEvent &aEvent) override
Event fired when the canvas auto-scale option is changed.
void ResetPanel() override
Reset the contents of this panel.
void OnRadioButtonPdfViewer(wxCommandEvent &event) override
bool Enable(bool aEnable=true) override
void SetBitmap(const wxBitmapBundle &aBmp)
Customized wxSlider with forced stepping.
void SetStep(int aSize)
Set the step size.
const int minSize
Push and Shove router track width and via size dialog.
#define _(s)
bool AllowIconsInMenus()
If the user has disabled icons system-wide, we check that here.
Definition: gtk/ui.cpp:209
see class PGM_BASE
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:115
int min_interval
Minimum time, in seconds, between subsequent backups.
bool backup_on_autosave
Trigger a backup on autosave.
unsigned long long limit_total_size
Maximum total size of backups (bytes), 0 for unlimited.
int limit_total_files
Maximum number of backup archives to retain.
int limit_daily_files
Maximum files to keep per day, 0 for unlimited.
bool enabled
Automatically back up the project when files are saved.