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 The 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>
29#include <dpi_scaling_common.h>
30#include <eda_draw_frame.h>
32#include <kiface_base.h>
33#include <kiplatform/ui.h>
34#include <pgm_base.h>
35#include <id.h>
39#include <wx/filedlg.h>
40
41/*
42 * What follows is a whole lot of ugly to handle various platform GUI deficiences with respect
43 * to light/dark mode, DPI scaling, and other foibles.
44 *
45 * Ugly as it all is, it does improve our usability on various platforms.
46 */
47
50{
51 // Rendering engine
52#ifdef __WXMAC__
53 // On MAC, Cairo render does not work.
54 m_renderingSizer->Show( false );
55#endif
56
58
61
62 /*
63 * Automatic dark mode detection works fine on Mac, so no need for the explicit options.
64 */
65#ifdef __WXMAC__
66 m_stIconTheme->Show( false );
67 m_rbIconThemeLight->Show( false );
68 m_rbIconThemeDark->Show( false );
69 m_rbIconThemeAuto->Show( false );
70#endif
71
72 /*
73 * Automatic canvas scaling works fine on all supported platforms, so manual scaling is disabled
74 */
75 if( ADVANCED_CFG::GetCfg().m_AllowManualCanvasScale )
76 {
77 static constexpr int dpi_scaling_precision = 1;
78 static constexpr double dpi_scaling_increment = 0.5;
79
82 m_canvasScaleCtrl->SetDigits( dpi_scaling_precision );
83 m_canvasScaleCtrl->SetIncrement( dpi_scaling_increment );
85
86 m_canvasScaleCtrl->SetToolTip(
87 _( "Set the scale for the canvas."
88 "\n\n"
89 "On high-DPI displays on some platforms, KiCad cannot determine the "
90 "scaling factor. In this case you may need to set this to a value to "
91 "match your system's DPI scaling. 2.0 is a common value. "
92 "\n\n"
93 "If this does not match the system DPI scaling, the canvas will "
94 "not match the window size and cursor position." ) );
95
96 m_canvasScaleAuto->SetToolTip(
97 _( "Use an automatic value for the canvas scale."
98 "\n\n"
99 "On some platforms, the automatic value is incorrect and should be "
100 "set manually." ) );
101 }
102 else
103 {
104 m_staticTextCanvasScale->Show( false );
105 m_canvasScaleCtrl->Show( false );
106 m_canvasScaleCtrl = nullptr;
107 m_canvasScaleAuto->Show( false );
108 }
109
111 Pgm().GetCommonSettings()->m_Appearance.zoom_correction_factor );
112 bLeftSizer->Add( m_zoomCorrectionCtrl, 1, wxEXPAND );
113
114 // Hide the option of icons in menus for platforms that do not support them
116
117 m_scaleFonts->Show( false );
118 m_fontScalingHelp->Show( false );
119
121 {
122 m_canvasScaleCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED,
123 wxCommandEventHandler( PANEL_COMMON_SETTINGS::OnCanvasScaleChange ),
124 nullptr, this );
125 }
126
127 wxSize minSize = m_highContrastCtrl->GetMinSize();
128 int minWidth = m_highContrastCtrl->GetTextExtent( wxT( "XXX.XXX" ) ).GetWidth();
129
130 m_highContrastCtrl->SetMinSize( wxSize( minWidth, minSize.GetHeight() ) );
131}
132
133
135{
137 {
138 m_canvasScaleCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED,
139 wxCommandEventHandler( PANEL_COMMON_SETTINGS::OnCanvasScaleChange ),
140 nullptr, this );
141 }
142}
143
144
146{
147 COMMON_SETTINGS* commonSettings = Pgm().GetCommonSettings();
148
149 applySettingsToPanel( *commonSettings );
150
151 m_textCtrlFileManager->SetValue( commonSettings->m_System.file_explorer );
152
153 // TODO(JE) Move these into COMMON_SETTINGS probably
154 m_textEditorPath->SetValue( Pgm().GetTextEditor( false ) );
155 m_defaultPDFViewer->SetValue( Pgm().UseSystemPdfBrowser() );
156 m_otherPDFViewer->SetValue( !Pgm().UseSystemPdfBrowser() );
157 m_PDFViewerPath->SetValue( Pgm().GetPdfBrowserName() );
159
160 return true;
161}
162
163
165{
166 COMMON_SETTINGS* commonSettings = Pgm().GetCommonSettings();
167
168 commonSettings->m_System.file_explorer = m_textCtrlFileManager->GetValue();
169
170 commonSettings->m_System.autosave_interval = m_SaveTime->GetValue() * 60;
171 commonSettings->m_System.file_history_size = m_fileHistorySize->GetValue();
172
173 commonSettings->m_Graphics.aa_mode = m_antialiasing->GetSelection();
174
175 if( m_rbAccelerated->GetValue() )
177 else
179
181 {
182 DPI_SCALING_COMMON dpi( commonSettings, this );
183 dpi.SetDpiConfig( m_canvasScaleAuto->GetValue(), m_canvasScaleCtrl->GetValue() );
184 }
185
186 if( m_rbIconThemeLight->GetValue() )
187 commonSettings->m_Appearance.icon_theme = ICON_THEME::LIGHT;
188 else if( m_rbIconThemeDark->GetValue() )
189 commonSettings->m_Appearance.icon_theme = ICON_THEME::DARK;
190 else if( m_rbIconThemeAuto->GetValue() )
191 commonSettings->m_Appearance.icon_theme = ICON_THEME::AUTO;
192
193 if( m_rbIconSizeSmall->GetValue() )
194 commonSettings->m_Appearance.toolbar_icon_size = 16;
195 else if( m_rbIconSizeNormal->GetValue() )
196 commonSettings->m_Appearance.toolbar_icon_size = 24;
197 else if( m_rbIconSizeLarge->GetValue() )
198 commonSettings->m_Appearance.toolbar_icon_size = 32;
199
200 commonSettings->m_Appearance.use_icons_in_menus = m_checkBoxIconsInMenus->GetValue();
201 commonSettings->m_Appearance.apply_icon_scale_to_fonts = m_scaleFonts->GetValue();
202
203 commonSettings->m_Appearance.show_scrollbars = m_showScrollbars->GetValue();
204
205 commonSettings->m_Appearance.grid_striping = m_gridStriping->GetValue();
206
207 commonSettings->m_Appearance.zoom_correction_factor = m_zoomCorrectionCtrl->GetValue();
208
209 double dimmingPercent = 80;
210 m_highContrastCtrl->GetValue().ToDouble( &dimmingPercent );
211 commonSettings->m_Appearance.hicontrast_dimming_factor = dimmingPercent / 100.0f;
212
213 commonSettings->m_Input.focus_follow_sch_pcb = m_focusFollowSchPcb->GetValue();
214 commonSettings->m_Input.hotkey_feedback = m_hotkeyFeedback->GetValue();
215 commonSettings->m_Input.immediate_actions = !m_NonImmediateActions->GetValue();
216 commonSettings->m_Input.warp_mouse_on_move = m_warpMouseOnMove->GetValue();
217
218 commonSettings->m_Backup.enabled = m_cbBackupEnabled->GetValue();
219 commonSettings->m_Backup.backup_on_autosave = m_cbBackupAutosave->GetValue();
220 commonSettings->m_Backup.limit_total_files = m_backupLimitTotalFiles->GetValue();
221 commonSettings->m_Backup.limit_daily_files = m_backupLimitDailyFiles->GetValue();
222 commonSettings->m_Backup.min_interval = m_backupMinInterval->GetValue() * 60;
223 commonSettings->m_Backup.limit_total_size = m_backupLimitTotalSize->GetValue() * 1024 * 1024;
224
225 commonSettings->m_Session.remember_open_files = m_cbRememberOpenFiles->GetValue();
226
227 Pgm().SetTextEditor( m_textEditorPath->GetValue());
228
229 Pgm().SetPdfBrowserName( m_PDFViewerPath->GetValue() );
232
233 Pgm().GetSettingsManager().Save( commonSettings );
234
235 return true;
236}
237
238
240{
241 COMMON_SETTINGS defaultSettings;
242
243 defaultSettings.ResetToDefaults();
244
245 applySettingsToPanel( defaultSettings );
246
247 // TODO(JE) Move these into COMMON_SETTINGS probably
248 m_textEditorPath->SetValue( defaultSettings.m_System.text_editor );
249 m_defaultPDFViewer->SetValue( defaultSettings.m_System.use_system_pdf_viewer );
250 m_otherPDFViewer->SetValue( !defaultSettings.m_System.use_system_pdf_viewer );
251 m_PDFViewerPath->SetValue( defaultSettings.m_System.pdf_viewer_name );
253}
254
255
257{
258 int timevalue = aSettings.m_System.autosave_interval;
259 wxString msg;
260
261 msg << timevalue / 60;
262 m_SaveTime->SetValue( msg );
263
264 m_fileHistorySize->SetValue( aSettings.m_System.file_history_size );
265
266 m_antialiasing->SetSelection( aSettings.m_Graphics.aa_mode );
267
269 m_rbAccelerated->SetValue( true );
270 else
271 m_rbFallback->SetValue( true );
272
274 {
275 const DPI_SCALING_COMMON dpi( &aSettings, this );
276 m_canvasScaleCtrl->SetValue( dpi.GetScaleFactor() );
277 m_canvasScaleAuto->SetValue( dpi.GetCanvasIsAutoScaled() );
278 }
279
280 switch( aSettings.m_Appearance.icon_theme )
281 {
282 case ICON_THEME::LIGHT: m_rbIconThemeLight->SetValue( true ); break;
283 case ICON_THEME::DARK: m_rbIconThemeDark->SetValue( true ); break;
284 case ICON_THEME::AUTO: m_rbIconThemeAuto->SetValue( true ); break;
285 }
286
287 switch( aSettings.m_Appearance.toolbar_icon_size )
288 {
289 case 16: m_rbIconSizeSmall->SetValue( true ); break;
290 case 24: m_rbIconSizeNormal->SetValue( true ); break;
291 case 32: m_rbIconSizeLarge->SetValue( true ); break;
292 }
293
296
297 m_gridStriping->SetValue( aSettings.m_Appearance.grid_striping );
298
299 m_zoomCorrectionCtrl->SetDisplayedValue( aSettings.m_Appearance.zoom_correction_factor );
300
301 double dimmingPercent = aSettings.m_Appearance.hicontrast_dimming_factor * 100.0f;
302 m_highContrastCtrl->SetValue( wxString::Format( "%.0f", dimmingPercent ) );
303
304 m_focusFollowSchPcb->SetValue( aSettings.m_Input.focus_follow_sch_pcb );
305 m_hotkeyFeedback->SetValue( aSettings.m_Input.hotkey_feedback );
306 m_warpMouseOnMove->SetValue( aSettings.m_Input.warp_mouse_on_move );
307 m_NonImmediateActions->SetValue( !aSettings.m_Input.immediate_actions );
308
310
311 m_cbBackupEnabled->SetValue( aSettings.m_Backup.enabled );
312 m_cbBackupAutosave->SetValue( aSettings.m_Backup.backup_on_autosave );
315 m_backupMinInterval->SetValue( aSettings.m_Backup.min_interval / 60 );
316 m_backupLimitTotalSize->SetValue( aSettings.m_Backup.limit_total_size / ( 1024 * 1024 ) );
317
318 m_showScrollbars->SetValue( aSettings.m_Appearance.show_scrollbars );
319}
320
321
322void PANEL_COMMON_SETTINGS::OnCanvasScaleChange( wxCommandEvent& aEvent )
323{
324 m_canvasScaleAuto->SetValue( false );
325}
326
327
328void PANEL_COMMON_SETTINGS::OnCanvasScaleAuto( wxCommandEvent& aEvent )
329{
330 const bool automatic = m_canvasScaleAuto->GetValue();
331
332 if( automatic && m_canvasScaleCtrl )
333 {
334 // set the scale to the auto value, without consulting the config
335 DPI_SCALING_COMMON dpi( nullptr, this );
336
337 // update the field (no events sent)
338 m_canvasScaleCtrl->SetValue( dpi.GetScaleFactor() );
339 }
340}
341
342
343void PANEL_COMMON_SETTINGS::OnTextEditorClick( wxCommandEvent& event )
344{
345 // Ask the user to select a new editor, but suggest the current one as the default.
346 wxString editorname = Pgm().AskUserForPreferredEditor( m_textEditorPath->GetValue() );
347
348 // If we have a new editor name request it to be copied to m_text_editor and saved
349 // to the preferences file. If the user cancelled the dialog then the previous
350 // value will be retained.
351 if( !editorname.IsEmpty() )
352 m_textEditorPath->SetValue( editorname );
353}
354
355
357{
358 m_staticTextFileManager->Show( aBool );
359 m_textCtrlFileManager->Show( aBool );
360
361 if( aBool )
362 {
363#if defined( __WINDOWS__ )
364 wxString msg = _( "Default 'explorer.exe /n,/select,%F' for this OS." );
365 m_textCtrlFileManager->SetToolTip( msg );
366 wxString str = "%F";
367#else
368 wxString msg = _( "File explorer command.\nexample:" ) + wxS( " 'nemo -n %F'" );
369 m_textCtrlFileManager->SetToolTip( msg );
370 wxString str= " %F";
371#endif
372 msg = _( "Explorer command with mandatory '%s' suffix after last entered character." );
373 m_staticTextFileManager->SetToolTip( wxString::Format( msg, str ) );
374 }
375}
376
377
378void PANEL_COMMON_SETTINGS::OnPDFViewerClick( wxCommandEvent& event )
379{
380 wxString mask( wxT( "*" ) );
381
382#ifdef __WINDOWS__
383 mask += wxT( ".exe" );
384#endif
385
386 wxString wildcard = _( "Executable files (" ) + mask + wxT( ")|" ) + mask;
387
389 wxFileName fn = Pgm().GetPdfBrowserName();
390
391 wxWindow* topLevelParent = wxGetTopLevelParent( this );
392
393 wxFileDialog dlg( topLevelParent, _( "Select Preferred PDF Viewer" ), fn.GetPath(),
394 fn.GetFullPath(), wildcard, wxFD_OPEN | wxFD_FILE_MUST_EXIST );
395
396 if( dlg.ShowModal() == wxID_CANCEL )
397 return;
398
399 m_otherPDFViewer->SetValue( true );
400 m_PDFViewerPath->SetValue( dlg.GetPath() );
401}
402
403
405{
407}
408
409
411{
412 m_PDFViewerPath->Enable( m_otherPDFViewer->GetValue() );
413 m_pdfViewerBtn->Enable( m_otherPDFViewer->GetValue() );
414}
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
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.
static double GetMaxScaleFactor()
Get the maximum scaling factor that should be presented to the user.
static double GetMinScaleFactor()
Get the minimum scaling factor that should be presented to the user.
@ GAL_TYPE_OPENGL
OpenGL implementation.
@ GAL_TYPE_CAIRO
Cairo implementation.
void ResetToDefaults()
Resets all parameters to default values.
PANEL_COMMON_SETTINGS_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxTAB_TRAVERSAL, const wxString &name=wxEmptyString)
void OnTextEditorClick(wxCommandEvent &event) override
ZOOM_CORRECTION_CTRL * m_zoomCorrectionCtrl
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:576
virtual void SetPdfBrowserName(const wxString &aFileName)
Definition pgm_base.h:178
virtual void ReadPdfBrowserInfos()
Read the PDF browser choice from the common configuration.
Definition pgm_base.cpp:896
virtual const wxString & GetPdfBrowserName() const
Definition pgm_base.h:176
virtual void SetTextEditor(const wxString &aFileName)
Definition pgm_base.cpp:197
virtual void ForceSystemPdfBrowser(bool aFlg)
Force the use of system PDF browser, even if a preferred PDF browser is set.
Definition pgm_base.h:193
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition pgm_base.h:125
virtual void WritePdfBrowserInfos()
Save the PDF browser choice to the common configuration.
Definition pgm_base.cpp:903
virtual const wxString AskUserForPreferredEditor(const wxString &aDefaultEditor=wxEmptyString)
Show a dialog that instructs the user to select a new preferred editor.
Definition pgm_base.cpp:240
Control to calibrate screen zoom to match real-world 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 wxgtk/ui.cpp:278
PGM_BASE & Pgm()
The global program "get" accessor.
Definition pgm_base.cpp:913
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.
int canvas_type
EDA_DRAW_PANEL_GAL::GAL_TYPE_* value, see gal_options_panel.cpp.