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-2023 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
49{
50 /*
51 * Cairo canvas doesn't work on Mac, so no need for fallback anti-aliasing options
52 */
53#ifdef __WXMAC__
54 m_antialiasingFallback->Show( false );
55 m_antialiasingFallbackLabel->Show( false );
56#endif
57
59
60 m_textEditorBtn->SetBitmap( KiBitmapBundle( BITMAPS::small_folder ) );
61 m_pdfViewerBtn->SetBitmap( KiBitmapBundle( BITMAPS::small_folder ) );
62
63 /*
64 * Automatic dark mode detection works fine on Mac, so no need for the explicit options.
65 */
66#ifdef __WXMAC__
67 m_stIconTheme->Show( false );
68 m_rbIconThemeLight->Show( false );
69 m_rbIconThemeDark->Show( false );
70 m_rbIconThemeAuto->Show( false );
71#endif
72
73 /*
74 * Automatic canvas scaling works fine on all supported platforms, so manual scaling is disabled
75 */
76 if( ADVANCED_CFG::GetCfg().m_AllowManualCanvasScale )
77 {
78 static constexpr int dpi_scaling_precision = 1;
79 static constexpr double dpi_scaling_increment = 0.5;
80
83 m_canvasScaleCtrl->SetDigits( dpi_scaling_precision );
84 m_canvasScaleCtrl->SetIncrement( dpi_scaling_increment );
86
87 m_canvasScaleCtrl->SetToolTip(
88 _( "Set the scale for the canvas."
89 "\n\n"
90 "On high-DPI displays on some platforms, KiCad cannot determine the "
91 "scaling factor. In this case you may need to set this to a value to "
92 "match your system's DPI scaling. 2.0 is a common value. "
93 "\n\n"
94 "If this does not match the system DPI scaling, the canvas will "
95 "not match the window size and cursor position." ) );
96
97 m_canvasScaleAuto->SetToolTip(
98 _( "Use an automatic value for the canvas scale."
99 "\n\n"
100 "On some platforms, the automatic value is incorrect and should be "
101 "set manually." ) );
102 }
103 else
104 {
105 m_staticTextCanvasScale->Show( false );
106 m_canvasScaleCtrl->Show( false );
107 m_canvasScaleCtrl = nullptr;
108 m_canvasScaleAuto->Show( false );
109 }
110
111 // Hide the option of icons in menus for platforms that do not support them
113
114 m_scaleFonts->Show( false );
115 m_fontScalingHelp->Show( false );
116
118 {
119 m_canvasScaleCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED,
120 wxCommandEventHandler( PANEL_COMMON_SETTINGS::OnCanvasScaleChange ),
121 nullptr, this );
122 }
123
124 wxSize minSize = m_highContrastCtrl->GetMinSize();
125 int minWidth = m_highContrastCtrl->GetTextExtent( wxT( "XXX.XXX" ) ).GetWidth();
126
127 m_highContrastCtrl->SetMinSize( wxSize( minWidth, minSize.GetHeight() ) );
128}
129
130
132{
134 {
135 m_canvasScaleCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED,
136 wxCommandEventHandler( PANEL_COMMON_SETTINGS::OnCanvasScaleChange ),
137 nullptr, this );
138 }
139}
140
141
143{
144 COMMON_SETTINGS* commonSettings = Pgm().GetCommonSettings();
145
146 applySettingsToPanel( *commonSettings );
147
148 m_textCtrlFileManager->SetValue( commonSettings->m_System.file_explorer );
149
150 // TODO(JE) Move these into COMMON_SETTINGS probably
151 m_textEditorPath->SetValue( Pgm().GetTextEditor( false ) );
152 m_defaultPDFViewer->SetValue( Pgm().UseSystemPdfBrowser() );
153 m_otherPDFViewer->SetValue( !Pgm().UseSystemPdfBrowser() );
154 m_PDFViewerPath->SetValue( Pgm().GetPdfBrowserName() );
156
157 return true;
158}
159
160
162{
163 COMMON_SETTINGS* commonSettings = Pgm().GetCommonSettings();
164
165 commonSettings->m_System.file_explorer = m_textCtrlFileManager->GetValue();
166
167 commonSettings->m_System.autosave_interval = m_SaveTime->GetValue() * 60;
168 commonSettings->m_System.file_history_size = m_fileHistorySize->GetValue();
169 commonSettings->m_System.clear_3d_cache_interval = m_Clear3DCacheFilesOlder->GetValue();
170
171 commonSettings->m_Graphics.opengl_aa_mode = m_antialiasing->GetSelection();
172 commonSettings->m_Graphics.cairo_aa_mode = m_antialiasingFallback->GetSelection();
173
175 {
176 DPI_SCALING_COMMON dpi( commonSettings, this );
177 dpi.SetDpiConfig( m_canvasScaleAuto->GetValue(), m_canvasScaleCtrl->GetValue() );
178 }
179
180 if( m_rbIconThemeLight->GetValue() )
181 commonSettings->m_Appearance.icon_theme = ICON_THEME::LIGHT;
182 else if( m_rbIconThemeDark->GetValue() )
183 commonSettings->m_Appearance.icon_theme = ICON_THEME::DARK;
184 else if( m_rbIconThemeAuto->GetValue() )
185 commonSettings->m_Appearance.icon_theme = ICON_THEME::AUTO;
186
187 if( m_rbIconSizeSmall->GetValue() )
188 commonSettings->m_Appearance.toolbar_icon_size = 16;
189 else if( m_rbIconSizeNormal->GetValue() )
190 commonSettings->m_Appearance.toolbar_icon_size = 24;
191 else if( m_rbIconSizeLarge->GetValue() )
192 commonSettings->m_Appearance.toolbar_icon_size = 32;
193
194 commonSettings->m_Appearance.use_icons_in_menus = m_checkBoxIconsInMenus->GetValue();
195 commonSettings->m_Appearance.apply_icon_scale_to_fonts = m_scaleFonts->GetValue();
196
197 commonSettings->m_Appearance.show_scrollbars = m_showScrollbars->GetValue();
198
199 commonSettings->m_Appearance.grid_striping = m_gridStriping->GetValue();
200
201 double dimmingPercent = 80;
202 m_highContrastCtrl->GetValue().ToDouble( &dimmingPercent );
203 commonSettings->m_Appearance.hicontrast_dimming_factor = dimmingPercent / 100.0f;
204
205 commonSettings->m_Input.focus_follow_sch_pcb = m_focusFollowSchPcb->GetValue();
206 commonSettings->m_Input.hotkey_feedback = m_hotkeyFeedback->GetValue();
207 commonSettings->m_Input.immediate_actions = !m_NonImmediateActions->GetValue();
208 commonSettings->m_Input.warp_mouse_on_move = m_warpMouseOnMove->GetValue();
209
210 commonSettings->m_Backup.enabled = m_cbBackupEnabled->GetValue();
211 commonSettings->m_Backup.backup_on_autosave = m_cbBackupAutosave->GetValue();
212 commonSettings->m_Backup.limit_total_files = m_backupLimitTotalFiles->GetValue();
213 commonSettings->m_Backup.limit_daily_files = m_backupLimitDailyFiles->GetValue();
214 commonSettings->m_Backup.min_interval = m_backupMinInterval->GetValue() * 60;
215 commonSettings->m_Backup.limit_total_size = m_backupLimitTotalSize->GetValue() * 1024 * 1024;
216
217 commonSettings->m_Session.remember_open_files = m_cbRememberOpenFiles->GetValue();
218
219 Pgm().SetTextEditor( m_textEditorPath->GetValue());
220
221 Pgm().SetPdfBrowserName( m_PDFViewerPath->GetValue() );
224
225 Pgm().GetSettingsManager().Save( commonSettings );
226
227 return true;
228}
229
230
232{
233 COMMON_SETTINGS defaultSettings;
234
235 defaultSettings.ResetToDefaults();
236
237 applySettingsToPanel( defaultSettings );
238
239 // TODO(JE) Move these into COMMON_SETTINGS probably
240 m_textEditorPath->SetValue( defaultSettings.m_System.text_editor );
241 m_defaultPDFViewer->SetValue( defaultSettings.m_System.use_system_pdf_viewer );
242 m_otherPDFViewer->SetValue( !defaultSettings.m_System.use_system_pdf_viewer );
243 m_PDFViewerPath->SetValue( defaultSettings.m_System.pdf_viewer_name );
245}
246
247
249{
250 int timevalue = aSettings.m_System.autosave_interval;
251 wxString msg;
252
253 msg << timevalue / 60;
254 m_SaveTime->SetValue( msg );
255
256 m_fileHistorySize->SetValue( aSettings.m_System.file_history_size );
257
258 m_antialiasing->SetSelection( aSettings.m_Graphics.opengl_aa_mode );
259 m_antialiasingFallback->SetSelection( aSettings.m_Graphics.cairo_aa_mode );
260
262
264 {
265 const DPI_SCALING_COMMON dpi( &aSettings, this );
266 m_canvasScaleCtrl->SetValue( dpi.GetScaleFactor() );
267 m_canvasScaleAuto->SetValue( dpi.GetCanvasIsAutoScaled() );
268 }
269
270 switch( aSettings.m_Appearance.icon_theme )
271 {
272 case ICON_THEME::LIGHT: m_rbIconThemeLight->SetValue( true ); break;
273 case ICON_THEME::DARK: m_rbIconThemeDark->SetValue( true ); break;
274 case ICON_THEME::AUTO: m_rbIconThemeAuto->SetValue( true ); break;
275 }
276
277 switch( aSettings.m_Appearance.toolbar_icon_size )
278 {
279 case 16: m_rbIconSizeSmall->SetValue( true ); break;
280 case 24: m_rbIconSizeNormal->SetValue( true ); break;
281 case 32: m_rbIconSizeLarge->SetValue( true ); break;
282 }
283
286
287 m_gridStriping->SetValue( aSettings.m_Appearance.grid_striping );
288
289 double dimmingPercent = aSettings.m_Appearance.hicontrast_dimming_factor * 100.0f;
290 m_highContrastCtrl->SetValue( wxString::Format( "%.0f", dimmingPercent ) );
291
292 m_focusFollowSchPcb->SetValue( aSettings.m_Input.focus_follow_sch_pcb );
293 m_hotkeyFeedback->SetValue( aSettings.m_Input.hotkey_feedback );
294 m_warpMouseOnMove->SetValue( aSettings.m_Input.warp_mouse_on_move );
295 m_NonImmediateActions->SetValue( !aSettings.m_Input.immediate_actions );
296
298
299 m_cbBackupEnabled->SetValue( aSettings.m_Backup.enabled );
300 m_cbBackupAutosave->SetValue( aSettings.m_Backup.backup_on_autosave );
303 m_backupMinInterval->SetValue( aSettings.m_Backup.min_interval / 60 );
304 m_backupLimitTotalSize->SetValue( aSettings.m_Backup.limit_total_size / ( 1024 * 1024 ) );
305
306 m_showScrollbars->SetValue( aSettings.m_Appearance.show_scrollbars );
307}
308
309
310void PANEL_COMMON_SETTINGS::OnCanvasScaleChange( wxCommandEvent& aEvent )
311{
312 m_canvasScaleAuto->SetValue( false );
313}
314
315
316void PANEL_COMMON_SETTINGS::OnCanvasScaleAuto( wxCommandEvent& aEvent )
317{
318 const bool automatic = m_canvasScaleAuto->GetValue();
319
320 if( automatic && m_canvasScaleCtrl )
321 {
322 // set the scale to the auto value, without consulting the config
323 DPI_SCALING_COMMON dpi( nullptr, this );
324
325 // update the field (no events sent)
326 m_canvasScaleCtrl->SetValue( dpi.GetScaleFactor() );
327 }
328}
329
330
331void PANEL_COMMON_SETTINGS::OnTextEditorClick( wxCommandEvent& event )
332{
333 // Ask the user to select a new editor, but suggest the current one as the default.
334 wxString editorname = Pgm().AskUserForPreferredEditor( m_textEditorPath->GetValue() );
335
336 // If we have a new editor name request it to be copied to m_text_editor and saved
337 // to the preferences file. If the user cancelled the dialog then the previous
338 // value will be retained.
339 if( !editorname.IsEmpty() )
340 m_textEditorPath->SetValue( editorname );
341}
342
343
345{
346 m_staticTextFileManager->Show( aBool );
347 m_textCtrlFileManager->Show( aBool );
348
349 if( aBool )
350 {
351#if defined( __WINDOWS__ )
352 wxString msg = _( "Default 'explorer.exe /n,/select,%F' for this OS." );
353 m_textCtrlFileManager->SetToolTip( msg );
354 wxString str = "%F";
355#else
356 wxString msg = _( "File explorer command.\nexample:" ) + wxS( " 'nemo -n %F'" );
357 m_textCtrlFileManager->SetToolTip( msg );
358 wxString str= " %F";
359#endif
360 msg = _( "Explorer command with mandatory '%s' suffix after last entered character." );
361 m_staticTextFileManager->SetToolTip( wxString::Format( msg, str ) );
362 }
363}
364
365
366void PANEL_COMMON_SETTINGS::OnPDFViewerClick( wxCommandEvent& event )
367{
368 wxString mask( wxT( "*" ) );
369
370#ifdef __WINDOWS__
371 mask += wxT( ".exe" );
372#endif
373
374 wxString wildcard = _( "Executable files (" ) + mask + wxT( ")|" ) + mask;
375
377 wxFileName fn = Pgm().GetPdfBrowserName();
378
379 wxWindow* topLevelParent = wxGetTopLevelParent( this );
380
381 wxFileDialog dlg( topLevelParent, _( "Select Preferred PDF Viewer" ), fn.GetPath(),
382 fn.GetFullPath(), wildcard, wxFD_OPEN | wxFD_FILE_MUST_EXIST );
383
384 if( dlg.ShowModal() == wxID_CANCEL )
385 return;
386
387 m_otherPDFViewer->SetValue( true );
388 m_PDFViewerPath->SetValue( dlg.GetPath() );
389}
390
391
393{
395}
396
397
399{
400 m_PDFViewerPath->Enable( m_otherPDFViewer->GetValue() );
401 m_pdfViewerBtn->Enable( m_otherPDFViewer->GetValue() );
402}
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap)
Definition: bitmap.cpp:110
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:42
static double GetMaxScaleFactor()
Definition: dpi_scaling.cpp:27
static double GetMinScaleFactor()
Definition: dpi_scaling.cpp:35
void ResetToDefaults()
Resets all parameters to default values.
Class PANEL_COMMON_SETTINGS_BASE.
void OnTextEditorClick(wxCommandEvent &event) override
bool TransferDataFromWindow() override
bool TransferDataToWindow() override
void OnCanvasScaleChange(wxCommandEvent &aEvent)
Event fired when the canvas scale field is modified.
void ShowFileManagerWidgets(bool aBool)
PANEL_COMMON_SETTINGS(wxWindow *aParent)
void applySettingsToPanel(COMMON_SETTINGS &aSettings)
void OnPDFViewerClick(wxCommandEvent &event) override
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
virtual COMMON_SETTINGS * GetCommonSettings() const
Definition: pgm_base.cpp:679
virtual void SetPdfBrowserName(const wxString &aFileName)
Definition: pgm_base.h:189
virtual void ReadPdfBrowserInfos()
Read the PDF browser choice from the common configuration.
Definition: pgm_base.cpp:1045
virtual const wxString & GetPdfBrowserName() const
Definition: pgm_base.h:187
virtual void SetTextEditor(const wxString &aFileName)
Definition: pgm_base.cpp:189
virtual void ForceSystemPdfBrowser(bool aFlg)
Force the use of system PDF browser, even if a preferred PDF browser is set.
Definition: pgm_base.h:204
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition: pgm_base.h:142
virtual void WritePdfBrowserInfos()
Save the PDF browser choice to the common configuration.
Definition: pgm_base.cpp:1052
virtual const wxString AskUserForPreferredEditor(const wxString &aDefaultEditor=wxEmptyString)
Shows a dialog that instructs the user to select a new preferred editor.
Definition: pgm_base.cpp:232
bool Enable(bool aEnable=true) override
void SetBitmap(const wxBitmapBundle &aBmp)
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: wxgtk/ui.cpp:209
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: pgm_base.cpp:1060
see class PGM_BASE
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.