Code::Blocks  SVN r11506
compileroptionsdlg.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the Code::Blocks IDE and licensed under the GNU General Public License, version 3
3  * http://www.gnu.org/licenses/gpl-3.0.html
4  *
5  * $Revision: 11175 $
6  * $Id: compileroptionsdlg.cpp 11175 2017-09-17 23:04:58Z fuscated $
7  * $HeadURL: https://svn.code.sf.net/p/codeblocks/code/trunk/src/plugins/compilergcc/compileroptionsdlg.cpp $
8  */
9 
10 #include <sdk.h>
11 #include <prep.h>
12 #ifndef CB_PRECOMP
13  #include <algorithm>
14  #include <wx/arrstr.h>
15  #include <wx/button.h>
16  #include <wx/checkbox.h>
17  #include <wx/checklst.h>
18  #include <wx/choice.h>
19  #include <wx/event.h>
20  #include <wx/filename.h>
21  #include <wx/listbox.h>
22  #include <wx/menu.h>
23  #include <wx/notebook.h>
24  #include <wx/stattext.h>
25  #include <wx/sizer.h>
26  #include <wx/spinctrl.h>
27  #include <wx/textdlg.h>
28  #include <wx/treectrl.h>
29  #include <wx/xrc/xmlres.h>
30 
31  #include "compiler.h"
32  #include "compilerfactory.h"
33  #include "configmanager.h"
34  #include "globals.h"
35  #include "macrosmanager.h"
36  #include "manager.h"
37  #include "logmanager.h"
38  #include "projectmanager.h"
39 #endif
40 #include <wx/filedlg.h>
41 #include <wx/propgrid/propgrid.h>
42 #include <wx/xml/xml.h>
43 
45 #include "annoyingdialog.h"
46 #include "cbexception.h"
47 #include "compilergcc.h"
48 #include "compileroptionsdlg.h"
49 #include "debuggermanager.h"
50 #include "editpathdlg.h"
51 #include "editpairdlg.h"
52 #include "compilerflagdlg.h"
53 
54 // TO DO : - add/edit/delete compiler : applies directly , so no cancel out (change this behaviour)
55 // - compiler change of project/target -> check if the policy is still sound (both should have the same compiler)
56 // - compiler change of project/target -> all options should be removed : different compiler is different options
57 // - directory add/edit and library add/edit : check if it already existed
58 
59 BEGIN_EVENT_TABLE(CompilerOptionsDlg, wxPanel)
60  EVT_UPDATE_UI( XRCID("btnEditDir"), CompilerOptionsDlg::OnUpdateUI)
61  EVT_UPDATE_UI( XRCID("btnDelDir"), CompilerOptionsDlg::OnUpdateUI)
62  EVT_UPDATE_UI( XRCID("btnClearDir"), CompilerOptionsDlg::OnUpdateUI)
63  EVT_UPDATE_UI( XRCID("btnCopyDirs"), CompilerOptionsDlg::OnUpdateUI)
64  EVT_UPDATE_UI( XRCID("btnMoveDirUp"), CompilerOptionsDlg::OnUpdateUI)
65  EVT_UPDATE_UI( XRCID("btnMoveDirDown"), CompilerOptionsDlg::OnUpdateUI)
66  EVT_UPDATE_UI( XRCID("btnEditVar"), CompilerOptionsDlg::OnUpdateUI)
67  EVT_UPDATE_UI( XRCID("btnDeleteVar"), CompilerOptionsDlg::OnUpdateUI)
68  EVT_UPDATE_UI( XRCID("btnClearVar"), CompilerOptionsDlg::OnUpdateUI)
69  EVT_UPDATE_UI( XRCID("cmbCompilerPolicy"), CompilerOptionsDlg::OnUpdateUI)
70  EVT_UPDATE_UI( XRCID("cmbLinkerPolicy"), CompilerOptionsDlg::OnUpdateUI)
71  EVT_UPDATE_UI( XRCID("cmbIncludesPolicy"), CompilerOptionsDlg::OnUpdateUI)
72  EVT_UPDATE_UI( XRCID("cmbLibDirsPolicy"), CompilerOptionsDlg::OnUpdateUI)
73  EVT_UPDATE_UI( XRCID("cmbResDirsPolicy"), CompilerOptionsDlg::OnUpdateUI)
74  EVT_UPDATE_UI( XRCID("btnSetDefaultCompiler"), CompilerOptionsDlg::OnUpdateUI)
75  EVT_UPDATE_UI( XRCID("btnAddCompiler"), CompilerOptionsDlg::OnUpdateUI)
76  EVT_UPDATE_UI( XRCID("btnRenameCompiler"), CompilerOptionsDlg::OnUpdateUI)
77  EVT_UPDATE_UI( XRCID("btnDelCompiler"), CompilerOptionsDlg::OnUpdateUI)
78  EVT_UPDATE_UI( XRCID("btnResetCompiler"), CompilerOptionsDlg::OnUpdateUI)
79  EVT_UPDATE_UI( XRCID("btnAddLib"), CompilerOptionsDlg::OnUpdateUI)
80  EVT_UPDATE_UI( XRCID("btnEditLib"), CompilerOptionsDlg::OnUpdateUI)
81  EVT_UPDATE_UI( XRCID("btnDelLib"), CompilerOptionsDlg::OnUpdateUI)
82  EVT_UPDATE_UI( XRCID("btnClearLib"), CompilerOptionsDlg::OnUpdateUI)
83  EVT_UPDATE_UI( XRCID("btnCopyLibs"), CompilerOptionsDlg::OnUpdateUI)
84  EVT_UPDATE_UI( XRCID("btnMoveLibUp"), CompilerOptionsDlg::OnUpdateUI)
85  EVT_UPDATE_UI( XRCID("btnMoveLibDown"), CompilerOptionsDlg::OnUpdateUI)
86  EVT_UPDATE_UI( XRCID("txtMasterPath"), CompilerOptionsDlg::OnUpdateUI)
87  EVT_UPDATE_UI( XRCID("btnMasterPath"), CompilerOptionsDlg::OnUpdateUI)
88  EVT_UPDATE_UI( XRCID("btnExtraAdd"), CompilerOptionsDlg::OnUpdateUI)
89  EVT_UPDATE_UI( XRCID("btnExtraEdit"), CompilerOptionsDlg::OnUpdateUI)
90  EVT_UPDATE_UI( XRCID("btnExtraDelete"), CompilerOptionsDlg::OnUpdateUI)
91  EVT_UPDATE_UI( XRCID("btnExtraClear"), CompilerOptionsDlg::OnUpdateUI)
92  EVT_UPDATE_UI( XRCID("txtCcompiler"), CompilerOptionsDlg::OnUpdateUI)
93  EVT_UPDATE_UI( XRCID("btnCcompiler"), CompilerOptionsDlg::OnUpdateUI)
94  EVT_UPDATE_UI( XRCID("txtCPPcompiler"), CompilerOptionsDlg::OnUpdateUI)
95  EVT_UPDATE_UI( XRCID("btnCPPcompiler"), CompilerOptionsDlg::OnUpdateUI)
96  EVT_UPDATE_UI( XRCID("txtLinker"), CompilerOptionsDlg::OnUpdateUI)
97  EVT_UPDATE_UI( XRCID("btnLinker"), CompilerOptionsDlg::OnUpdateUI)
98  EVT_UPDATE_UI( XRCID("txtLibLinker"), CompilerOptionsDlg::OnUpdateUI)
99  EVT_UPDATE_UI( XRCID("btnLibLinker"), CompilerOptionsDlg::OnUpdateUI)
100  EVT_UPDATE_UI( XRCID("cmbDebugger"), CompilerOptionsDlg::OnUpdateUI)
101  EVT_UPDATE_UI( XRCID("txtResComp"), CompilerOptionsDlg::OnUpdateUI)
102  EVT_UPDATE_UI( XRCID("btnResComp"), CompilerOptionsDlg::OnUpdateUI)
103  EVT_UPDATE_UI( XRCID("txtMake"), CompilerOptionsDlg::OnUpdateUI)
104  EVT_UPDATE_UI( XRCID("btnMake"), CompilerOptionsDlg::OnUpdateUI)
105  EVT_UPDATE_UI( XRCID("cmbCompiler"), CompilerOptionsDlg::OnUpdateUI)
106  EVT_UPDATE_UI( XRCID("btnIgnoreAdd"), CompilerOptionsDlg::OnUpdateUI)
107  EVT_UPDATE_UI( XRCID("btnIgnoreRemove"), CompilerOptionsDlg::OnUpdateUI)
108  //
109  EVT_TREE_SEL_CHANGED( XRCID("tcScope"), CompilerOptionsDlg::OnTreeSelectionChange)
110  EVT_TREE_SEL_CHANGING( XRCID("tcScope"), CompilerOptionsDlg::OnTreeSelectionChanging)
111  EVT_CHOICE( XRCID("cmbCategory"), CompilerOptionsDlg::OnCategoryChanged)
112  EVT_CHOICE( XRCID("cmbCompiler"), CompilerOptionsDlg::OnCompilerChanged)
113  EVT_LISTBOX_DCLICK( XRCID("lstVars"), CompilerOptionsDlg::OnEditVarClick)
114  EVT_BUTTON( XRCID("btnSetDefaultCompiler"), CompilerOptionsDlg::OnSetDefaultCompilerClick)
115  EVT_BUTTON( XRCID("btnAddCompiler"), CompilerOptionsDlg::OnAddCompilerClick)
116  EVT_BUTTON( XRCID("btnRenameCompiler"), CompilerOptionsDlg::OnEditCompilerClick)
117  EVT_BUTTON( XRCID("btnDelCompiler"), CompilerOptionsDlg::OnRemoveCompilerClick)
118  EVT_BUTTON( XRCID("btnResetCompiler"), CompilerOptionsDlg::OnResetCompilerClick)
119  EVT_BUTTON( XRCID("btnAddDir"), CompilerOptionsDlg::OnAddDirClick)
120  EVT_BUTTON( XRCID("btnEditDir"), CompilerOptionsDlg::OnEditDirClick)
121  EVT_LISTBOX_DCLICK( XRCID("lstIncludeDirs"), CompilerOptionsDlg::OnEditDirClick)
122  EVT_LISTBOX_DCLICK( XRCID("lstLibDirs"), CompilerOptionsDlg::OnEditDirClick)
123  EVT_LISTBOX_DCLICK( XRCID("lstResDirs"), CompilerOptionsDlg::OnEditDirClick)
124  EVT_BUTTON( XRCID("btnDelDir"), CompilerOptionsDlg::OnRemoveDirClick)
125  EVT_BUTTON( XRCID("btnClearDir"), CompilerOptionsDlg::OnClearDirClick)
126  EVT_BUTTON( XRCID("btnCopyDirs"), CompilerOptionsDlg::OnCopyDirsClick)
127  EVT_BUTTON( XRCID("btnAddLib"), CompilerOptionsDlg::OnAddLibClick)
128  EVT_BUTTON( XRCID("btnEditLib"), CompilerOptionsDlg::OnEditLibClick)
129  EVT_LISTBOX_DCLICK( XRCID("lstLibs"), CompilerOptionsDlg::OnEditLibClick)
130  EVT_BUTTON( XRCID("btnDelLib"), CompilerOptionsDlg::OnRemoveLibClick)
131  EVT_BUTTON( XRCID("btnClearLib"), CompilerOptionsDlg::OnClearLibClick)
132  EVT_BUTTON( XRCID("btnCopyLibs"), CompilerOptionsDlg::OnCopyLibsClick)
133  EVT_LISTBOX_DCLICK( XRCID("lstExtraPaths"), CompilerOptionsDlg::OnEditExtraPathClick)
134  EVT_BUTTON( XRCID("btnExtraAdd"), CompilerOptionsDlg::OnAddExtraPathClick)
135  EVT_BUTTON( XRCID("btnExtraEdit"), CompilerOptionsDlg::OnEditExtraPathClick)
136  EVT_BUTTON( XRCID("btnExtraDelete"), CompilerOptionsDlg::OnRemoveExtraPathClick)
137  EVT_BUTTON( XRCID("btnExtraClear"), CompilerOptionsDlg::OnClearExtraPathClick)
138  EVT_BUTTON( XRCID("btnMoveLibUp"), CompilerOptionsDlg::OnMoveLibUpClick)
139  EVT_BUTTON( XRCID("btnMoveLibDown"), CompilerOptionsDlg::OnMoveLibDownClick)
140  EVT_BUTTON( XRCID("btnMoveDirUp"), CompilerOptionsDlg::OnMoveDirUpClick)
141  EVT_BUTTON( XRCID("btnMoveDirDown"), CompilerOptionsDlg::OnMoveDirDownClick)
142  EVT_BUTTON( XRCID("btnAddVar"), CompilerOptionsDlg::OnAddVarClick)
143  EVT_BUTTON( XRCID("btnEditVar"), CompilerOptionsDlg::OnEditVarClick)
144  EVT_BUTTON( XRCID("btnDeleteVar"), CompilerOptionsDlg::OnRemoveVarClick)
145  EVT_BUTTON( XRCID("btnClearVar"), CompilerOptionsDlg::OnClearVarClick)
146  EVT_BUTTON( XRCID("btnMasterPath"), CompilerOptionsDlg::OnMasterPathClick)
147  EVT_BUTTON( XRCID("btnAutoDetect"), CompilerOptionsDlg::OnAutoDetectClick)
148  EVT_BUTTON( XRCID("btnCcompiler"), CompilerOptionsDlg::OnSelectProgramClick)
149  EVT_BUTTON( XRCID("btnCPPcompiler"), CompilerOptionsDlg::OnSelectProgramClick)
150  EVT_BUTTON( XRCID("btnLinker"), CompilerOptionsDlg::OnSelectProgramClick)
151  EVT_BUTTON( XRCID("btnLibLinker"), CompilerOptionsDlg::OnSelectProgramClick)
152  EVT_BUTTON( XRCID("btnResComp"), CompilerOptionsDlg::OnSelectProgramClick)
153  EVT_BUTTON( XRCID("btnMake"), CompilerOptionsDlg::OnSelectProgramClick)
154  EVT_BUTTON( XRCID("btnAdvanced"), CompilerOptionsDlg::OnAdvancedClick)
155  EVT_BUTTON( XRCID("btnIgnoreAdd"), CompilerOptionsDlg::OnIgnoreAddClick)
156  EVT_BUTTON( XRCID("btnIgnoreRemove"), CompilerOptionsDlg::OnIgnoreRemoveClick)
157  EVT_CHOICE( XRCID("cmbCompilerPolicy"), CompilerOptionsDlg::OnDirty)
158  EVT_CHOICE( XRCID("cmbLinkerPolicy"), CompilerOptionsDlg::OnDirty)
159  EVT_CHOICE( XRCID("cmbIncludesPolicy"), CompilerOptionsDlg::OnDirty)
160  EVT_CHOICE( XRCID("cmbLibDirsPolicy"), CompilerOptionsDlg::OnDirty)
161  EVT_CHOICE( XRCID("cmbResDirsPolicy"), CompilerOptionsDlg::OnDirty)
162  EVT_CHOICE( XRCID("cmbLogging"), CompilerOptionsDlg::OnDirty)
163  EVT_CHECKBOX( XRCID("chkAlwaysRunPost"), CompilerOptionsDlg::OnDirty)
164  EVT_CHECKBOX( XRCID("chkNonPlatComp"), CompilerOptionsDlg::OnDirty)
165  EVT_TEXT( XRCID("txtCompilerOptions"), CompilerOptionsDlg::OnDirty)
166  EVT_TEXT( XRCID("txtResourceCompilerOptions"), CompilerOptionsDlg::OnDirty)
167  EVT_TEXT( XRCID("txtCompilerDefines"), CompilerOptionsDlg::OnDirty)
168  EVT_TEXT( XRCID("txtLinkerOptions"), CompilerOptionsDlg::OnDirty)
169  EVT_TEXT( XRCID("txtCmdBefore"), CompilerOptionsDlg::OnDirty)
170  EVT_TEXT( XRCID("txtCmdAfter"), CompilerOptionsDlg::OnDirty)
171  EVT_TEXT( XRCID("txtMasterPath"), CompilerOptionsDlg::OnDirty)
172  EVT_TEXT( XRCID("txtCcompiler"), CompilerOptionsDlg::OnDirty)
173  EVT_TEXT( XRCID("txtCPPcompiler"), CompilerOptionsDlg::OnDirty)
174  EVT_TEXT( XRCID("txtLinker"), CompilerOptionsDlg::OnDirty)
175  EVT_TEXT( XRCID("txtLibLinker"), CompilerOptionsDlg::OnDirty)
176  EVT_TEXT( XRCID("txtResComp"), CompilerOptionsDlg::OnDirty)
177  EVT_TEXT( XRCID("txtMake"), CompilerOptionsDlg::OnDirty)
178  EVT_TEXT( XRCID("txtMakeCmd_Build"), CompilerOptionsDlg::OnDirty)
179  EVT_TEXT( XRCID("txtMakeCmd_Compile"), CompilerOptionsDlg::OnDirty)
180  EVT_TEXT( XRCID("txtMakeCmd_Clean"), CompilerOptionsDlg::OnDirty)
181 // EVT_TEXT( XRCID("txtMakeCmd_DistClean"), CompilerOptionsDlg::OnDirty)
182  EVT_TEXT( XRCID("txtMakeCmd_AskRebuildNeeded"), CompilerOptionsDlg::OnDirty)
183 // EVT_TEXT( XRCID("txtMakeCmd_SilentBuild"), CompilerOptionsDlg::OnDirty)
184  EVT_CHAR_HOOK(CompilerOptionsDlg::OnMyCharHook)
185 
186  EVT_PG_CHANGED( XRCID("pgCompilerFlags"), CompilerOptionsDlg::OnOptionChanged)
187  EVT_PG_RIGHT_CLICK( XRCID("pgCompilerFlags"), CompilerOptionsDlg::OnFlagsPopup)
188  EVT_PG_DOUBLE_CLICK( XRCID("pgCompilerFlags"), CompilerOptionsDlg::OnOptionDoubleClick)
189 END_EVENT_TABLE()
190 
192 {
193  public:
194  ScopeTreeData(cbProject* project, ProjectBuildTarget* target){ m_Project = project; m_Target = target; }
195  cbProject* GetProject(){ return m_Project; }
196  ProjectBuildTarget* GetTarget(){ return m_Target; }
197  private:
200 };
201 
203 {
206 };
207 
209 {
210  VariableListClientData(const wxString &key, const wxString &value) : key(key), value(value) {}
212 };
213 
214 /*
215  CompilerOptions can exist on 3 different levels :
216  Level 1 : compiler level
217  - the options exist on the global level of the compiler
218  Level 2 : project level
219  - the options exist on the level of the project
220  Level 3 : the target level
221  - the options exist on the level of the target
222 */
223 
225  m_FlagsPG(nullptr),
226  m_Compiler(compiler),
227  m_CurrentCompilerIdx(0),
228  m_pProject(project),
229  m_pTarget(target),
230  m_bDirty(false),
231  m_BuildingTree(false)
232 {
233  wxXmlResource::Get()->LoadPanel(this, parent, _T("dlgCompilerOptions"));
234 
235  m_FlagsPG = new wxPropertyGrid(this, XRCID("pgCompilerFlags"), wxDefaultPosition, wxDefaultSize,
237  m_FlagsPG->SetExtraStyle(wxPG_EX_HELP_AS_TOOLTIPS);
240 
241  m_FlagsPG->SetMinSize(wxSize(400, 400));
242  wxXmlResource::Get()->AttachUnknownControl(wxT("pgCompilerFlags"), m_FlagsPG);
243 
244  if (m_pProject)
245  {
246  bool hasBuildScripts = m_pProject->GetBuildScripts().GetCount() != 0;
247  if (!hasBuildScripts)
248  {
249  // look in targets
250  for (int x = 0; x < m_pProject->GetBuildTargetsCount(); ++x)
251  {
252  ProjectBuildTarget* curr_target = m_pProject->GetBuildTarget(x);
253  hasBuildScripts = curr_target->GetBuildScripts().GetCount() != 0;
254  if (hasBuildScripts)
255  break;
256  }
257  }
258 
259  XRCCTRL(*this, "lblBuildScriptsNote", wxStaticText)->Show(hasBuildScripts);
260  }
261 
262  wxTreeCtrl* tree = XRCCTRL(*this, "tcScope", wxTreeCtrl);
263  wxSizer* sizer = tree->GetContainingSizer();
264  wxNotebook* nb = XRCCTRL(*this, "nbMain", wxNotebook);
265  if (!m_pProject)
266  {
267  // global settings
268  SetLabel(_("Compiler Settings"));
269  sizer->Show(tree,false);
270  sizer->Detach(tree);
271  nb->DeletePage(6); // remove "Make" page
272  nb->DeletePage(3); // remove "Commands" page
273  }
274  else
275  {
276  // project settings
277  nb->DeletePage(8); // remove "Other settings" page
278  nb->DeletePage(7); // remove "Build options" page
279  nb->DeletePage(4); // remove "Toolchain executables" page
280 
281  // remove "Compiler" buttons
282  wxWindow* win = XRCCTRL(*this, "btnAddCompiler", wxButton);
283  wxSizer* sizer2 = win->GetContainingSizer();
284  sizer2->Clear(true);
285  sizer2->RecalcSizes();
286  sizer2->Layout();
287 
288  // disable "Make" elements, if project is not using custom makefile
289  bool en = project->IsMakefileCustom();
290  XRCCTRL(*this, "txtMakeCmd_Build", wxTextCtrl)->Enable(en);
291  XRCCTRL(*this, "txtMakeCmd_Compile", wxTextCtrl)->Enable(en);
292  XRCCTRL(*this, "txtMakeCmd_Clean", wxTextCtrl)->Enable(en);
293  XRCCTRL(*this, "txtMakeCmd_DistClean", wxTextCtrl)->Enable(en);
294  XRCCTRL(*this, "txtMakeCmd_AskRebuildNeeded", wxTextCtrl)->Enable(en);
295  XRCCTRL(*this, "txtMakeCmd_SilentBuild", wxTextCtrl)->Enable(en);
296  }
297 
298  // let's start filling in all the panels of the configuration dialog
299  // there are compiler dependent settings and compiler independent settings
300 
301  // compiler independent (so settings these ones is sufficient)
302  DoFillOthers();
303  DoFillTree();
305  if (m_pTarget)
307  else if (m_pProject)
309  if ((m_pTarget || m_pProject) && compilerIdx == -1)
310  { // unknown user compiler
311  // similar code can be found @ OnTreeSelectionChange()
312  // see there for more info : duplicate code now, since here we still need
313  // to fill in the compiler list for the choice control, where in
314  // OnTreeSelectionChange we just need to set an entry
315  // TODO : make 1 help method out of this, with some argument indicating
316  // to fill the choice list, or break it in 2 methods with the list filling in between them
317  // or maybe time will bring even brighter ideas
319  wxString msg;
320  msg.Printf(_("The defined compiler cannot be located (ID: %s).\n"
321  "Please choose the compiler you want to use instead and click \"OK\".\n"
322  "If you click \"Cancel\", the project/target will remain configured for\n"
323  "that compiler and consequently can not be configured and will not be built."),
324  CompilerId.wx_str());
325  Compiler* comp = 0;
328 
329  if (comp)
330  { // a new compiler was chosen, proceed as if the user manually selected another compiler
331  // that means set the compiler selection list accordingly
332  // and go directly to (On)CompilerChanged
333  int NewCompilerIdx = CompilerFactory::GetCompilerIndex(comp);
334  DoFillCompilerSets(NewCompilerIdx);
335  wxCommandEvent Dummy;
336  OnCompilerChanged(Dummy);
337  }
338  else
339  { // the user cancelled and wants to keep the compiler
340  DoFillCompilerSets(compilerIdx);
341  if (nb)
342  nb->Disable();
343  }
344  }
345  else
346  {
347  if (!CompilerFactory::GetCompiler(compilerIdx))
348  compilerIdx = 0;
349  DoFillCompilerSets(compilerIdx);
351  m_CurrentCompilerIdx = compilerIdx;
352  // compiler dependent settings
354  }
356  {
357  // disable pages for commands only target
358  nb->GetPage(0)->Disable(); // Compiler settings
359  nb->GetPage(1)->Disable(); // Linker settings
360  nb->GetPage(2)->Disable(); // Search directories
361  nb->GetPage(5)->Disable(); // "Make" commands
362  nb->SetSelection(3); // Pre/post build steps
363  }
364  else
365  nb->SetSelection(0);
366  sizer->Layout();
367  Layout();
368  GetSizer()->Layout();
369  GetSizer()->SetSizeHints(this);
370 #ifdef __WXMAC__
371  // seems it's not big enough on the Apple/Mac : hacking time
372  int min_width, min_height;
373  GetSize(&min_width, &min_height);
374  this->SetSizeHints(min_width+140,min_height,-1,-1);
375 #endif
376  this->SetSize(-1, -1, 0, 0);
377  // disable some elements, if project is using custom makefile
378  // we do this after the layout is done, so the resulting dialog has always the same size
379  if (project && project->IsMakefileCustom())
380  {
381  nb->RemovePage(2); // remove "Search directories" page
382  nb->RemovePage(1); // remove "Linker settings" page
383  nb->RemovePage(0); // remove "Compiler settings" page
384  XRCCTRL(*this, "tabCompiler", wxPanel)->Show(false);
385  XRCCTRL(*this, "tabLinker", wxPanel)->Show(false);
386  XRCCTRL(*this, "tabDirs", wxPanel)->Show(false);
387  }
388 
389  Fit();
390 } // constructor
391 
393 {
394  //dtor
395 }
396 
398 {
399  wxChoice* cmb = XRCCTRL(*this, "cmbCompiler", wxChoice);
400  cmb->Clear();
401  for (unsigned int i = 0; i < CompilerFactory::GetCompilersCount(); ++i)
402  {
403  cmb->Append(CompilerFactory::GetCompiler(i)->GetName());
404  }
405 
406 // int compilerIdx = CompilerFactory::GetCompilerIndex(CompilerFactory::GetDefaultCompilerID());
407 // if (m_pTarget)
408 // compilerIdx = CompilerFactory::GetCompilerIndex(m_pTarget->GetCompilerID());
409 // else if (m_pProject)
410 // compilerIdx = CompilerFactory::GetCompilerIndex(m_pProject->GetCompilerID());
411 
412 // if (!CompilerFactory::GetCompiler(compilerIdx))
413 // compilerIdx = 0;
414 // m_Options = CompilerFactory::GetCompiler(compilerIdx)->GetOptions();
415  if (compilerIdx != -1)
416  cmb->SetSelection(compilerIdx);
417 
418 // m_CurrentCompilerIdx = compilerIdx;
419 } // DoFillCompilerSets
420 
422 {
423  DoFillCompilerPrograms(); // the programs executable's ...
424  DoLoadOptions();
425  DoFillVars();
426  // by the way we listen to changes in the textctrl, we also end up in the callbacks as
427  // a result of wxTextCtrl::SetValue, the preceding called methods did some of those -> reset dirty flag
428  m_bDirty = false;
429  m_bFlagsDirty = false;
430 } // DoFillCompilerDependentSettings
431 
433 {
435  DoSaveOptions();
436  DoSaveVars();
437  if (m_bFlagsDirty)
440  m_bDirty = false;
441  m_bFlagsDirty = false;
442 } // DoSaveCompilerDependentSettings
443 
444 inline void ArrayString2ListBox(const wxArrayString& array, wxListBox* control)
445 {
446  control->Clear();
447  int count = array.GetCount();
448  for (int i = 0; i < count; ++i)
449  {
450  if (!array[i].IsEmpty())
451  control->Append(array[i]);
452  }
453 } // ArrayString2ListBox
454 
455 inline void ListBox2ArrayString(wxArrayString& array, const wxListBox* control)
456 {
457  array.Clear();
458  int count = control->GetCount();
459  for (int i = 0; i < count; ++i)
460  {
461  wxString tmp = control->GetString(i);
462  if (!tmp.IsEmpty())
463  array.Add(tmp);
464  }
465 } // ListBox2ArrayString
466 
468 {
469  if (m_pProject)
470  return; // no "Programs" page
471 
473  if (!compiler)
474  return;
475  const CompilerPrograms& progs = compiler->GetPrograms();
476 
477  XRCCTRL(*this, "txtMasterPath", wxTextCtrl)->SetValue(compiler->GetMasterPath());
478  XRCCTRL(*this, "txtCcompiler", wxTextCtrl)->SetValue(progs.C);
479  XRCCTRL(*this, "txtCPPcompiler", wxTextCtrl)->SetValue(progs.CPP);
480  XRCCTRL(*this, "txtLinker", wxTextCtrl)->SetValue(progs.LD);
481  XRCCTRL(*this, "txtLibLinker", wxTextCtrl)->SetValue(progs.LIB);
482  wxChoice *cmbDebugger = XRCCTRL(*this, "cmbDebugger", wxChoice);
483  if (cmbDebugger)
484  {
485  cmbDebugger->Clear();
486  // Add an invalid debugger entry and store the old value in the client data, so no user settings are changed.
487  cmbDebugger->Append(_("--- Invalid debugger ---"), new DebuggerClientData(progs.DBGconfig));
488  cmbDebugger->SetSelection(0);
489 
491  for (DebuggerManager::RegisteredPlugins::const_iterator it = plugins.begin(); it != plugins.end(); ++it)
492  {
493  const DebuggerManager::PluginData &data = it->second;
494  for (DebuggerManager::ConfigurationVector::const_iterator itConf = data.GetConfigurations().begin();
495  itConf != data.GetConfigurations().end();
496  ++itConf)
497  {
498  const wxString &def = it->first->GetSettingsName() + wxT(":") + (*itConf)->GetName();
499  int index = cmbDebugger->Append(it->first->GetGUIName() + wxT(" : ") + (*itConf)->GetName(),
500  new DebuggerClientData(def));
501  if (def == progs.DBGconfig)
502  cmbDebugger->SetSelection(index);
503  }
504  }
505  }
506 
507  XRCCTRL(*this, "txtResComp", wxTextCtrl)->SetValue(progs.WINDRES);
508  XRCCTRL(*this, "txtMake", wxTextCtrl)->SetValue(progs.MAKE);
509 
510  const wxArrayString& extraPaths = compiler->GetExtraPaths();
511  ArrayString2ListBox(extraPaths, XRCCTRL(*this, "lstExtraPaths", wxListBox));
512 } // DoFillCompilerPrograms
513 
515 {
516  wxListBox* lst = XRCCTRL(*this, "lstVars", wxListBox);
517  if (!lst)
518  return;
519  lst->Clear();
520  const StringHash* vars = 0;
521  const CompileOptionsBase* base = GetVarsOwner();
522  if (base)
523  {
524  vars = &base->GetAllVars();
525  }
526  if (!vars)
527  return;
528  for (StringHash::const_iterator it = vars->begin(); it != vars->end(); ++it)
529  {
530  wxString text = it->first + _T(" = ") + it->second;
531  lst->Append(text, new VariableListClientData(it->first, it->second));
532  }
533 } // DoFillVars
534 
536 {
537  if (m_pProject)
538  return; // projects don't have Other tab
539 
540  wxCheckBox* chk = XRCCTRL(*this, "chkIncludeFileCwd", wxCheckBox);
541  if (chk)
542  chk->SetValue(Manager::Get()->GetConfigManager(_T("compiler"))->ReadBool(_T("/include_file_cwd"), false));
543 
544  chk = XRCCTRL(*this, "chkIncludePrjCwd", wxCheckBox);
545  if (chk)
546  chk->SetValue(Manager::Get()->GetConfigManager(_T("compiler"))->ReadBool(_T("/include_prj_cwd"), false));
547 
548  chk = XRCCTRL(*this, "chkSkipIncludeDeps", wxCheckBox);
549  if (chk)
550  chk->SetValue(Manager::Get()->GetConfigManager(_T("compiler"))->ReadBool(_T("/skip_include_deps"), false));
551 
552  chk = XRCCTRL(*this, "chkSaveHtmlLog", wxCheckBox);
553  if (chk)
554  chk->SetValue(Manager::Get()->GetConfigManager(_T("compiler"))->ReadBool(_T("/save_html_build_log"), false));
555 
556  chk = XRCCTRL(*this, "chkFullHtmlLog", wxCheckBox);
557  if (chk)
558  chk->SetValue(Manager::Get()->GetConfigManager(_T("compiler"))->ReadBool(_T("/save_html_build_log/full_command_line"), false));
559 
560  chk = XRCCTRL(*this, "chkBuildProgressBar", wxCheckBox);
561  if (chk)
562  chk->SetValue(Manager::Get()->GetConfigManager(_T("compiler"))->ReadBool(_T("/build_progress/bar"), false));
563 
564  chk = XRCCTRL(*this, "chkBuildProgressPerc", wxCheckBox);
565  if (chk)
566  chk->SetValue(Manager::Get()->GetConfigManager(_T("compiler"))->ReadBool(_T("/build_progress/percentage"), false));
567 
568  wxSpinCtrl* spn = XRCCTRL(*this, "spnParallelProcesses", wxSpinCtrl);
569  if (spn)
570  spn->SetValue(Manager::Get()->GetConfigManager(_T("compiler"))->ReadInt(_T("/parallel_processes"), 0));
571 
572  spn = XRCCTRL(*this, "spnMaxErrors", wxSpinCtrl);
573  if (spn)
574  {
575  spn->SetRange(0, 1000);
576  spn->SetValue(Manager::Get()->GetConfigManager(_T("compiler"))->ReadInt(_T("/max_reported_errors"), 50));
577  }
578 
579  chk = XRCCTRL(*this, "chkRebuildSeperately", wxCheckBox);
580  if (chk)
581  chk->SetValue(Manager::Get()->GetConfigManager(_T("compiler"))->ReadBool(_T("/rebuild_seperately"), false));
582 
583  wxListBox* lst = XRCCTRL(*this, "lstIgnore", wxListBox);
584  if (lst)
585  {
586  wxArrayString IgnoreOutput;
587  IgnoreOutput = Manager::Get()->GetConfigManager(_T("compiler"))->ReadArrayString(_T("/ignore_output"));
588  ArrayString2ListBox(IgnoreOutput, lst);
589  }
590 
591  chk = XRCCTRL(*this, "chkNonPlatComp", wxCheckBox);
592  if (chk)
593  chk->SetValue(Manager::Get()->GetConfigManager(_T("compiler"))->ReadBool(_T("/non_plat_comp"), false));
594 } // DoFillOthers
595 
597 {
598  m_BuildingTree = true;
599  wxTreeCtrl* tc = XRCCTRL(*this, "tcScope", wxTreeCtrl);
600  tc->DeleteAllItems();
601 
602  wxTreeItemId root;
603  wxTreeItemId selectedItem;
604 
605  if (!m_pProject)
606  {
607  // global settings
608  root = tc->AddRoot(_("Global options"), -1, -1);
609  selectedItem = root;
610  }
611  else
612  {
613  // project settings
614  // in case you wonder : the delete of data will be done by the wxTreeCtrl
615  ScopeTreeData* data = new ScopeTreeData(m_pProject, 0L);
616  root = tc->AddRoot(m_pProject->GetTitle(), -1, -1, data);
617  selectedItem = root;
618  for (int x = 0; x < m_pProject->GetBuildTargetsCount(); ++x)
619  {
621  data = new ScopeTreeData(m_pProject, target);
622  wxTreeItemId targetItem = tc->AppendItem(root, target->GetTitle(), -1, -1, data);
623  if (target == m_pTarget)
624  selectedItem = targetItem;
625  }
626  }
627  // normally the target should be found in the targets of the project
628  // in case it is not, we will reset m_pTarget to 0 (in sync with tree selection)
629  if (selectedItem == root)
630  m_pTarget = 0;
631 
632  tc->Expand(root);
633  tc->SelectItem(selectedItem);
634  m_BuildingTree = false;
635 } // DoFillTree
636 
638 {
639  m_FlagsPG->Freeze();
640  m_FlagsPG->Clear();
641  typedef std::map<wxString, wxPropertyCategory*> MapCategories;
642  MapCategories categories;
643 
644  // If there is a "General" category make sure it is added first.
645  for (size_t i = 0; i < m_Options.GetCount(); ++i)
646  {
647  const CompOption* option = m_Options.GetOption(i);
648  if (option->category == wxT("General"))
649  {
650  wxPropertyCategory *categoryProp = new wxPropertyCategory(option->category);
651  m_FlagsPG->Append(categoryProp);
652  categories[option->category] = categoryProp;
653  break;
654  }
655  }
656 
657  // Add all flags and categories to the property grid
658  for (size_t i = 0; i < m_Options.GetCount(); ++i)
659  {
660  const CompOption* option = m_Options.GetOption(i);
661  wxPropertyCategory *categoryProp = nullptr;
662  MapCategories::iterator itCat = categories.find(option->category);
663  if (itCat != categories.end())
664  categoryProp = itCat->second;
665  else
666  {
667  categoryProp = new wxPropertyCategory(option->category);
668  m_FlagsPG->Append(categoryProp);
669  categories[option->category] = categoryProp;
670  }
671 
672  wxPGProperty *prop = new wxBoolProperty(option->name, wxPG_LABEL, option->enabled);
673  m_FlagsPG->AppendIn(categoryProp, prop);
674  m_FlagsPG->SetPropertyAttribute(prop, wxPG_BOOL_USE_CHECKBOX, true, wxPG_RECURSE);
675  }
676 
677  wxPGProperty *root = m_FlagsPG->GetRoot();
678  if (root)
679  {
680  unsigned count = root->GetChildCount();
681  for (unsigned ii = 0; ii < count; ++ii)
682 #if wxCHECK_VERSION(3, 0, 0)
683  m_FlagsPG->SortChildren(root->Item(ii), wxPG_RECURSE);
684 #else
685  m_FlagsPG->Sort(root->Item(ii));
686 #endif
687  }
688  m_FlagsPG->Thaw();
689 } // DoFillOptions
690 
692 {
693  // disable all options
694  for (size_t n = 0; n < m_Options.GetCount(); ++n)
695  {
696  if (CompOption* copt = m_Options.GetOption(n))
697  copt->enabled = false;
698  }
699 
700  wxString rest;
701 
703 
704  XRCCTRL(*this, "txtCompilerDefines", wxTextCtrl)->Clear();
705  unsigned int i = 0;
706  while (i < m_CompilerOptions.GetCount())
707  {
709  opt = opt.Strip(wxString::both);
711  if (copt)
712  {
713 // Manager::Get()->GetLogManager()->DebugLog("Enabling option %s", copt->option.c_str());
714  copt->enabled = true;
716  }
717  else if (compiler && opt.StartsWith(compiler->GetSwitches().defines, &rest))
718  {
719  // definition
720  XRCCTRL(*this, "txtCompilerDefines", wxTextCtrl)->AppendText(rest);
721  XRCCTRL(*this, "txtCompilerDefines", wxTextCtrl)->AppendText(_T("\n"));
723  }
724  else
725  ++i;
726  }
727  i = 0;
728  while (i < m_LinkerOptions.GetCount())
729  {
730  wxString opt = m_LinkerOptions.Item(i);
731  opt = opt.Strip(wxString::both);
733  if (copt)
734  {
735 // Manager::Get()->GetLogManager()->DebugLog("Enabling option %s", copt->option.c_str());
736  copt->enabled = true;
738  }
739  else
740  ++i;
741  }
742 
743  XRCCTRL(*this, "lstLibs", wxListBox)->Clear();
744  for (unsigned int j = 0; j < m_LinkLibs.GetCount(); ++j)
745  XRCCTRL(*this, "lstLibs", wxListBox)->Append(m_LinkLibs[j]);
746 
747  m_LinkLibs.Clear();
748 } // TextToOptions
749 
750 inline void ArrayString2TextCtrl(const wxArrayString& array, wxTextCtrl* control)
751 {
752  control->Clear();
753  int count = array.GetCount();
754  for (int i = 0; i < count; ++i)
755  {
756  if (!array[i].IsEmpty())
757  {
758  control->AppendText(array[i]);
759  control->AppendText(_T('\n'));
760  }
761  }
762 } // ArrayString2TextCtrl
763 
764 inline void DoGetCompileOptions(wxArrayString& array, const wxTextCtrl* control)
765 {
766 /* NOTE (mandrav#1#): Under Gnome2, wxTextCtrl::GetLineLength() returns always 0,
767  so wxTextCtrl::GetLineText() is always empty...
768  Now, we 're breaking up by newlines. */
769  array.Clear();
770 #if 1
771  wxString tmp = control->GetValue();
772  int nl = tmp.Find(_T('\n'));
773  wxString line;
774  if (nl == -1)
775  {
776  line = tmp;
777  tmp = _T("");
778  }
779  else
780  line = tmp.Left(nl);
781  while (nl != -1 || !line.IsEmpty())
782  {
783 // Manager::Get()->GetLogManager()->DebugLog("%s text=%s", control->GetName().c_str(), line.c_str());
784  if (!line.IsEmpty())
785  {
786  // just to make sure..
787  line.Replace(_T("\r"), _T(" "), true); // remove CRs
788  line.Replace(_T("\n"), _T(" "), true); // remove LFs
789  array.Add(line.Strip(wxString::both));
790  }
791  tmp.Remove(0, nl + 1);
792  nl = tmp.Find(_T('\n'));
793  if (nl == -1)
794  {
795  line = tmp;
796  tmp = _T("");
797  }
798  else
799  line = tmp.Left(nl);
800  }
801 #else
802  int count = control->GetNumberOfLines();
803  for (int i = 0; i < count; ++i)
804  {
805  wxString tmp = control->GetLineText(i);
806  if (!tmp.IsEmpty())
807  {
808  tmp.Replace(_T("\r"), _T(" "), true); // remove CRs
809  tmp.Replace(_T("\n"), _T(" "), true); // remove LFs
810  array.Add(tmp.Strip(wxString::both));
811  }
812  }
813 #endif
814 } // DoGetCompileOptions
815 
817 {
818  wxArrayString CommandsBeforeBuild;
819  wxArrayString CommandsAfterBuild;
820  bool AlwaysUsePost = false;
821  wxArrayString IncludeDirs;
822  wxArrayString LibDirs;
823  wxArrayString ResDirs;
824  if (!m_pProject && !m_pTarget)
825  {
826  // global options
828  if (compiler)
829  {
830  IncludeDirs = compiler->GetIncludeDirs();
831  ResDirs = compiler->GetResourceIncludeDirs();
832  LibDirs = compiler->GetLibDirs();
835  m_LinkerOptions = compiler->GetLinkerOptions();
836  m_LinkLibs = compiler->GetLinkLibs();
837 
838  wxChoice* cmb = XRCCTRL(*this, "cmbLogging", wxChoice);
839  if (cmb)
840  cmb->SetSelection((int)compiler->GetSwitches().logging);
841  }
842  }
843  else
844  {
845  if (!m_pTarget)
846  {
847  // project options
848  SetLabel(_("Project build options"));
849  IncludeDirs = m_pProject->GetIncludeDirs();
850  ResDirs = m_pProject->GetResourceIncludeDirs();
851  LibDirs = m_pProject->GetLibDirs();
856  CommandsAfterBuild = m_pProject->GetCommandsAfterBuild();
857  CommandsBeforeBuild = m_pProject->GetCommandsBeforeBuild();
858  AlwaysUsePost = m_pProject->GetAlwaysRunPostBuildSteps();
859 
860  XRCCTRL(*this, "txtMakeCmd_Build", wxTextCtrl)->SetValue(m_pProject->GetMakeCommandFor(mcBuild));
861  XRCCTRL(*this, "txtMakeCmd_Compile", wxTextCtrl)->SetValue(m_pProject->GetMakeCommandFor(mcCompileFile));
862  XRCCTRL(*this, "txtMakeCmd_Clean", wxTextCtrl)->SetValue(m_pProject->GetMakeCommandFor(mcClean));
863  XRCCTRL(*this, "txtMakeCmd_DistClean", wxTextCtrl)->SetValue(m_pProject->GetMakeCommandFor(mcDistClean));
864  XRCCTRL(*this, "txtMakeCmd_AskRebuildNeeded", wxTextCtrl)->SetValue(m_pProject->GetMakeCommandFor(mcAskRebuildNeeded));
865  XRCCTRL(*this, "txtMakeCmd_SilentBuild", wxTextCtrl)->SetValue(m_pProject->GetMakeCommandFor(mcSilentBuild));
866  }
867  else
868  {
869  // target options
870  SetLabel(_("Target build options: ") + m_pTarget->GetTitle());
871  IncludeDirs = m_pTarget->GetIncludeDirs();
872  ResDirs = m_pTarget->GetResourceIncludeDirs();
873  LibDirs = m_pTarget->GetLibDirs();
878  CommandsAfterBuild = m_pTarget->GetCommandsAfterBuild();
879  CommandsBeforeBuild = m_pTarget->GetCommandsBeforeBuild();
880  AlwaysUsePost = m_pTarget->GetAlwaysRunPostBuildSteps();
881  XRCCTRL(*this, "cmbCompilerPolicy", wxChoice)->SetSelection(m_pTarget->GetOptionRelation(ortCompilerOptions));
882  XRCCTRL(*this, "cmbLinkerPolicy", wxChoice)->SetSelection(m_pTarget->GetOptionRelation(ortLinkerOptions));
883  XRCCTRL(*this, "cmbIncludesPolicy", wxChoice)->SetSelection(m_pTarget->GetOptionRelation(ortIncludeDirs));
884  XRCCTRL(*this, "cmbLibDirsPolicy", wxChoice)->SetSelection(m_pTarget->GetOptionRelation(ortLibDirs));
885  XRCCTRL(*this, "cmbResDirsPolicy", wxChoice)->SetSelection(m_pTarget->GetOptionRelation(ortResDirs));
886 
887  XRCCTRL(*this, "txtMakeCmd_Build", wxTextCtrl)->SetValue(m_pTarget->GetMakeCommandFor(mcBuild));
888  XRCCTRL(*this, "txtMakeCmd_Compile", wxTextCtrl)->SetValue(m_pTarget->GetMakeCommandFor(mcCompileFile));
889  XRCCTRL(*this, "txtMakeCmd_Clean", wxTextCtrl)->SetValue(m_pTarget->GetMakeCommandFor(mcClean));
890  XRCCTRL(*this, "txtMakeCmd_DistClean", wxTextCtrl)->SetValue(m_pTarget->GetMakeCommandFor(mcDistClean));
891  XRCCTRL(*this, "txtMakeCmd_AskRebuildNeeded", wxTextCtrl)->SetValue(m_pTarget->GetMakeCommandFor(mcAskRebuildNeeded));
892  XRCCTRL(*this, "txtMakeCmd_SilentBuild", wxTextCtrl)->SetValue(m_pTarget->GetMakeCommandFor(mcSilentBuild));
893  }
894  }
895  TextToOptions();
896 
897  DoFillOptions();
898  ArrayString2ListBox(IncludeDirs, XRCCTRL(*this, "lstIncludeDirs", wxListBox));
899  ArrayString2ListBox(LibDirs, XRCCTRL(*this, "lstLibDirs", wxListBox));
900  ArrayString2ListBox(ResDirs, XRCCTRL(*this, "lstResDirs", wxListBox));
901  ArrayString2TextCtrl(m_CompilerOptions, XRCCTRL(*this, "txtCompilerOptions", wxTextCtrl));
902  ArrayString2TextCtrl(m_ResourceCompilerOptions, XRCCTRL(*this, "txtResourceCompilerOptions", wxTextCtrl));
903  ArrayString2TextCtrl(m_LinkerOptions, XRCCTRL(*this, "txtLinkerOptions", wxTextCtrl));
904 
905  // only if "Commands" page exists
906  if (m_pProject)
907  {
908  ArrayString2TextCtrl(CommandsBeforeBuild, XRCCTRL(*this, "txtCmdBefore", wxTextCtrl));
909  ArrayString2TextCtrl(CommandsAfterBuild, XRCCTRL(*this, "txtCmdAfter", wxTextCtrl));
910  XRCCTRL(*this, "chkAlwaysRunPost", wxCheckBox)->SetValue(AlwaysUsePost);
911  }
912 } // DoLoadOptions
913 
915 {
916  wxArrayString array;
917  DoGetCompileOptions(array, XRCCTRL(*this, "txtCompilerDefines", wxTextCtrl));
918 
919  int compilerIdx = XRCCTRL(*this, "cmbCompiler", wxChoice)->GetSelection();
920  const Compiler* compiler = CompilerFactory::GetCompiler(compilerIdx);
921 
922  for (unsigned int i = 0; i < array.GetCount(); ++i)
923  {
924  if (!array[i].IsEmpty())
925  {
926  if (array[i].StartsWith(compiler ? compiler->GetSwitches().genericSwitch : _T("-")))
927  {
928  if (m_CompilerOptions.Index(array[i]) == wxNOT_FOUND)
929  m_CompilerOptions.Add(array[i]);
930  }
931  else
932  {
933  if (compiler && m_CompilerOptions.Index(compiler->GetSwitches().defines + array[i]) == wxNOT_FOUND)
934  m_CompilerOptions.Add(compiler->GetSwitches().defines + array[i]);
935  }
936  }
937  }
938 
939  wxArrayString compilerOpConflicts;
940  wxArrayString linkerOpConflicts;
941  for (size_t i = 0; i < m_Options.GetCount(); ++i)
942  {
943  CompOption* copt = m_Options.GetOption(i);
944  if (copt->enabled)
945  {
946  if (!copt->option.Trim().IsEmpty()) // don't add empty options
947  m_CompilerOptions.Insert(copt->option, 0);
948 
949  if (!copt->additionalLibs.Trim().IsEmpty())
950  {
953  }
954  }
955  else
956  {
957  // mark items for removal
959  compilerOpConflicts.Add(copt->option);
961  linkerOpConflicts.Add(copt->additionalLibs);
962  }
963  }
964 
965  if (!compilerOpConflicts.IsEmpty() || !linkerOpConflicts.IsEmpty())
966  {
967  wxString msg = _("The compiler flags\n ")
968  + GetStringFromArray(compilerOpConflicts, wxT("\n "))
969  + GetStringFromArray(linkerOpConflicts, wxT("\n "));
970  msg.RemoveLast(2); // remove two trailing spaces
971  msg += _("were stated in 'Other Options' but unchecked in 'Compiler Flags'.\n"
972  "Do you want to enable these flags?");
973  AnnoyingDialog dlg(_("Enable compiler flags?"), msg, wxART_QUESTION,
975  if (dlg.ShowModal() == AnnoyingDialog::rtNO)
976  {
977  // for disabled options, remove relative text option *and*
978  // relative linker option
979  for (size_t i = 0; i < compilerOpConflicts.GetCount(); ++i)
980  m_CompilerOptions.Remove(compilerOpConflicts[i]);
981  for (size_t i = 0; i < linkerOpConflicts.GetCount(); ++i)
982  m_LinkerOptions.Remove(linkerOpConflicts[i]);
983  }
984  }
985 
986  // linker options and libs
987  wxListBox* lstLibs = XRCCTRL(*this, "lstLibs", wxListBox);
988  for (size_t i = 0; i < lstLibs->GetCount(); ++i)
989  m_LinkLibs.Add(lstLibs->GetString(i));
990 } // OptionsToText
991 
993 {
994  wxArrayString IncludeDirs;
995  wxArrayString LibDirs;
996  wxArrayString ResDirs;
997  ListBox2ArrayString(IncludeDirs, XRCCTRL(*this, "lstIncludeDirs", wxListBox));
998  ListBox2ArrayString(LibDirs, XRCCTRL(*this, "lstLibDirs", wxListBox));
999  ListBox2ArrayString(ResDirs, XRCCTRL(*this, "lstResDirs", wxListBox));
1000  DoGetCompileOptions(m_CompilerOptions, XRCCTRL(*this, "txtCompilerOptions", wxTextCtrl));
1001  DoGetCompileOptions(m_ResourceCompilerOptions, XRCCTRL(*this, "txtResourceCompilerOptions", wxTextCtrl));
1002  DoGetCompileOptions(m_LinkerOptions, XRCCTRL(*this, "txtLinkerOptions", wxTextCtrl));
1003  OptionsToText();
1004 
1005  if (!m_pProject && !m_pTarget)
1006  {
1007  // global options
1009  if (compiler)
1010  {
1011  compiler->SetIncludeDirs(IncludeDirs);
1012  compiler->SetLibDirs(LibDirs);
1013  compiler->SetResourceIncludeDirs(ResDirs);
1016  compiler->SetLinkerOptions(m_LinkerOptions);
1017  compiler->SetLinkLibs(m_LinkLibs);
1018 
1019  wxChoice* cmb = XRCCTRL(*this, "cmbLogging", wxChoice);
1020  if (cmb)
1021  {
1022  CompilerSwitches switches = compiler->GetSwitches();
1023  switches.logging = (CompilerLoggingType)cmb->GetSelection();
1024  compiler->SetSwitches(switches);
1025  }
1026  }
1027  }
1028  else
1029  {
1030  // only if "Commands" page exists
1031  wxArrayString CommandsBeforeBuild;
1032  wxArrayString CommandsAfterBuild;
1033  bool AlwaysUsePost = false;
1034  if (m_pProject)
1035  {
1036  AlwaysUsePost = XRCCTRL(*this, "chkAlwaysRunPost", wxCheckBox)->GetValue();
1037  DoGetCompileOptions(CommandsBeforeBuild, XRCCTRL(*this, "txtCmdBefore", wxTextCtrl));
1038  DoGetCompileOptions(CommandsAfterBuild, XRCCTRL(*this, "txtCmdAfter", wxTextCtrl));
1039  }
1040  if (!m_pTarget)
1041  {
1042  // project options
1043  m_pProject->SetIncludeDirs(IncludeDirs);
1045  m_pProject->SetLibDirs(LibDirs);
1050  m_pProject->SetCommandsBeforeBuild(CommandsBeforeBuild);
1051  m_pProject->SetCommandsAfterBuild(CommandsAfterBuild);
1052  m_pProject->SetAlwaysRunPostBuildSteps(AlwaysUsePost);
1053 
1054  m_pProject->SetMakeCommandFor(mcBuild, XRCCTRL(*this, "txtMakeCmd_Build", wxTextCtrl)->GetValue());
1055  m_pProject->SetMakeCommandFor(mcCompileFile, XRCCTRL(*this, "txtMakeCmd_Compile", wxTextCtrl)->GetValue());
1056  m_pProject->SetMakeCommandFor(mcClean, XRCCTRL(*this, "txtMakeCmd_Clean", wxTextCtrl)->GetValue());
1057  m_pProject->SetMakeCommandFor(mcDistClean, XRCCTRL(*this, "txtMakeCmd_DistClean", wxTextCtrl)->GetValue());
1058  m_pProject->SetMakeCommandFor(mcAskRebuildNeeded, XRCCTRL(*this, "txtMakeCmd_AskRebuildNeeded", wxTextCtrl)->GetValue());
1059 // m_pProject->SetMakeCommandFor(mcSilentBuild, XRCCTRL(*this, "txtMakeCmd_SilentBuild", wxTextCtrl)->GetValue());
1060  m_pProject->SetMakeCommandFor(mcSilentBuild, XRCCTRL(*this, "txtMakeCmd_Build", wxTextCtrl)->GetValue() + _T(" > $(CMD_NULL)"));
1061  }
1062  else
1063  {
1064  // target options
1065  m_pTarget->SetIncludeDirs(IncludeDirs);
1067  m_pTarget->SetLibDirs(LibDirs);
1072  m_pTarget->SetOptionRelation(ortCompilerOptions, OptionsRelation(XRCCTRL(*this, "cmbCompilerPolicy", wxChoice)->GetSelection()));
1073  m_pTarget->SetOptionRelation(ortLinkerOptions, OptionsRelation(XRCCTRL(*this, "cmbLinkerPolicy", wxChoice)->GetSelection()));
1074  m_pTarget->SetOptionRelation(ortIncludeDirs, OptionsRelation(XRCCTRL(*this, "cmbIncludesPolicy", wxChoice)->GetSelection()));
1075  m_pTarget->SetOptionRelation(ortLibDirs, OptionsRelation(XRCCTRL(*this, "cmbLibDirsPolicy", wxChoice)->GetSelection()));
1076  m_pTarget->SetOptionRelation(ortResDirs, OptionsRelation(XRCCTRL(*this, "cmbResDirsPolicy", wxChoice)->GetSelection()));
1077  m_pTarget->SetCommandsBeforeBuild(CommandsBeforeBuild);
1078  m_pTarget->SetCommandsAfterBuild(CommandsAfterBuild);
1079  m_pTarget->SetAlwaysRunPostBuildSteps(AlwaysUsePost);
1080 
1081  m_pTarget->SetMakeCommandFor(mcBuild, XRCCTRL(*this, "txtMakeCmd_Build", wxTextCtrl)->GetValue());
1082  m_pTarget->SetMakeCommandFor(mcCompileFile, XRCCTRL(*this, "txtMakeCmd_Compile", wxTextCtrl)->GetValue());
1083  m_pTarget->SetMakeCommandFor(mcClean, XRCCTRL(*this, "txtMakeCmd_Clean", wxTextCtrl)->GetValue());
1084  m_pTarget->SetMakeCommandFor(mcDistClean, XRCCTRL(*this, "txtMakeCmd_DistClean", wxTextCtrl)->GetValue());
1085  m_pTarget->SetMakeCommandFor(mcAskRebuildNeeded, XRCCTRL(*this, "txtMakeCmd_AskRebuildNeeded", wxTextCtrl)->GetValue());
1086 // m_pTarget->SetMakeCommandFor(mcSilentBuild, XRCCTRL(*this, "txtMakeCmd_SilentBuild", wxTextCtrl)->GetValue());
1087  m_pTarget->SetMakeCommandFor(mcSilentBuild, XRCCTRL(*this, "txtMakeCmd_Build", wxTextCtrl)->GetValue() + _T(" > $(CMD_NULL)"));
1088  }
1089  }
1090 } // DoSaveOptions
1091 
1093 {
1095  if (m_pProject || !compiler) // no "Programs" page or no compiler
1096  return;
1097 
1098  CompilerPrograms progs;
1099  wxString masterPath = XRCCTRL(*this, "txtMasterPath", wxTextCtrl)->GetValue();
1100  progs.C = (XRCCTRL(*this, "txtCcompiler", wxTextCtrl)->GetValue()).Trim();
1101  progs.CPP = (XRCCTRL(*this, "txtCPPcompiler", wxTextCtrl)->GetValue()).Trim();
1102  progs.LD = (XRCCTRL(*this, "txtLinker", wxTextCtrl)->GetValue()).Trim();
1103  progs.LIB = (XRCCTRL(*this, "txtLibLinker", wxTextCtrl)->GetValue()).Trim();
1104  progs.WINDRES = (XRCCTRL(*this, "txtResComp", wxTextCtrl)->GetValue()).Trim();
1105  progs.MAKE = (XRCCTRL(*this, "txtMake", wxTextCtrl)->GetValue()).Trim();
1106  wxChoice *cmbDebugger = XRCCTRL(*this, "cmbDebugger", wxChoice);
1107  if (cmbDebugger)
1108  {
1109  int index = cmbDebugger->GetSelection();
1110  const DebuggerClientData* data = static_cast<const DebuggerClientData*>(cmbDebugger->GetClientObject(index));
1111  progs.DBGconfig = data->string;
1112  }
1113  compiler->SetPrograms(progs);
1114  compiler->SetMasterPath(masterPath);
1115  // and the extra paths
1116  wxListBox* control = XRCCTRL(*this, "lstExtraPaths", wxListBox);
1117  if (control)
1118  {
1119  // get all listBox entries in array String
1120  wxArrayString extraPaths;
1121  ListBox2ArrayString(extraPaths, control);
1122  compiler->SetExtraPaths(extraPaths);
1123  }
1124 } // DoSaveCompilerPrograms
1125 
1127 {
1128  CompileOptionsBase* pBase = GetVarsOwner();
1129  if (pBase)
1130  {
1131  // let's process all the stored CustomVarActions
1132  for (unsigned int idxAction = 0; idxAction < m_CustomVarActions.size(); ++idxAction)
1133  {
1134  CustomVarAction Action = m_CustomVarActions[idxAction];
1135  switch(Action.m_Action)
1136  {
1137  case CVA_Add:
1138  pBase->SetVar(Action.m_Key, Action.m_KeyValue);
1139  break;
1140  case CVA_Edit:
1141  {
1142  // first split up the KeyValue
1143  wxString NewKey = Action.m_KeyValue.BeforeFirst(_T('=')).Trim(true).Trim(false);
1144  wxString NewValue = Action.m_KeyValue.AfterFirst(_T('=')).Trim(true).Trim(false);
1145  if (Action.m_Key != NewKey)
1146  { // the key name changed
1147  pBase->UnsetVar(Action.m_Key);
1148  }
1149  pBase->SetVar(NewKey, NewValue);
1150  break;
1151  }
1152  case CVA_Remove:
1153  pBase->UnsetVar(Action.m_Key);
1154  break;
1155  default:
1156  break;
1157  } // end switch
1158  } // end for : idx : idxAction
1159  m_CustomVarActions.clear();
1160  }
1161 } // DoSaveVars
1162 
1164 {
1165  wxXmlNode* root = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("CodeBlocks_compiler_options"));
1167  const wxString name = wxT("name");
1168  const wxString value = wxT("value");
1169  wxXmlNode* node = new wxXmlNode(root, wxXML_ELEMENT_NODE, wxT("Program"));
1170  node->AddAttribute(name, wxT("C"));
1171  node->AddAttribute(value, compiler->GetPrograms().C);
1172  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Program")));
1173  node = node->GetNext();
1174  node->AddAttribute(name, wxT("CPP"));
1175  node->AddAttribute(value, compiler->GetPrograms().CPP);
1176  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Program")));
1177  node = node->GetNext();
1178  node->AddAttribute(name, wxT("LD"));
1179  node->AddAttribute(value, compiler->GetPrograms().LD);
1180  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Program")));
1181  node = node->GetNext();
1182  node->AddAttribute(name, wxT("DBGconfig"));
1183  node->AddAttribute(value, compiler->GetPrograms().DBGconfig);
1184  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Program")));
1185  node = node->GetNext();
1186  node->AddAttribute(name, wxT("LIB"));
1187  node->AddAttribute(value, compiler->GetPrograms().LIB);
1188  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Program")));
1189  node = node->GetNext();
1190  node->AddAttribute(name, wxT("WINDRES"));
1191  node->AddAttribute(value, compiler->GetPrograms().WINDRES);
1192  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Program")));
1193  node = node->GetNext();
1194  node->AddAttribute(name, wxT("MAKE"));
1195  node->AddAttribute(value, compiler->GetPrograms().MAKE);
1196 
1197 
1198  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Switch")));
1199  node = node->GetNext();
1200  node->AddAttribute(name, wxT("includeDirs"));
1201  node->AddAttribute(value, compiler->GetSwitches().includeDirs);
1202  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Switch")));
1203  node = node->GetNext();
1204  node->AddAttribute(name, wxT("libDirs"));
1205  node->AddAttribute(value, compiler->GetSwitches().libDirs);
1206  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Switch")));
1207  node = node->GetNext();
1208  node->AddAttribute(name, wxT("linkLibs"));
1209  node->AddAttribute(value, compiler->GetSwitches().linkLibs);
1210  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Switch")));
1211  node = node->GetNext();
1212  node->AddAttribute(name, wxT("defines"));
1213  node->AddAttribute(value, compiler->GetSwitches().defines);
1214  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Switch")));
1215  node = node->GetNext();
1216  node->AddAttribute(name, wxT("genericSwitch"));
1217  node->AddAttribute(value, compiler->GetSwitches().genericSwitch);
1218  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Switch")));
1219  node = node->GetNext();
1220  node->AddAttribute(name, wxT("objectExtension"));
1221  node->AddAttribute(value, compiler->GetSwitches().objectExtension);
1222  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Switch")));
1223  node = node->GetNext();
1224  node->AddAttribute(name, wxT("forceFwdSlashes"));
1225  node->AddAttribute(value, (compiler->GetSwitches().forceFwdSlashes ? wxT("true") : wxT("false")));
1226  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Switch")));
1227  node = node->GetNext();
1228  node->AddAttribute(name, wxT("forceLinkerUseQuotes"));
1229  node->AddAttribute(value, (compiler->GetSwitches().forceLinkerUseQuotes ? wxT("true") : wxT("false")));
1230  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Switch")));
1231  node = node->GetNext();
1232  node->AddAttribute(name, wxT("forceCompilerUseQuotes"));
1233  node->AddAttribute(value, (compiler->GetSwitches().forceCompilerUseQuotes ? wxT("true") : wxT("false")));
1234  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Switch")));
1235  node = node->GetNext();
1236  node->AddAttribute(name, wxT("needDependencies"));
1237  node->AddAttribute(value, (compiler->GetSwitches().needDependencies ? wxT("true") : wxT("false")));
1238  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Switch")));
1239  node = node->GetNext();
1240  node->AddAttribute(name, wxT("logging"));
1242  node->AddAttribute(value, wxT("default"));
1243  else if (compiler->GetSwitches().logging == clogFull)
1244  node->AddAttribute(value, wxT("full"));
1245  else if (compiler->GetSwitches().logging == clogSimple)
1246  node->AddAttribute(value, wxT("simple"));
1247  else if (compiler->GetSwitches().logging == clogNone)
1248  node->AddAttribute(value, wxT("none"));
1249  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Switch")));
1250  node = node->GetNext();
1251  node->AddAttribute(name, wxT("libPrefix"));
1252  node->AddAttribute(value, compiler->GetSwitches().libPrefix);
1253  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Switch")));
1254  node = node->GetNext();
1255  node->AddAttribute(name, wxT("libExtension"));
1256  node->AddAttribute(value, compiler->GetSwitches().libExtension);
1257  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Switch")));
1258  node = node->GetNext();
1259  node->AddAttribute(name, wxT("linkerNeedsLibPrefix"));
1260  node->AddAttribute(value, (compiler->GetSwitches().linkerNeedsLibPrefix ? wxT("true") : wxT("false")));
1261  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Switch")));
1262  node = node->GetNext();
1263  node->AddAttribute(name, wxT("linkerNeedsLibExtension"));
1264  node->AddAttribute(value, (compiler->GetSwitches().linkerNeedsLibExtension ? wxT("true") : wxT("false")));
1265  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Switch")));
1266  node = node->GetNext();
1267  node->AddAttribute(name, wxT("linkerNeedsPathResolved"));
1268  node->AddAttribute(value, (compiler->GetSwitches().linkerNeedsPathResolved ? wxT("true") : wxT("false")));
1269  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Switch")));
1270  node = node->GetNext();
1271  node->AddAttribute(name, wxT("supportsPCH"));
1272  node->AddAttribute(value, (compiler->GetSwitches().supportsPCH ? wxT("true") : wxT("false")));
1273  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Switch")));
1274  node = node->GetNext();
1275  node->AddAttribute(name, wxT("PCHExtension"));
1276  node->AddAttribute(value, compiler->GetSwitches().PCHExtension);
1277  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Switch")));
1278  node = node->GetNext();
1279  node->AddAttribute(name, wxT("UseFlatObjects"));
1280  node->AddAttribute(value, (compiler->GetSwitches().UseFlatObjects ? wxT("true") : wxT("false")));
1281  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Switch")));
1282  node = node->GetNext();
1283  node->AddAttribute(name, wxT("UseFullSourcePaths"));
1284  node->AddAttribute(value, (compiler->GetSwitches().UseFullSourcePaths ? wxT("true") : wxT("false")));
1285  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Switch")));
1286  node = node->GetNext();
1287  node->AddAttribute(name, wxT("includeDirSeparator"));
1288  node->AddAttribute(value, compiler->GetSwitches().includeDirSeparator);
1289  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Switch")));
1290  node = node->GetNext();
1291  node->AddAttribute(name, wxT("libDirSeparator"));
1292  node->AddAttribute(value, compiler->GetSwitches().libDirSeparator);
1293  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Switch")));
1294  node = node->GetNext();
1295  node->AddAttribute(name, wxT("objectSeparator"));
1296  node->AddAttribute(value, compiler->GetSwitches().objectSeparator);
1297  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Switch")));
1298  node = node->GetNext();
1299  node->AddAttribute(name, wxT("statusSuccess"));
1300  node->AddAttribute(value, wxString::Format(wxT("%d"), compiler->GetSwitches().statusSuccess));
1301  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Switch")));
1302  node = node->GetNext();
1303  node->AddAttribute(name, wxT("Use83Paths"));
1304  node->AddAttribute(value, (compiler->GetSwitches().Use83Paths ? wxT("true") : wxT("false")));
1305 
1306  for (size_t i = 0; i < m_Options.GetCount(); ++i)
1307  {
1308  CompOption* opt = m_Options.GetOption(i);
1309  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Option")));
1310  node = node->GetNext();
1311  wxString oName;
1312  opt->name.EndsWith(wxT("[") + opt->option + wxT("]"), &oName);
1313  if (oName == wxEmptyString)
1314  opt->name.EndsWith(wxT("[") + opt->additionalLibs + wxT("]"), &oName);
1315  if (oName == wxEmptyString)
1316  oName = opt->name;
1317  node->AddAttribute(name, oName.Trim());
1318  if (opt->option != wxEmptyString)
1319  node->AddAttribute(wxT("option"), opt->option);
1320  if (opt->category != wxT("General"))
1321  node->AddAttribute(wxT("category"), opt->category);
1322  if (opt->additionalLibs != wxEmptyString)
1323  node->AddAttribute(wxT("additionalLibs"), opt->additionalLibs);
1324  if (opt->checkAgainst != wxEmptyString)
1325  {
1326  node->AddAttribute(wxT("checkAgainst"), opt->checkAgainst);
1327  node->AddAttribute(wxT("checkMessage"), opt->checkMessage);
1328  }
1329  if (opt->supersedes != wxEmptyString)
1330  node->AddAttribute(wxT("supersedes"), opt->supersedes);
1331  if (opt->exclusive)
1332  node->AddAttribute(wxT("exclusive"), wxT("true"));
1333  }
1334 
1335  for (int i = 0; i < ctCount; ++i)
1336  {
1337  const CompilerToolsVector& vec = compiler->GetCommandToolsVector((CommandType)i);
1338  wxString op;
1339  if (i == ctCompileObjectCmd)
1340  op = wxT("CompileObject");
1341  else if (i == ctGenDependenciesCmd)
1342  op = wxT("GenDependencies");
1343  else if (i == ctCompileResourceCmd)
1344  op = wxT("CompileResource");
1345  else if (i == ctLinkExeCmd)
1346  op = wxT("LinkExe");
1347  else if (i == ctLinkConsoleExeCmd)
1348  op = wxT("LinkConsoleExe");
1349  else if (i == ctLinkDynamicCmd)
1350  op = wxT("LinkDynamic");
1351  else if (i == ctLinkStaticCmd)
1352  op = wxT("LinkStatic");
1353  else if (i == ctLinkNativeCmd)
1354  op = wxT("LinkNative");
1355  for (size_t j = 0; j < vec.size(); ++j)
1356  {
1357  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Command")));
1358  node = node->GetNext();
1359  node->AddAttribute(name, op);
1360  node->AddAttribute(value, vec[j].command);
1361  if (!vec[j].extensions.IsEmpty())
1362  node->AddAttribute(wxT("ext"), GetStringFromArray(vec[j].extensions, DEFAULT_ARRAY_SEP, false));
1363  if (!vec[j].generatedFiles.IsEmpty())
1364  node->AddAttribute(wxT("gen"), GetStringFromArray(vec[j].generatedFiles, DEFAULT_ARRAY_SEP, false));
1365  }
1366  }
1367 
1368  const RegExArray& regexes = compiler->GetRegExArray();
1369  for (size_t i = 0; i < regexes.size(); ++i)
1370  {
1371  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("RegEx")));
1372  node = node->GetNext();
1373  node->AddAttribute(name, regexes[i].desc);
1374  wxString tp;
1375  if (regexes[i].lt == cltNormal)
1376  tp = wxT("normal");
1377  else if (regexes[i].lt == cltWarning)
1378  tp = wxT("warning");
1379  else if (regexes[i].lt == cltError)
1380  tp = wxT("error");
1381  else if (regexes[i].lt == cltInfo)
1382  tp = wxT("info");
1383  node->AddAttribute(wxT("type"), tp);
1384  tp = wxString::Format(wxT("%d;%d;%d"), regexes[i].msg[0], regexes[i].msg[1], regexes[i].msg[2]);
1385  tp.Replace(wxT(";0"), wxEmptyString);
1386  node->AddAttribute(wxT("msg"), tp);
1387  if (regexes[i].filename != 0)
1388  node->AddAttribute(wxT("file"), wxString::Format(wxT("%d"), regexes[i].filename));
1389  if (regexes[i].line != 0)
1390  node->AddAttribute(wxT("line"), wxString::Format(wxT("%d"), regexes[i].line));
1391  tp = regexes[i].GetRegExString();
1392  tp.Replace(wxT("\t"), wxT("\\t"));
1394  }
1395 
1396  if (!compiler->GetCOnlyFlags().IsEmpty())
1397  {
1398  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Sort")));
1399  node = node->GetNext();
1400  node->AddAttribute(wxT("CFlags"), compiler->GetCOnlyFlags());
1401  }
1402  if (!compiler->GetCPPOnlyFlags().IsEmpty())
1403  {
1404  node->SetNext(new wxXmlNode(wxXML_ELEMENT_NODE, wxT("Sort")));
1405  node = node->GetNext();
1406  node->AddAttribute(wxT("CPPFlags"), compiler->GetCPPOnlyFlags());
1407  }
1408 
1409  wxXmlDocument doc;
1410  doc.SetVersion(wxT("1.0"));
1411  doc.SetRoot(root);
1412  if (!wxDirExists(ConfigManager::GetFolder(sdDataUser) + wxT("/compilers")))
1413  wxMkdir(ConfigManager::GetFolder(sdDataUser) + wxT("/compilers"));
1414  doc.Save(ConfigManager::GetFolder(sdDataUser) + wxT("/compilers/options_") + compiler->GetID() + wxT(".xml"));
1415 
1416  // update the in-memory cache
1417  compiler->SetOptions(m_Options);
1418 } // DoSaveCompilerDefinition
1419 
1420 // events
1421 
1423 {
1424  m_bDirty = true;
1425 } // OnDirty
1426 
1428 { // note this can also be called when on global compiler level, won't do anything (well reset a member which has
1429  // no use in this case)
1430  // check if the compilerID needs to be updated
1431  if (m_pTarget)
1432  { // target was the (tree) selection
1434  {
1436  cbMessageBox(_("You changed the compiler used for this target.\n"
1437  "It is recommended that you fully rebuild this target, "
1438  "otherwise linking errors might occur..."),
1439  _("Notice"),
1441  }
1442  }
1443  else if (m_pProject)
1444  { // the project was the (tree) selection
1446  { // should be project then
1449  cbMessageBox(_("You changed the compiler used for this project.\n"
1450  "It is recommended that you fully rebuild this project, "
1451  "otherwise linking errors might occur..."),
1452  _("Notice"),
1454  }
1455  }
1457 } // ProjectTargetCompilerAdjust
1458 
1460 {
1461  if (m_BuildingTree)
1462  return;
1463  wxTreeCtrl* tc = XRCCTRL(*this, "tcScope", wxTreeCtrl);
1464  ScopeTreeData* data = (ScopeTreeData*)tc->GetItemData(event.GetItem());
1465  if (!data)
1466  return;
1467  int compilerIdx = data->GetTarget() ? CompilerFactory::GetCompilerIndex(data->GetTarget()->GetCompilerID()) :
1469  XRCCTRL(*this, "cmbCompiler", wxChoice)->GetSelection());
1470  // in order to support projects/targets which have an unknown "user compiler", that is on the current
1471  // system that compiler is not (or no longer) installed, we should check the compilerIdx, in such a case it will
1472  // be '-1' [NOTE : maybe to the check already on the Id ?]
1473  // we then allow the user to make a choice :
1474  // a) adjust to another compiler
1475  // b) leave that compiler --> no settings can be set then (done by disabling the notebook,
1476  // as a consequence might need to be re-enabled when another target/project is chosen in the tree)
1477  if (compilerIdx != -1)
1478  {
1479  wxNotebook* nb = XRCCTRL(*this, "nbMain", wxNotebook);
1480  XRCCTRL(*this, "cmbCompiler", wxChoice)->SetSelection(compilerIdx);
1481  // we don't update the compiler index yet, we leave that to CompilerChanged();
1482  m_pTarget = data->GetTarget();
1484  {
1485  if (nb)
1486  nb->Disable();
1487  }
1488  else
1489  {
1490  if (nb)
1491  {
1492  // enable/disable invalid pages for commands only target
1493  const bool cmd = (m_pTarget && m_pTarget->GetTargetType() == ttCommandsOnly);
1494  int pageOffset;
1495  if (!m_pProject->IsMakefileCustom())
1496  {
1497  nb->GetPage(0)->Enable(!cmd); // Compiler settings
1498  nb->GetPage(1)->Enable(!cmd); // Linker settings
1499  nb->GetPage(2)->Enable(!cmd); // Search directories
1500  pageOffset = 3;
1501  }
1502  else
1503  pageOffset = 0;
1504  nb->GetPage(pageOffset + 2)->Enable(!cmd); // "Make" commands
1505  if ( cmd
1506  && nb->GetSelection() != pageOffset // Pre/post build steps
1507  && nb->GetSelection() != pageOffset + 1 ) // Custom variables
1508  {
1509  nb->SetSelection(pageOffset);
1510  }
1511 
1512  nb->Enable();
1513  }
1514  // the new selection might have a different compiler settings and/or even a different compiler
1515  // load all those new settings
1516  m_CurrentCompilerIdx = compilerIdx;
1518  if (compiler)
1519  m_Options = compiler->GetOptions();
1521  }
1522  }
1523  else
1524  {
1525  m_pTarget = data->GetTarget();
1527  wxString msg;
1528  msg.Printf(_("The defined compiler cannot be located (ID: %s).\n"
1529  "Please choose the compiler you want to use instead and click \"OK\".\n"
1530  "If you click \"Cancel\", the project/target will remain configured for that compiler and consequently can not be configured and will not be built."),
1531  CompilerId.wx_str());
1532  Compiler* compiler = 0;
1534  compiler = CompilerFactory::SelectCompilerUI(msg);
1535 
1536  if (compiler)
1537  { // a new compiler was chosen, proceed as if the user manually selected another compiler
1538  // that means set the compiler selection list accordingly
1539  // and go directly to (On)CompilerChanged
1540  int NewCompilerIdx = CompilerFactory::GetCompilerIndex(compiler);
1541  XRCCTRL(*this, "cmbCompiler", wxChoice)->SetSelection(NewCompilerIdx);
1542  wxCommandEvent Dummy;
1543  OnCompilerChanged(Dummy);
1544  }
1545  else
1546  { // the user cancelled and wants to keep the compiler
1547  if (wxNotebook* nb = XRCCTRL(*this, "nbMain", wxNotebook))
1548  nb->Disable();
1549  }
1550  }
1551 } // OnTreeSelectionChange
1552 
1554 {
1555  if (m_BuildingTree)
1556  return;
1557  wxTreeCtrl* tc = XRCCTRL(*this, "tcScope", wxTreeCtrl);
1558  ScopeTreeData* data = (ScopeTreeData*)tc->GetItemData(event.GetOldItem());
1559  if (data && (m_bDirty || m_bFlagsDirty))
1560  { // data : should always be the case, since on global compiler level, there's no tree
1561  // when changes are made prompt the user if these changes should be applied
1562  // YES -> do the changes
1563  // NO -> no changes, just switch
1564  // CANCEL : don't switch
1565 
1566  AnnoyingDialog dlg(_("Project/Target change with changed settings"),
1567  _("You have changed some settings. Do you want these settings saved ?\n\n"
1568  "Yes : will apply the changes\n"
1569  "No : will undo the changes\n"
1570  "Cancel : will revert your selection in the project/target tree"),
1573 
1574  switch(dlg.ShowModal())
1575  {
1576  case AnnoyingDialog::rtYES :
1578  break;
1580  event.Veto();
1581  break;
1582  case AnnoyingDialog::rtNO :
1583  default:
1584  {
1585  m_bDirty = false;
1586  m_bFlagsDirty = false;
1587  }
1588  break;
1589  } // end switch
1590  }
1591 } // OnTreeSelectionChanging
1592 
1594 {
1595  // when changes are made prompt the user if these changes should be applied
1596  // YES -> do the changes
1597  // NO -> no changes, just switch
1598  // CANCEL : don't switch
1599  bool bChanged = true;
1600  if (m_bDirty || m_bFlagsDirty)
1601  {
1602  switch(cbMessageBox(_("You have changed some settings. Do you want these settings saved ?\n\n"
1603  "Yes : will apply the changes\n"
1604  "No : will undo the changes\n"
1605  "Cancel : will revert your compiler change."),
1606  _("Compiler change with changed settings"),
1608  {
1609  case wxID_CANCEL :
1610  XRCCTRL(*this, "cmbCompiler", wxChoice)->SetSelection(m_CurrentCompilerIdx);
1611  bChanged = false;
1612  break;
1613  case wxID_YES :
1615  break;
1616  case wxID_NO :
1617  default:
1618  m_bDirty = false;
1619  m_bFlagsDirty = false;
1620  break;
1621  } // end switch
1622  }
1623  if (bChanged)
1624  {
1625  CompilerChanged();
1626  if (m_pProject)
1627  { // in case of project/target --> dirty
1628  m_bDirty = true;
1629  }
1630  }
1631 } // OnCompilerChanged
1632 
1634 {
1635  m_CurrentCompilerIdx = XRCCTRL(*this, "cmbCompiler", wxChoice)->GetSelection();
1636  // in case we are not on the global level (== project/target) we need to remember this switch
1637  // so that on "SAVE" time we can adjust the project/target with it's new compiler
1638  // SAVE time for this particular setting means (Apply or TreeSelection change
1639  // not compiler change since we could (re)change the compiler of that project/target
1640  if (m_pProject)
1641  {
1643  }
1644  //load the new options (== options of the new selected compiler)
1646  if (compiler)
1647  m_Options = compiler->GetOptions();
1649 } // CompilerChanged
1650 
1652 {
1653  int ret = cbMessageBox(_("You have changed the compiler used for the project.\n"
1654  "Do you want to use the same compiler for all the project's build targets too?"),
1655  _("Question"),
1657  if (ret == wxID_YES)
1658  {
1659  for (int i = 0; i < m_pProject->GetBuildTargetsCount(); ++i)
1660  {
1662  Compiler* compiler = CompilerFactory::GetCompiler(compilerIdx);
1663  if (compiler)
1664  target->SetCompilerID(compiler->GetID());
1665  }
1666  }
1667 } // UpdateCompilerForTargets
1668 
1670 {
1672  if (!compiler)
1673  return;
1674 
1675  wxString backup = XRCCTRL(*this, "txtMasterPath", wxTextCtrl)->GetValue();
1676  wxArrayString ExtraPathsBackup = compiler->GetExtraPaths();
1677 
1679  compiler->SetExtraPaths(empty);
1680 
1681  switch (compiler->AutoDetectInstallationDir())
1682  {
1683  case adrDetected:
1684  {
1685  wxString msg;
1686  msg.Printf(_("Auto-detected installation path of \"%s\"\nin \"%s\""), compiler->GetName().wx_str(), compiler->GetMasterPath().wx_str());
1687  cbMessageBox(msg);
1688  }
1689  break;
1690 
1691  case adrGuessed:
1692  {
1693  wxString msg;
1694  msg.Printf(_("Could not auto-detect installation path of \"%s\"...\n"
1695  "Do you want to use this compiler's default installation directory?"),
1696  compiler->GetName().wx_str());
1697  if (cbMessageBox(msg, _("Confirmation"), wxICON_QUESTION | wxYES_NO) == wxID_NO)
1698  {
1699  compiler->SetMasterPath(backup);
1700  compiler->SetExtraPaths(ExtraPathsBackup);
1701  }
1702  }
1703  break;
1704 
1705  default:
1706  break;
1707  }
1708  XRCCTRL(*this, "txtMasterPath", wxTextCtrl)->SetValue(compiler->GetMasterPath());
1709  XRCCTRL(*this, "lstExtraPaths", wxListBox)->Clear();
1711  ArrayString2ListBox(extraPaths, XRCCTRL(*this, "lstExtraPaths", wxListBox));
1712  m_bDirty = true;
1713 } // AutoDetectCompiler
1714 
1716 {
1717  wxNotebook* nb = XRCCTRL(*this, "nbDirs", wxNotebook);
1718  if (!nb)
1719  return 0;
1720  switch (nb->GetSelection())
1721  {
1722  case 0: // compiler dirs
1723  return XRCCTRL(*this, "lstIncludeDirs", wxListBox);
1724  case 1: // linker dirs
1725  return XRCCTRL(*this, "lstLibDirs", wxListBox);
1726  case 2: // resource compiler dirs
1727  return XRCCTRL(*this, "lstResDirs", wxListBox);
1728  default: break;
1729  }
1730  return 0;
1731 } // GetDirsListBox
1732 
1734 {
1735  return m_pTarget ? m_pTarget
1736  : (m_pProject ? m_pProject
1738 } // GetVarsOwner
1739 
1741 { // reshow the compiler options, but with different filter (category) applied
1742  DoFillOptions();
1743 } // OnCategoryChanged
1744 
1746 {
1747  wxPGProperty* property = event.GetProperty();
1748  if (!property)
1749  return;
1750  // Make sure the property is bool. Other properties are ignored for now.
1751  if (!property->IsKindOf(CLASSINFO(wxBoolProperty)))
1752  return;
1753  CompOption* option = m_Options.GetOptionByName(property->GetLabel());
1754  wxVariant value = property->GetValue();
1755  if (value.IsNull() || !option)
1756  return;
1757  option->enabled = value.GetBool();
1758  if (option->enabled)
1759  {
1760  if (!option->checkAgainst.IsEmpty())
1761  {
1762  wxArrayString check = GetArrayFromString(option->checkAgainst, wxT(" "));
1763  for (size_t i = 0; i < check.Count(); ++i)
1764  {
1765  CompOption* against = m_Options.GetOptionByOption(check[i]);
1766  if (!against)
1767  against = m_Options.GetOptionByAdditionalLibs(check[i]);
1768  if (against && against->enabled)
1769  {
1770  wxString message = (option->checkMessage.IsEmpty() ?
1771  wxT("\"") + option->name + _("\" conflicts with \"") + against->name + wxT("\".") :
1772  option->checkMessage );
1773  AnnoyingDialog dlg(_("Compiler options conflict"),
1774  message,
1777  dlg.ShowModal();
1778  break;
1779  }
1780  }
1781  }
1782  if (option->supersedes != wxEmptyString)
1783  {
1784  wxArrayString supersede = GetArrayFromString(option->supersedes, wxT(" "));
1785  for (size_t i = 0; i < supersede.Count(); ++i)
1786  {
1787  for (size_t j = 0; j < m_Options.GetCount(); ++j)
1788  {
1789  if (option != m_Options.GetOption(j) &&
1790  (supersede[i] == m_Options.GetOption(j)->option ||
1791  supersede[i] == m_Options.GetOption(j)->additionalLibs))
1792  {
1793  m_Options.GetOption(j)->enabled = false;
1794  }
1795  }
1796 
1797  for (wxPropertyGridIterator it = m_FlagsPG->GetIterator(); !it.AtEnd(); ++it)
1798  {
1799  wxPGProperty* p = *it;
1800  if (p->IsCategory() || p == property)
1801  continue;
1802  if (p->GetLabel().EndsWith(wxT("[") + supersede[i] + wxT("]")))
1803  m_FlagsPG->SetPropertyValue(p, false);
1804  }
1805  }
1806  }
1807  if (option->exclusive)
1808  {
1809  for (size_t i = 0; i < m_Options.GetCount(); ++i)
1810  {
1811  if (option != m_Options.GetOption(i) &&
1812  option->category == m_Options.GetOption(i)->category)
1813  {
1814  m_Options.GetOption(i)->enabled = false;
1815  }
1816  }
1817  for (wxPropertyGridIterator it = m_FlagsPG->GetIterator(); !it.AtEnd(); ++it)
1818  {
1819  wxPGProperty* p = *it;
1820  if (p->IsCategory() || p == property)
1821  continue;
1823  if (option != opt && option->category == opt->category)
1824  m_FlagsPG->SetPropertyValue(p, false);
1825  }
1826  }
1827  }
1828  m_bDirty = true;
1829 }
1830 
1831 // some handlers for adding/editing/removing/clearing of include/libraries/resources directories
1833 {
1834  EditPathDlg dlg(this,
1835  m_pProject ? m_pProject->GetBasePath() : _T(""),
1836  m_pProject ? m_pProject->GetBasePath() : _T(""),
1837  _("Add directory"));
1838 
1839  PlaceWindow(&dlg);
1840  if (dlg.ShowModal() == wxID_OK)
1841  {
1842  wxString path = dlg.GetPath();
1843 
1844  wxListBox* control = GetDirsListBox();
1845  if (control)
1846  {
1847  control->Append(path);
1848  m_bDirty = true;
1849  }
1850  }
1851 } // OnAddDirClick
1852 
1854 {
1855  wxListBox* control = GetDirsListBox();
1856  wxArrayInt selections;
1857  if (!control || control->GetSelections(selections) < 1)
1858  return;
1859 
1860  if (selections.GetCount()>1)
1861  {
1862  cbMessageBox(_("Please select only one directory you would like to edit."),
1863  _("Error"), wxICON_ERROR);
1864  return;
1865  }
1866 
1867  EditPathDlg dlg(this,
1868  control->GetString(selections[0]),
1869  m_pProject ? m_pProject->GetBasePath() : _T(""),
1870  _("Edit directory"));
1871 
1872  PlaceWindow(&dlg);
1873  if (dlg.ShowModal() == wxID_OK)
1874  {
1875  wxString path = dlg.GetPath();
1876  control->SetString(selections[0], path);
1877  m_bDirty = true;
1878  }
1879 } // OnEditDirClick
1880 
1882 {
1883  wxListBox* control = GetDirsListBox();
1884  wxArrayInt selections;
1885  if (!control || control->GetSelections(selections) < 1)
1886  return;
1887 
1888  if (cbMessageBox(_("Remove selected folders from the list?"),
1889  _("Confirmation"),
1891  {
1892  std::sort(selections.begin(), selections.end());
1893  for (unsigned int i=selections.GetCount(); i>0; --i)
1894  control->Delete(selections[i-1]);
1895  m_bDirty = true;
1896  }
1897 } // OnRemoveDirClick
1898 
1900 {
1901  wxListBox* control = GetDirsListBox();
1902  if (!control || control->GetCount() == 0)
1903  return;
1904 
1905  if (cbMessageBox(_("Remove all directories from the list?"),
1906  _("Confirmation"),
1908  {
1909  control->Clear();
1910  m_bDirty = true;
1911  }
1912 } // OnClearDirClick
1913 
1915 {
1916  if (!m_pProject)
1917  return;
1918 
1919  wxListBox* control = GetDirsListBox();
1920  wxArrayInt selections;
1921  if (!control || control->GetSelections(selections) < 1)
1922  return;
1923 
1924  wxArrayString choices;
1925  choices.Add(m_pProject->GetTitle());
1926  for (int i = 0; i < m_pProject->GetBuildTargetsCount(); ++i)
1927  {
1929  choices.Add(bt->GetTitle());
1930  }
1931 
1932  const wxArrayInt &sel = cbGetMultiChoiceDialog(_("Please select which target to copy these directories to:"),
1933  _("Copy directories"), choices, this);
1934  if (sel.empty())
1935  return;
1936 
1937  wxNotebook* nb = XRCCTRL(*this, "nbDirs", wxNotebook);
1938  int notebookPage = nb->GetSelection();
1939 
1940  for (wxArrayInt::const_iterator itr = sel.begin(); itr != sel.end(); ++itr)
1941  {
1942  CompileOptionsBase* base;
1943  if((*itr) == 0)
1944  base = m_pProject; // "copy to project"
1945  else
1946  base = m_pProject->GetBuildTarget((*itr) - 1);
1947 
1948  if (!base)
1949  {
1950  Manager::Get()->GetLogManager()->LogWarning(_T("Could not get build target in CompilerOptionsDlg::OnCopyLibsClick"));
1951  continue;
1952  }
1953 
1954  for (size_t i = 0; i < selections.GetCount(); ++i)
1955  {
1956  switch (notebookPage)
1957  {
1958  case 0: // compiler dirs
1959  base->AddIncludeDir(control->GetString(selections[i]));
1960  break;
1961  case 1: // linker dirs
1962  base->AddLibDir(control->GetString(selections[i]));
1963  break;
1964  case 2: // resource compiler dirs
1965  base->AddResourceIncludeDir(control->GetString(selections[i]));
1966  break;
1967  default:
1968  break;
1969  }
1970  }
1971  }
1972 } // OnCopyDirsClick
1973 
1974 static void QuoteString(wxString &value, const wxString &caption)
1975 {
1976  if (NeedQuotes(value))
1977  {
1978  AnnoyingDialog dlgQuestion(caption, wxT("Variable quote string"),
1979  _("The value contains spaces or strange characters. Do you want to quote it?"),
1981  _("&Quote"), _("&Leave unquoted"));
1982  if (dlgQuestion.ShowModal() == AnnoyingDialog::rtYES)
1983  ::QuoteStringIfNeeded(value);
1984  }
1985 }
1986 
1988 {
1989  wxString key;
1990  wxString value;
1991  EditPairDlg dlg(this, key, value, _("Add new variable"), EditPairDlg::bmBrowseForDirectory);
1992  PlaceWindow(&dlg);
1993  if (dlg.ShowModal() == wxID_OK)
1994  {
1995  key.Trim(true).Trim(false);
1996  value.Trim(true).Trim(false);
1997  QuoteString(value, _("Add variable quote string"));
1998  CustomVarAction Action = {CVA_Add, key, value};
1999  m_CustomVarActions.push_back(Action);
2000  XRCCTRL(*this, "lstVars", wxListBox)->Append(key + _T(" = ") + value, new VariableListClientData(key, value));
2001  m_bDirty = true;
2002  }
2003 } // OnAddVarClick
2004 
2006 {
2007  wxListBox *list = XRCCTRL(*this, "lstVars", wxListBox);
2008  int sel = list->GetSelection();
2009  if (sel == -1)
2010  return;
2011 
2012  VariableListClientData *data = static_cast<VariableListClientData*>(list->GetClientObject(sel));
2013  wxString key = data->key;
2014  wxString value = data->value;
2015 
2016  EditPairDlg dlg(this, key, value, _("Edit variable"), EditPairDlg::bmBrowseForDirectory);
2017  PlaceWindow(&dlg);
2018  if (dlg.ShowModal() == wxID_OK)
2019  {
2020  key.Trim(true).Trim(false);
2021  value.Trim(true).Trim(false);
2022  QuoteString(value, _("Edit variable quote string"));
2023 
2024  if (value != data->value || key != data->key)
2025  { // something has changed
2026  CustomVarAction Action = {CVA_Edit, data->key, key + _T(" = ") + value};
2027  m_CustomVarActions.push_back(Action);
2028  list->SetString(sel, key + _T(" = ") + value);
2029  data->key = key;
2030  data->value = value;
2031  m_bDirty = true;
2032  }
2033  }
2034 } // OnEditVarClick
2035 
2037 {
2038  wxListBox *list = XRCCTRL(*this, "lstVars", wxListBox);
2039  int sel = list->GetSelection();
2040  if (sel == -1)
2041  return;
2042  const wxString &key = static_cast<VariableListClientData*>(list->GetClientObject(sel))->key;
2043  if (key.IsEmpty())
2044  return;
2045 
2046  if (cbMessageBox(_("Are you sure you want to delete this variable?"),
2047  _("Confirmation"),
2049  {
2050  CustomVarAction Action = {CVA_Remove, key, wxEmptyString};
2051  m_CustomVarActions.push_back(Action);
2052  list->Delete(sel);
2053  m_bDirty = true;
2054  }
2055 } // OnRemoveVarClick
2056 
2058 {
2059  wxListBox* lstVars = XRCCTRL(*this, "lstVars", wxListBox);
2060  if (lstVars->IsEmpty())
2061  return;
2062 
2063  if (cbMessageBox(_("Are you sure you want to clear all variables?"),
2064  _("Confirmation"),
2066  {
2067  // Unset all variables of lstVars
2068  for (size_t i=0; i < lstVars->GetCount(); ++i)
2069  {
2070  const wxString &key = static_cast<VariableListClientData*>(lstVars->GetClientObject(i))->key;
2071  if (!key.IsEmpty())
2072  {
2073  CustomVarAction Action = {CVA_Remove, key, wxEmptyString};
2074  m_CustomVarActions.push_back(Action);
2075  }
2076  }
2077  lstVars->Clear();
2078  m_bDirty = true;
2079  }
2080 } // OnClearVarClick
2081 
2083 {
2084  wxChoice* cmb = XRCCTRL(*this, "cmbCompiler", wxChoice);
2085  int idx = cmb->GetSelection();
2087  wxString msg;
2089  #if wxCHECK_VERSION(3, 0, 0)
2090  msg.Printf(_("%s is now selected as the default compiler for new projects"), compiler ? compiler->GetName().wx_str() : _("[invalid]").wx_str());
2091  #else
2092  msg.Printf(_("%s is now selected as the default compiler for new projects"), compiler ? compiler->GetName().c_str() : _("[invalid]"));
2093  #endif
2094  cbMessageBox(msg);
2095 } // OnSetDefaultCompilerClick
2096 
2098 {
2099  if (m_bDirty)
2100  { // changes had been made to the current selected compiler
2101  switch(cbMessageBox(_("You have changed some settings. Do you want these settings saved ?\n\n"
2102  "Yes : will apply the changes\n"
2103  "No : will undo the changes\n"
2104  "Cancel : will cancel your compiler addition."),
2105  _("Compiler change with changed settings"),
2107  {
2108  case wxID_CANCEL :
2109  return;
2110  break;
2111  case wxID_YES :
2113  break;
2114  case wxID_NO :
2115  default:
2116  // we don't clear the dirty flag yet (in case something goes wrong with the compiler copy we need to reload the
2117  // 'selected compiler' options omitting the current 'No'-ed changes
2118  break;
2119  } // end switch
2120  }
2121  wxChoice* cmb = 0;
2122  cmb = XRCCTRL(*this, "cmbCompiler", wxChoice);
2123  wxString value = cbGetTextFromUser(_("Please enter the new compiler's name:"),
2124  _("Add new compiler"),
2125  _("Copy of ") + CompilerFactory::GetCompiler(m_CurrentCompilerIdx)->GetName());
2126  if (!value.IsEmpty())
2127  {
2128  // make a copy of current compiler
2129  Compiler* newC = 0;
2130  try
2131  {
2133  }
2134  catch (cbException& e)
2135  {
2136  // usually throws because of non-unique ID
2137  e.ShowErrorMessage(false);
2138  newC = 0; // just to be sure
2139  }
2140 
2141  if (!newC)
2142  {
2143  cbMessageBox(_("The new compiler could not be created.\n(maybe a compiler with the same name already exists?)"),
2144  _("Error"), wxICON_ERROR);
2145  return;
2146  }
2147  else
2148  {
2150 
2151  cmb->Append(value);
2152  cmb->SetSelection(cmb->GetCount() - 1);
2153  // refresh settings in dialog
2155  cbMessageBox(_("The new compiler has been added! Don't forget to update the \"Toolchain executables\" page..."));
2156  }
2157  }
2158  if (m_bDirty)
2159  { // something went wrong -> reload current settings omitting the NO-ed changes
2160  m_bDirty = false;
2161  CompilerChanged();
2162  }
2163 } // OnAddCompilerClick
2164 
2166 {
2167  wxChoice* cmb = XRCCTRL(*this, "cmbCompiler", wxChoice);
2168  wxString value = cbGetTextFromUser(_("Please edit the compiler's name:"), _("Rename compiler"), cmb->GetStringSelection());
2169  if (!value.IsEmpty())
2170  {
2172  if (compiler)
2173  compiler->SetName(value);
2174  cmb->SetString(m_CurrentCompilerIdx, value);
2176  }
2177 } // OnEditCompilerClick
2178 
2180 {
2181  if (cbMessageBox(_("Are you sure you want to remove this compiler?"),
2182  _("Confirmation"),
2184  {
2185  wxChoice* cmb = XRCCTRL(*this, "cmbCompiler", wxChoice);
2186  int compilerIdx = m_CurrentCompilerIdx;
2188  cmb->Delete(compilerIdx);
2189  while (compilerIdx >= (int)(cmb->GetCount()))
2190  --compilerIdx;
2191  cmb->SetSelection(compilerIdx);
2192  m_CurrentCompilerIdx = compilerIdx;
2194  }
2195 } // OnRemoveCompilerClick
2196 
2198 {
2199  if (cbMessageBox(_("Reset this compiler's settings to the defaults?"),
2200  _("Confirmation"),
2202  if (cbMessageBox(_("Reset this compiler's settings to the defaults?\n"
2203  "\nAre you REALLY sure?"),
2204  _("Confirmation"),
2206  {
2208  if (compiler)
2209  {
2210  const wxString file = wxT("/compilers/options_") + compiler->GetID() + wxT(".xml");
2211  if ( wxFileExists(ConfigManager::GetDataFolder(true) + file)
2212  && wxFileExists(ConfigManager::GetDataFolder(false) + file) )
2213  {
2215  }
2216  compiler->Reset();
2217  }
2218  // run auto-detection
2221  // refresh settings in dialog
2223  }
2224 } // OnResetCompilerClick
2225 
2226 // 4 handlers for the adding/editing/removing/clearing of Linker Libs
2228 {
2229  wxListBox* lstLibs = XRCCTRL(*this, "lstLibs", wxListBox);
2230 
2231  EditPathDlg dlg(this,
2232  _T(""),
2233  m_pProject ? m_pProject->GetBasePath() : _T(""),
2234  _("Add library"),
2235  _("Choose library to link"),
2236  false,
2237  true,
2238  _("Library files (*.a, *.so, *.lib, *.dylib, *.bundle)|*.a;*.so;*.lib;*.dylib;*.bundle|All files (*)|*"));
2239 
2240  PlaceWindow(&dlg);
2241  if (dlg.ShowModal() == wxID_OK)
2242  {
2243  wxArrayString paths = GetArrayFromString(dlg.GetPath());
2244  for (size_t i = 0; i < paths.GetCount(); ++i)
2245  lstLibs->Append(paths[i]);
2246  m_bDirty = true;
2247  }
2248 } // OnAddLibClick
2249 
2251 {
2252  wxListBox* lstLibs = XRCCTRL(*this, "lstLibs", wxListBox);
2253  if (!lstLibs)
2254  return;
2255 
2256  wxArrayInt sels;
2257  int num = lstLibs->GetSelections(sels);
2258  if (num<1)
2259  {
2260  cbMessageBox(_("Please select a library you wish to edit."),
2261  _("Error"), wxICON_ERROR);
2262  }
2263  else if (num == 1)
2264  {
2265  EditPathDlg dlg(this,
2266  lstLibs->GetString(sels[0]),
2267  m_pProject ? m_pProject->GetBasePath() : _T(""),
2268  _("Edit library"),
2269  _("Choose library to link"),
2270  false,
2271  false,
2272  _("Library files (*.a, *.so, *.lib, *.dylib, *.bundle)|*.a;*.so;*.lib;*.dylib;*.bundle|All files (*)|*"));
2273 
2274  PlaceWindow(&dlg);
2275  if (dlg.ShowModal() == wxID_OK)
2276  {
2277  lstLibs->SetString(sels[0], dlg.GetPath());
2278  m_bDirty = true;
2279  }
2280  }
2281  else
2282  {
2283  cbMessageBox(_("Please select only *one* library you wish to edit."),
2284  _("Error"), wxICON_ERROR);
2285  }
2286 } // OnEditLibClick
2287 
2289 {
2290  wxListBox* lstLibs = XRCCTRL(*this, "lstLibs", wxListBox);
2291  if (!lstLibs)
2292  return;
2293 
2294  wxArrayInt sels;
2295  int num = lstLibs->GetSelections(sels);
2296  if (num == 1) // mimic old behaviour
2297  {
2298  if (cbMessageBox(_("Remove library '")+lstLibs->GetString(sels[0])+_("' from the list?"),
2299  _("Confirmation"), wxICON_QUESTION | wxOK | wxCANCEL) == wxID_OK)
2300  {
2301  lstLibs->Delete(sels[0]);
2302  m_bDirty = true;
2303  }
2304  }
2305  else if (num > 1)
2306  {
2307  wxString msg; msg.Printf(_("Remove all (%d) selected libraries from the list?"), num);
2308  if (cbMessageBox(msg, _("Confirmation"), wxICON_QUESTION | wxOK | wxCANCEL) == wxID_OK)
2309  {
2310  // remove starting with the last lib. otherwise indices will change
2311  for (size_t i = sels.GetCount(); i>0; --i)
2312  lstLibs->Delete(sels[i-1]);
2313  m_bDirty = true;
2314  }
2315  }
2316  // else: No lib selected
2317 } // OnRemoveLibClick
2318 
2320 {
2321  wxListBox* lstLibs = XRCCTRL(*this, "lstLibs", wxListBox);
2322  if (!lstLibs || lstLibs->GetCount() == 0)
2323  return;
2324  if (cbMessageBox(_("Remove all libraries from the list?"), _("Confirmation"), wxICON_QUESTION | wxOK | wxCANCEL) == wxID_OK)
2325  {
2326  lstLibs->Clear();
2327  m_bDirty = true;
2328  }
2329 } // OnClearLibClick
2330 
2332 {
2333  if (!m_pProject)
2334  return;
2335  wxListBox* lstLibs = XRCCTRL(*this, "lstLibs", wxListBox);
2336  if (!lstLibs || lstLibs->GetCount() == 0)
2337  return;
2338 
2339  wxArrayString choices;
2340  choices.Add(m_pProject->GetTitle());
2341  for (int i = 0; i < m_pProject->GetBuildTargetsCount(); ++i)
2342  {
2344  choices.Add(bt->GetTitle());
2345  }
2346 
2347  const wxArrayInt &sel = cbGetMultiChoiceDialog(_("Please select which target to copy these libraries to:"),
2348  _("Copy libraries"), choices, this);
2349  if (sel.empty())
2350  return;
2351 
2352  for (wxArrayInt::const_iterator itr = sel.begin(); itr != sel.end(); ++itr)
2353  {
2354  CompileOptionsBase* base;
2355  if((*itr) == 0)
2356  base = m_pProject; // "copy to project"
2357  else
2358  base = m_pProject->GetBuildTarget((*itr) - 1);
2359 
2360  if (!base)
2361  {
2362  Manager::Get()->GetLogManager()->LogWarning(_T("Could not get build target in CompilerOptionsDlg::OnCopyLibsClick"));
2363  continue;
2364  }
2365 
2366  for (size_t i = 0; i < lstLibs->GetCount(); ++i)
2367  {
2368  if (lstLibs->IsSelected(i))
2369  base->AddLinkLib(lstLibs->GetString(i));
2370  }
2371  }
2372 } // OnCopyLibsClick
2373 
2375 {
2376  EditPathDlg dlg(this, _T(""), _T(""), _("Add directory"));
2377 
2378  PlaceWindow(&dlg);
2379  if (dlg.ShowModal() == wxID_OK)
2380  {
2381  wxListBox* control = XRCCTRL(*this, "lstExtraPaths", wxListBox);
2382  if (control)
2383  {
2384  wxString path = dlg.GetPath();
2385 
2386  // get all listBox entries in array String
2387  wxArrayString extraPaths;
2388  ListBox2ArrayString(extraPaths, control);
2389  if (extraPaths.Index(path) != wxNOT_FOUND)
2390  {
2391  cbMessageBox(_("Path already in extra paths list!"), _("Warning"), wxICON_WARNING);
2392  }
2393  else
2394  {
2395  control->Append(path);
2396  m_bDirty = true;
2397  }
2398  }
2399  }
2400 } // OnAddExtraPathClick
2401 
2403 {
2404  wxListBox* control = XRCCTRL(*this, "lstExtraPaths", wxListBox);
2405  if (!control || control->GetSelection() < 0)
2406  return;
2407 
2408  wxFileName dir(control->GetString(control->GetSelection()) + wxFileName::GetPathSeparator());
2409  wxString initial = control->GetString(control->GetSelection()); // might be a macro
2410  if (dir.DirExists())
2411  initial = dir.GetPath(wxPATH_GET_VOLUME);
2412 
2413  EditPathDlg dlg(this, initial, _T(""), _("Edit directory"));
2414 
2415  PlaceWindow(&dlg);
2416  if (dlg.ShowModal() == wxID_OK)
2417  {
2418  wxString path = dlg.GetPath();
2419 
2420  // get all listBox entries in array String
2421  wxArrayString extraPaths;
2422  ListBox2ArrayString(extraPaths, control);
2423  if (extraPaths.Index(path) != wxNOT_FOUND)
2424  {
2425  cbMessageBox(_("Path already in extra paths list!"), _("Warning"), wxICON_WARNING);
2426  }
2427  else
2428  {
2429  control->SetString(control->GetSelection(), path);
2430  m_bDirty = true;
2431  }
2432  }
2433 } // OnEditExtraPathClick
2434 
2436 {
2437  wxListBox* control = XRCCTRL(*this, "lstExtraPaths", wxListBox);
2438  if (!control || control->GetSelection() < 0)
2439  return;
2440  control->Delete(control->GetSelection());
2441  m_bDirty = true;
2442 } // OnRemoveExtraPathClick
2443 
2445 {
2446  wxListBox* control = XRCCTRL(*this, "lstExtraPaths", wxListBox);
2447  if (!control || control->IsEmpty())
2448  return;
2449 
2450  if (cbMessageBox(_("Remove all extra paths from the list?"), _("Confirmation"), wxICON_QUESTION | wxOK | wxCANCEL) == wxID_OK)
2451  {
2452  control->Clear();
2453  m_bDirty = true;
2454  }
2455 } // OnClearExtraPathClick
2456 
2458 {
2459  wxListBox* list = XRCCTRL(*this, "lstIgnore", wxListBox);
2460  wxTextCtrl* text = XRCCTRL(*this, "txtIgnore", wxTextCtrl);
2461 
2462  wxString ignore_str = text->GetValue().Trim();
2463  if ( (ignore_str.Len()>0)
2464  && (list->FindString(ignore_str)==wxNOT_FOUND) )
2465  {
2466  list->Append(ignore_str);
2467  m_bDirty = true;
2468  }
2469 } // OnIgnoreAddClick
2470 
2472 {
2473  wxListBox* list = XRCCTRL(*this, "lstIgnore", wxListBox);
2474  if (!list || list->IsEmpty())
2475  return;
2476 
2477  int selection = list->GetSelection();
2478  if (selection!=wxNOT_FOUND)
2479  {
2480  list->Delete(selection);
2481  m_bDirty = true;
2482  }
2483 } // OnIgnoreRemoveClick
2484 
2486 {
2487  wxListBox* lstLibs = XRCCTRL(*this, "lstLibs", wxListBox);
2488  if (!lstLibs)
2489  return;
2490 
2491  wxArrayInt sels;
2492  int num = lstLibs->GetSelections(sels);
2493  if (num == 0)
2494  return;
2495 
2496  // moving upwards: need to start from the first element
2497  // starting at second element, the first one cannot be moved upwards
2498  for (size_t i=1; i<lstLibs->GetCount(); ++i)
2499  {
2500  // do not move upwards if the lib before is selected, too
2501  if (lstLibs->IsSelected(i) && !lstLibs->IsSelected(i-1))
2502  {
2503  wxString lib = lstLibs->GetString(i);
2504  lstLibs->Delete(i);
2505 
2506  lstLibs->InsertItems(1, &lib, i - 1);
2507  lstLibs->SetSelection(i - 1);
2508 
2509  m_bDirty = true;
2510  }
2511  }
2512 } // OnMoveLibUpClick
2513 
2515 {
2516  wxListBox* lstLibs = XRCCTRL(*this, "lstLibs", wxListBox);
2517  if (!lstLibs)
2518  return;
2519 
2520  wxArrayInt sels;
2521  int num = lstLibs->GetSelections(sels);
2522  if (num == 0)
2523  return;
2524 
2525  // moving downwards: need to start from the last element
2526  // starting at pre-last element, the last one cannot be moved downwards
2527  for (size_t i=lstLibs->GetCount()-1; i>0; --i)
2528  {
2529  // do not move downwards if the lib after is selected, too
2530  // notice here: as started with index+1 (due to GetCount)...
2531  // ... subtract 1 all the way to achieve the real index operated on
2532  if (lstLibs->IsSelected(i-1) && !lstLibs->IsSelected(i))
2533  {
2534  wxString lib = lstLibs->GetString(i-1);
2535  lstLibs->Delete(i-1);
2536 
2537  lstLibs->InsertItems(1, &lib, i);
2538  lstLibs->SetSelection(i);
2539 
2540  m_bDirty = true;
2541  }
2542  }
2543 } // OnMoveLibDownClick
2544 
2546 {
2547  wxListBox* lst = GetDirsListBox();
2548  wxArrayInt sels;
2549  if (!lst || lst->GetSelections(sels) < 1)
2550  return;
2551 
2552  // moving upwards: need to start from the first element
2553  // starting at second element, the first one cannot be moved upwards
2554  for (size_t i=1; i<lst->GetCount(); ++i)
2555  {
2556  // do not move upwards if the dir before is selected, too
2557  if (lst->IsSelected(i) && !lst->IsSelected(i-1))
2558  {
2559  wxString dir = lst->GetString(i);
2560  lst->Delete(i);
2561 
2562  lst->InsertItems(1, &dir, i - 1);
2563  lst->SetSelection(i - 1);
2564 
2565  m_bDirty = true;
2566  }
2567  }
2568 } // OnMoveDirUpClick
2569 
2571 {
2572  wxListBox* lst = GetDirsListBox();
2573  wxArrayInt sels;
2574  if (!lst || lst->GetSelections(sels) < 1)
2575  return;
2576 
2577  // moving downwards: need to start from the last element
2578  // starting at pre-last element, the last one cannot be moved downwards
2579  for (size_t i=lst->GetCount()-1; i>0; --i)
2580  {
2581  // do not move downwards if the dir after is selected, too
2582  // notice here: as started with index+1 (due to GetCount)...
2583  // ... subtract 1 all the way to achieve the real index operated on
2584  if (lst->IsSelected(i-1) && !lst->IsSelected(i))
2585  {
2586  wxString dir = lst->GetString(i-1);
2587  lst->Delete(i-1);
2588 
2589  lst->InsertItems(1, &dir, i);
2590  lst->SetSelection(i);
2591 
2592  m_bDirty = true;
2593  }
2594  }
2595 } // OnMoveDirDownClick
2596 
2598 {
2599  wxString path = ChooseDirectory(this,
2600  _("Select directory"),
2601  XRCCTRL(*this, "txtMasterPath", wxTextCtrl)->GetValue());
2602  if (!path.IsEmpty())
2603  {
2604  XRCCTRL(*this, "txtMasterPath", wxTextCtrl)->SetValue(path);
2605  m_bDirty = true;
2606  }
2607 } // OnMasterPathClick
2608 
2610 {
2612 } // OnAutoDetectClick
2613 
2615 {
2616  // see who called us
2617  wxTextCtrl* obj = 0L;
2618  if (event.GetId() == XRCID("btnCcompiler"))
2619  obj = XRCCTRL(*this, "txtCcompiler", wxTextCtrl);
2620  else if (event.GetId() == XRCID("btnCPPcompiler"))
2621  obj = XRCCTRL(*this, "txtCPPcompiler", wxTextCtrl);
2622  else if (event.GetId() == XRCID("btnLinker"))
2623  obj = XRCCTRL(*this, "txtLinker", wxTextCtrl);
2624  else if (event.GetId() == XRCID("btnLibLinker"))
2625  obj = XRCCTRL(*this, "txtLibLinker", wxTextCtrl);
2626  else if (event.GetId() == XRCID("btnResComp"))
2627  obj = XRCCTRL(*this, "txtResComp", wxTextCtrl);
2628  else if (event.GetId() == XRCID("btnMake"))
2629  obj = XRCCTRL(*this, "txtMake", wxTextCtrl);
2630 
2631  if (!obj)
2632  return; // called from invalid caller
2633 
2634  // common part follows
2635  wxString file_selection = _("All files (*)|*");
2636  if (platform::windows)
2637  file_selection = _("Executable files (*.exe)|*.exe");
2638  wxFileDialog dlg(this,
2639  _("Select file"),
2640  XRCCTRL(*this, "txtMasterPath", wxTextCtrl)->GetValue() + _T("/bin"),
2641  obj->GetValue(),
2642  file_selection,
2643  wxFD_OPEN | wxFD_FILE_MUST_EXIST | compatibility::wxHideReadonly );
2644  dlg.SetFilterIndex(0);
2645 
2646  PlaceWindow(&dlg);
2647  if (dlg.ShowModal() != wxID_OK)
2648  return;
2649  wxFileName fname(dlg.GetPath());
2650  obj->SetValue(fname.GetFullName());
2651  m_bDirty = true;
2652 } // OnSelectProgramClick
2653 
2655 {
2656  AnnoyingDialog dlg(_("Edit advanced compiler settings?"),
2657  _("The compiler's advanced settings, need command-line "
2658  "compiler knowledge to be tweaked.\nIf you don't know "
2659  "*exactly* what you 're doing, it is suggested to "
2660  "NOT tamper with these...\n\n"
2661  "Are you sure you want to proceed?"),
2662  wxART_QUESTION);
2663  if (dlg.ShowModal() == AnnoyingDialog::rtYES)
2664  {
2665  wxChoice* cmb = XRCCTRL(*this, "cmbCompiler", wxChoice);
2666  int compilerIdx = cmb->GetSelection();
2667  AdvancedCompilerOptionsDlg dlg2(this, CompilerFactory::GetCompiler(compilerIdx)->GetID());
2668  PlaceWindow(&dlg2);
2669  dlg2.ShowModal();
2670  // check if dirty
2671  if (dlg2.IsDirty())
2672  {
2673 // m_bDirty = true; // TO DO : Activate when implemented in the adv dialog
2674  }
2675  }
2676 } // OnAdvancedClick
2677 
2678 static void UpdateUIListBoxAndButtons(wxListBox &list, wxButton &edit, wxButton &del, wxButton &clear, wxButton &copy,
2679  wxButton &up, wxButton &down)
2680 {
2681  wxArrayInt selections;
2682  int num = list.GetSelections(selections);
2683  int itemCount = list.GetCount();
2684  bool en = (num > 0);
2685 
2686  edit.Enable(num == 1);
2687  del.Enable(en);
2688  clear.Enable(itemCount != 0);
2689  copy.Enable(en);
2690 
2691  if (en)
2692  {
2693  int minIndex = selections.size();
2694  int maxIndex = 0;
2695  for (int index : selections)
2696  {
2697  minIndex = std::min(index, minIndex);
2698  maxIndex = std::max(index, maxIndex);
2699  }
2700  up.Enable(minIndex > 0);
2701  down.Enable(maxIndex < itemCount - 1);
2702  }
2703  else
2704  {
2705  up.Enable(false);
2706  down.Enable(false);
2707  }
2708 }
2709 
2711 {
2712  bool en = false;
2713 
2714  wxListBox* control = GetDirsListBox();
2715  if (control)
2716  {
2717  UpdateUIListBoxAndButtons(*control, *XRCCTRL(*this, "btnEditDir", wxButton),
2718  *XRCCTRL(*this, "btnDelDir", wxButton), *XRCCTRL(*this, "btnClearDir", wxButton),
2719  *XRCCTRL(*this, "btnCopyDirs", wxButton), *XRCCTRL(*this, "btnMoveDirUp", wxButton),
2720  *XRCCTRL(*this, "btnMoveDirDown", wxButton));
2721  }
2722 
2723  // edit/delete/clear/copy/moveup/movedown lib dirs
2724  wxListBox* lstLibs = XRCCTRL(*this, "lstLibs", wxListBox);
2725  if (lstLibs)
2726  {
2727  UpdateUIListBoxAndButtons(*lstLibs, *XRCCTRL(*this, "btnEditLib", wxButton),
2728  *XRCCTRL(*this, "btnDelLib", wxButton), *XRCCTRL(*this, "btnClearLib", wxButton),
2729  *XRCCTRL(*this, "btnCopyLibs", wxButton), *XRCCTRL(*this, "btnMoveLibUp", wxButton),
2730  *XRCCTRL(*this, "btnMoveLibDown", wxButton));
2731  }
2732 
2733  // edit/delete/clear/copy/moveup/movedown extra path
2734  if (!m_pProject)
2735  {
2736  en = XRCCTRL(*this, "lstExtraPaths", wxListBox)->GetSelection() >= 0;
2737  XRCCTRL(*this, "btnExtraEdit", wxButton)->Enable(en);
2738  XRCCTRL(*this, "btnExtraDelete", wxButton)->Enable(en);
2739  XRCCTRL(*this, "btnExtraClear", wxButton)->Enable(XRCCTRL(*this, "lstExtraPaths", wxListBox)->GetCount() != 0);
2740  }
2741 
2742  // add/edit/delete/clear vars
2743  en = XRCCTRL(*this, "lstVars", wxListBox)->GetSelection() >= 0;
2744  XRCCTRL(*this, "btnEditVar", wxButton)->Enable(en);
2745  XRCCTRL(*this, "btnDeleteVar", wxButton)->Enable(en);
2746  XRCCTRL(*this, "btnClearVar", wxButton)->Enable(XRCCTRL(*this, "lstVars", wxListBox)->GetCount() != 0);
2747 
2748  // policies
2749  wxTreeCtrl* tc = XRCCTRL(*this, "tcScope", wxTreeCtrl);
2750  ScopeTreeData* data = (ScopeTreeData*)tc->GetItemData(tc->GetSelection());
2751  en = (data && data->GetTarget());
2752  XRCCTRL(*this, "cmbCompilerPolicy", wxChoice)->Enable(en);
2753  XRCCTRL(*this, "cmbLinkerPolicy", wxChoice)->Enable(en);
2754  XRCCTRL(*this, "cmbIncludesPolicy", wxChoice)->Enable(en);
2755  XRCCTRL(*this, "cmbLibDirsPolicy", wxChoice)->Enable(en);
2756  XRCCTRL(*this, "cmbResDirsPolicy", wxChoice)->Enable(en);
2757 
2758  // compiler set buttons
2759  if (!m_pProject)
2760  {
2761  en = !data; // global options selected
2762  int idx = XRCCTRL(*this, "cmbCompiler", wxChoice)->GetSelection();
2763  int count = XRCCTRL(*this, "cmbCompiler", wxChoice)->GetCount(); // compilers count
2764  Compiler* compiler = CompilerFactory::GetCompiler(idx);
2765 
2766  XRCCTRL(*this, "btnSetDefaultCompiler", wxButton)->Enable(CompilerFactory::GetCompilerIndex(CompilerFactory::GetDefaultCompiler()) != idx);
2767  XRCCTRL(*this, "btnAddCompiler", wxButton)->Enable(en);
2768  XRCCTRL(*this, "btnRenameCompiler", wxButton)->Enable(en && count);
2769  XRCCTRL(*this, "btnDelCompiler", wxButton)->Enable(en &&
2770  compiler &&
2771  !compiler->GetParentID().IsEmpty());
2772  XRCCTRL(*this, "btnResetCompiler", wxButton)->Enable(en &&
2773  compiler &&
2774  compiler->GetParentID().IsEmpty());
2775 
2776  XRCCTRL(*this, "chkFullHtmlLog", wxCheckBox)->Enable(XRCCTRL(*this, "chkSaveHtmlLog", wxCheckBox)->IsChecked());
2777  XRCCTRL(*this, "btnIgnoreRemove", wxButton)->Enable(XRCCTRL(*this, "lstIgnore", wxListBox)->GetCount()>0);
2778  XRCCTRL(*this, "btnIgnoreAdd", wxButton)->Enable(XRCCTRL(*this, "txtIgnore", wxTextCtrl)->GetValue().Trim().Len()>0);
2779  }
2780 } // OnUpdateUI
2781 
2783 {
2784  m_CurrentCompilerIdx = XRCCTRL(*this, "cmbCompiler", wxChoice)->GetSelection();
2787 
2788  //others (projects don't have Other tab)
2789  if (!m_pProject)
2790  {
2791  ConfigManager* cfg = Manager::Get()->GetConfigManager(_T("compiler"));
2792  wxCheckBox* chk = XRCCTRL(*this, "chkIncludeFileCwd", wxCheckBox);
2793  if (chk)
2794  cfg->Write(_T("/include_file_cwd"), (bool)chk->IsChecked());
2795  chk = XRCCTRL(*this, "chkIncludePrjCwd", wxCheckBox);
2796  if (chk)
2797  cfg->Write(_T("/include_prj_cwd"), (bool)chk->IsChecked());
2798  chk = XRCCTRL(*this, "chkSkipIncludeDeps", wxCheckBox);
2799  if (chk)
2800  cfg->Write(_T("/skip_include_deps"), (bool)chk->IsChecked());
2801  chk = XRCCTRL(*this, "chkSaveHtmlLog", wxCheckBox);
2802  if (chk)
2803  cfg->Write(_T("/save_html_build_log"), (bool)chk->IsChecked());
2804  chk = XRCCTRL(*this, "chkFullHtmlLog", wxCheckBox);
2805  if (chk)
2806  cfg->Write(_T("/save_html_build_log/full_command_line"), (bool)chk->IsChecked());
2807  chk = XRCCTRL(*this, "chkBuildProgressBar", wxCheckBox);
2808  if (chk)
2809  cfg->Write(_T("/build_progress/bar"), (bool)chk->IsChecked());
2810  chk = XRCCTRL(*this, "chkBuildProgressPerc", wxCheckBox);
2811  if (chk)
2812  {
2813  cfg->Write(_T("/build_progress/percentage"), (bool)chk->IsChecked());
2815  }
2816  wxSpinCtrl* spn = XRCCTRL(*this, "spnParallelProcesses", wxSpinCtrl);
2817  if (spn && (((int)spn->GetValue()) != cfg->ReadInt(_T("/parallel_processes"), 0)))
2818  {
2819  if (m_Compiler->IsRunning())
2820  cbMessageBox(_("You can't change the number of parallel processes while building!\nSetting ignored..."), _("Warning"), wxICON_WARNING);
2821  else
2822  {
2823  cfg->Write(_T("/parallel_processes"), (int)spn->GetValue());
2825  }
2826  }
2827  spn = XRCCTRL(*this, "spnMaxErrors", wxSpinCtrl);
2828  if (spn)
2829  cfg->Write(_T("/max_reported_errors"), (int)spn->GetValue());
2830 
2831  chk = XRCCTRL(*this, "chkRebuildSeperately", wxCheckBox);
2832  if (chk)
2833  cfg->Write(_T("/rebuild_seperately"), (bool)chk->IsChecked());
2834 
2835  wxListBox* lst = XRCCTRL(*this, "lstIgnore", wxListBox);
2836  if (lst)
2837  {
2838  wxArrayString IgnoreOutput;
2839  ListBox2ArrayString(IgnoreOutput, lst);
2840  cfg->Write(_T("/ignore_output"), IgnoreOutput);
2841  }
2842 
2843  chk = XRCCTRL(*this, "chkNonPlatComp", wxCheckBox);
2844  if (chk && (chk->IsChecked() != cfg->ReadBool(_T("/non_plat_comp"), false)))
2845  {
2846  if (m_Compiler->IsRunning())
2847  cbMessageBox(_("You can't change the option to enable or disable non-platform compilers while building!\nSetting ignored..."), _("Warning"), wxICON_WARNING);
2848  else
2849  {
2850  cfg->Write(_T("/non_plat_comp"), (bool)chk->IsChecked());
2854  }
2855  }
2856  }
2857 
2861  m_bDirty = false;
2862 } // OnApply
2863 
2865 {
2866  wxWindow* focused = wxWindow::FindFocus();
2867  if (!focused)
2868  {
2869  event.Skip();
2870  return;
2871  }
2872  int keycode = event.GetKeyCode();
2873  int id = focused->GetId();
2874 
2875  int myid = 0;
2876  unsigned int myidx = 0;
2877 
2878  const wxChar* str_libs[4] = { _T("btnEditLib"), _T("btnAddLib"), _T("btnDelLib"), _T("btnClearLib") };
2879  const wxChar* str_dirs[4] = { _T("btnEditDir"), _T("btnAddDir"), _T("btnDelDir"), _T("btnClearDir") };
2880  const wxChar* str_vars[4] = { _T("btnEditVar"), _T("btnAddVar"), _T("btnDeleteVar"), _T("btnClearVar") };
2881  const wxChar* str_xtra[4] = { _T("btnExtraEdit"),_T("btnExtraAdd"),_T("btnExtraDelete"),_T("btnExtraClear") };
2882 
2883  if (keycode == WXK_RETURN || keycode == WXK_NUMPAD_ENTER)
2884  { myidx = 0; } // Edit
2885  else if (keycode == WXK_INSERT || keycode == WXK_NUMPAD_INSERT)
2886  { myidx = 1; } // Add
2887  else if (keycode == WXK_DELETE || keycode == WXK_NUMPAD_DELETE)
2888  { myidx = 2; } // Delete
2889  else
2890  {
2891  event.Skip();
2892  return;
2893  }
2894 
2895  if ( id == XRCID("lstLibs")) // Link libraries
2896  { myid = wxXmlResource::GetXRCID(str_libs[myidx]); }
2897  else if (id == XRCID("lstIncludeDirs") || id == XRCID("lstLibDirs") || id == XRCID("lstResDirs")) // Directories
2898  { myid = wxXmlResource::GetXRCID(str_dirs[myidx]); }
2899  else if (id == XRCID("lstVars")) // Custom Vars
2900  { myid = wxXmlResource::GetXRCID(str_vars[myidx]); }
2901  else if (id == XRCID("lstExtraPaths")) // Extra Paths
2902  { myid = wxXmlResource::GetXRCID(str_xtra[myidx]); }
2903  else
2904  myid = 0;
2905 
2906  // Generate the event
2907  if (myid == 0)
2908  event.Skip();
2909  else
2910  {
2911  wxCommandEvent newevent(wxEVT_COMMAND_BUTTON_CLICKED,myid);
2912  this->ProcessEvent(newevent);
2913  }
2914 } // OnMyCharHook
2915 
2916 int CompilerOptionsDlg::m_MenuOption = -1;
2917 
2919 {
2920  int scroll = m_FlagsPG->GetScrollPos(wxVERTICAL);
2921  wxPGProperty *property = event.GetProperty();
2922 
2923  enum FlagsMenuOptions
2924  {
2925  FMO_None = -1,
2926  FMO_New = 0,
2927  FMO_Modify,
2928  FMO_Delete,
2929  FMO_COnly,
2930  FMO_CPPOnly,
2931  FMO_ExpandAll,
2932  FMO_CollapseAll
2933  };
2934 
2935  wxMenu* pop = new wxMenu;
2936  pop->Append(FMO_New, _("New flag..."));
2937  if (property && !property->IsCategory())
2938  {
2939  pop->Append(FMO_Modify, _("Modify flag..."));
2940  pop->Append(FMO_Delete, _("Delete flag"));
2941  }
2942  pop->AppendSeparator();
2943  pop->Append(FMO_COnly, _("C - only flags..."));
2944  pop->Append(FMO_CPPOnly, _("C++ - only flags..."));
2945  pop->AppendSeparator();
2946  pop->Append(FMO_ExpandAll, _("Expand all categories"));
2947  pop->Append(FMO_CollapseAll, _("Collapse all categories"));
2948  pop->Connect(wxEVT_COMMAND_MENU_SELECTED, (wxObjectEventFunction)&CompilerOptionsDlg::OnFlagsPopupClick);
2949  m_MenuOption = FMO_None;
2950  m_FlagsPG->PopupMenu(pop);
2951  delete pop;
2952  if (m_MenuOption == FMO_None)
2953  return;
2954  if (m_MenuOption == FMO_COnly)
2955  {
2957  wxTextEntryDialog dlg(this, wxT("List flags that will only be used during C compilation"),
2958  wxT("C - only flags"), compiler->GetCOnlyFlags(), wxTextEntryDialogStyle|wxTE_MULTILINE|wxRESIZE_BORDER);
2959  // TODO: Hack for Ubuntu, see here: http://forums.codeblocks.org/index.php/topic,16463.msg115270.html#msg115270 (Remove if no longer needed.)
2960  if (dlg.GetSize().GetHeight() < 220)
2961  {
2962  dlg.SetSize(dlg.GetPosition().x, dlg.GetPosition().y - (220 - dlg.GetSize().GetHeight()) / 2,
2963  dlg.GetSize().GetWidth(), 220);
2964  }
2965  PlaceWindow(&dlg);
2966  dlg.ShowModal();
2967  wxString flags = dlg.GetValue();
2968  flags.Replace(wxT("\n"), wxT(" "));
2969  flags.Replace(wxT("\r"), wxT(" "));
2970  flags.Replace(wxT("\t"), wxT(" "));
2971  flags = MakeUniqueString(flags, wxT(" "));
2972  if (flags != compiler->GetCOnlyFlags())
2973  {
2974  compiler->SetCOnlyFlags(flags);
2975  m_bDirty = true;
2976  }
2977  return;
2978  }
2979  else if (m_MenuOption == FMO_CPPOnly)
2980  {
2982  wxTextEntryDialog dlg(this, wxT("List flags that will only be used during C++ compilation"),
2983  wxT("C++ - only flags"), compiler->GetCPPOnlyFlags(), wxTextEntryDialogStyle|wxTE_MULTILINE|wxRESIZE_BORDER);
2984  // TODO: Hack for Ubuntu, see here: http://forums.codeblocks.org/index.php/topic,16463.msg115270.html#msg115270 (Remove if no longer needed.)
2985  if (dlg.GetSize().GetHeight() < 220)
2986  {
2987  dlg.SetSize(dlg.GetPosition().x, dlg.GetPosition().y - (220 - dlg.GetSize().GetHeight()) / 2,
2988  dlg.GetSize().GetWidth(), 220);
2989  }
2990  dlg.ShowModal();
2991  wxString flags = dlg.GetValue();
2992  flags.Replace(wxT("\n"), wxT(" "));
2993  flags.Replace(wxT("\r"), wxT(" "));
2994  flags.Replace(wxT("\t"), wxT(" "));
2995  flags = MakeUniqueString(flags, wxT(" "));
2996  if (flags != compiler->GetCPPOnlyFlags())
2997  {
2998  compiler->SetCPPOnlyFlags(flags);
2999  m_bDirty = true;
3000  }
3001  return;
3002  }
3003  else if (m_MenuOption == FMO_Delete)
3004  {
3005  size_t i = 0;
3006  for (; i < m_Options.GetCount(); ++i)
3007  {
3008  if (m_Options.GetOption(i)->name == property->GetLabel())
3009  break;
3010  }
3012  }
3013  else if (m_MenuOption == FMO_ExpandAll)
3014  {
3015  m_FlagsPG->ExpandAll();
3016  return;
3017  }
3018  else if (m_MenuOption == FMO_CollapseAll)
3019  {
3021  return;
3022  }
3023  else
3024  {
3025  wxArrayString categ;
3026  for (size_t i = 0; i < m_Options.GetCount(); ++i)
3027  {
3028  CompOption* opt = m_Options.GetOption(i);
3029  bool known = false;
3030  for (size_t j = 0; j < categ.GetCount(); ++j)
3031  {
3032  if (categ[j] == opt->category)
3033  {
3034  known = true;
3035  break;
3036  }
3037  }
3038  if (!known)
3039  categ.Add(opt->category);
3040  }
3041  if (categ.IsEmpty())
3042  categ.Add(wxT("General"));
3043  CompOption copt;
3044  if (m_MenuOption == FMO_Modify)
3045  copt = *m_Options.GetOptionByName(property->GetLabel());
3046 
3047  wxString categoryName;
3048  if (property)
3049  {
3050  // If we have a selected property try to find the name of the category.
3051  if (property->IsCategory())
3052  categoryName = property->GetLabel();
3053  else
3054  {
3055  wxPGProperty *category = property->GetParent();
3056  if (category)
3057  categoryName = category->GetLabel();
3058  }
3059  }
3060  CompilerFlagDlg dlg(nullptr, &copt, categ, categoryName);
3061  PlaceWindow(&dlg);
3062  if (dlg.ShowModal() != wxID_OK)
3063  return;
3064  if (m_MenuOption == FMO_New)
3065  {
3066  size_t i;
3067  if (property)
3068  {
3069  wxString name;
3070  if (property->IsCategory())
3071  {
3072  wxPGProperty *child = m_FlagsPG->GetFirstChild(property);
3073  if (child)
3074  name = child->GetLabel();
3075  }
3076  else
3077  name = property->GetLabel();
3078  for (i = 0; i < m_Options.GetCount(); ++i)
3079  {
3080  if (m_Options.GetOption(i)->name == name)
3081  break;
3082  }
3083  }
3084  else
3085  i = m_Options.GetCount() - 1;
3086 
3087  m_Options.AddOption(copt.name, copt.option,
3088  copt.category, copt.additionalLibs,
3089  copt.checkAgainst, copt.checkMessage,
3090  copt.supersedes, copt.exclusive, i + 1);
3091  }
3092  else
3093  {
3094  CompOption* opt = m_Options.GetOptionByName(property->GetLabel());
3095  wxString name = copt.name + wxT(" [");
3096  if (copt.option.IsEmpty())
3097  name += copt.additionalLibs;
3098  else
3099  name += copt.option;
3100  name += wxT("]");
3101  opt->name = name;
3102  opt->option = copt.option;
3103  opt->additionalLibs = copt.additionalLibs;
3104  opt->category = copt.category;
3105  opt->checkAgainst = copt.checkAgainst;
3106  opt->checkMessage = copt.checkMessage;
3107  opt->supersedes = copt.supersedes;
3108  opt->exclusive = copt.exclusive;
3109  }
3110  }
3111  DoFillOptions();
3112  m_FlagsPG->ScrollLines(scroll);
3113  m_bFlagsDirty = true;
3114 }
3115 
3117 {
3118  m_MenuOption = event.GetId();
3119 }
3120 
3122 {
3123  wxPGProperty* property = event.GetProperty();
3124  // For bool properties automatically toggle the checkbox on double click.
3125  if (property && property->IsKindOf(CLASSINFO(wxBoolProperty)))
3126  {
3127  bool realValue = m_FlagsPG->GetPropertyValue(property);
3128  m_FlagsPG->ChangePropertyValue(property, !realValue);
3129  }
3130  event.Skip();
3131 }
bool linkerNeedsLibExtension
Definition: compiler.h:226
bool IsNull() const
void OnClearLibClick(wxCommandEvent &event)
void OnAddExtraPathClick(wxCommandEvent &event)
virtual const RegExArray & GetRegExArray()
Get the array of regexes used in errors/warnings recognition.
Definition: compiler.h:314
wxString additionalLibs
DLLIMPORT wxArrayString GetArrayFromString(const wxString &text, const wxString &separator=DEFAULT_ARRAY_SEP, bool trimSpaces=true)
Definition: globals.cpp:134
virtual bool IsRunning() const
Is the plugin currently compiling?
virtual void SetOptionRelation(OptionsRelationType type, OptionsRelation rel)
Set the target&#39;s options relation for type to rel.
void UpdateCompilerForTargets(int compilerIdx)
const wxString & GetLabel() const
CompilerLoggingType logging
Definition: compiler.h:222
virtual void AddAttribute(const wxString &name, const wxString &value)
DLLIMPORT bool NeedQuotes(const wxString &str)
Definition: globals.cpp:266
void OnRemoveDirClick(wxCommandEvent &event)
virtual void SetMakeCommandFor(MakeCommand cmd, const wxString &make)
Set the "make" command used for cmd.
static int GetXRCID(const wxString &str_id, int value_if_not_found=wxID_NONE)
virtual bool UnsetVar(const wxString &key)
void Remove(const wxString &sz)
void OnAddDirClick(wxCommandEvent &event)
wxString PCHExtension
Definition: compiler.h:229
#define wxTextEntryDialogStyle
static wxString GetFolder(SearchDirs dir)
Access one of Code::Blocks&#39; folders.
bool CollapseAll()
bool wxRemoveFile(const wxString &file)
#define wxICON_QUESTION
Data folder in user&#39;s dir.
Definition: configmanager.h:75
const wxString empty(_T(""))
virtual const wxString & GetMasterPath() const
Get the compiler&#39;s master path (must contain "bin", "include" and "lib")
Definition: compiler.h:295
virtual void SetName(const wxString &name)
Set the compiler&#39;s name.
Definition: compiler.h:319
ConfigurationVector & GetConfigurations()
virtual void SetPrograms(const CompilerPrograms &programs)
Set the compiler&#39;s programs.
Definition: compiler.h:325
#define wxICON_WARNING
static const CompilerLoggingType defaultLogging
Definition: compiler.h:211
virtual void SetResourceCompilerOptions(const wxArrayString &resourceCompilerOpts)
CompileOptionsBase * GetVarsOwner()
CompilerLoggingType
Helper enum for type of compiler logging.
Definition: compiler.h:183
bool IsCategory() const
ConfigManager * GetConfigManager(const wxString &name_space) const
Definition: manager.cpp:474
wxString genericSwitch
Definition: compiler.h:216
std::vector< CustomVarAction > m_CustomVarActions
the actions carried out on the custom vars that need to be saved/applied
void SetNext(wxXmlNode *next)
void DoRegisterCompilers()
int ReadInt(const wxString &name, int defaultVal=0)
virtual bool SupportsCurrentPlatform() const
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
virtual const CompilerOptions & GetOptions() const
Get the compiler&#39;s options.
Definition: compiler.h:303
#define wxNO
void OnSetDefaultCompilerClick(wxCommandEvent &event)
wxString libDirs
Definition: compiler.h:213
wxPGProperty * Item(unsigned int i) const
Linker include dir option.
wxString WINDRES
Definition: compiler.h:203
wxString m_NewProjectOrTargetCompilerId
keeps track of the changes of compiler of the selected project/target
void OnEditLibClick(wxCommandEvent &event)
ProjectBuildTarget * m_pTarget
wxPGProperty * Append(wxPGProperty *property)
void OnEditExtraPathClick(wxCommandEvent &event)
#define wxTE_MULTILINE
void OnRemoveExtraPathClick(wxCommandEvent &event)
virtual int GetSelection() const
wxPropertyGridIterator GetIterator(int flags=wxPG_ITERATE_DEFAULT, wxPGProperty *firstProp=NULL)
void OnCompilerChanged(wxCommandEvent &event)
void OnTreeSelectionChange(wxTreeEvent &event)
#define wxICON_ERROR
virtual void DeleteAllItems()
bool wxFileExists(const wxString &filename)
void LogWarning(const wxString &msg, int i=app_log)
Definition: logmanager.h:141
DLLIMPORT wxString cbGetTextFromUser(const wxString &message, const wxString &caption=cbGetTextFromUserPromptStr, const wxString &default_value=wxEmptyString, wxWindow *parent=NULL, int x=wxDefaultCoord, int y=wxDefaultCoord, bool centre=true)
Definition: globals.cpp:1465
wxString Strip(stripType s=trailing) const
static Compiler * GetDefaultCompiler()
virtual void SetLibDirs(const wxArrayString &libDirs)
wxString supersedes
Link console executable command, e.g. "$linker $libdirs -o $exe_output $link_objects $libs"...
Definition: compiler.h:172
wxTreeItemId GetOldItem() const
void OnClearVarClick(wxCommandEvent &event)
VariableListClientData(const wxString &key, const wxString &value)
virtual void OnApply()
Called when the user chooses to apply the configuration.
bool ReadBool(const wxString &name, bool defaultVal=false)
DLLIMPORT wxString ChooseDirectory(wxWindow *parent, const wxString &message=_("Select directory"), const wxString &initialPath=_T(""), const wxString &basePath=_T(""), bool askToMakeRelative=false, bool showCreateDirButton=false)
Definition: globals.cpp:639
Generate dependencies command.
Definition: compiler.h:169
int Index(const wxString &sz, bool bCase=true, bool bFromEnd=false) const
virtual void SetFilterIndex(int filterIndex)
DebuggerClientData(const wxString &s)
virtual wxTreeItemId GetSelection() const
CompOption * GetOption(int index)
#define wxCANCEL
wxString CPP
Definition: compiler.h:200
virtual const wxArrayString & GetCompilerOptions() const
wxArrayString m_ResourceCompilerOptions
wxCStrData c_str() const
bool wxDirExists(const wxString &dirname)
wxMenuItem * Append(int id, const wxString &item=wxEmptyString, const wxString &helpString=wxEmptyString, wxItemKind kind=wxITEM_NORMAL)
static Compiler * GetCompiler(size_t index)
static int GetCompilerIndex(const wxString &id)
void OnRemoveLibClick(wxCommandEvent &event)
virtual void Reset()
Reset settings to defaults.
Definition: compiler.cpp:157
ScopeTreeData(cbProject *project, ProjectBuildTarget *target)
#define wxNO_DEFAULT
#define _T(string)
void SetPropertyAttribute(wxPGPropArg id, const wxString &attrName, wxVariant value, long argFlags=0)
virtual void AddIncludeDir(const wxString &option)
static const wxString & GetDefaultCompilerID()
wxArrayString m_LinkerOptions
#define wxYES_NO
void OnResetCompilerClick(wxCommandEvent &event)
bool SetColumnProportion(unsigned int column, int proportion)
void OnMoveDirUpClick(wxCommandEvent &event)
DLLIMPORT wxString GetStringFromArray(const wxArrayString &array, const wxString &separator=DEFAULT_ARRAY_SEP, bool SeparatorAtEnd=true)
Definition: globals.cpp:122
const wxString & GetCPPOnlyFlags()
Definition: compiler.h:376
Compile object command, e.g. "$compiler $options $includes -c $file -o $object".
Definition: compiler.h:168
virtual wxTreeItemData * GetItemData(const wxTreeItemId &item) const
void SetCPPOnlyFlags(const wxString &flags)
Definition: compiler.h:373
cbProject * GetProject()
wxString & Remove(size_t pos)
void OnMasterPathClick(wxCommandEvent &event)
bool UseFullSourcePaths
Definition: compiler.h:231
virtual unsigned int GetCount() const
bool GetBool() const
wxString name
void ProjectTargetCompilerAdjust()
checks if compiler changed for project/target and takes actions accordingly
void SetRange(int minVal, int maxVal)
void OnFlagsPopupClick(wxCommandEvent &event)
void OnEditVarClick(wxCommandEvent &event)
virtual void SetLinkLibs(const wxArrayString &linkLibs)
wxString AfterFirst(wxUniChar ch) const
#define wxT(string)
virtual const wxArrayString & GetBuildScripts() const
static void UnregisterCompilers()
Unregister all compilers.
bool wxMkdir(const wxString &dir, int perm=wxS_DIR_DEFAULT)
#define wxNOT_FOUND
virtual void RecalcSizes()=0
Struct to keep programs.
Definition: compiler.h:197
void OnClearExtraPathClick(wxCommandEvent &event)
CompilerOptions m_Options
wxArrayString ReadArrayString(const wxString &name)
wxString defines
Definition: compiler.h:215
void OnRemoveVarClick(wxCommandEvent &event)
CompOption * GetOptionByName(const wxString &name)
#define wxPG_BOOL_USE_CHECKBOX
virtual void SetCompilerID(const wxString &id)
! Set the flag if the host app should be run in terminal
wxString LD
Definition: compiler.h:201
wxPanel * LoadPanel(wxWindow *parent, const wxString &name)
wxTreeItemId GetItem() const
bool forceFwdSlashes
Definition: compiler.h:218
bool ExpandAll(bool expand=true)
void OnTreeSelectionChanging(wxTreeEvent &event)
void ListBox2ArrayString(wxArrayString &array, const wxListBox *control)
static Compiler * CreateCompilerCopy(Compiler *compiler, const wxString &newName)
Create a copy of a compiler.
void OnOptionChanged(wxPropertyGridEvent &event)
wxString option
wxPGProperty * GetFirstChild(wxPGPropArg id)
#define wxICON_EXCLAMATION
virtual TargetType GetTargetType() const
Read the target&#39;s type.
void SetPropertyValue(wxPGPropArg id, long value)
wxXmlNode * GetNext() const
void DoFillCompilerSets(int compilerIdx)
virtual void SetCompilerOptions(const wxArrayString &compilerOpts)
wxUSE_UNICODE_dependent wxChar
static void RemoveCompiler(Compiler *compiler)
Remove a compiler.
std::vector< RegExStruct > RegExArray
Definition: compiler.h:163
wxString BeforeFirst(wxUniChar ch, wxString *rest=NULL) const
static Compiler * SelectCompilerUI(const wxString &message=_("Select compiler"), const wxString &preselectedID=wxEmptyString)
void OnIgnoreAddClick(wxCommandEvent &event)
virtual void SetString(unsigned int pos, const wxString &s)
const wxString & GetID() const
Get this compiler&#39;s unique ID.
Definition: compiler.h:351
virtual bool DeletePage(size_t page)
virtual void AddResourceIncludeDir(const wxString &option)
void SetCompilerID(const wxString &id) override
! Set the flag if the host app should be run in terminal
Definition: cbproject.cpp:129
virtual OptionsRelation GetOptionRelation(OptionsRelationType type) const
Read the target&#39;s options relation for type.
void Write(const wxString &name, const wxString &value, bool ignoreEmpty=false)
DebuggerManager * GetDebuggerManager() const
Definition: manager.cpp:484
void OnMoveLibUpClick(wxCommandEvent &event)
virtual const wxArrayString & GetResourceIncludeDirs() const
void Insert(wxString lItem, size_t nIndex, size_t copies=1)
Represents a Code::Blocks project.
Definition: cbproject.h:96
void OnMyCharHook(wxKeyEvent &event)
void OnAddCompilerClick(wxCommandEvent &event)
void ArrayString2ListBox(const wxArrayString &array, wxListBox *control)
virtual const wxArrayString & GetLinkerOptions() const
const wxString & GetCOnlyFlags()
Definition: compiler.h:375
virtual void AddLinkLib(const wxString &option)
std::vector< CompilerTool > CompilerToolsVector
Definition: compiler.h:267
Link dynamic (dll) lib command, e.g. "$linker -shared -Wl,--output-def=$def_output -Wl...
Definition: compiler.h:173
void OnClearDirClick(wxCommandEvent &event)
CompilerGCC * m_Compiler
ProjectBuildTarget * m_Target
wxArtID wxART_QUESTION
wxString & RemoveLast(size_t n=1)
virtual const wxArrayString & GetLinkLibs() const
void OnDirty(wxCommandEvent &event)
null_pointer_t nullptr
Definition: nullptr.cpp:16
virtual wxString GetMakeCommandFor(MakeCommand cmd) const
Get the "make" command used for cmd.
wxString objectExtension
Definition: compiler.h:217
virtual bool Save(const wxString &filename, int indentstep=2) const
virtual const wxString & GetTitle() const
Read the target&#39;s title.
Resource compiler include dir option.
virtual void AddLibDir(const wxString &option)
wxString Left(size_t count) const
virtual const wxArrayString & GetResourceCompilerOptions() const
wxString MAKE
Definition: compiler.h:204
#define wxTAB_TRAVERSAL
static void QuoteString(wxString &value, const wxString &caption)
size_t Replace(const wxString &strOld, const wxString &strNew, bool replaceAll=true)
OptionsRelation
Option&#39;s relation.
virtual void SelectItem(const wxTreeItemId &item, bool select=true)
bool m_LogBuildProgressPercentage
Definition: compilergcc.h:328
const wxSize wxDefaultSize
const wxPoint wxDefaultPosition
#define wxCHECK_VERSION(major, minor, release)
wxChar includeDirSeparator
Definition: compiler.h:240
unsigned int GetCount() const
static void SetDefaultCompiler(size_t index)
virtual const CompilerPrograms & GetPrograms() const
Get the compiler&#39;s programs.
Definition: compiler.h:299
wxMenuItem * AppendSeparator()
virtual const wxArrayString & GetExtraPaths() const
Get the compiler&#39;s extra paths.
Definition: compiler.h:297
LogManager * GetLogManager() const
Definition: manager.cpp:439
const wxString & GetPath()
Definition: editpathdlg.h:27
wxString & Item(size_t nIndex)
virtual void SetIncludeDirs(const wxArrayString &includeDirs)
void OnRemoveCompilerClick(wxCommandEvent &event)
virtual wxString GetBasePath() const
Read the target&#39;s base path, e.g. if GetFilename() returns "/usr/local/bin/xxx", base path will retur...
wxString libExtension
Definition: compiler.h:224
wxPGProperty * GetParent() const
void OnAddLibClick(wxCommandEvent &event)
bool IsEmpty() const
wxChar objectSeparator
Definition: compiler.h:242
wxString linkLibs
Definition: compiler.h:214
virtual void SetCommandsBeforeBuild(const wxArrayString &commands)
static void SaveSettings()
Compiler include dir option.
virtual const wxArrayString & GetCommandsAfterBuild() const
void OnAdvancedClick(wxCommandEvent &event)
This is a base class for all classes needing compilation parameters.
static wxUniChar GetPathSeparator(wxPathFormat format=wxPATH_NATIVE)
wxString DBGconfig
Definition: compiler.h:205
void SortChildren(wxPGPropArg id, int flags=0)
const wxStringCharType * wx_str() const
virtual int ShowModal()
DLLIMPORT wxArrayInt cbGetMultiChoiceDialog(const wxString &message, const wxString &caption, const wxArrayString &choices, wxWindow *parent=nullptr, const wxSize &size=wxSize(300, 300), const wxArrayInt &initialSelection=wxArrayInt())
wxMultiChoiceDialog wrapper.
Definition: globals.cpp:1441
Link executable command, e.g. "$linker $libdirs -o $exe_output $link_objects $libs -mwindows"...
Definition: compiler.h:171
wxPropertyGrid * m_FlagsPG
wxString includeDirs
Definition: compiler.h:212
wxString wxEmptyString
virtual void SetExtraPaths(const wxArrayString &paths)
Set the compiler&#39;s extra paths.
Definition: compiler.h:323
void OnAddVarClick(wxCommandEvent &event)
void OnAutoDetectClick(wxCommandEvent &event)
static void UpdateUIListBoxAndButtons(wxListBox &list, wxButton &edit, wxButton &del, wxButton &clear, wxButton &copy, wxButton &up, wxButton &down)
#define wxOK
wxVariant GetPropertyValue(wxPGPropArg id)
virtual void SetAlwaysRunPostBuildSteps(bool always)
virtual void SetValue(const wxString &text)
void Sort(int flags=0)
MacrosManager * GetMacrosManager() const
Definition: manager.cpp:454
unsigned int GetChildCount() const
const wxString & _(const wxString &string)
DLLIMPORT void QuoteStringIfNeeded(wxString &str)
Definition: globals.cpp:260
wxString & Trim(bool fromRight=true)
wxString category
bool IsMakefileCustom()
Definition: cbproject.h:159
void ShowErrorMessage(bool safe=true)
Display exception error message.
Definition: cbexception.cpp:31
int cbMessageBox(const wxString &message, const wxString &caption=wxEmptyString, int style=wxOK, wxWindow *parent=NULL, int x=-1, int y=-1)
Call global cbMessageBox with m_parentDialog as parent window when no parent window specified...
std::map< cbDebuggerPlugin *, PluginData > RegisteredPlugins
int GetBuildTargetsCount()
Definition: cbproject.h:200
virtual void SetOptions(const CompilerOptions &options)
Set the compiler&#39;s options.
Definition: compiler.h:329
ProjectBuildTarget * GetTarget()
void OnSelectProgramClick(wxCommandEvent &event)
void OnEditDirClick(wxCommandEvent &event)
void ArrayString2TextCtrl(const wxArrayString &array, wxTextCtrl *control)
bool ChangePropertyValue(wxPGPropArg id, wxVariant newValue)
virtual const wxArrayString & GetIncludeDirs() const
CommandType
Helper enum to retrieve compiler commands.
Definition: compiler.h:166
void SaveOptions()
wxPGProperty * AppendIn(wxPGPropArg id, wxPGProperty *newProperty)
wxArrayString m_CompilerOptions
wxArray< int > wxArrayInt
bool IsChecked() const
wxString checkMessage
static wxString GetDataFolder(bool global=true)
ProjectBuildTarget * GetBuildTarget(int index)
Access a build target.
Definition: cbproject.cpp:1392
virtual void Expand(const wxTreeItemId &item)
Compile Win32 resources command, e.g. "$rescomp -i $file -J rc -o $resource_output -O coff $includes"...
Definition: compiler.h:170
Abstract base class for compilers.
Definition: compiler.h:274
bool m_bDirty
true if a setting has changed since last save
void OnFlagsPopup(wxPropertyGridEvent &event)
DLLIMPORT const wxString DEFAULT_ARRAY_SEP
Definition: globals.cpp:56
virtual void SetLinkerOptions(const wxArrayString &linkerOpts)
void SetRoot(wxXmlNode *node)
void OnCopyDirsClick(wxCommandEvent &event)
void OnMoveLibDownClick(wxCommandEvent &event)
wxString libPrefix
Definition: compiler.h:223
bool IsEmpty() const
DLLIMPORT void PlaceWindow(wxTopLevelWindow *w, cbPlaceDialogMode mode=pdlBest, bool enforce=false)
Definition: globals.cpp:1177
virtual bool GetAlwaysRunPostBuildSteps() const
virtual const wxArrayString & GetLibDirs() const
void OnCopyLibsClick(wxCommandEvent &event)
virtual int GetSelection() const
void OnOptionDoubleClick(wxPropertyGridEvent &event)
RegisteredPlugins const & GetAllDebuggers() const
virtual const wxString & GetCompilerID() const
Read the target&#39;s compiler.
bool forceLinkerUseQuotes
Definition: compiler.h:219
void AddOption(CompOption *coption, int index=-1)
size_t Len() const
virtual bool SetVar(const wxString &key, const wxString &value, bool onlyIfExists=false)
wxString C
Definition: compiler.h:199
int GetValue() const
bool AttachUnknownControl(const wxString &name, wxWindow *control, wxWindow *parent=NULL)
CompOption * GetOptionByAdditionalLibs(const wxString &libs)
virtual const wxString & GetName() const
Get the compiler&#39;s name.
Definition: compiler.h:293
const wxString & GetParentID() const
Get this compiler&#39;s parent&#39;s unique ID.
Definition: compiler.h:353
virtual int SetSelection(size_t page)
wxString checkAgainst
virtual const CompilerSwitches & GetSwitches() const
Get the compiler&#39;s generic switches.
Definition: compiler.h:301
bool EndsWith(const wxString &suffix, wxString *rest=NULL) const
int ShowModal() override
wxChar libDirSeparator
Definition: compiler.h:241
void RemoveOption(int index)
void OnEditCompilerClick(wxCommandEvent &event)
virtual void SetResourceIncludeDirs(const wxArrayString &resIncludeDirs)
virtual CompilerToolsVector & GetCommandToolsVector(CommandType ct)
Get a command tool vector based on CommandType (used by advanced compiler dialog) ...
Definition: compiler.h:312
void DoGetCompileOptions(wxArrayString &array, const wxTextCtrl *control)
#define wxYES
void SetVersion(const wxString &version)
virtual wxTreeItemId AddRoot(const wxString &text, int image=-1, int selImage=-1, wxTreeItemData *data=NULL)
DLLIMPORT wxString MakeUniqueString(const wxString &text, const wxString &separator=DEFAULT_ARRAY_SEP, bool caseSens=true)
Definition: globals.cpp:217
size_t Add(const wxString &str, size_t copies=1)
bool StartsWith(const wxString &prefix, wxString *rest=NULL) const
bool linkerNeedsLibPrefix
Definition: compiler.h:225
Represents a Code::Blocks project build target.
void OnIgnoreRemoveClick(wxCommandEvent &event)
static size_t GetCompilersCount()
Linker option.
wxString LIB
Definition: compiler.h:202
wxPGProperty * GetRoot() const
size_t GetCount() const
int Find(wxUniChar ch, bool fromEnd=false) const
Link native binary command.
Definition: compiler.h:175
static wxXmlResource * Get()
void OnUpdateUI(wxUpdateUIEvent &event)
virtual void Clear()
wxArrayString m_LinkLibs
virtual void SetSwitches(const CompilerSwitches &switches)
Set the compiler&#39;s generic switches.
Definition: compiler.h:327
Link static lib command, e.g. "ar -r $output $link_objects\n\tranlib $static_output".
Definition: compiler.h:174
bool m_bFlagsDirty
true if a flag (not its value) has changed since last save
bool m_BuildingTree
flag to ignore tree changing events while building it
void RemoveAt(size_t nIndex, size_t count=1)
#define wxRESIZE_BORDER
virtual AutoDetectResult AutoDetectInstallationDir()=0
Try to auto-detect the compiler&#39;s installation directory.
virtual bool RemovePage(size_t page)
Compiler option.
int Printf(const wxString &pszFormat,...)
virtual void SetSelection(int n)
void OnMoveDirDownClick(wxCommandEvent &event)
virtual const StringHash & GetAllVars() const
bool forceCompilerUseQuotes
Definition: compiler.h:220
virtual void SetValue(bool state)
CompOption * GetOptionByOption(const wxString &option)
Code::Blocks error handling unit.
Definition: cbexception.h:23
Struct to keep switches.
Definition: compiler.h:209
Do NOT use.
Definition: compiler.h:177
wxArtID wxART_INFORMATION
virtual void SetCommandsAfterBuild(const wxArrayString &commands)
void LoadOptions()
static wxString Format(const wxString &format,...)
CompilerOptionsDlg(wxWindow *parent, CompilerGCC *compiler, cbProject *project=0L, ProjectBuildTarget *target=0L)
bool ReAllocProcesses()
bool needDependencies
Definition: compiler.h:221
Dialog that contains a "Don&#39;t annoy me" checkbox.
void SetupEnvironment()
const wxString lt(_T("<"))
virtual void SetMasterPath(const wxString &path)
Set the compiler&#39;s master path (must contain "bin", "include" and "lib")
Definition: compiler.h:321
void OnCategoryChanged(wxCommandEvent &event)
virtual void AddChild(wxXmlNode *child)
wxTreeItemId AppendItem(const wxTreeItemId &parent, const wxString &text, int image=-1, int selImage=-1, wxTreeItemData *data=NULL)
void SetCOnlyFlags(const wxString &flags)
Definition: compiler.h:372
bool linkerNeedsPathResolved
Definition: compiler.h:227
Target only runs commands in pre-build and/or post-build steps.
bool UseFlatObjects
Definition: compiler.h:230
virtual const wxArrayString & GetCommandsBeforeBuild() const