KiCad PCB EDA Suite
Loading...
Searching...
No Matches
confirm.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) 2007 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#include <confirm.h>
26
27#include <functional>
28#include <wx/app.h>
29#include <wx/stockitem.h>
30#include <wx/richmsgdlg.h>
31#include <wx/msgdlg.h>
32#include <wx/choicdlg.h>
33#include <wx/crt.h>
34
35
36bool AskOverrideLock( wxWindow* aParent, const wxString& aMessage )
37{
38#ifdef __APPLE__
39 // wxMessageDialog gets the button spacing wrong on Mac so we have to use wxRichMessageDialog.
40 // Note that its warning icon is more like wxMessageDialog's error icon, so we use it instead
41 // of wxICON_ERROR.
42 wxRichMessageDialog dlg( aParent, aMessage, _( "File Open Warning" ),
43 wxYES_NO | wxICON_WARNING | wxCENTER );
44 dlg.SetExtendedMessage( _( "Interleaved saves may produce very unexpected results." )
45 + wxS( "\n" ) );
46 dlg.SetYesNoLabels( _( "Cancel" ), _( "Open Anyway" ) );
47#else
48 wxMessageDialog dlg( aParent, aMessage, _( "File Open Warning" ),
49 wxYES_NO | wxICON_ERROR | wxCENTER );
50 dlg.SetExtendedMessage( _( "Interleaved saves may produce very unexpected results." ) );
51 dlg.SetYesNoLabels( _( "Cancel" ), _( "Open Anyway" ) );
52#endif
53
54 return dlg.ShowModal() == wxID_NO;
55}
56
57
58int UnsavedChangesDialog( wxWindow* parent, const wxString& aMessage, bool* aApplyToAll )
59{
60 static bool s_apply_to_all = false;
61
62 wxRichMessageDialog dlg( parent, aMessage, _( "Save Changes?" ),
63 wxYES_NO | wxCANCEL | wxYES_DEFAULT | wxICON_WARNING | wxCENTER );
64 dlg.SetExtendedMessage( _( "If you don't save, all your changes will be permanently lost." )
65 + wxS( "\n" ) );
66 dlg.SetYesNoLabels( _( "Save" ), _( "Discard Changes" ) );
67
68 if( aApplyToAll )
69 dlg.ShowCheckBox( _( "Apply to all" ), s_apply_to_all );
70
71 int ret = dlg.ShowModal();
72
73 if( aApplyToAll )
74 {
75 *aApplyToAll = dlg.IsCheckBoxChecked();
76 s_apply_to_all = dlg.IsCheckBoxChecked();
77 }
78
79 // Returns wxID_YES, wxID_NO, or wxID_CANCEL
80 return ret;
81}
82
83
84int UnsavedChangesDialog( wxWindow* parent, const wxString& aMessage )
85{
86#ifdef __APPLE__
87 // wxMessageDialog gets the button order (and spacing) wrong on Mac so we have to use
88 // wxRichMessageDialog.
89 return UnsavedChangesDialog( parent, aMessage, nullptr );
90#else
91 #ifdef _WIN32
92 // wxMessageDialog on windows invokes TaskDialogIndirect which is a native function for a dialog
93 // As a result it skips wxWidgets for modal management...and we don't parent frames properly
94 // among other things for Windows to do the right thing by default
95 // Disable all the windows manually to avoid being able to hit this dialog from the tool frame and kicad frame at the same time
96 wxWindowDisabler disable( true );
97 #endif
98
99 wxMessageDialog dlg( parent, aMessage, _( "Save Changes?" ),
100 wxYES_NO | wxCANCEL | wxYES_DEFAULT | wxICON_WARNING | wxCENTER );
101 dlg.SetExtendedMessage( _( "If you don't save, all your changes will be permanently lost." ) );
102 dlg.SetYesNoLabels( _( "Save" ), _( "Discard Changes" ) );
103
104 // Returns wxID_YES, wxID_NO, or wxID_CANCEL
105 return dlg.ShowModal();
106#endif
107}
108
109
110bool ConfirmRevertDialog( wxWindow* parent, const wxString& aMessage )
111{
112 wxMessageDialog dlg( parent, aMessage, wxEmptyString,
113 wxOK | wxCANCEL | wxOK_DEFAULT | wxICON_WARNING | wxCENTER );
114 dlg.SetExtendedMessage( _( "Your current changes will be permanently lost." ) );
115 dlg.SetOKCancelLabels( _( "Revert" ), _( "Cancel" ) );
116
117 return dlg.ShowModal() == wxID_OK;
118}
119
120
121bool HandleUnsavedChanges( wxWindow* aParent, const wxString& aMessage,
122 const std::function<bool()>& aSaveFunction )
123{
124 switch( UnsavedChangesDialog( aParent, aMessage ) )
125 {
126 case wxID_YES: return aSaveFunction();
127 case wxID_NO: return true;
128 default:
129 case wxID_CANCEL: return false;
130 }
131}
132
133
134int OKOrCancelDialog( wxWindow* aParent, const wxString& aWarning, const wxString& aMessage,
135 const wxString& aDetailedMessage, const wxString& aOKLabel,
136 const wxString& aCancelLabel, bool* aApplyToAll )
137{
138 wxRichMessageDialog dlg( aParent, aMessage, aWarning,
139 wxOK | wxCANCEL | wxOK_DEFAULT | wxICON_WARNING | wxCENTER );
140
141 dlg.SetOKCancelLabels( ( aOKLabel.IsEmpty() ) ? _( "OK" ) : aOKLabel,
142 ( aCancelLabel.IsEmpty() ) ? _( "Cancel" ) : aCancelLabel );
143
144 if( !aDetailedMessage.IsEmpty() )
145 dlg.SetExtendedMessage( aDetailedMessage );
146
147 if( aApplyToAll )
148 dlg.ShowCheckBox( _( "Apply to all" ), true );
149
150 int ret = dlg.ShowModal();
151
152 if( aApplyToAll )
153 *aApplyToAll = dlg.IsCheckBoxChecked();
154
155 // Returns wxID_OK or wxID_CANCEL
156 return ret;
157}
158
159
160// DisplayError should be deprecated, use DisplayErrorMessage instead
161void DisplayError( wxWindow* aParent, const wxString& aText, int aDisplayTime )
162{
163 if( !wxTheApp || !wxTheApp->IsMainLoopRunning() )
164 {
165 wxLogError( "%s", aText );
166 return;
167 }
168
169 if( !wxTheApp->IsGUI() )
170 {
171 wxFprintf( stderr, aText );
172 return;
173 }
174
175 wxMessageDialog* dlg;
176 int icon = aDisplayTime > 0 ? wxICON_INFORMATION : wxICON_ERROR;
177
178 dlg = new wxMessageDialog( aParent, aText, _( "Warning" ),
179 wxOK | wxCENTRE | wxRESIZE_BORDER | icon | wxSTAY_ON_TOP );
180
181 dlg->ShowModal();
182 dlg->Destroy();
183}
184
185
186void DisplayErrorMessage( wxWindow* aParent, const wxString& aText, const wxString& aExtraInfo )
187{
188 if( !wxTheApp || !wxTheApp->IsMainLoopRunning() )
189 {
190 wxLogError( "%s %s", aText, aExtraInfo );
191 return;
192 }
193
194 if( !wxTheApp->IsGUI() )
195 {
196 wxFprintf( stderr, aText );
197 return;
198 }
199
200 wxMessageDialog* dlg;
201
202 dlg = new wxMessageDialog( aParent, aText, _( "Error" ),
203 wxOK | wxCENTRE | wxRESIZE_BORDER | wxICON_ERROR | wxSTAY_ON_TOP );
204
205 if( !aExtraInfo.IsEmpty() )
206 dlg->SetExtendedMessage( aExtraInfo );
207
208 dlg->ShowModal();
209 dlg->Destroy();
210}
211
212
213void DisplayInfoMessage( wxWindow* aParent, const wxString& aMessage, const wxString& aExtraInfo )
214{
215 if( !wxTheApp || !wxTheApp->GetTopWindow() )
216 {
217 wxLogDebug( "%s %s", aMessage, aExtraInfo );
218 return;
219 }
220
221 if( !wxTheApp->IsGUI() )
222 {
223 wxFprintf( stdout, "%s %s", aMessage, aExtraInfo );
224 return;
225 }
226
227 wxMessageDialog* dlg;
228 int icon = wxICON_INFORMATION;
229
230 dlg = new wxMessageDialog( aParent, aMessage, _( "Information" ),
231 wxOK | wxCENTRE | wxRESIZE_BORDER | icon | wxSTAY_ON_TOP );
232
233 if( !aExtraInfo.IsEmpty() )
234 dlg->SetExtendedMessage( aExtraInfo );
235
236 dlg->ShowModal();
237 dlg->Destroy();
238}
239
240
241bool IsOK( wxWindow* aParent, const wxString& aMessage )
242{
243 // wxMessageDialog no longer responds correctly to the <ESC> key (on at least OSX and MSW)
244 // so we're now using wxRichMessageDialog.
245 //
246 // Note also that we have to repurpose an OK/Cancel version of it because otherwise wxWidgets
247 // uses "destructive" spacing for the "No" button.
248
249#ifdef __APPLE__
250 // Why is wxICON_QUESTION a light-bulb on Mac? That has more of a hint or info connotation.
251 int icon = wxICON_WARNING;
252#else
253 int icon = wxICON_QUESTION;
254#endif
255
256#if !defined( __WXGTK__ )
257 wxRichMessageDialog dlg( aParent, aMessage, _( "Confirmation" ),
258 wxOK | wxCANCEL | wxOK_DEFAULT | wxCENTRE | icon | wxSTAY_ON_TOP );
259#else
260 wxMessageDialog dlg( aParent, aMessage, _( "Confirmation" ),
261 wxOK | wxCANCEL | wxOK_DEFAULT | wxCENTRE | icon | wxSTAY_ON_TOP );
262#endif
263
264 dlg.SetOKCancelLabels( _( "Yes" ), _( "No" ) );
265
266 return dlg.ShowModal() == wxID_OK;
267}
268
269
270int SelectSingleOption( wxWindow* aParent, const wxString& aTitle,
271 const wxString& aMessage, const wxArrayString& aOptions )
272{
273 wxSingleChoiceDialog dlg( aParent, aMessage, aTitle, aOptions );
274
275 if( dlg.ShowModal() != wxID_OK )
276 return -1;
277
278 return dlg.GetSelection();
279}
280
bool AskOverrideLock(wxWindow *aParent, const wxString &aMessage)
Display a dialog indicating the file is already open, with an option to reset the lock.
Definition: confirm.cpp:36
int SelectSingleOption(wxWindow *aParent, const wxString &aTitle, const wxString &aMessage, const wxArrayString &aOptions)
Display a dialog with radioboxes asking the user to select an option.
Definition: confirm.cpp:270
int OKOrCancelDialog(wxWindow *aParent, const wxString &aWarning, const wxString &aMessage, const wxString &aDetailedMessage, const wxString &aOKLabel, const wxString &aCancelLabel, bool *aApplyToAll)
Display a warning dialog with aMessage and returns the user response.
Definition: confirm.cpp:134
bool IsOK(wxWindow *aParent, const wxString &aMessage)
Display a yes/no dialog with aMessage and returns the user response.
Definition: confirm.cpp:241
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:161
void DisplayInfoMessage(wxWindow *aParent, const wxString &aMessage, const wxString &aExtraInfo)
Display an informational message box with aMessage.
Definition: confirm.cpp:213
bool HandleUnsavedChanges(wxWindow *aParent, const wxString &aMessage, const std::function< bool()> &aSaveFunction)
Display a dialog with Save, Cancel and Discard Changes buttons.
Definition: confirm.cpp:121
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:186
int UnsavedChangesDialog(wxWindow *parent, const wxString &aMessage, bool *aApplyToAll)
A specialized version of HandleUnsavedChanges which handles an apply-to-all checkbox.
Definition: confirm.cpp:58
bool ConfirmRevertDialog(wxWindow *parent, const wxString &aMessage)
Display a confirmation dialog for a revert action.
Definition: confirm.cpp:110
This file is part of the common library.
#define _(s)