1 /*
2 * This file is part of lib_finder plugin for Code::Blocks Studio
3 * Copyright (C) 2007 Bartlomiej Swiecki
4 *
5 * wxSmith is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * wxSmith is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with wxSmith; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
18 *
19 * $Revision: 10771 $
20 * $Id: projectconfigurationpanel.cpp 10771 2016-02-06 14:29:31Z mortenmacfly $
21 * $HeadURL: svn://svn.code.sf.net/p/codeblocks/code/branches/release-20.xx/src/plugins/contrib/lib_finder/projectconfigurationpanel.cpp $
22 */
23
24 #include "projectconfigurationpanel.h"
25
26 //(*InternalHeaders(ProjectConfigurationPanel)
27 #include <wx/checkbox.h>
28 #include <wx/sizer.h>
29 #include <wx/button.h>
30 #include <wx/string.h>
31 #include <wx/intl.h>
32 #include <wx/stattext.h>
33 #include <wx/textctrl.h>
34 #include <wx/treectrl.h>
35 #include <wx/listbox.h>
36 //*)
37
38 #include <wx/tokenzr.h>
39 #include <wx/choicdlg.h>
40
41 #include "lib_finder.h"
42 #include "headersdetectordlg.h"
43
44 //(*IdInit(ProjectConfigurationPanel)
45 const long ProjectConfigurationPanel::ID_LISTBOX1 = wxNewId();
46 const long ProjectConfigurationPanel::ID_BUTTON6 = wxNewId();
47 const long ProjectConfigurationPanel::ID_CHECKBOX2 = wxNewId();
48 const long ProjectConfigurationPanel::ID_BUTTON4 = wxNewId();
49 const long ProjectConfigurationPanel::ID_BUTTON1 = wxNewId();
50 const long ProjectConfigurationPanel::ID_BUTTON2 = wxNewId();
51 const long ProjectConfigurationPanel::ID_TREECTRL1 = wxNewId();
52 const long ProjectConfigurationPanel::ID_STATICTEXT1 = wxNewId();
53 const long ProjectConfigurationPanel::ID_TEXTCTRL2 = wxNewId();
54 const long ProjectConfigurationPanel::ID_CHECKBOX1 = wxNewId();
55 const long ProjectConfigurationPanel::ID_BUTTON5 = wxNewId();
56 const long ProjectConfigurationPanel::ID_TEXTCTRL1 = wxNewId();
57 const long ProjectConfigurationPanel::ID_BUTTON3 = wxNewId();
58 const long ProjectConfigurationPanel::ID_STATICTEXT2 = wxNewId();
59 const long ProjectConfigurationPanel::ID_TIMER1 = wxNewId();
60 //*)
61
62 BEGIN_EVENT_TABLE(ProjectConfigurationPanel,cbConfigurationPanel)
63 //(*EventTable(ProjectConfigurationPanel)
64 //*)
65 END_EVENT_TABLE()
66
67 namespace
68 {
69 class TreeItemData: public wxTreeItemData
70 {
71 // Warning: since we use reference to string instead of string itself,
72 // the base string must exist as long as this item data exists
73 public:
TreeItemData(const wxString & ShortCode)74 TreeItemData(const wxString& ShortCode): m_ShortCode(ShortCode) {}
~TreeItemData()75 ~TreeItemData() {}
76
77 const wxString& m_ShortCode;
78 };
79
80 class ListItemData: public wxClientData
81 {
82 // We don't use string's reference here since project's libraries set
83 // should be much smaller than list of known libraries
84 public:
ListItemData(const wxString & ShortCode)85 ListItemData(const wxString& ShortCode): m_ShortCode(ShortCode) {}
~ListItemData()86 ~ListItemData() {}
87
88 const wxString m_ShortCode;
89 };
90 }
91
ProjectConfigurationPanel(wxWindow * parent,ProjectConfiguration * Configuration,cbProject * Project,TypedResults & KnownLibs)92 ProjectConfigurationPanel::ProjectConfigurationPanel(wxWindow* parent,ProjectConfiguration* Configuration,cbProject* Project,TypedResults& KnownLibs):
93 m_Configuration(Configuration),
94 m_Project(Project),
95 m_KnownLibs(KnownLibs)
96 {
97 //(*Initialize(ProjectConfigurationPanel)
98 wxStaticBoxSizer* StaticBoxSizer2;
99 wxBoxSizer* BoxSizer3;
100 wxBoxSizer* BoxSizer7;
101 wxBoxSizer* BoxSizer2;
102 wxStaticBoxSizer* StaticBoxSizer3;
103 wxBoxSizer* BoxSizer4;
104 wxBoxSizer* BoxSizer1;
105 wxStaticBoxSizer* m_DisableAuto;
106 wxBoxSizer* BoxSizer6;
107 wxBoxSizer* BoxSizer5;
108 wxStaticBoxSizer* StaticBoxSizer1;
109
110 Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, _T("wxID_ANY"));
111 BoxSizer1 = new wxBoxSizer(wxVERTICAL);
112 BoxSizer6 = new wxBoxSizer(wxHORIZONTAL);
113 BoxSizer5 = new wxBoxSizer(wxVERTICAL);
114 StaticBoxSizer1 = new wxStaticBoxSizer(wxVERTICAL, this, _("Libraries used in project"));
115 m_UsedLibraries = new wxListBox(this, ID_LISTBOX1, wxDefaultPosition, wxSize(147,123), 0, 0, 0, wxDefaultValidator, _T("ID_LISTBOX1"));
116 StaticBoxSizer1->Add(m_UsedLibraries, 1, wxALL|wxEXPAND, 5);
117 Button2 = new wxButton(this, ID_BUTTON6, _("Try to detect missing ones"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON6"));
118 StaticBoxSizer1->Add(Button2, 0, wxLEFT|wxRIGHT|wxEXPAND, 5);
119 BoxSizer5->Add(StaticBoxSizer1, 1, wxALL|wxEXPAND, 5);
120 m_DisableAuto = new wxStaticBoxSizer(wxVERTICAL, this, _("Extra settings"));
121 m_NoAuto = new wxCheckBox(this, ID_CHECKBOX2, _("Don\'t setup automatically"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_CHECKBOX2"));
122 m_NoAuto->SetValue(false);
123 m_NoAuto->SetToolTip(_("If you check this option, lib_finder won\'t add settings of libraries automatically.\nNote that automatic setup is available only after applying extra patch to code::blocks available at forums."));
124 m_DisableAuto->Add(m_NoAuto, 0, wxEXPAND, 5);
125 m_AddScript = new wxButton(this, ID_BUTTON4, _("Add manual build script"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BUTTON4"));
126 m_AddScript->SetToolTip(_("When you use this option, extra script will be added to the project.\nThis script does invoke lib_finder and will add settings of libraries\njust as in case of automatic setup.\nIt may be usefull when no extra-event patch has been applied."));
127 m_DisableAuto->Add(m_AddScript, 0, wxEXPAND, 5);
128 BoxSizer5->Add(m_DisableAuto, 0, wxALL|wxEXPAND, 5);
129 BoxSizer6->Add(BoxSizer5, 3, wxEXPAND, 5);
130 BoxSizer2 = new wxBoxSizer(wxVERTICAL);
131 m_Add = new wxButton(this, ID_BUTTON1, _("<"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT, wxDefaultValidator, _T("ID_BUTTON1"));
132 m_Add->Disable();
133 m_Add->SetToolTip(_("Add selected library to project"));
134 BoxSizer2->Add(m_Add, 1, wxEXPAND, 5);
135 m_Remove = new wxButton(this, ID_BUTTON2, _(">"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT, wxDefaultValidator, _T("ID_BUTTON2"));
136 m_Remove->Disable();
137 m_Remove->SetToolTip(_("Remove selected library from project"));
138 BoxSizer2->Add(m_Remove, 1, wxEXPAND, 5);
139 BoxSizer6->Add(BoxSizer2, 0, wxALIGN_CENTER_VERTICAL, 5);
140 BoxSizer3 = new wxBoxSizer(wxVERTICAL);
141 StaticBoxSizer2 = new wxStaticBoxSizer(wxVERTICAL, this, _("Known libraries"));
142 m_KnownLibrariesTree = new wxTreeCtrl(this, ID_TREECTRL1, wxDefaultPosition, wxDefaultSize, wxTR_HIDE_ROOT|wxTR_SINGLE|wxTR_DEFAULT_STYLE|wxSUNKEN_BORDER, wxDefaultValidator, _T("ID_TREECTRL1"));
143 StaticBoxSizer2->Add(m_KnownLibrariesTree, 1, wxALL|wxEXPAND, 5);
144 BoxSizer4 = new wxBoxSizer(wxHORIZONTAL);
145 StaticText1 = new wxStaticText(this, ID_STATICTEXT1, _("Filter:"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT1"));
146 BoxSizer4->Add(StaticText1, 0, wxTOP|wxBOTTOM|wxLEFT|wxALIGN_CENTER_VERTICAL, 5);
147 m_Filter = new wxTextCtrl(this, ID_TEXTCTRL2, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_TEXTCTRL2"));
148 BoxSizer4->Add(m_Filter, 1, wxALL|wxALIGN_CENTER_VERTICAL, 5);
149 StaticBoxSizer2->Add(BoxSizer4, 0, wxEXPAND, 5);
150 BoxSizer7 = new wxBoxSizer(wxHORIZONTAL);
151 m_Tree = new wxCheckBox(this, ID_CHECKBOX1, _("Show as tree"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_CHECKBOX1"));
152 m_Tree->SetValue(true);
153 BoxSizer7->Add(m_Tree, 1, wxLEFT|wxRIGHT|wxEXPAND, 5);
154 Button1 = new wxButton(this, ID_BUTTON5, _("Edit"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT, wxDefaultValidator, _T("ID_BUTTON5"));
155 Button1->Hide();
156 BoxSizer7->Add(Button1, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 5);
157 StaticBoxSizer2->Add(BoxSizer7, 0, wxEXPAND, 5);
158 BoxSizer3->Add(StaticBoxSizer2, 1, wxBOTTOM|wxEXPAND, 5);
159 StaticBoxSizer3 = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Unknown library"));
160 m_UnknownLibrary = new wxTextCtrl(this, ID_TEXTCTRL1, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_TEXTCTRL1"));
161 StaticBoxSizer3->Add(m_UnknownLibrary, 1, wxTOP|wxBOTTOM|wxLEFT|wxEXPAND, 5);
162 m_AddUnknown = new wxButton(this, ID_BUTTON3, _("Add"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT, wxDefaultValidator, _T("ID_BUTTON3"));
163 m_AddUnknown->Disable();
164 StaticBoxSizer3->Add(m_AddUnknown, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5);
165 BoxSizer3->Add(StaticBoxSizer3, 0, wxTOP|wxEXPAND, 5);
166 BoxSizer6->Add(BoxSizer3, 4, wxALL|wxEXPAND, 5);
167 BoxSizer1->Add(BoxSizer6, 1, wxEXPAND, 5);
168 m_EventText = new wxStaticText(this, ID_STATICTEXT2, _("Note: Because there\'s not yet ability to update project\'s build options\nfrom plugin, the only way to automatically add library configurations\nis to use build script"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE, _T("ID_STATICTEXT2"));
169 m_EventText->Hide();
170 BoxSizer1->Add(m_EventText, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5);
171 SetSizer(BoxSizer1);
172 Timer1.SetOwner(this, ID_TIMER1);
173 BoxSizer1->Fit(this);
174 BoxSizer1->SetSizeHints(this);
175
176 Connect(ID_LISTBOX1,wxEVT_COMMAND_LISTBOX_SELECTED,(wxObjectEventFunction)&ProjectConfigurationPanel::Onm_UsedLibrariesSelect);
177 Connect(ID_BUTTON6,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&ProjectConfigurationPanel::OnButton2Click);
178 Connect(ID_BUTTON4,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&ProjectConfigurationPanel::Onm_AddScriptClick);
179 Connect(ID_BUTTON1,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&ProjectConfigurationPanel::Onm_AddClick);
180 Connect(ID_BUTTON2,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&ProjectConfigurationPanel::Onm_RemoveClick);
181 Connect(ID_TREECTRL1,wxEVT_COMMAND_TREE_SEL_CHANGED,(wxObjectEventFunction)&ProjectConfigurationPanel::Onm_KnownLibrariesTreeSelectionChanged);
182 Connect(ID_TEXTCTRL2,wxEVT_COMMAND_TEXT_UPDATED,(wxObjectEventFunction)&ProjectConfigurationPanel::Onm_FilterText);
183 Connect(ID_TEXTCTRL2,wxEVT_COMMAND_TEXT_ENTER,(wxObjectEventFunction)&ProjectConfigurationPanel::Onm_FilterTextEnter);
184 Connect(ID_CHECKBOX1,wxEVT_COMMAND_CHECKBOX_CLICKED,(wxObjectEventFunction)&ProjectConfigurationPanel::Onm_TreeClick);
185 Connect(ID_TEXTCTRL1,wxEVT_COMMAND_TEXT_UPDATED,(wxObjectEventFunction)&ProjectConfigurationPanel::Onm_UnknownLibraryText);
186 Connect(ID_BUTTON3,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&ProjectConfigurationPanel::Onm_AddUnknownClick);
187 Connect(ID_TIMER1,wxEVT_TIMER,(wxObjectEventFunction)&ProjectConfigurationPanel::OnTimer1Trigger);
188 //*)
189
190 m_EventText->Show(!lib_finder::IsExtraEvent());
191
192 if ( m_Project->GetBuildScripts().Index(_T("lib_finder.script")) != wxNOT_FOUND )
193 m_AddScript->Disable(); // There's a build script yet
194
195 m_ConfCopy = *m_Configuration;
196 FillKnownLibraries();
197 LoadData();
198 }
199
~ProjectConfigurationPanel()200 ProjectConfigurationPanel::~ProjectConfigurationPanel()
201 {
202 //(*Destroy(ProjectConfigurationPanel)
203 //*)
204 }
205
GetTitle() const206 wxString ProjectConfigurationPanel::GetTitle() const
207 {
208 return _("Libraries");
209 }
210
GetBitmapBaseName() const211 wxString ProjectConfigurationPanel::GetBitmapBaseName() const
212 {
213 return _T("");
214 }
215
OnApply()216 void ProjectConfigurationPanel::OnApply()
217 {
218 StoreData();
219 *m_Configuration = m_ConfCopy;
220 }
221
OnCancel()222 void ProjectConfigurationPanel::OnCancel()
223 {
224 }
225
LoadData()226 void ProjectConfigurationPanel::LoadData()
227 {
228 m_UsedLibraries->Freeze();
229 for ( size_t i=0; i<m_ConfCopy.m_GlobalUsedLibs.Count(); i++ )
230 {
231 wxString Name = m_ConfCopy.m_GlobalUsedLibs[i];
232 m_UsedLibraries->Append(GetUserListName(Name),new ListItemData(Name));
233 }
234 m_UsedLibraries->Thaw();
235 m_NoAuto->SetValue(m_ConfCopy.m_DisableAuto);
236 }
237
GetUserListName(const wxString & Name)238 wxString ProjectConfigurationPanel::GetUserListName(const wxString& Name)
239 {
240 for ( int i=0; i<rtCount; i++ )
241 {
242 if ( m_KnownLibs[i].IsShortCode(Name) )
243 {
244 switch ( i )
245 {
246 case rtPkgConfig:
247 return Name + _T(" (pkg-config)");
248
249 default:
250 return Name + _T(": ") + m_KnownLibs[i].GetShortCode(Name)[0]->LibraryName;
251 }
252 }
253 }
254
255 return Name + _T(" (Unknown library)");
256 }
257
StoreData()258 void ProjectConfigurationPanel::StoreData()
259 {
260 m_ConfCopy.m_DisableAuto = m_NoAuto->GetValue();
261 }
262
FillKnownLibraries()263 void ProjectConfigurationPanel::FillKnownLibraries()
264 {
265 Timer1.Stop();
266 m_KnownLibrariesTree->Freeze();
267 m_KnownLibrariesTree->DeleteAllItems();
268 m_KnownLibrariesTree->AddRoot(_("Known libraries"));
269
270 m_CategoryMap.clear();
271 m_IsOtherCategory = false;
272 m_IsPkgConfig = false;
273
274 wxString Filter = m_Filter->GetValue().Upper();
275 bool Tree = m_Tree->GetValue();
276
277 // Collecting list of all global variable names,
278 // currently without pkg-config entries (will be used later)
279 wxArrayString Vars;
280 for ( int i = 0; i < rtCount; ++i )
281 {
282 if ( i==rtPkgConfig ) continue;
283 m_KnownLibs[i].GetShortCodes(Vars);
284 }
285
286 for ( size_t i = 0; i < Vars.Count(); ++i )
287 {
288 ResultArray* Array = 0;
289 for ( int j = 0; j < rtCount; ++j )
290 {
291 if ( j!=rtPkgConfig )
292 {
293 if ( m_KnownLibs[j].IsShortCode(Vars[i]) )
294 Array = &m_KnownLibs[j].GetShortCode(Vars[i]);
295 }
296 }
297
298 if ( !Array || Array->IsEmpty() ) continue;
299
300 if ( !Filter.IsEmpty() )
301 {
302 if ( (*Array)[0]->LibraryName.Upper().Find(Filter) == wxNOT_FOUND &&
303 (*Array)[0]->ShortCode.Upper().Find(Filter) == wxNOT_FOUND )
304 {
305 // This result has been filtered
306 continue;
307 }
308 }
309
310 if ( Tree )
311 {
312 wxArrayString& Categories = (*Array)[0]->Categories;
313 if ( Categories.IsEmpty() )
314 BuildEntry(OtherCategoryId(),*Array);
315 else
316 {
317 for ( size_t cat = 0; cat < Categories.Count(); ++cat )
318 BuildEntry(CategoryId(Categories[cat]), *Array);
319 }
320 }
321 else
322 BuildEntry(m_KnownLibrariesTree->GetRootItem(), *Array);
323 }
324
325 // Now add pkg-config entries in separate category at the end
326 Vars.Clear();
327 m_KnownLibs[rtPkgConfig].GetShortCodes(Vars);
328
329 if ( !Vars.IsEmpty() )
330 {
331 for ( size_t i=0; i<Vars.Count(); i++ )
332 {
333 ResultArray& Array = m_KnownLibs[rtPkgConfig].GetShortCode(Vars[i]);
334 if ( Array.IsEmpty() ) continue;
335
336 if ( !Filter.IsEmpty() )
337 {
338 if ( Array[0]->LibraryName.Upper().Find(Filter) == wxNOT_FOUND &&
339 Array[0]->ShortCode.Upper().Find(Filter) == wxNOT_FOUND )
340 {
341 // This result has been filtered
342 continue;
343 }
344 }
345
346 BuildEntry(Tree ? PkgConfigId() : m_KnownLibrariesTree->GetRootItem(),Array);
347 }
348 }
349
350 // Ok, let's present all results
351 // m_KnownLibrariesTree->ExpandAll();
352 m_KnownLibrariesTree->Thaw();
353 }
354
BuildEntry(const wxTreeItemId & Id,ResultArray & Array)355 void ProjectConfigurationPanel::BuildEntry(const wxTreeItemId& Id,ResultArray& Array)
356 {
357 wxString Name = Array[0]->ShortCode;
358 if ( !Array[0]->LibraryName.IsEmpty() )
359 Name = Name + _T(": ") + Array[0]->LibraryName;
360 m_KnownLibrariesTree->AppendItem(Id,Name,0,0,new TreeItemData(Array[0]->ShortCode));
361 }
362
OtherCategoryId()363 wxTreeItemId ProjectConfigurationPanel::OtherCategoryId()
364 {
365 if ( m_IsOtherCategory )
366 return m_CategoryMap[_T(".other")];
367
368 m_IsOtherCategory = true;
369 return m_CategoryMap[_T(".other")] = m_KnownLibrariesTree->AppendItem(m_KnownLibrariesTree->GetRootItem(),_("Other"));
370 }
371
PkgConfigId()372 wxTreeItemId ProjectConfigurationPanel::PkgConfigId()
373 {
374 if ( m_IsPkgConfig )
375 return m_CategoryMap[_T(".pkg-config")];
376 m_IsPkgConfig = true;
377 return m_CategoryMap[_T(".pkg-config")] = m_KnownLibrariesTree->AppendItem(m_KnownLibrariesTree->GetRootItem(),_("Available in pkg-config"));
378 }
379
CategoryId(const wxString & Category)380 wxTreeItemId ProjectConfigurationPanel::CategoryId(const wxString& Category)
381 {
382 if ( m_CategoryMap.find(Category.Lower()) != m_CategoryMap.end() )
383 return m_CategoryMap[Category.Lower()];
384
385 wxStringTokenizer Tokens(Category,_T("."),wxTOKEN_STRTOK);
386 wxString PathSoFar = _T("");
387 wxTreeItemId IdSoFar = m_KnownLibrariesTree->GetRootItem();
388 bool FirstElem = true;
389 while ( Tokens.HasMoreTokens() )
390 {
391 // Iterate through items already added to map
392 wxString Part = Tokens.GetNextToken();
393 PathSoFar += Part.Lower();
394 if ( m_CategoryMap.find(PathSoFar) == m_CategoryMap.end() )
395 {
396 // Ok, found first node which is not yet added, this mean
397 // that all subnodes are also not yet added
398 int SkipLast = FirstElem ? (m_IsOtherCategory?1:0) + (m_IsPkgConfig?1:0) : 0;
399
400 // First elem of the path must take into consideration
401 // that some categoies must remain at the end
402 if ( SkipLast )
403 {
404 IdSoFar = m_CategoryMap[PathSoFar] =
405 m_KnownLibrariesTree->InsertItem(
406 IdSoFar,
407 m_KnownLibrariesTree->GetChildrenCount(IdSoFar,false)-SkipLast,
408 Part);
409 FirstElem = false;
410 }
411 else
412 {
413 IdSoFar = m_CategoryMap[PathSoFar] =
414 m_KnownLibrariesTree->AppendItem(IdSoFar,Part);
415 }
416
417 // Next items are always added at the end
418 while ( Tokens.HasMoreTokens() )
419 {
420 Part = Tokens.GetNextToken();
421 PathSoFar += _T(".");
422 PathSoFar = Part.Lower();
423 IdSoFar = m_CategoryMap[PathSoFar] =
424 m_KnownLibrariesTree->AppendItem(IdSoFar,Part);
425 }
426
427 // If we're here, all remaining path has been added, so we
428 // finished here
429 break;
430 }
431 FirstElem = false;
432 PathSoFar += _T(".");
433 }
434 // Just for sure if there are multiple dots
435 m_CategoryMap[Category.Lower()] = IdSoFar;
436 return IdSoFar;
437 }
438
Onm_TreeClick(wxCommandEvent &)439 void ProjectConfigurationPanel::Onm_TreeClick(wxCommandEvent& /*event*/)
440 {
441 FillKnownLibraries();
442 }
443
OnTimer1Trigger(wxTimerEvent &)444 void ProjectConfigurationPanel::OnTimer1Trigger(wxTimerEvent& /*event*/)
445 {
446 FillKnownLibraries();
447 }
448
Onm_FilterText(wxCommandEvent &)449 void ProjectConfigurationPanel::Onm_FilterText(wxCommandEvent& /*event*/)
450 {
451 Timer1.Start(500,true);
452 }
453
Onm_FilterTextEnter(wxCommandEvent &)454 void ProjectConfigurationPanel::Onm_FilterTextEnter(wxCommandEvent& /*event*/)
455 {
456 FillKnownLibraries();
457 }
458
Onm_KnownLibrariesTreeSelectionChanged(wxTreeEvent &)459 void ProjectConfigurationPanel::Onm_KnownLibrariesTreeSelectionChanged(wxTreeEvent& /*event*/)
460 {
461 if ( m_KnownLibrariesTree->GetSelection().IsOk() )
462 {
463 TreeItemData* Data = (TreeItemData*)m_KnownLibrariesTree->GetItemData(m_KnownLibrariesTree->GetSelection());
464 if ( Data )
465 {
466 wxString Library = Data->m_ShortCode;
467 if ( m_ConfCopy.m_GlobalUsedLibs.Index(Library) == wxNOT_FOUND )
468 {
469 m_Add->Enable();
470 return;
471 }
472 }
473 }
474 m_Add->Disable();
475 }
476
Onm_UsedLibrariesSelect(wxCommandEvent &)477 void ProjectConfigurationPanel::Onm_UsedLibrariesSelect(wxCommandEvent& /*event*/)
478 {
479 m_Remove->Enable( m_UsedLibraries->GetSelection() != wxNOT_FOUND );
480 }
481
Onm_RemoveClick(wxCommandEvent &)482 void ProjectConfigurationPanel::Onm_RemoveClick(wxCommandEvent& /*event*/)
483 {
484 if ( m_UsedLibraries->GetSelection() != wxNOT_FOUND )
485 {
486 wxString Library =
487 ((ListItemData*)m_UsedLibraries->GetClientObject(
488 m_UsedLibraries->GetSelection()))->m_ShortCode;
489 m_ConfCopy.m_GlobalUsedLibs.Remove(Library);
490 m_UsedLibraries->Delete(m_UsedLibraries->GetSelection());
491 m_Remove->Disable();
492 wxTreeEvent ev;
493 Onm_KnownLibrariesTreeSelectionChanged(ev);
494 }
495 }
496
Onm_AddClick(wxCommandEvent &)497 void ProjectConfigurationPanel::Onm_AddClick(wxCommandEvent& /*event*/)
498 {
499 if ( m_KnownLibrariesTree->GetSelection().IsOk() )
500 {
501 TreeItemData* Data = (TreeItemData*)m_KnownLibrariesTree->GetItemData(m_KnownLibrariesTree->GetSelection());
502 if ( Data )
503 {
504 wxString Library = Data->m_ShortCode;
505 if ( m_ConfCopy.m_GlobalUsedLibs.Index(Library) == wxNOT_FOUND )
506 {
507 m_ConfCopy.m_GlobalUsedLibs.Add(Library);
508 m_UsedLibraries->Append(GetUserListName(Library),new ListItemData(Library));
509 m_Add->Disable();
510 return;
511 }
512 }
513 }
514 }
515
Onm_UnknownLibraryText(wxCommandEvent &)516 void ProjectConfigurationPanel::Onm_UnknownLibraryText(wxCommandEvent& /*event*/)
517 {
518 m_AddUnknown->Enable(m_UnknownLibrary->GetLastPosition()!=0);
519 }
520
Onm_AddUnknownClick(wxCommandEvent &)521 void ProjectConfigurationPanel::Onm_AddUnknownClick(wxCommandEvent& /*event*/)
522 {
523 wxString Library = m_UnknownLibrary->GetValue();
524 if ( !Library.IsEmpty() )
525 {
526 if ( m_ConfCopy.m_GlobalUsedLibs.Index(Library) == wxNOT_FOUND )
527 {
528 m_ConfCopy.m_GlobalUsedLibs.Add(Library);
529 m_UsedLibraries->Append(GetUserListName(Library),new ListItemData(Library));
530 wxTreeEvent ev;
531 Onm_KnownLibrariesTreeSelectionChanged(ev);
532 }
533 }
534 }
535
Onm_AddScriptClick(wxCommandEvent &)536 void ProjectConfigurationPanel::Onm_AddScriptClick(wxCommandEvent& /*event*/)
537 {
538 wxFile Fl(m_Project->GetBasePath() + wxFileName::GetPathSeparator() + _T("lib_finder.script"),wxFile::write);
539 if ( !Fl.IsOpened() )
540 {
541 wxMessageBox(_("Couldn't create file \"lib_finder.script\" in project's base path"),_("lib_finder.script error"),wxOK|wxICON_ERROR,this);
542 return;
543 }
544
545 if ( !Fl.Write(
546 _T("function SetBuildOptions(base)\n")
547 _T("{\n")
548 _T("\tif ( \"LibFinder\" in getroottable() )\n")
549 _T("\t{\n")
550 _T("\t\tLibFinder.SetupTarget(base);\n")
551 _T("\t}\n")
552 _T("}\n"),
553 wxConvUTF8) )
554 {
555 wxMessageBox(_("Couldn't write script file \"lib_finder.script\"."),_("lib_finder.script error"),wxOK|wxICON_ERROR,this);
556 return;
557 }
558 Fl.Close();
559
560 m_Project->AddBuildScript(_T("lib_finder.script"));
561 m_AddScript->Disable();
562 m_NoAuto->SetValue(true);
563
564 wxMessageBox(_("Script \"lib_finder.script\" successfully added."),_("lib_finder.script Success"),wxOK|wxICON_INFORMATION,this);
565 }
566
OnButton2Click(wxCommandEvent &)567 void ProjectConfigurationPanel::OnButton2Click(wxCommandEvent& /*event*/)
568 {
569 wxArrayString HeadersBase;
570 if ( HeadersDetectorDlg(this,m_Project,HeadersBase).ShowModal() != wxID_OK )
571 {
572 cbMessageBox( _("Cancelled the search"), _("Cancelled"), wxOK | wxICON_WARNING, this );
573 return;
574 }
575
576 if ( HeadersBase.IsEmpty() )
577 {
578 cbMessageBox( _("Didn't found any #include directive."), _("Error"), wxOK | wxICON_ERROR, this );
579 return;
580 }
581
582 // Getting array of all known libraries
583 ResultArray AllArray;
584 for ( int i=0; i<rtCount; i++ )
585 m_KnownLibs[i].GetAllResults(AllArray);
586 wxArrayString NewLibs;
587
588 // Sorting and removing duplicates and processing results
589 HeadersBase.Sort();
590 wxString Previous;
591 for ( size_t i=0; i<HeadersBase.Count(); i++ )
592 {
593 if ( Previous != HeadersBase[i] )
594 {
595 Previous = HeadersBase[i];
596 DetectNewLibs( Previous, AllArray, NewLibs );
597 }
598 }
599
600 // Filtering detected results
601 wxArrayString NewLibsFiltered;
602 NewLibs.Sort();
603 Previous.Clear();
604 for ( size_t i=0; i<NewLibs.Count(); i++ )
605 {
606 if ( Previous != NewLibs[i] )
607 {
608 Previous = NewLibs[i];
609 if ( m_ConfCopy.m_GlobalUsedLibs.Index(Previous) == wxNOT_FOUND )
610 NewLibsFiltered.Add( Previous );
611 }
612 }
613
614 if ( NewLibsFiltered.IsEmpty() )
615 {
616 cbMessageBox(
617 _("Didn't found any missing library for your project.\n"
618 "\n"
619 "This may mean that you project is fully configured\n"
620 "or that missing libraries are not yet recognized\n"
621 "or fully supported in lib_finder plugin"),
622 _("No libraries found"),
623 wxOK | wxICON_ASTERISK,
624 this );
625 return;
626 }
627
628 wxArrayInt Choices;
629 #if wxCHECK_VERSION(3, 0, 0)
630 wxGetSelectedChoices(
631 #else
632 wxGetMultipleChoices(
633 #endif
634 Choices,
635 _("Select libraries to include in your project"),
636 _("Adding new libraries"),
637 NewLibsFiltered,
638 this);
639
640 if ( Choices.IsEmpty() )
641 return;
642
643 for ( size_t i=0; i<Choices.Count(); i++ )
644 {
645 wxString Library = NewLibsFiltered[ Choices[i] ];
646 m_ConfCopy.m_GlobalUsedLibs.Add(Library);
647 m_UsedLibraries->Append(GetUserListName(Library),new ListItemData(Library));
648 }
649
650 // Make sure that after the scan, used won't be able to manually
651 // add currently selected "known" library (through '<' button)
652 // which has just been added automatically
653 wxTreeEvent ev;
654 Onm_KnownLibrariesTreeSelectionChanged(ev);
655 }
656
DetectNewLibs(const wxString & IncludeName,ResultArray & known,wxArrayString & LibsList)657 void ProjectConfigurationPanel::DetectNewLibs( const wxString& IncludeName, ResultArray& known, wxArrayString& LibsList )
658 {
659 wxString FixedInclude = IncludeName;
660 FixedInclude.MakeLower();
661 FixedInclude.Replace(_T("\\"),_T("/"),true);
662 for ( size_t i=0; i<known.Count(); i++ )
663 {
664 for ( size_t j=0; j<known[i]->Headers.Count(); j++ )
665 {
666 if ( FixedInclude.Matches( known[i]->Headers[j].Lower() ) )
667 {
668 LibsList.Add( known[i]->ShortCode );
669 break;
670 }
671 }
672 }
673 }
674