Code::Blocks  SVN r11506
annoyingdialog.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the Code::Blocks IDE and licensed under the GNU Lesser General Public License, version 3
3  * http://www.gnu.org/licenses/lgpl-3.0.html
4  *
5  * $Revision: 10907 $
6  * $Id: annoyingdialog.cpp 10907 2016-09-25 16:09:48Z fuscated $
7  * $HeadURL: https://svn.code.sf.net/p/codeblocks/code/trunk/src/sdk/annoyingdialog.cpp $
8  */
9 
10 #include "sdk_precomp.h"
11 #ifndef CB_PRECOMP
12  #include <wx/button.h>
13  #include <wx/checkbox.h>
14  #include <wx/intl.h>
15  #include <wx/sizer.h>
16  #include <wx/stattext.h>
17  #include "cbexception.h"
18  #include "configmanager.h"
19  #include "manager.h"
20  #include "logmanager.h"
21  #include "globals.h"
22 #endif
23 #include <wx/statbmp.h>
24 #include "annoyingdialog.h"
25 
26 BEGIN_EVENT_TABLE(AnnoyingDialog, wxScrollingDialog)
27  EVT_BUTTON(-1, AnnoyingDialog::OnButton)
28 END_EVENT_TABLE()
29 
30 AnnoyingDialog::AnnoyingDialog(const wxString& caption, const wxString& message, const wxArtID icon,
31  dStyle style, dReturnType defaultReturn,
32  const wxString& b1, const wxString& b2, const wxString& b3)
33  : wxScrollingDialog(nullptr, -1, caption, wxDefaultPosition, wxDefaultSize, wxCAPTION),
34  m_DefRet(defaultReturn)
35 {
36  Init(caption, caption, message, icon, style, b1, b2, b3);
37 }
38 
39 AnnoyingDialog::AnnoyingDialog(const wxString& caption, const wxString &id, const wxString& message,
40  const wxArtID icon, dStyle style, dReturnType defaultReturn,
41  const wxString& b1, const wxString& b2, const wxString& b3)
43  m_DefRet(defaultReturn)
44 {
45  Init(caption, id, message, icon, style, b1, b2, b3);
46 }
47 
48 void AnnoyingDialog::Init(const wxString &caption, const wxString &id, const wxString& message, const wxArtID icon,
49  dStyle style, const wxString& b1, const wxString& b2, const wxString& b3)
50 {
51  m_CheckBox = nullptr;
52  m_DontAnnoy = false;
53  m_Id = id;
54 
55  static_assert(wxMinimumVersion<2,8,12>::eval, "wxWidgets 2.8.12 is required");
56 
58  ConfigManager* cfg = Manager::Get()->GetConfigManager(wxT("an_dlg"));
59  if (cfg->Exists(wxT("/disabled_ret")))
60  {
61  // new config style, includes return code in format:
62  // "id:dReturnType"
63  // example:
64  // "Question XYZ?:4"
65  disabled = cfg->ReadSSet(wxT("/disabled_ret"));
66  }
67  else
68  {
69  // if the new config key does not exist, read from the old one
70  // old keys are in format:
71  // "id"
72  disabled = cfg->ReadSSet(wxT("/disabled"));
73  // and copy it to the new one
74  cfg->Write(wxT("/disabled_ret"), disabled);
75  // we do not do an in place upgrade of the format to maintain
76  // compatibility with previous versions
77  }
78 
79  ConfigManagerContainer::StringSet::const_iterator it = disabled.lower_bound(m_Id);
80  if (it != disabled.end())
81  {
82  if (*it == m_Id)
83  {
84  // upgrade old settings
85  m_DontAnnoy = true;
86  if (m_DefRet == rtSAVE_CHOICE)
87  m_DefRet = rtYES; // default value
88  disabled.erase(it);
89  disabled.insert(m_Id + F(wxT(":%d"), m_DefRet));
90  // save updated format
91  cfg->Write(wxT("/disabled_ret"), disabled);
92  return;
93  }
94  else if (it->BeforeLast(wxT(':')) == m_Id)
95  {
96  m_DontAnnoy = true;
97  // read the saved choice and store it for ShowModal() to use
98  long ret = rtSAVE_CHOICE;
99  if (it->AfterLast(wxT(':')).ToLong(&ret) && ret != rtSAVE_CHOICE)
100  {
101  Manager::Get()->GetLogManager()->Log(*it);
102  m_DefRet = (dReturnType)ret;
103  }
104  else if (m_DefRet == rtSAVE_CHOICE)
105  m_DefRet = rtYES; // default value
106  return;
107  }
108  }
109 
110  wxBoxSizer *outerSizer = new wxBoxSizer( wxVERTICAL );
111 
112  wxFlexGridSizer *mainArea = new wxFlexGridSizer(2, 0, 0);
114  mainArea->Add(bitmap, 0, wxALL, 5);
115 
116  wxStaticText *txt = new wxStaticText(this, -1, message, wxDefaultPosition, wxDefaultSize, 0);
117  mainArea->Add( txt, 0, wxALIGN_CENTER|wxALL, 5 );
118 
119  mainArea->Add( 1, 1, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 );
120 
121  int numButtons = 0;
122  dReturnType id1 = rtINVALID;
123  dReturnType id2 = rtINVALID;
124  dReturnType id3 = rtINVALID;
125  wxString bTxt1;
126  wxString bTxt2;
127  wxString bTxt3;
128 
129  if(style == OK || style == ONE_BUTTON)
130  {
131  numButtons = 1;
132  // only one choice, so set m_DefRet
133  m_DefRet = (style == OK ? rtOK : rtONE);
134  id1 = m_DefRet;
135  bTxt1 = b1.IsEmpty() ? wxString(_("&OK")) : b1;
136  }
137  else if(style == YES_NO || style == OK_CANCEL || style == TWO_BUTTONS)
138  {
139  numButtons = 2;
140  id1 = (style == YES_NO ? rtYES : (style == OK_CANCEL ? rtOK : rtONE));
141  id2 = (style == YES_NO ? rtNO : (style == OK_CANCEL ? rtCANCEL : rtTWO));
142  bTxt1 = b1.IsEmpty() ? (style == YES_NO ? wxString(_("&Yes")) : wxString(_("&OK"))) : b1;
143  bTxt2 = b2.IsEmpty() ? (style == YES_NO ? wxString(_("&No")) : wxString(_("&Cancel"))) : b2;
144  // this is the default, so apply correct return type (if it was not set)
145  if (m_DefRet == rtYES)
146  m_DefRet = id1;
147  }
148  else if(style == YES_NO_CANCEL || style == THREE_BUTTONS)
149  {
150  numButtons = 3;
151  id1 = (style == YES_NO_CANCEL ? rtYES : rtONE);
152  id2 = (style == YES_NO_CANCEL ? rtNO : rtTWO);
153  id3 = (style == YES_NO_CANCEL ? rtCANCEL : rtTHREE);
154  bTxt1 = b1.IsEmpty() ? wxString(_("&Yes")) : b1;
155  bTxt2 = b2.IsEmpty() ? wxString(_("&No")) : b2;
156  bTxt3 = b3.IsEmpty() ? wxString(_("&Cancel")) : b3;
157  }
158  else
159  cbThrow(wxString(_T("Fatal error:\nUndefined style in dialog ")) << caption);
160 
161  wxSizer* buttonSizer = nullptr;
162  if (style < ONE_BUTTON) // standard buttons? use wxStdDialogButtonSizer
163  {
165 
166  wxButton* but1 = new wxButton(this, id1 == rtYES ? wxID_YES : wxID_OK, bTxt1, wxDefaultPosition, wxDefaultSize, 0);
167  but1->SetDefault();
168  buttonArea->AddButton(but1);
169 
170  if(numButtons > 1)
171  {
172  wxButton* but2 = new wxButton(this, id2 == rtNO ? wxID_NO : wxID_CANCEL, bTxt2, wxDefaultPosition, wxDefaultSize, 0);
173  if (id2 == m_DefRet)
174  but2->SetDefault();
175  buttonArea->AddButton(but2);
176  }
177  if(numButtons > 2)
178  {
179  wxButton* but3 = new wxButton(this, wxID_CANCEL, bTxt3, wxDefaultPosition, wxDefaultSize, 0);
180  if (id3 == m_DefRet)
181  but3->SetDefault();
182  buttonArea->AddButton(but3);
183  }
184  buttonArea->Realize();
185  buttonSizer = buttonArea;
186  }
187  else
188  {
189  // wxStdDialogButtonSizer accepts only standard IDs for its buttons, so we can't use
190  // it with custom buttons
191  buttonSizer = new wxBoxSizer(wxHORIZONTAL);
192 
193  wxButton *but1 = new wxButton(this, id1, bTxt1, wxDefaultPosition, wxDefaultSize, 0);
194  but1->SetDefault();
195  buttonSizer->Add(but1, 0, wxRIGHT, 5);
196 
197  if(numButtons > 1)
198  {
199  wxButton *but2 = new wxButton(this, id2, bTxt2, wxDefaultPosition, wxDefaultSize, 0);
200  if (id2 == m_DefRet)
201  but2->SetDefault();
202  buttonSizer->Add(but2, 0, wxRIGHT, 5);
203  }
204  if(numButtons > 2)
205  {
206  wxButton *but3 = new wxButton(this, id3, bTxt3, wxDefaultPosition, wxDefaultSize, 0);
207  if (id3 == m_DefRet)
208  but3->SetDefault();
209  buttonSizer->Add(but3, 0, wxRIGHT, 5);
210  }
211  }
212 
213  outerSizer->Add( mainArea, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
214  outerSizer->Add( buttonSizer, 0, wxALIGN_CENTER_HORIZONTAL);
215 
216  m_CheckBox = new wxCheckBox(this, wxID_ANY, _("Don't annoy me again!"), wxDefaultPosition, wxDefaultSize, 0);
217  outerSizer->Add(m_CheckBox, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxBOTTOM, 5);
218 
219  SetSizer( outerSizer );
220  outerSizer->SetSizeHints(this);
221 
222  Centre();
223 }
224 
226 {
227  if(!m_CheckBox)
228  cbThrow(_T("Ow... null pointer."));
229 
230  int id = event.GetId();
231  // convert IDs from standard buttons to dReturnType
232  switch (id)
233  {
234  case wxID_YES:
235  id = rtYES;
236  break;
237  case wxID_OK:
238  id = rtOK;
239  break;
240  case wxID_NO:
241  id = rtNO;
242  break;
243  case wxID_CANCEL:
244  id = rtCANCEL;
245  break;
246  default:
247  break;
248  }
249 
250  if(m_CheckBox->IsChecked())
251  {
252  ConfigManager* cfg = Manager::Get()->GetConfigManager(wxT("an_dlg"));
253  ConfigManagerContainer::StringSet disabled = cfg->ReadSSet(wxT("/disabled_ret"));
254  // if we are supposed to remember the users choice, save the button
255  disabled.insert(m_Id + F(wxT(":%d"), m_DefRet == rtSAVE_CHOICE ? id : m_DefRet));
256  cfg->Write(wxT("/disabled_ret"), disabled);
257  }
258  EndModal(id);
259 }
260 
262 {
263  if(m_DontAnnoy)
264  return m_DefRet;
265  PlaceWindow(this);
267 }
wxString F(const wxChar *msg,...)
sprintf-like function
Definition: logmanager.h:20
wxCheckBox * m_CheckBox
void EndModal(int retCode)
Definition: sc_dialog.cpp:112
static const wxString b1
AnnoyingDialog(const wxString &caption, const wxString &message, const wxArtID icon=wxART_INFORMATION, dStyle style=YES_NO, dReturnType defaultReturn=rtYES, const wxString &b1=wxEmptyString, const wxString &b2=wxEmptyString, const wxString &b3=wxEmptyString)
ConfigManager * GetConfigManager(const wxString &name_space) const
Definition: manager.cpp:474
static Manager * Get()
Use Manager::Get() to get a pointer to its instance Manager::Get() is guaranteed to never return an i...
Definition: manager.cpp:182
#define _T(string)
void AddButton(wxButton *button)
#define wxT(string)
void Write(const wxString &name, const wxString &value, bool ignoreEmpty=false)
null_pointer_t nullptr
Definition: nullptr.cpp:16
bool Exists(const wxString &name)
wxSizerItem * Add(wxWindow *window, const wxSizerFlags &flags)
const wxSize wxDefaultSize
const wxPoint wxDefaultPosition
wxArtClient wxART_MESSAGE_BOX
void Init(const wxString &caption, const wxString &id, const wxString &message, const wxArtID icon, dStyle style, const wxString &b1, const wxString &b2, const wxString &b3)
LogManager * GetLogManager() const
Definition: manager.cpp:439
void OnButton(wxCommandEvent &event)
#define wxCAPTION
virtual int ShowModal()
std::set< wxString > StringSet
Definition: configmanager.h:56
const wxString & _(const wxString &string)
#define cbThrow(message)
Definition: cbexception.h:42
bool IsChecked() const
bool IsEmpty() const
DLLIMPORT void PlaceWindow(wxTopLevelWindow *w, cbPlaceDialogMode mode=pdlBest, bool enforce=false)
Definition: globals.cpp:1177
dReturnType m_DefRet
void Log(const wxString &msg, int i=app_log, Logger::level lv=Logger::info)
Definition: logmanager.h:140
void SetSizeHints(wxWindow *window)
int ShowModal() override
static wxBitmap GetBitmap(const wxArtID &id, const wxArtClient &client=wxART_OTHER, const wxSize &size=wxDefaultSize)
ConfigManagerContainer::StringSet ReadSSet(const wxString &name)
Dialog that contains a "Don&#39;t annoy me" checkbox.