]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - tools/src/tools/configtool/standalone/wxwin/packagesdlg.cpp
Initial revision
[karo-tx-redboot.git] / tools / src / tools / configtool / standalone / wxwin / packagesdlg.cpp
1 //####COPYRIGHTBEGIN####
2 //
3 // ----------------------------------------------------------------------------
4 // Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
5 // Copyright (C) 2003 John Dallaway
6 //
7 // This program is part of the eCos host tools.
8 //
9 // This program is free software; you can redistribute it and/or modify it
10 // under the terms of the GNU General Public License as published by the Free
11 // Software Foundation; either version 2 of the License, or (at your option)
12 // any later version.
13 //
14 // This program is distributed in the hope that it will be useful, but WITHOUT
15 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
17 // more details.
18 //
19 // You should have received a copy of the GNU General Public License along with
20 // this program; if not, write to the Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22 //
23 // ----------------------------------------------------------------------------
24 //
25 //####COPYRIGHTEND####
26 // packages :
27 //
28 //===========================================================================
29 //#####DESCRIPTIONBEGIN####
30 //
31 // Author(s):   julians, jld
32 // Contact(s):  julians
33 // Date:        2000/09/28
34 // Version:     $Id$
35 // Purpose:
36 // Description: Implementation file for ecPackagesDialog
37 // Requires:
38 // Provides:
39 // See also:
40 // Known bugs:
41 // Usage:
42 //
43 //####DESCRIPTIONEND####
44 //
45 //===========================================================================
46
47 // ============================================================================
48 // declarations
49 // ============================================================================
50
51 // ----------------------------------------------------------------------------
52 // headers
53 // ----------------------------------------------------------------------------
54 #ifdef __GNUG__
55 #pragma implementation "packagesdlg.h"
56 #endif
57
58 // Includes other headers for precompiled compilation
59 #include "ecpch.h"
60
61 #ifdef __BORLANDC__
62 #pragma hdrstop
63 #endif
64
65 #include "wx/cshelp.h"
66 #include "wx/valgen.h"
67 #include "wx/tokenzr.h"
68
69 #include "configtool.h"
70 #include "packagesdlg.h"
71 #include "configtooldoc.h"
72 #include "ecutils.h"
73
74 BEGIN_EVENT_TABLE(ecPackagesDialog, ecDialog)
75     EVT_BUTTON(wxID_OK, ecPackagesDialog::OnOK)
76     EVT_BUTTON(wxID_CANCEL, ecPackagesDialog::OnCancel)
77     EVT_BUTTON(ecID_PACKAGES_DIALOG_ADD, ecPackagesDialog::OnAdd)
78     EVT_BUTTON(ecID_PACKAGES_DIALOG_REMOVE, ecPackagesDialog::OnRemove)
79     EVT_LISTBOX_DCLICK(ecID_PACKAGES_DIALOG_AVAILABLE_LIST, ecPackagesDialog::OnDblClickListBox1)
80     EVT_LISTBOX_DCLICK(ecID_PACKAGES_DIALOG_USE_LIST, ecPackagesDialog::OnDblClickListBox2)
81     EVT_LISTBOX(ecID_PACKAGES_DIALOG_AVAILABLE_LIST, ecPackagesDialog::OnClickListBox1)
82     EVT_LISTBOX(ecID_PACKAGES_DIALOG_USE_LIST, ecPackagesDialog::OnClickListBox2)
83     EVT_LISTBOX(ecID_PACKAGES_DIALOG_VERSION, ecPackagesDialog::OnSelectVersion)
84     EVT_INIT_DIALOG(ecPackagesDialog::OnInitDialog)
85     EVT_BUTTON(ecID_PACKAGES_DIALOG_CLEAR, ecPackagesDialog::OnClearKeywords)
86     EVT_CHECKBOX(ecID_PACKAGES_DIALOG_OMIT_HARDWARE, ecPackagesDialog::OnClickOmitHardwarePackages)
87     EVT_CHECKBOX(ecID_PACKAGES_DIALOG_EXACT_MATCH, ecPackagesDialog::OnClickExactMatch)
88     EVT_TEXT(ecID_PACKAGES_DIALOG_KEYWORDS, ecPackagesDialog::OnUpdateKeywordText)
89     EVT_IDLE(ecPackagesDialog::OnIdle)
90 END_EVENT_TABLE()
91
92 // ----------------------------------------------------------------------------
93 // main frame
94 // ----------------------------------------------------------------------------
95
96 // Frame constructor
97 ecPackagesDialog::ecPackagesDialog(wxWindow* parent):
98 m_timer(this)
99 {
100     m_bHardwarePackageSelected = FALSE;
101     m_keywords = wxEmptyString;
102     m_updateLists = FALSE;
103     m_updateInterval = 600; // Milliseconds
104     wxStartTimer();
105     
106     SetExtraStyle(wxDIALOG_EX_CONTEXTHELP);
107     
108     ecDialog::Create(parent, ecID_PACKAGES_DIALOG, _("Packages"),
109         wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER);
110     
111     CreateControls(this);
112     
113     m_timer.Start(200);
114     
115     Centre(wxBOTH);
116 }
117
118 ecPackagesDialog::~ecPackagesDialog()
119 {
120     m_timer.Stop();
121 }
122
123 // TODO: implement wxLB_SORT style in wxGTK.
124 void ecPackagesDialog::CreateControls(wxWindow* parent)
125 {
126     wxSizer *item0 = new wxBoxSizer( wxVERTICAL );
127     
128     wxSizer *item1 = new wxBoxSizer( wxHORIZONTAL );
129     
130     wxSizer *item2 = new wxBoxSizer( wxVERTICAL );
131
132     wxStaticText *item3 = new wxStaticText( parent, wxID_STATIC, _("Available &packages:"), wxDefaultPosition, wxDefaultSize, 0 );
133     item2->Add( item3, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
134     
135     wxString *strs4 = (wxString*) NULL;
136     wxListBox *item4 = new wxListBox( parent, ecID_PACKAGES_DIALOG_AVAILABLE_LIST, wxDefaultPosition, wxSize(230,190), 0, strs4, wxLB_SORT|wxLB_HSCROLL );
137     item2->Add( item4, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5 );
138     
139     item1->Add( item2, 1, wxGROW|wxALIGN_CENTER_HORIZONTAL|wxALL, 0 );
140     
141     wxSizer *item5 = new wxBoxSizer( wxVERTICAL );
142     
143     wxButton *item6 = new wxButton( parent, ecID_PACKAGES_DIALOG_ADD, _("&Add >>"), wxDefaultPosition, wxDefaultSize, 0 );
144     item5->Add( item6, 0, wxALIGN_CENTRE|wxALL, 5 );
145     
146     wxButton *item7 = new wxButton( parent, ecID_PACKAGES_DIALOG_REMOVE, _("<< &Remove"), wxDefaultPosition, wxDefaultSize, 0 );
147     item5->Add( item7, 0, wxALIGN_CENTRE|wxALL, 5 );
148     
149     item1->Add( item5, 0, wxALIGN_CENTRE|wxALL, 0 );
150     
151     wxSizer *item8 = new wxBoxSizer( wxVERTICAL );
152     
153     wxStaticText *item9 = new wxStaticText( parent, wxID_STATIC, _("&Use these packages:"), wxDefaultPosition, wxDefaultSize, 0 );
154     item8->Add( item9, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
155     
156     wxString *strs10 = (wxString*) NULL;
157     wxListBox *item10 = new wxListBox( parent, ecID_PACKAGES_DIALOG_USE_LIST, wxDefaultPosition, wxSize(230,190), 0, strs10, wxLB_SORT|wxLB_HSCROLL );
158     item8->Add( item10, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5 );
159     
160     item1->Add( item8, 1, wxGROW|wxALIGN_CENTER_HORIZONTAL|wxALL, 0 );
161     
162     item0->Add( item1, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
163     
164     wxStaticText *item11 = new wxStaticText( parent, wxID_STATIC, _("&Version:"), wxDefaultPosition, wxDefaultSize, 0 );
165     item0->Add( item11, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 10 );
166     
167     wxString *strs12 = (wxString*) NULL;
168     wxChoice *item12 = new wxChoice( parent, ecID_PACKAGES_DIALOG_VERSION, wxDefaultPosition, wxSize(100,-1), 0, strs12, 0 );
169     item0->Add( item12, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 10 );
170     
171     wxTextCtrl *item13 = new wxTextCtrl( parent, ecID_PACKAGES_DIALOG_DESCRIPTION, _(""), wxDefaultPosition, wxSize(80,110), wxTE_MULTILINE );
172     item0->Add( item13, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 10 );
173     
174     wxStaticText *item14 = new wxStaticText( parent, wxID_STATIC, _("&Keywords:"), wxDefaultPosition, wxDefaultSize, 0 );
175     item0->Add( item14, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 10 );
176     
177     wxSizer *item15 = new wxBoxSizer( wxHORIZONTAL );
178     
179     wxTextCtrl *item16 = new wxTextCtrl( parent, ecID_PACKAGES_DIALOG_KEYWORDS, _(""), wxDefaultPosition, wxSize(80,-1), 0 );
180     item15->Add( item16, 1, wxALIGN_CENTRE|wxALL, 5 );
181     
182     wxButton *item17 = new wxButton( parent, ecID_PACKAGES_DIALOG_CLEAR, _("C&lear"), wxDefaultPosition, wxDefaultSize, 0 );
183     item15->Add( item17, 0, wxALIGN_CENTRE|wxALL, 5 );
184     
185     item0->Add( item15, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
186     
187     wxSizer *item18 = new wxBoxSizer( wxHORIZONTAL );
188     
189     wxCheckBox *item19 = new wxCheckBox( parent, ecID_PACKAGES_DIALOG_OMIT_HARDWARE, _("&Omit hardware packages"), wxDefaultPosition, wxDefaultSize, 0 );
190     item18->Add( item19, 0, wxALIGN_CENTRE|wxALL, 5 );
191     
192     wxCheckBox *item20 = new wxCheckBox( parent, ecID_PACKAGES_DIALOG_EXACT_MATCH, _("&Match exactly"), wxDefaultPosition, wxDefaultSize, 0 );
193     item18->Add( item20, 0, wxALIGN_CENTRE|wxALL, 5 );
194     
195     item18->Add( 20, 20, 1, wxALIGN_CENTRE|wxALL, 5 );
196     
197     wxButton *item21 = new wxButton( parent, wxID_OK, _("&OK"), wxDefaultPosition, wxDefaultSize, 0 );
198     item21->SetDefault();
199     item18->Add( item21, 0, wxALIGN_CENTRE|wxALL, 5 );
200     
201     wxButton *item22 = new wxButton( parent, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
202     item18->Add( item22, 0, wxALIGN_CENTRE|wxALL, 5 );
203     
204     item0->Add( item18, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5 );
205     
206 #if 0
207     wxSizer *item0 = new wxBoxSizer( wxVERTICAL );
208     
209     wxSizer *item1 = new wxBoxSizer( wxHORIZONTAL );
210     
211     wxSizer *item2 = new wxBoxSizer( wxVERTICAL );
212     
213     wxStaticText *item3 = new wxStaticText( parent, wxID_STATIC, _("Available &packages:"), wxDefaultPosition, wxDefaultSize, 0 );
214     item2->Add( item3, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
215     
216     wxString *strs4 = (wxString*) NULL;
217     wxListBox *item4 = new wxListBox( parent, ecID_PACKAGES_DIALOG_AVAILABLE_LIST, wxDefaultPosition, wxSize(230,190), 0, strs4, wxLB_SORT|wxLB_HSCROLL );
218     item2->Add( item4, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5 );
219     
220     item1->Add( item2, 1, wxGROW|wxALIGN_CENTER_HORIZONTAL|wxALL, 0 );
221     
222     wxSizer *item5 = new wxBoxSizer( wxVERTICAL );
223     
224     wxButton *item6 = new wxButton( parent, ecID_PACKAGES_DIALOG_ADD, _("&Add >>"), wxDefaultPosition, wxDefaultSize, 0 );
225     item5->Add( item6, 0, wxALIGN_CENTRE|wxALL, 5 );
226     
227     wxButton *item7 = new wxButton( parent, ecID_PACKAGES_DIALOG_REMOVE, _("<< &Remove"), wxDefaultPosition, wxDefaultSize, 0 );
228     item5->Add( item7, 0, wxALIGN_CENTRE|wxALL, 5 );
229
230     item1->Add( item5, 0, wxALIGN_CENTRE|wxALL, 0 );
231     
232     wxSizer *item8 = new wxBoxSizer( wxVERTICAL );
233     
234     wxStaticText *item9 = new wxStaticText( parent, wxID_STATIC, _("&Use these packages:"), wxDefaultPosition, wxDefaultSize, 0 );
235     item8->Add( item9, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
236     
237     wxString *strs10 = (wxString*) NULL;
238     wxListBox *item10 = new wxListBox( parent, ecID_PACKAGES_DIALOG_USE_LIST, wxDefaultPosition, wxSize(230,190), 0, strs10, wxLB_SORT|wxLB_HSCROLL );
239     item8->Add( item10, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5 );
240     
241     item1->Add( item8, 1, wxGROW|wxALIGN_CENTER_HORIZONTAL|wxALL, 0 );
242     
243     item0->Add( item1, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
244     
245     wxStaticText *item11 = new wxStaticText( parent, wxID_STATIC, _("&Version:"), wxDefaultPosition, wxDefaultSize, 0 );
246     item0->Add( item11, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 10 );
247     
248     wxString *strs12 = (wxString*) NULL;
249     wxChoice *item12 = new wxChoice( parent, ecID_PACKAGES_DIALOG_VERSION, wxDefaultPosition, wxSize(100,-1), 0, strs12, 0 );
250     item0->Add( item12, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 10 );
251     
252     wxTextCtrl *item13 = new wxTextCtrl( parent, ecID_PACKAGES_DIALOG_DESCRIPTION, _(""), wxDefaultPosition, wxSize(80,110), wxTE_MULTILINE );
253     item0->Add( item13, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 10 );
254     
255     wxStaticText *item14 = new wxStaticText( parent, wxID_STATIC, _("&Keywords:"), wxDefaultPosition, wxDefaultSize, 0 );
256     item0->Add( item14, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 10 );
257     
258     wxSizer *item15 = new wxBoxSizer( wxHORIZONTAL );
259     
260     wxTextCtrl *item16 = new wxTextCtrl( parent, ecID_PACKAGES_DIALOG_KEYWORDS, _(""), wxDefaultPosition, wxSize(80,-1), 0 );
261     item15->Add( item16, 1, wxALIGN_CENTRE|wxALL, 5 );
262     
263     wxButton *item17 = new wxButton( parent, ecID_PACKAGES_DIALOG_CLEAR, _("C&lear"), wxDefaultPosition, wxDefaultSize, 0 );
264     item15->Add( item17, 0, wxALIGN_CENTRE|wxALL, 5 );
265     
266     item0->Add( item15, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
267     
268     wxSizer *item18 = new wxBoxSizer( wxHORIZONTAL );
269     
270     wxCheckBox *item19 = new wxCheckBox( parent, ecID_PACKAGES_DIALOG_OMIT_HARDWARE, _("Omit hardware packages"), wxDefaultPosition, wxDefaultSize, 0 );
271     item18->Add( item19, 0, wxALIGN_CENTRE|wxALL, 5 );
272     
273     item18->Add( 20, 20, 1, wxALIGN_CENTRE|wxALL, 5 );
274     
275     wxButton *item20 = new wxButton( parent, wxID_OK, _("&OK"), wxDefaultPosition, wxDefaultSize, 0 );
276     item20->SetDefault();
277     item18->Add( item20, 0, wxALIGN_CENTRE|wxALL, 5 );
278
279     wxButton *item21 = new wxButton( parent, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
280     item18->Add( item21, 0, wxALIGN_CENTRE|wxALL, 5 );
281     
282     item0->Add( item18, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5 );
283 #endif
284     
285 #ifdef __WXGTK__
286     wxButton *contextButton = new wxContextHelpButton( parent );
287     item18->Add( contextButton, 0, wxALIGN_CENTRE|wxALL, 5 );
288 #endif
289     
290     parent->FindWindow( ecID_PACKAGES_DIALOG_KEYWORDS )->SetFocus();
291     
292     parent->SetAutoLayout( TRUE );
293     parent->SetSizer( item0 );
294     parent->Layout();
295     item0->Fit( parent );
296     //item0->SetSizeHints( parent );
297     
298     // Add context-sensitive help text
299     parent->FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST )->SetHelpText(_("Displays the list of packages available, but not currently loaded."));
300     parent->FindWindow( ecID_PACKAGES_DIALOG_USE_LIST )->SetHelpText(_("Displays the list of packages currently loaded."));
301     parent->FindWindow( ecID_PACKAGES_DIALOG_ADD )->SetHelpText(_("Add one or more packages to the list to be loaded."));
302     parent->FindWindow( ecID_PACKAGES_DIALOG_REMOVE )->SetHelpText(_("Removes one or more packages from the list to be loaded."));
303     parent->FindWindow( ecID_PACKAGES_DIALOG_VERSION )->SetHelpText(_("Displays the version of the selected packages."));
304     parent->FindWindow( ecID_PACKAGES_DIALOG_DESCRIPTION )->SetHelpText(_("Displays a description of the selected package (blank if more than one package is selected)."));
305     parent->FindWindow( ecID_PACKAGES_DIALOG_KEYWORDS )->SetHelpText(_("Enter keywords here to restrict displayed packages."));
306     parent->FindWindow( ecID_PACKAGES_DIALOG_CLEAR )->SetHelpText(_("Clears the keyword field."));
307     parent->FindWindow( ecID_PACKAGES_DIALOG_OMIT_HARDWARE)->SetHelpText(_("Check this to omit hardware packages, uncheck to show all packages."));
308     parent->FindWindow( ecID_PACKAGES_DIALOG_EXACT_MATCH )->SetHelpText(_("Check this to display exact matches between keyword and aliases (case insensitive)."));
309     parent->FindWindow( wxID_OK )->SetHelpText(_("Closes the dialog and saves any changes you have made."));
310     parent->FindWindow( wxID_CANCEL )->SetHelpText(_("Closes the dialog without saving any changes you have made."));
311     
312 #if __WXGTK__
313     parent->FindWindow( wxID_CONTEXT_HELP )->SetHelpText(_("Invokes context-sensitive help for the clicked-on window."));
314 #endif
315     
316     // Add validators
317     parent->FindWindow( ecID_PACKAGES_DIALOG_DESCRIPTION )->SetValidator(wxGenericValidator(& m_packageDescription));
318     parent->FindWindow( ecID_PACKAGES_DIALOG_KEYWORDS )->SetValidator(wxGenericValidator(& m_keywords));
319     parent->FindWindow( ecID_PACKAGES_DIALOG_OMIT_HARDWARE )->SetValidator(wxGenericValidator(& wxGetApp().GetSettings().m_omitHardwarePackages));
320     parent->FindWindow( ecID_PACKAGES_DIALOG_EXACT_MATCH )->SetValidator(wxGenericValidator(& wxGetApp().GetSettings().m_matchPackageNamesExactly));
321 }
322
323 void ecPackagesDialog::OnInitDialog(wxInitDialogEvent& event)
324 {
325     // Note: InitControls must be here, because data will be added
326     // between construction of the dialog, and OnInitDialog.
327     InitControls();
328     TransferDataToWindow();
329 }
330
331 void ecPackagesDialog::InitControls()
332 {
333     Fill();
334 }
335
336 void ecPackagesDialog::OnCancel(wxCommandEvent& event)
337 {
338     event.Skip();
339 }
340
341 void ecPackagesDialog::OnOK(wxCommandEvent& event)
342 {
343     TransferDataFromWindow();
344     event.Skip();
345 }
346
347 // For each word in keywords, is it contained in 'str'?
348 bool ecPackagesDialog::MatchesKeyword(wxArrayString& keywords, const wxString& str)
349 {
350     // _Every_ keyword must match
351     size_t i;
352     for (i = 0; i < keywords.GetCount(); i++)
353     {
354         if (str.Find(keywords[i]) == -1)
355             return FALSE;
356     }
357     return TRUE;
358 }
359
360 void ecPackagesDialog::Fill()
361 {
362     wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
363     wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
364     ecConfigToolDoc * pDoc = wxGetApp().GetConfigToolDoc ();
365
366     // wxGTK doesn't deselect items properly when clearing, I think
367     int i;
368     for (i = 0; i < availableList->GetCount(); i++)
369         if (availableList->Selected(i))
370             availableList->Deselect(i);
371     for (i = 0; i < useList->GetCount(); i++)
372         if (useList->Selected(i))
373             useList->Deselect(i);
374     
375     availableList->Clear();
376     useList->Clear();
377     ClearDescription();
378     
379     wxString s2(m_keywords);
380     s2.MakeLower();
381     
382     // Tokenize
383     wxArrayString keywords;
384     wxStringTokenizer tok(s2);
385     while (tok.HasMoreTokens())
386     {
387         keywords.Add(tok.GetNextToken());
388     }
389     
390     // Initialize the controls
391     for (i = 0; i < GetCount(); i++)
392     {
393         const wxString& str = m_items[i];
394         wxListBox* lb = m_arnItems[i] ? useList : availableList;
395         
396         wxString macroName(pDoc->GetPackageName (str));
397         
398         // check if the package is a hardware package
399         
400         if ((!wxGetApp().GetSettings().m_omitHardwarePackages) || !pDoc->GetCdlPkgData ()->is_hardware_package (ecUtils::UnicodeToStdStr (macroName)))
401         {
402             bool matches = TRUE;
403             
404             if (!m_keywords.IsEmpty())
405             {
406                 // Descriptive name
407                 wxString s1(str);
408                 s1.MakeLower();
409
410                 // macro name
411                 wxString s3(macroName);
412                 s3.MakeLower();
413
414                 // Match all aliases
415                 const std::vector<std::string> & aliases = pDoc->GetCdlPkgData ()->get_package_aliases (ecUtils::UnicodeToStdStr (macroName));
416                     
417                 if (wxGetApp().GetSettings().m_matchPackageNamesExactly)
418                 {
419                     int noMatches = 0;
420
421                     if (s2 == s1 || s2 == s3)
422                         noMatches ++;
423
424                     size_t j;
425                     for (j = 0; j < aliases.size(); j ++)
426                     {
427                         wxString alias(aliases[j].c_str());
428                         alias.MakeLower();
429                         if (s2 == alias)
430                             noMatches ++;
431                     }
432
433                     matches = (noMatches > 0);                   
434
435                 }
436                 else
437                 {
438                     // Concatenate all possible text together, and match against that
439                     wxString toMatch;
440                     
441                     toMatch += s1;
442                     
443                     toMatch += s3;
444                     
445                     size_t j;
446                     for (j = 0; j < aliases.size(); j ++)
447                     {
448                         wxString alias(aliases[j].c_str());
449                         alias.MakeLower();
450                         toMatch += alias;
451                     }
452                     
453                     matches = MatchesKeyword(keywords, toMatch);
454                 }
455             }
456             
457             if (matches)
458                 lb->Append(str, (void*) i);
459         }
460     }
461     
462     UpdateAddRemoveButtons();
463     
464     if (availableList->GetCount() == 1)
465     {
466         availableList->SetSelection(0);
467         UpdatePackageDescription();
468         UpdateVersionList ();
469         UpdateHardwareSelectionFlag ();
470     }
471     else if (useList->GetCount() == 1)
472     {
473         useList->SetSelection(0);
474         UpdatePackageDescription();
475         UpdateVersionList ();
476         UpdateHardwareSelectionFlag ();
477     }
478     wxTextCtrl* textCtrl = (wxTextCtrl*) FindWindow( ecID_PACKAGES_DIALOG_KEYWORDS );
479     // Necessary or TransferDataToWindow will cause insertion position to change
480     textCtrl->SetInsertionPointEnd();
481 }
482
483 void ecPackagesDialog::Add(wxListBox* from, wxListBox* to)
484 {
485     wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
486     
487     wxArrayInt selections;
488     wxStringList selectionsStrings;
489     int n = from -> GetSelections( selections );
490     
491     if (n > 0)
492     {
493         int i;
494         for (i = 0; i < selections.GetCount(); i++)
495         {
496             wxString str = from -> GetString(selections[i]);
497             selectionsStrings.Add(str);
498         }
499         
500         // Now delete from one list and remove from t'other
501         for (i = 0; i < selectionsStrings.Number(); i++)
502         {
503             wxString str = selectionsStrings[i];
504             
505             // Remove
506             int toDelete =  from -> FindString(str);
507             int itemIndex = -1;
508             if (toDelete > -1)
509             {
510                 itemIndex = (int) from -> GetClientData(toDelete);
511                 from -> Delete(toDelete);
512             }
513             
514             wxASSERT (itemIndex > -1);
515             
516             // Add
517             to -> Append(str, (void*) itemIndex);
518             
519             if (to == useList)
520             {
521                 m_added.Add(str);
522             }
523             else
524             {
525                 m_added.Remove(str);
526             }
527             
528             // Select it
529             int addedIndex = to->FindString(str);
530             to->Select(addedIndex);
531             
532         }
533         //ClearDescription();
534         ClearSelections(* from);
535         UpdateHardwareSelectionFlag();
536         UpdatePackageDescription();
537         to->SetFocus();
538     }
539 }
540
541 void ecPackagesDialog::OnAdd(wxCommandEvent& event)
542 {
543     if (m_bHardwarePackageSelected)
544     {
545         HardwarePackageMessageBox ();
546         return;
547     }
548     wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
549     wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
550     
551     Add(availableList, useList);
552     
553     UpdateAddRemoveButtons();
554 }
555
556 void ecPackagesDialog::OnRemove(wxCommandEvent& event)
557 {
558     if (m_bHardwarePackageSelected)
559     {
560         HardwarePackageMessageBox ();
561         return;
562     }
563     
564     wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
565     wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
566     
567     Add(useList, availableList);
568     
569     UpdateAddRemoveButtons();
570 }
571
572 void ecPackagesDialog::OnDblClickListBox1(wxCommandEvent& event)
573 {
574     if (m_bHardwarePackageSelected)
575     {
576         HardwarePackageMessageBox ();
577         return;
578     }
579     
580     wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
581     wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
582     
583     Add(availableList, useList);
584     
585     UpdateAddRemoveButtons();
586 }
587
588 void ecPackagesDialog::OnDblClickListBox2(wxCommandEvent& event)
589 {
590     if (m_bHardwarePackageSelected)
591     {
592         HardwarePackageMessageBox ();
593         return;
594     }
595     
596     wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
597     wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
598     
599     Add(useList, availableList);
600     
601     UpdateAddRemoveButtons();
602 }
603
604 void ecPackagesDialog::OnClickListBox1(wxCommandEvent& event)
605 {
606     wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
607     wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
608     
609 #if 0    
610     int sel = event.GetSelection();
611     if (sel > -1)
612     {
613         // TODO: check that this works for multiple-selection listboxes
614         DisplayDescription(availableList->GetString(sel));
615     }
616 #endif
617     
618     ClearSelections(*useList);
619     UpdatePackageDescription ();
620     UpdateVersionList ();
621     UpdateHardwareSelectionFlag ();
622     UpdateAddRemoveButtons();
623 }
624
625 void ecPackagesDialog::OnClickListBox2(wxCommandEvent& event)
626 {
627     wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
628     wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
629     
630 #if 0    
631     int sel = event.GetSelection();
632     if (sel > -1)
633     {
634         // TODO: check that this works for multiple-selection listboxes
635         DisplayDescription(useList->GetString(sel));
636     }
637 #endif
638     
639     ClearSelections(*availableList);
640     UpdatePackageDescription ();
641     UpdateVersionList ();
642     UpdateHardwareSelectionFlag ();
643     UpdateAddRemoveButtons();
644 }
645
646 void ecPackagesDialog::OnSelectVersion(wxCommandEvent& event)
647 {
648     wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
649     wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
650     wxChoice* versionChoice = (wxChoice*) FindWindow( ecID_PACKAGES_DIALOG_VERSION );
651     
652     if (-1 == versionChoice->GetSelection ()) // if there is no version selection
653         return; // do nothing
654     
655     wxListBox * pListBox = NULL;
656     
657     wxArrayInt selected1, selected2;
658     availableList->GetSelections(selected1);
659     useList->GetSelections(selected2);
660     
661     int nListSelCount = selected1.GetCount ();
662     if (nListSelCount > 0)
663     {
664         pListBox = availableList;
665     }
666     else
667     {
668         nListSelCount = selected2.GetCount ();
669         if (nListSelCount)
670             pListBox = useList;
671     }
672     
673     wxASSERT (pListBox);
674     
675     if (!pListBox)
676         return;
677     
678     // retrieve the list box indices of the selected packages
679     
680     wxArrayInt* selected = (pListBox == availableList ? & selected1 : & selected2);
681     
682     int nIndex;
683     for (nIndex = 0; nIndex < nListSelCount; nIndex++) // for each selected package
684     {
685         // set the package version to that specified in the version combo box
686         wxString str = versionChoice->GetString(nIndex);
687         
688         // itemIndex is the index into the list of item names. It gets stored with all the listbox items.
689         int itemIndex = (int) pListBox->GetClientData((*selected)[nIndex]);
690         m_currentVersions[(size_t)itemIndex] = str;
691     }
692 }
693
694 void ecPackagesDialog::OnClearKeywords(wxCommandEvent& event)
695 {
696     wxTextCtrl* textCtrl = (wxTextCtrl*) FindWindow( ecID_PACKAGES_DIALOG_KEYWORDS );
697     textCtrl->SetValue(wxT(""));
698     TransferDataFromWindow();
699     Fill();
700     m_updateLists = FALSE;
701     wxStartTimer();
702     FindWindow( ecID_PACKAGES_DIALOG_KEYWORDS )->SetFocus();
703 }
704
705 void ecPackagesDialog::OnUpdateKeywordText(wxCommandEvent& event)
706 {
707     // Work around a bug in GTK+ that sends a text update command when
708     // clicking on one of the listboxes.
709     wxTextCtrl* textCtrl = (wxTextCtrl*) FindWindow( ecID_PACKAGES_DIALOG_KEYWORDS );
710     wxString value = textCtrl->GetValue();
711     if (value == m_keywords)
712         return;
713     
714     TransferDataFromWindow();
715     m_updateLists = TRUE;
716     wxStartTimer();
717 }
718
719 void ecPackagesDialog::OnClickOmitHardwarePackages(wxCommandEvent& event)
720 {
721     TransferDataFromWindow();
722     Fill();
723 }
724
725 void ecPackagesDialog::OnClickExactMatch(wxCommandEvent& event)
726 {
727     TransferDataFromWindow();
728     Fill();
729 }
730
731 void ecPackagesDialog::OnIdle(wxIdleEvent& event)
732 {
733     long elapsed = wxGetElapsedTime(FALSE);
734     if (m_updateLists && (elapsed > m_updateInterval))
735     {
736         m_updateLists = FALSE;
737         Fill();
738         wxStartTimer();
739     }
740 }
741
742 void ecPackagesDialog::Insert(const wxString& str, bool added, const wxString& descr, const wxString& version)
743 {
744     wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
745     wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
746     
747     m_items.Add(str);
748     m_descriptions.Add(str);
749     m_currentVersions.Add(version);
750     m_arnItems.Add(added);
751     
752     if (added)
753         m_added.Add(str);
754     
755     //(added ? useList : availableList) -> Append(str);
756 }
757
758 bool ecPackagesDialog::IsAdded(const wxString& str)
759 {
760     return (m_added.Index(str) != wxNOT_FOUND);
761     
762     //  return (((wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST ))->FindString(str) > -1) ;
763 }
764
765 static int ecPositionInStringList(const wxStringList& list, const wxString& item)
766 {
767     int i;
768     for (i = 0 ; i < list.Number(); i++)
769         if (list[i] == item)
770             return i;
771         else
772             i ++;
773         return -1;
774 }
775
776 void ecPackagesDialog::DisplayDescription(const wxString& item)
777 {
778     //wxTextCtrl* descrCtrl = (wxTextCtrl*) FindWindow( ecID_PACKAGES_DIALOG_DESCRIPTION ) ;
779     ecConfigToolDoc * pDoc = wxGetApp().GetConfigToolDoc ();
780     
781     //    int pos = ecPositionInStringList(m_items, item);
782     //    if (pos > -1)
783     {
784         wxString text;
785         //        wxString descr = m_descriptions[pos];
786         //        text += descr;
787         //        text += wxT("\n");
788         
789         wxString macroName(pDoc->GetPackageName (item));
790         
791         // Match all aliases
792         const std::vector<std::string> & aliases = pDoc->GetCdlPkgData ()->get_package_aliases (ecUtils::UnicodeToStdStr (macroName));
793         
794         size_t j;
795         for (j = 0; j < aliases.size(); j ++)
796         {
797             if (j == 1)
798                 text += wxT(".\nAliases: ");
799             else if (j > 1)
800                 text += wxT(", ");
801             
802             wxString alias(aliases[j].c_str());
803             text += alias;
804         }
805         text += wxT("\nMacro: ");
806         text += macroName;
807         text += wxT("\n\n");
808         
809         wxString descr = pDoc->GetCdlPkgData ()->get_package_description (ecUtils::UnicodeToStdStr (macroName)).c_str ();
810         
811         text += ecUtils::StripExtraWhitespace (descr);
812         
813         m_packageDescription = text;
814         
815         //descrCtrl->SetValue(text);
816     }
817 }
818
819 void ecPackagesDialog::ClearDescription()
820 {
821     wxTextCtrl* descrCtrl = (wxTextCtrl*) FindWindow( ecID_PACKAGES_DIALOG_DESCRIPTION ) ;
822     descrCtrl->SetValue(wxEmptyString);
823 }
824
825 wxString ecPackagesDialog::GetVersion (const wxString& item)
826 {
827     int nCount;
828     for (nCount = GetCount() - 1; nCount >= 0; --nCount)
829     {
830         if (m_items [nCount] == item)
831         {
832             return m_currentVersions [nCount];
833         }
834     }
835     wxASSERT (FALSE);
836     return wxEmptyString;
837 }
838
839 void ecPackagesDialog::UpdateHardwareSelectionFlag()
840 {
841     m_bHardwarePackageSelected = FALSE;
842     
843     wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
844     wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
845     wxListBox * pListBox = NULL;
846     
847     wxArrayInt selections1, selections2;
848     wxArrayInt* selections = NULL;
849     availableList->GetSelections(selections1);
850     useList->GetSelections(selections2);
851     
852     int nListSelCount = selections1.GetCount ();
853     if (nListSelCount)
854     {
855         pListBox = availableList;
856         selections = & selections1;
857     }
858     else
859     {
860         nListSelCount = selections2.GetCount ();
861         if (nListSelCount)
862         {
863             pListBox = useList;
864             selections = & selections2;
865         }
866     }
867     
868     if (pListBox) // if there are packages selected
869     {
870         ecConfigToolDoc * pDoc = wxGetApp().GetConfigToolDoc ();
871         
872         // retrieve the list box indices of the selected packages
873         
874         //int * arnIndices = new int [nListSelCount];
875         //pListBox->GetSelItems (nListSelCount, arnIndices);
876         
877         int nIndex;
878         for (nIndex = 0; nIndex < nListSelCount; nIndex++) // for each selected package
879         {
880             wxString strPackageAlias = pListBox->GetString((*selections)[nIndex]);
881             
882             // check if the package is a hardware package
883             
884             //TRACE (_T("Checking '%s' for hardware status\n"), strPackageAlias);
885             if (pDoc->GetCdlPkgData ()->is_hardware_package (ecUtils::UnicodeToStdStr (pDoc->GetPackageName (strPackageAlias))))
886             {
887                 m_bHardwarePackageSelected = TRUE;
888                 break;
889             }
890         }
891     }
892 }
893
894 void ecPackagesDialog::HardwarePackageMessageBox()
895 {
896     // TODO: could give the user the choice of going to the template dialog.
897     wxMessageBox (wxT("Add and remove hardware packages by selecting a new hardware template."),
898         wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK, this);
899 }
900
901 void ecPackagesDialog::UpdatePackageDescription ()
902 {
903     ecConfigToolDoc * pDoc = wxGetApp().GetConfigToolDoc ();
904     
905     wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
906     wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
907     
908     wxListBox * pListBox = NULL;
909     
910     wxArrayInt selections1, selections2;
911     wxArrayInt* selections = NULL;
912     availableList->GetSelections(selections1);
913     useList->GetSelections(selections2);
914     
915     if (1 == selections1.GetCount ())
916     {
917         pListBox = availableList;
918         selections = & selections1;
919     }
920     else if (1 == selections2.GetCount ())
921     {
922         pListBox = useList;
923         selections = & selections2;
924     }
925     
926     if (pListBox && selections)
927     {
928         int nIndex = (*selections)[0];
929         wxString strPackageAlias = pListBox->GetString(nIndex);
930         
931         DisplayDescription(strPackageAlias);
932         //m_packageDescription = pDoc->GetCdlPkgData ()->get_package_description (ecUtils::UnicodeToStdStr (pDoc->GetPackageName (strPackageAlias))).c_str ();
933         //m_packageDescription = ecUtils::StripExtraWhitespace (m_packageDescription);
934     }
935     else
936     {
937         m_packageDescription = wxEmptyString;
938     }
939     TransferDataToWindow ();
940 }
941
942 void ecPackagesDialog::UpdateVersionList ()
943 {
944     ecConfigToolDoc * pDoc = wxGetApp().GetConfigToolDoc ();
945     
946     wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
947     wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
948     wxChoice* versionChoice = (wxChoice*) FindWindow( ecID_PACKAGES_DIALOG_VERSION );
949     
950     versionChoice->Clear(); // clear the version combo box
951     
952     wxArrayInt selections1, selections2;
953     wxArrayInt* selections = NULL;
954     availableList->GetSelections(selections1);
955     useList->GetSelections(selections2);
956     wxListBox* pListBox = NULL;
957     
958     if (selections1.GetCount () > 0)
959     {
960         pListBox = availableList;
961         selections = & selections1;
962     }
963     else if (selections2.GetCount () > 0)
964     {
965         pListBox = useList;
966         selections = & selections2;
967     }
968     
969     if (pListBox) // if there are packages selected
970     {
971         std::list<std::string> common_versions;
972         bool bCommonSelectedVersion = true;
973         int nCommonVersionIndex=-1;
974         int nListSelCount = selections->GetCount();
975         
976         // retrieve the list box indices of the selected packages
977         
978         //int * arnIndices = new int [nListSelCount];
979         //pListBox->GetSelItems (nListSelCount, arnIndices);
980         int nIndex;
981         for (nIndex = 0; nIndex < nListSelCount; nIndex++) // for each selected package
982         {
983             // retrieve the first package alias
984             wxString strPackageAlias = pListBox->GetString ((*selections)[nIndex]);
985             
986             // retrieve the dialog item array index for use in
987             // comparing current version strings
988             const int nVersionIndex = (int) pListBox->GetClientData ((*selections)[nIndex]);
989             
990             // retrieve the installed version array
991             
992             //TRACE (_T("Retrieving versions for '%s'\n"), strPackageAlias);
993             const std::vector<std::string>& versions = pDoc->GetCdlPkgData ()->get_package_versions (ecUtils::UnicodeToStdStr (pDoc->GetPackageName (strPackageAlias)));
994             
995             if (0 == nIndex) // if this is the first selected package
996             {
997                 // use the version array to initialise a linked list of version
998                 // strings held in common between the selected packages
999                 unsigned int uCount;
1000                 for (uCount = 0; uCount < versions.size (); uCount++)
1001                 {
1002                     //TRACE (_T("Adding common version '%s'\n"), wxString (versions [uCount].c_str ()));
1003                     common_versions.push_back (versions [uCount]);
1004                 }
1005                 nCommonVersionIndex = nVersionIndex; // save the item array index
1006             }
1007             else // this is not the first selected package
1008             {
1009                 std::list<std::string>::iterator i_common_versions = common_versions.begin ();
1010                 while (i_common_versions != common_versions.end ()) // iterate through the common versions
1011                 {
1012                     if (versions.end () == std::find (versions.begin (), versions.end (), * i_common_versions)) // if the common version is not in the versions list
1013                     {
1014                         //TRACE (_T("Removing common version '%s'\n"), CString (i_common_versions->c_str ()));
1015                         common_versions.erase (i_common_versions++); // remove the version from the common versions list
1016                     }
1017                     else
1018                     {
1019                         i_common_versions++;
1020                     }
1021                 }
1022                 if (bCommonSelectedVersion) // if the selected versions of all preceding packages are identical
1023                 {
1024                     // check if the selected version of this package matches that of the preceding ones
1025                     bCommonSelectedVersion = (m_currentVersions [nVersionIndex] == m_currentVersions [nCommonVersionIndex]);
1026                 }
1027             }
1028         }
1029         
1030         // add the common versions to the version combo box
1031         
1032         std::list<std::string>::iterator i_common_versions;
1033         for (i_common_versions = common_versions.begin (); i_common_versions != common_versions.end (); i_common_versions++)
1034         {
1035             //TRACE (_T("Adding version '%s'\n"), CString (i_common_versions->c_str ()));
1036             versionChoice->Append(wxString (i_common_versions->c_str ()));
1037         }
1038         
1039         // select the common current version (if any) in the version combo box
1040         
1041         if (bCommonSelectedVersion)
1042         {
1043             //TRACE (_T("Selecting version '%s'\n"), m_arstrVersions [nCommonVersionIndex]);
1044             versionChoice->SetStringSelection (m_currentVersions [nCommonVersionIndex]);
1045         }
1046         
1047         // enable the version combo box only if there are multiple common versions
1048         
1049         versionChoice->Enable (common_versions.size () > 1);
1050     }
1051     else // there are no packages selected
1052     {
1053         versionChoice->Enable (FALSE); // disable the version combo box
1054     }
1055 }
1056
1057 void ecPackagesDialog::UpdateAddRemoveButtons()
1058 {
1059     wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
1060     wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
1061     
1062     wxArrayInt selections1, selections2;
1063     availableList->GetSelections(selections1);
1064     useList->GetSelections(selections2);
1065     
1066     FindWindow( ecID_PACKAGES_DIALOG_ADD )->Enable( selections1.GetCount() > 0 );
1067     FindWindow( ecID_PACKAGES_DIALOG_REMOVE )->Enable( selections2.GetCount() > 0 );
1068 }
1069
1070 void ecPackagesDialog::ClearSelections(wxListBox& lbox)
1071 {
1072     int i;
1073     for (i = 0; i < lbox.Number(); i++)
1074     {
1075         lbox.Deselect(i);
1076     }
1077 }
1078
1079 void ecPackagesTimer::Notify()
1080 {
1081     static bool s_inNotify = FALSE;
1082     
1083     if (s_inNotify)
1084         return;
1085     
1086     s_inNotify = TRUE;
1087     
1088     // On Windows, simply having the timer going will ping the message queue
1089     // and cause idle processing to happen.
1090     // On Unix, this doesn't happen so we have to do the processing explicitly.
1091 #ifdef __WXMSW__
1092     // Nothing to do
1093 #else
1094     if ( m_dialog )
1095     {
1096         wxIdleEvent event;
1097         m_dialog->OnIdle(event);
1098     }
1099 #endif
1100     
1101     s_inNotify = FALSE;
1102 }