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
6
* $Id: advancedcompileroptionsdlg.cpp 4909 2008-02-27 13:15:26Z mortenmacfly $
7
* $HeadURL: svn://svn.berlios.de/codeblocks/tags/8.02/src/plugins/compilergcc/advancedcompileroptionsdlg.cpp $
12
#include <wx/checkbox.h>
13
#include <wx/choice.h>
14
#include <wx/combobox.h>
16
#include <wx/listbox.h>
18
#include <wx/spinctrl.h>
19
#include <wx/textctrl.h>
20
#include <wx/textdlg.h>
21
#include <wx/xrc/xmlres.h>
22
#include "compilerfactory.h"
25
#include "advancedcompileroptionsdlg.h"
27
// TODO : implement full IsDirty mechanism, now always forced to true when ok is pressed
28
// NOTE : when OK pressed settings are already applied to the compiler, although in the compiler settings
29
// that the parent dialog that spawned this dialog the user can still click on cancel there,
30
// meaning also the changes here should not be applied, but as it is now : too late, applied (TO FIX)
33
wxString ControlCharsToString(const wxString& src)
36
ret.Replace(_T("\t"), _T("\\t"));
37
ret.Replace(_T("\n"), _T("\\n"));
38
ret.Replace(_T("\r"), _T("\\r"));
39
ret.Replace(_T("\a"), _T("\\a"));
40
ret.Replace(_T("\b"), _T("\\b"));
42
} // end of ControlCharsToString
44
wxString StringToControlChars(const wxString& src)
47
ret.Replace(_T("\\t"), _T("\t"));
48
ret.Replace(_T("\\n"), _T("\n"));
49
ret.Replace(_T("\\r"), _T("\r"));
50
ret.Replace(_T("\\a"), _T("\a"));
51
ret.Replace(_T("\\b"), _T("\b"));
53
} // end of StringToControlChars
55
BEGIN_EVENT_TABLE(AdvancedCompilerOptionsDlg, wxDialog)
56
EVT_CHOICE(XRCID("lstCommands"), AdvancedCompilerOptionsDlg::OnCommandsChange)
57
EVT_CHOICE(XRCID("lstExt"), AdvancedCompilerOptionsDlg::OnExtChange)
58
EVT_BUTTON(XRCID("btnAddExt"), AdvancedCompilerOptionsDlg::OnAddExt)
59
EVT_BUTTON(XRCID("btnRemoveExt"), AdvancedCompilerOptionsDlg::OnDelExt)
60
EVT_LISTBOX(XRCID("lstRegex"), AdvancedCompilerOptionsDlg::OnRegexChange)
61
EVT_BUTTON(XRCID("btnRegexTest"), AdvancedCompilerOptionsDlg::OnRegexTest)
62
EVT_BUTTON(XRCID("btnRegexAdd"), AdvancedCompilerOptionsDlg::OnRegexAdd)
63
EVT_BUTTON(XRCID("btnRegexDelete"), AdvancedCompilerOptionsDlg::OnRegexDelete)
64
EVT_BUTTON(XRCID("btnRegexDefaults"), AdvancedCompilerOptionsDlg::OnRegexDefaults)
65
EVT_SPIN_UP(XRCID("spnRegexOrder"), AdvancedCompilerOptionsDlg::OnRegexUp)
66
EVT_SPIN_DOWN(XRCID("spnRegexOrder"), AdvancedCompilerOptionsDlg::OnRegexDown)
69
AdvancedCompilerOptionsDlg::AdvancedCompilerOptionsDlg(wxWindow* parent, const wxString& compilerId)
70
: m_CompilerId(compilerId),
75
wxXmlResource::Get()->LoadDialog(this, parent, _T("dlgAdvancedCompilerOptions"));
76
ReadCompilerOptions();
79
GetSizer()->SetSizeHints(this);
80
} // end of constructor
82
AdvancedCompilerOptionsDlg::~AdvancedCompilerOptionsDlg()
87
void AdvancedCompilerOptionsDlg::ReadCompilerOptions()
89
Compiler* compiler = CompilerFactory::GetCompiler(m_CompilerId);
91
wxChoice* lst = XRCCTRL(*this, "lstCommands", wxChoice);
93
for (int i = 0; i < ctCount; ++i)
95
m_Commands[i] = compiler->GetCommandToolsVector((CommandType)i);
96
lst->Append(Compiler::CommandTypeDescriptions[i]);
103
const CompilerSwitches& switches = compiler->GetSwitches();
104
XRCCTRL(*this, "txtAddIncludePath", wxTextCtrl)->SetValue(switches.includeDirs);
105
XRCCTRL(*this, "txtAddLibPath", wxTextCtrl)->SetValue(switches.libDirs);
106
XRCCTRL(*this, "txtAddLib", wxTextCtrl)->SetValue(switches.linkLibs);
107
XRCCTRL(*this, "txtLibPrefix", wxTextCtrl)->SetValue(switches.libPrefix);
108
XRCCTRL(*this, "txtLibExt", wxTextCtrl)->SetValue(switches.libExtension);
109
XRCCTRL(*this, "txtDefine", wxTextCtrl)->SetValue(switches.defines);
110
XRCCTRL(*this, "txtGenericSwitch", wxTextCtrl)->SetValue(switches.genericSwitch);
111
XRCCTRL(*this, "txtObjectExt", wxTextCtrl)->SetValue(switches.objectExtension);
112
XRCCTRL(*this, "chkFwdSlashes", wxCheckBox)->SetValue(switches.forceFwdSlashes);
113
XRCCTRL(*this, "chkLinkerNeedsLibPrefix", wxCheckBox)->SetValue(switches.linkerNeedsLibPrefix);
114
XRCCTRL(*this, "chkLinkerNeedsLibExt", wxCheckBox)->SetValue(switches.linkerNeedsLibExtension);
115
XRCCTRL(*this, "chkNeedDeps", wxCheckBox)->SetValue(switches.needDependencies);
116
XRCCTRL(*this, "chkForceCompilerQuotes", wxCheckBox)->SetValue(switches.forceCompilerUseQuotes);
117
XRCCTRL(*this, "chkForceLinkerQuotes", wxCheckBox)->SetValue(switches.forceLinkerUseQuotes);
118
XRCCTRL(*this, "chkSupportsPCH", wxCheckBox)->SetValue(switches.supportsPCH);
119
XRCCTRL(*this, "txtPCHExt", wxTextCtrl)->SetValue(switches.PCHExtension);
120
XRCCTRL(*this, "chkUseFlatObjects", wxCheckBox)->SetValue(switches.UseFlatObjects);
121
XRCCTRL(*this, "chkUseFullSourcePaths", wxCheckBox)->SetValue(switches.UseFullSourcePaths);
123
m_Regexes = compiler->GetRegExArray();
124
m_SelectedRegex = m_Regexes.Count() > 0 ? 0 : -1;
126
} // end of ReadCompilerOptions
128
void AdvancedCompilerOptionsDlg::WriteCompilerOptions()
130
Compiler* compiler = CompilerFactory::GetCompiler(m_CompilerId);
132
for (int i = 0; i < ctCount; ++i)
134
compiler->GetCommandToolsVector((CommandType)i) = m_Commands[i];
138
CompilerSwitches switches;
139
switches.includeDirs = XRCCTRL(*this, "txtAddIncludePath", wxTextCtrl)->GetValue();
140
switches.libDirs = XRCCTRL(*this, "txtAddLibPath", wxTextCtrl)->GetValue();
141
switches.linkLibs = XRCCTRL(*this, "txtAddLib", wxTextCtrl)->GetValue();
142
switches.libPrefix = XRCCTRL(*this, "txtLibPrefix", wxTextCtrl)->GetValue();
143
switches.libExtension = XRCCTRL(*this, "txtLibExt", wxTextCtrl)->GetValue();
144
switches.defines = XRCCTRL(*this, "txtDefine", wxTextCtrl)->GetValue();
145
switches.genericSwitch = XRCCTRL(*this, "txtGenericSwitch", wxTextCtrl)->GetValue();
146
switches.objectExtension = XRCCTRL(*this, "txtObjectExt", wxTextCtrl)->GetValue();
147
switches.forceFwdSlashes = XRCCTRL(*this, "chkFwdSlashes", wxCheckBox)->GetValue();
148
switches.linkerNeedsLibPrefix = XRCCTRL(*this, "chkLinkerNeedsLibPrefix", wxCheckBox)->GetValue();
149
switches.linkerNeedsLibExtension = XRCCTRL(*this, "chkLinkerNeedsLibExt", wxCheckBox)->GetValue();
150
switches.needDependencies = XRCCTRL(*this, "chkNeedDeps", wxCheckBox)->GetValue();
151
switches.forceCompilerUseQuotes = XRCCTRL(*this, "chkForceCompilerQuotes", wxCheckBox)->GetValue();
152
switches.forceLinkerUseQuotes = XRCCTRL(*this, "chkForceLinkerQuotes", wxCheckBox)->GetValue();
153
switches.supportsPCH = XRCCTRL(*this, "chkSupportsPCH", wxCheckBox)->GetValue();
154
switches.PCHExtension = XRCCTRL(*this, "txtPCHExt", wxTextCtrl)->GetValue();
155
switches.UseFlatObjects = XRCCTRL(*this, "chkUseFlatObjects", wxCheckBox)->GetValue();
156
switches.UseFullSourcePaths = XRCCTRL(*this, "chkUseFullSourcePaths", wxCheckBox)->GetValue();
157
compiler->SetSwitches(switches);
158
} // end of WriteCompilerOptions
160
void AdvancedCompilerOptionsDlg::ReadExtensions(int nr)
162
wxChoice* cmb = XRCCTRL(*this, "lstExt", wxChoice);
164
for (size_t i = 0; i < m_Commands[nr].size(); ++i)
166
cmb->Append(GetStringFromArray(m_Commands[nr][i].extensions, DEFAULT_ARRAY_SEP, false));
168
cmb->SetSelection(cmb->FindString(wxEmptyString));
171
CompilerTool* AdvancedCompilerOptionsDlg::GetCompilerTool(int cmd, int ext)
173
const wxChoice* cmb = XRCCTRL(*this, "lstExt", wxChoice);
174
for (size_t i = 0; i < m_Commands[cmd].size(); ++i)
176
if (cmb->GetString(ext).IsEmpty() && m_Commands[cmd][i].extensions.GetCount() == 0)
177
return &m_Commands[cmd][i];
179
int selExt = m_Commands[cmd][i].extensions.Index(cmb->GetString(ext));
181
return &m_Commands[cmd][i];
186
void AdvancedCompilerOptionsDlg::DisplayCommand(int cmd, int ext)
188
wxTextCtrl* text = XRCCTRL(*this, "txtCommand", wxTextCtrl);
189
wxTextCtrl* gen = XRCCTRL(*this, "txtGenerated", wxTextCtrl);
190
if (CompilerTool* tool = GetCompilerTool(cmd,ext))
192
text->SetValue(tool->command);
193
gen->SetValue(GetStringFromArray(tool->generatedFiles, _T("\n"), false));
200
m_LastCmdIndex = cmd;
201
m_LastExtIndex = ext;
202
} // end of DisplayCommand
204
void AdvancedCompilerOptionsDlg::CheckForChanges()
206
// changes can only happen after constructor : aka no longer (-1, -1)
207
if(m_LastCmdIndex != -1 && m_LastExtIndex != -1)
209
SaveCommands(m_LastCmdIndex, m_LastExtIndex);
211
} // end of CheckForChanges
213
void AdvancedCompilerOptionsDlg::SaveCommands(int cmd, int ext)
215
if (cmd == -1 || ext == -1)
217
if (CompilerTool* tool = GetCompilerTool(cmd, ext))
219
wxTextCtrl* text = XRCCTRL(*this, "txtCommand", wxTextCtrl);
220
wxTextCtrl* gen = XRCCTRL(*this, "txtGenerated", wxTextCtrl);
221
if (text->GetValue() != tool->command)
223
// last command was changed; save it
224
tool->command = text->GetValue();
226
wxString gens = GetStringFromArray(tool->generatedFiles, _T("\n"), false);
227
if (gen->GetValue() != gens)
229
// last genfiles are changed; save it
230
tool->generatedFiles = GetArrayFromString(gen->GetValue(), _T("\n"));
233
} // end of SaveCommands
235
void AdvancedCompilerOptionsDlg::FillRegexes()
237
wxListBox* list = XRCCTRL(*this, "lstRegex", wxListBox);
240
for (size_t i = 0; i < m_Regexes.Count(); ++i)
242
RegExStruct& rs = m_Regexes[i];
243
list->Append(rs.desc);
245
list->SetSelection(m_SelectedRegex);
246
FillRegexDetails(m_SelectedRegex);
249
void AdvancedCompilerOptionsDlg::FillRegexDetails(int index)
253
XRCCTRL(*this, "txtRegexDesc", wxTextCtrl)->SetValue(_T(""));
254
XRCCTRL(*this, "cmbRegexType", wxComboBox)->SetSelection(-1);
255
XRCCTRL(*this, "txtRegex", wxTextCtrl)->SetValue(_T(""));
256
XRCCTRL(*this, "spnRegexMsg1", wxSpinCtrl)->SetValue(0);
257
XRCCTRL(*this, "spnRegexMsg2", wxSpinCtrl)->SetValue(0);
258
XRCCTRL(*this, "spnRegexMsg3", wxSpinCtrl)->SetValue(0);
259
XRCCTRL(*this, "spnRegexFilename", wxSpinCtrl)->SetValue(0);
260
XRCCTRL(*this, "spnRegexLine", wxSpinCtrl)->SetValue(0);
264
RegExStruct& rs = m_Regexes[index];
265
XRCCTRL(*this, "txtRegexDesc", wxTextCtrl)->SetValue(rs.desc);
266
XRCCTRL(*this, "cmbRegexType", wxComboBox)->SetSelection((int)rs.lt);
267
XRCCTRL(*this, "txtRegex", wxTextCtrl)->SetValue(ControlCharsToString(rs.regex));
268
XRCCTRL(*this, "spnRegexMsg1", wxSpinCtrl)->SetValue(rs.msg[0]);
269
XRCCTRL(*this, "spnRegexMsg2", wxSpinCtrl)->SetValue(rs.msg[1]);
270
XRCCTRL(*this, "spnRegexMsg3", wxSpinCtrl)->SetValue(rs.msg[2]);
271
XRCCTRL(*this, "spnRegexFilename", wxSpinCtrl)->SetValue(rs.filename);
272
XRCCTRL(*this, "spnRegexLine", wxSpinCtrl)->SetValue(rs.line);
275
void AdvancedCompilerOptionsDlg::SaveRegexDetails(int index)
280
RegExStruct& rs = m_Regexes[index];
281
rs.desc = XRCCTRL(*this, "txtRegexDesc", wxTextCtrl)->GetValue();
282
rs.lt = (CompilerLineType)XRCCTRL(*this, "cmbRegexType", wxComboBox)->GetSelection();
283
rs.regex = StringToControlChars(XRCCTRL(*this, "txtRegex", wxTextCtrl)->GetValue());
284
rs.msg[0] = XRCCTRL(*this, "spnRegexMsg1", wxSpinCtrl)->GetValue();
285
rs.msg[1] = XRCCTRL(*this, "spnRegexMsg2", wxSpinCtrl)->GetValue();
286
rs.msg[2] = XRCCTRL(*this, "spnRegexMsg3", wxSpinCtrl)->GetValue();
287
rs.filename = XRCCTRL(*this, "spnRegexFilename", wxSpinCtrl)->GetValue();
288
rs.line = XRCCTRL(*this, "spnRegexLine", wxSpinCtrl)->GetValue();
291
void AdvancedCompilerOptionsDlg::OnCommandsChange(wxCommandEvent& WXUNUSED(event))
294
int cmd = XRCCTRL(*this, "lstCommands", wxChoice)->GetSelection();
295
ReadExtensions(cmd); // can change the extension cmb list !!!!!!!!!!!!!!!
296
int ext = XRCCTRL(*this, "lstExt", wxChoice)->GetSelection();
297
DisplayCommand(cmd, ext);
298
} // end of OnCommandsChange
300
void AdvancedCompilerOptionsDlg::OnExtChange(wxCommandEvent& WXUNUSED(event))
303
int cmd = XRCCTRL(*this, "lstCommands", wxChoice)->GetSelection();
304
int ext = XRCCTRL(*this, "lstExt", wxChoice)->GetSelection();
305
DisplayCommand(cmd, ext);
308
void AdvancedCompilerOptionsDlg::OnAddExt(wxCommandEvent& WXUNUSED(event))
310
wxString ext = wxGetTextFromUser(_("Please enter a semi-colon separated list of extensions, without the leading dot:"), _("New extension"));
315
int nr = XRCCTRL(*this, "lstCommands", wxChoice)->GetSelection();
316
CompilerTool* ptool = GetCompilerTool(nr,0);
317
CompilerTool tool(ptool ? ptool->command : wxString(), ext);
318
m_Commands[nr].push_back(tool);
320
wxChoice* cmb = XRCCTRL(*this, "lstExt", wxChoice);
321
cmb->SetStringSelection(ext);
322
DisplayCommand(nr,cmb->GetSelection());
326
void AdvancedCompilerOptionsDlg::OnDelExt(wxCommandEvent& WXUNUSED(event))
328
if (cbMessageBox(_("Are you sure you want to remove this extension set from the list?"), _T("Confirmation"), wxYES_NO) == wxID_YES)
330
int nr = XRCCTRL(*this, "lstCommands", wxChoice)->GetSelection();
331
wxChoice* cmb = XRCCTRL(*this, "lstExt", wxChoice);
332
wxString extS = cmb->GetStringSelection();
335
int ext = cmb->GetSelection();
336
m_Commands[nr].erase(m_Commands[nr].begin() + ext);
338
cmb->SetSelection(0);
340
DisplayCommand(nr,0);
343
cbMessageBox(_("Can't remove default commands!"), _("Error"));
347
void AdvancedCompilerOptionsDlg::OnRegexChange(wxCommandEvent& WXUNUSED(event))
349
SaveRegexDetails(m_SelectedRegex);
351
// update regex list, in case desc was changed
352
XRCCTRL(*this, "lstRegex", wxListBox)->SetString(m_SelectedRegex, XRCCTRL(*this, "txtRegexDesc", wxTextCtrl)->GetValue());
354
m_SelectedRegex = XRCCTRL(*this, "lstRegex", wxListBox)->GetSelection();
355
FillRegexDetails(m_SelectedRegex);
358
void AdvancedCompilerOptionsDlg::OnRegexAdd(wxCommandEvent& WXUNUSED(event))
360
SaveRegexDetails(m_SelectedRegex);
361
m_Regexes.Add(RegExStruct(_("New regular expression"), cltError, _T(""), 0));
362
m_SelectedRegex = m_Regexes.Count() - 1;
366
void AdvancedCompilerOptionsDlg::OnRegexDelete(wxCommandEvent& WXUNUSED(event))
368
if (cbMessageBox(_("Are you sure you want to delete this regular expression?"), _("Confirmation"), wxICON_QUESTION | wxYES_NO | wxNO_DEFAULT) == wxID_YES)
370
m_Regexes.RemoveAt(m_SelectedRegex);
371
if (m_SelectedRegex >= (int)m_Regexes.Count())
377
void AdvancedCompilerOptionsDlg::OnRegexDefaults(wxCommandEvent& WXUNUSED(event))
379
if (cbMessageBox(_("Are you sure you want to load the default regular expressions "
380
"for this compiler?\n"
381
"ALL regular expressions will be erased and replaced with their default "
383
"Are you REALLY sure?"), _("Confirmation"), wxICON_QUESTION | wxYES_NO | wxNO_DEFAULT) == wxID_YES)
385
Compiler* compiler = CompilerFactory::GetCompiler(m_CompilerId);
386
compiler->LoadDefaultRegExArray();
387
m_Regexes = compiler->GetRegExArray();
388
while (m_SelectedRegex >= (int)m_Regexes.Count())
394
void AdvancedCompilerOptionsDlg::OnRegexUp(wxSpinEvent& WXUNUSED(event))
396
if (m_SelectedRegex <= 0)
399
RegExStruct rs = m_Regexes[m_SelectedRegex];
400
m_Regexes.RemoveAt(m_SelectedRegex);
401
m_Regexes.Insert(rs, m_SelectedRegex - 1);
406
void AdvancedCompilerOptionsDlg::OnRegexDown(wxSpinEvent& WXUNUSED(event))
408
if (m_SelectedRegex >= (int)m_Regexes.Count() - 1)
411
RegExStruct rs = m_Regexes[m_SelectedRegex];
412
m_Regexes.RemoveAt(m_SelectedRegex);
413
m_Regexes.Insert(rs, m_SelectedRegex + 1);
418
void AdvancedCompilerOptionsDlg::OnRegexTest(wxCommandEvent& WXUNUSED(event))
420
if (m_SelectedRegex == -1)
422
wxString text = XRCCTRL(*this, "txtRegexTest", wxTextCtrl)->GetValue();
425
cbMessageBox(_("Please enter a compiler line in the \"Compiler output\" text box..."), _("Error"), wxICON_ERROR);
429
Compiler* compiler = CompilerFactory::GetCompiler(m_CompilerId);
432
RegExArray regex_copy = m_Regexes;
433
SaveRegexDetails(m_SelectedRegex);
436
compiler->SetRegExArray(m_Regexes);
437
CompilerLineType clt = compiler->CheckForWarningsAndErrors(text);
440
compiler->SetRegExArray(regex_copy);
441
m_Regexes = regex_copy;
444
msg.Printf(_("Regular expression analyzed as follows:\n\n"
449
clt == cltNormal ? _("Normal") : (clt == cltInfo ? _("Info") : (clt == cltError ? _("Error") : _("Warning"))),
450
compiler->GetLastErrorFilename().c_str(),
451
compiler->GetLastErrorLine().c_str(),
452
compiler->GetLastError().c_str()
455
cbMessageBox(msg, _("Test results"), wxICON_INFORMATION);
458
void AdvancedCompilerOptionsDlg::EndModal(int retCode)
460
if (retCode == wxID_OK)
463
Compiler* compiler = CompilerFactory::GetCompiler(m_CompilerId);
465
// make sure we update the first command, if it changed
468
WriteCompilerOptions();
470
SaveRegexDetails(m_SelectedRegex);
471
compiler->SetRegExArray(m_Regexes);
473
wxDialog::EndModal(retCode);