KiCad PCB EDA Suite
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-2020 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 <gal/dpi_scaling.h>
30 #include <kiface_i.h>
31 #include <pgm_base.h>
32 #include <id.h>
35 
36 #include <wx/filedlg.h>
37 
38 static constexpr int dpi_scaling_precision = 1;
39 static constexpr double dpi_scaling_increment = 0.5;
40 
41 
43  : PANEL_COMMON_SETTINGS_BASE( aParent ),
44  m_dialog( aDialog ),
45  m_last_scale( -1 )
46 {
47  m_canvasScaleCtrl->SetRange(
52 
53  m_canvasScaleCtrl->SetToolTip(
54  _( "Set the scale for the canvas."
55  "\n\n"
56  "On high-DPI displays on some platforms, KiCad cannot determine the "
57  "scaling factor. In this case you may need to set this to a value to "
58  "match your system's DPI scaling. 2.0 is a common value. "
59  "\n\n"
60  "If this does not match the system DPI scaling, the canvas will "
61  "not match the window size and cursor position." ) );
62 
63  m_canvasScaleAuto->SetToolTip(
64  _( "Use an automatic value for the canvas scale."
65  "\n\n"
66  "On some platforms, the automatic value is incorrect and should be "
67  "set manually." ) );
68 
70 
71 #ifdef __WXMAC__
72  // Cairo canvas doesn't work on Mac, so no need for anti-aliasing options
73  m_antialiasingFallback->Show( false );
74  m_antialiasingFallbackLabel->Show( false );
75 #endif
76 
79 
80  m_canvasScaleCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED,
81  wxCommandEventHandler( PANEL_COMMON_SETTINGS::OnCanvasScaleChange ),
82  NULL, this );
83 }
84 
85 
87 {
88  m_canvasScaleCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED,
89  wxCommandEventHandler( PANEL_COMMON_SETTINGS::OnCanvasScaleChange ),
90  NULL, this );
91 }
92 
93 
95 {
96  COMMON_SETTINGS* commonSettings = Pgm().GetCommonSettings();
97 
98  applySettingsToPanel( *commonSettings );
99 
100  // TODO(JE) Move these into COMMON_SETTINGS probably
101  m_textEditorPath->SetValue( Pgm().GetEditorName( false ) );
102  m_defaultPDFViewer->SetValue( Pgm().UseSystemPdfBrowser() );
103  m_otherPDFViewer->SetValue( !Pgm().UseSystemPdfBrowser() );
104  m_PDFViewerPath->SetValue( Pgm().GetPdfBrowserName() );
105 
106  return true;
107 }
108 
109 
111 {
112  COMMON_SETTINGS* commonSettings = Pgm().GetCommonSettings();
113 
114  commonSettings->m_System.autosave_interval = m_SaveTime->GetValue() * 60;
115  commonSettings->m_System.file_history_size = m_fileHistorySize->GetValue();
116  commonSettings->m_System.clear_3d_cache_interval = m_Clear3DCacheFilesOlder->GetValue();
117 
118  commonSettings->m_Graphics.opengl_aa_mode = m_antialiasing->GetSelection();
119  commonSettings->m_Graphics.cairo_aa_mode = m_antialiasingFallback->GetSelection();
120 
121  const int scale_fourths = m_iconScaleAuto->GetValue() ? -1 : m_iconScaleSlider->GetValue() / 25;
122  commonSettings->m_Appearance.icon_scale = scale_fourths;
123 
124  {
125  DPI_SCALING dpi( commonSettings, this );
126  dpi.SetDpiConfig( m_canvasScaleAuto->GetValue(), m_canvasScaleCtrl->GetValue() );
127  }
128 
129  if( m_rbIconThemeLight->GetValue() )
130  commonSettings->m_Appearance.icon_theme = ICON_THEME::LIGHT;
131  else if( m_rbIconThemeDark->GetValue() )
132  commonSettings->m_Appearance.icon_theme = ICON_THEME::DARK;
133  else if( m_rbIconThemeAuto->GetValue() )
134  commonSettings->m_Appearance.icon_theme = ICON_THEME::AUTO;
135 
136  commonSettings->m_Appearance.use_icons_in_menus = m_checkBoxIconsInMenus->GetValue();
137 
138  commonSettings->m_Input.immediate_actions = !m_NonImmediateActions->GetValue();
139  commonSettings->m_Input.warp_mouse_on_move = m_warpMouseOnMove->GetValue();
140 
141  commonSettings->m_Backup.enabled = m_cbBackupEnabled->GetValue();
142  commonSettings->m_Backup.backup_on_autosave = m_cbBackupAutosave->GetValue();
143  commonSettings->m_Backup.limit_total_files = m_backupLimitTotalFiles->GetValue();
144  commonSettings->m_Backup.limit_daily_files = m_backupLimitDailyFiles->GetValue();
145  commonSettings->m_Backup.min_interval = m_backupMinInterval->GetValue() * 60;
146  commonSettings->m_Backup.limit_total_size = m_backupLimitTotalSize->GetValue() * 1024 * 1024;
147 
148  commonSettings->m_Session.remember_open_files = m_cbRememberOpenFiles->GetValue();
149 
150  Pgm().SetEditorName( m_textEditorPath->GetValue() );
151 
152  Pgm().SetPdfBrowserName( m_PDFViewerPath->GetValue() );
153  Pgm().ForceSystemPdfBrowser( m_defaultPDFViewer->GetValue() );
154  Pgm().WritePdfBrowserInfos();
155 
156  Pgm().GetSettingsManager().Save( commonSettings );
157 
158  return true;
159 }
160 
161 
163 {
164  COMMON_SETTINGS defaultSettings;
165 
166  defaultSettings.ResetToDefaults();
167 
168  applySettingsToPanel( defaultSettings );
169 
170  // TODO(JE) Move these into COMMON_SETTINGS probably
171  m_textEditorPath->SetValue( defaultSettings.m_System.editor_name );
172  m_defaultPDFViewer->SetValue( defaultSettings.m_System.use_system_pdf_viewer );
173  m_otherPDFViewer->SetValue( !defaultSettings.m_System.use_system_pdf_viewer );
174  m_PDFViewerPath->SetValue( defaultSettings.m_System.pdf_viewer_name );
175 }
176 
177 
179 {
180  int timevalue = aSettings.m_System.autosave_interval;
181  wxString msg;
182 
183  msg << timevalue / 60;
184  m_SaveTime->SetValue( msg );
185 
186  m_fileHistorySize->SetValue( aSettings.m_System.file_history_size );
187 
188  m_antialiasing->SetSelection( aSettings.m_Graphics.opengl_aa_mode );
189  m_antialiasingFallback->SetSelection( aSettings.m_Graphics.cairo_aa_mode );
190 
192 
193  int icon_scale_fourths = aSettings.m_Appearance.icon_scale;
194 
195  if( icon_scale_fourths <= 0 )
196  {
197  m_iconScaleAuto->SetValue( true );
198  m_iconScaleSlider->SetValue( 25 * KiIconScale( GetParent() ) );
199  }
200  else
201  {
202  m_iconScaleAuto->SetValue( false );
203  m_iconScaleSlider->SetValue( icon_scale_fourths * 25 );
204  }
205 
206  {
207  const DPI_SCALING dpi( &aSettings, this );
208  m_canvasScaleCtrl->SetValue( dpi.GetScaleFactor() );
209  m_canvasScaleAuto->SetValue( dpi.GetCanvasIsAutoScaled() );
210  }
211 
212  switch( aSettings.m_Appearance.icon_theme )
213  {
214  case ICON_THEME::LIGHT: m_rbIconThemeLight->SetValue( true ); break;
215  case ICON_THEME::DARK: m_rbIconThemeDark->SetValue( true ); break;
216  case ICON_THEME::AUTO: m_rbIconThemeAuto->SetValue( true ); break;
217  }
218 
220 
221  m_warpMouseOnMove->SetValue( aSettings.m_Input.warp_mouse_on_move );
222  m_NonImmediateActions->SetValue( !aSettings.m_Input.immediate_actions );
223 
224  m_cbRememberOpenFiles->SetValue( aSettings.m_Session.remember_open_files );
225 
226  m_cbBackupEnabled->SetValue( aSettings.m_Backup.enabled );
227  m_cbBackupAutosave->SetValue( aSettings.m_Backup.backup_on_autosave );
228  m_backupLimitTotalFiles->SetValue( aSettings.m_Backup.limit_total_files );
229  m_backupLimitDailyFiles->SetValue( aSettings.m_Backup.limit_daily_files );
230  m_backupMinInterval->SetValue( aSettings.m_Backup.min_interval / 60 );
231  m_backupLimitTotalSize->SetValue( aSettings.m_Backup.limit_total_size / ( 1024 * 1024 ) );
232 }
233 
234 
235 void PANEL_COMMON_SETTINGS::OnScaleSlider( wxScrollEvent& aEvent )
236 {
237  m_iconScaleAuto->SetValue( false );
238  aEvent.Skip();
239 }
240 
241 
242 void PANEL_COMMON_SETTINGS::OnIconScaleAuto( wxCommandEvent& aEvent )
243 {
244  if( m_iconScaleAuto->GetValue() )
245  {
246  m_last_scale = m_iconScaleAuto->GetValue();
247  m_iconScaleSlider->SetValue( 25 * KiIconScale( GetParent() ) );
248  }
249  else
250  {
251  if( m_last_scale >= 0 )
252  m_iconScaleSlider->SetValue( m_last_scale );
253  }
254 }
255 
256 
257 void PANEL_COMMON_SETTINGS::OnCanvasScaleChange( wxCommandEvent& aEvent )
258 {
259  m_canvasScaleAuto->SetValue( false );
260 }
261 
262 
263 void PANEL_COMMON_SETTINGS::OnCanvasScaleAuto( wxCommandEvent& aEvent )
264 {
265  const bool automatic = m_canvasScaleAuto->GetValue();
266 
267  if( automatic )
268  {
269  // set the scale to the auto value, without consulting the config
270  DPI_SCALING dpi( nullptr, this );
271 
272  // update the field (no events sent)
273  m_canvasScaleCtrl->SetValue( dpi.GetScaleFactor() );
274  }
275 }
276 
277 
278 void PANEL_COMMON_SETTINGS::OnTextEditorClick( wxCommandEvent& event )
279 {
280  // Ask the user to select a new editor, but suggest the current one as the default.
281  wxString editorname = Pgm().AskUserForPreferredEditor( m_textEditorPath->GetValue() );
282 
283  // If we have a new editor name request it to be copied to m_editor_name and saved
284  // to the preferences file. If the user cancelled the dialog then the previous
285  // value will be retained.
286  if( !editorname.IsEmpty() )
287  m_textEditorPath->SetValue( editorname );
288 }
289 
290 
291 void PANEL_COMMON_SETTINGS::OnPDFViewerClick( wxCommandEvent& event )
292 {
293  wxString mask( wxT( "*" ) );
294 
295 #ifdef __WINDOWS__
296  mask += wxT( ".exe" );
297 #endif
298 
299  wxString wildcard = _( "Executable files (" ) + mask + wxT( ")|" ) + mask;
300 
301  Pgm().ReadPdfBrowserInfos();
302  wxFileName fn = Pgm().GetPdfBrowserName();
303 
304  wxFileDialog dlg( this, _( "Select Preferred PDF Viewer" ), fn.GetPath(), fn.GetFullPath(),
305  wildcard, wxFD_OPEN | wxFD_FILE_MUST_EXIST );
306 
307  if( dlg.ShowModal() == wxID_CANCEL )
308  return;
309 
310  m_otherPDFViewer->SetValue( true );
311  m_PDFViewerPath->SetValue( dlg.GetPath() );
312 }
313 
314 
315 void PANEL_COMMON_SETTINGS::onUpdateUIPdfPath( wxUpdateUIEvent& event )
316 {
317  // Used by both the m_pdfViewerBtn and m_PDFViewerPath
318  event.Enable( m_otherPDFViewer->GetValue() );
319 }
void ResetToDefaults()
Resets all parameters to default values.
void ResetPanel() override
Reset the contents of this panel.
unsigned long long limit_total_size
Maximum total size of backups (bytes), 0 for unlimited.
void OnCanvasScaleChange(wxCommandEvent &aEvent)
Event fired when the canvas scale field is modified.
void OnScaleSlider(wxScrollEvent &aEvent) override
int KiIconScale(wxWindow *aWindow)
Return the automatic scale factor that would be used for a given window by KiScaledBitmap and KiScale...
Definition: bitmap.cpp:122
bool enabled
Automatically back up the project when files are saved.
AUTO_BACKUP m_Backup
void OnPDFViewerClick(wxCommandEvent &event) override
APPEARANCE m_Appearance
Dialog helper object to sit in the inheritance tree between wxDialog and any class written by wxFormB...
Definition: dialog_shim.h:82
static double GetDefaultScaleFactor()
Get the "default" scaling factor to use if not other config is available.
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:106
Class PANEL_COMMON_SETTINGS_BASE.
double GetScaleFactor() const
Get the DPI scale from all known sources in order:
Class to handle configuration and automatic determination of the DPI scale to use for canvases.
Definition: dpi_scaling.h:36
bool TransferDataFromWindow() override
void OnTextEditorClick(wxCommandEvent &event) override
static constexpr int dpi_scaling_precision
void SetDpiConfig(bool aAuto, double aValue)
Set the common DPI config in a given config object.
void applySettingsToPanel(COMMON_SETTINGS &aSettings)
#define NULL
static constexpr double dpi_scaling_increment
static double GetMaxScaleFactor()
static double GetMinScaleFactor()
#define _(s)
void onUpdateUIPdfPath(wxUpdateUIEvent &event) override
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:105
int m_last_scale
saved icon scale when Auto selected
int min_interval
Minimum time, in seconds, between subsequent backups.
see class PGM_BASE
void OnIconScaleAuto(wxCommandEvent &aEvent) override
void OnCanvasScaleAuto(wxCommandEvent &aEvent) override
Event fired when the canvas auto-scale option is changed.
bool TransferDataToWindow() override
bool backup_on_autosave
Trigger a backup on autosave.
PANEL_COMMON_SETTINGS(DIALOG_SHIM *aDialog, wxWindow *aParent)
int limit_daily_files
Maximum files to keep per day, 0 for unlimited.
void SetStep(int aSize)
Set the step size.
int limit_total_files
Maximum number of backup archives to retain.
bool GetCanvasIsAutoScaled() const
Is the current value auto scaled, or is it user-set in the config.