]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - tools/src/tools/configtool/standalone/wxwin/templatesdlg.cpp
Cleanup CVS ipmorted branch
[karo-tx-redboot.git] / tools / src / tools / configtool / standalone / wxwin / templatesdlg.cpp
1 //####COPYRIGHTBEGIN####
2 //
3 // ----------------------------------------------------------------------------
4 // Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
5 //
6 // This program is part of the eCos host tools.
7 //
8 // This program is free software; you can redistribute it and/or modify it
9 // under the terms of the GNU General Public License as published by the Free
10 // Software Foundation; either version 2 of the License, or (at your option)
11 // any later version.
12 //
13 // This program is distributed in the hope that it will be useful, but WITHOUT
14 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16 // more details.
17 //
18 // You should have received a copy of the GNU General Public License along with
19 // this program; if not, write to the Free Software Foundation, Inc.,
20 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21 //
22 // ----------------------------------------------------------------------------
23 //
24 //####COPYRIGHTEND####
25 // templatesdlg.cpp :
26 //
27 //===========================================================================
28 //#####DESCRIPTIONBEGIN####
29 //
30 // Author(s):   julians
31 // Contact(s):  julians
32 // Date:        2000/09/27
33 // Version:     $Id: templatesdlg.cpp,v 1.10 2001/12/03 16:05:40 julians Exp $
34 // Purpose:
35 // Description: Implementation file for ecTemplatesDialog
36 // Requires:
37 // Provides:
38 // See also:
39 // Known bugs:
40 // Usage:
41 //
42 //####DESCRIPTIONEND####
43 //
44 //===========================================================================
45
46 // ============================================================================
47 // declarations
48 // ============================================================================
49
50 // ----------------------------------------------------------------------------
51 // headers
52 // ----------------------------------------------------------------------------
53 #ifdef __GNUG__
54 #pragma implementation "templatesdlg.h"
55 #endif
56
57 // Includes other headers for precompiled compilation
58 #include "ecpch.h"
59
60 #ifdef __BORLANDC__
61 #pragma hdrstop
62 #endif
63
64 #include "wx/cshelp.h"
65 #include "wx/valgen.h"
66
67 #include "configtool.h"
68 #include "configtooldoc.h"
69 #include "templatesdlg.h"
70 #include "ecutils.h"
71
72 BEGIN_EVENT_TABLE(ecTemplatesDialog, ecDialog)
73     EVT_BUTTON(wxID_OK, ecTemplatesDialog::OnOK)
74     EVT_BUTTON(wxID_CANCEL, ecTemplatesDialog::OnCancel)
75     EVT_COMBOBOX(ecID_TEMPLATES_DIALOG_HARDWARE_TEMPLATES, ecTemplatesDialog::OnSelHardwareTemplates)
76     EVT_CHOICE(ecID_TEMPLATES_DIALOG_PACKAGE_TEMPLATES, ecTemplatesDialog::OnSelPackageTemplates)
77     EVT_CHOICE(ecID_TEMPLATES_DIALOG_VERSION, ecTemplatesDialog::OnSelPackageVersion)
78     EVT_BUTTON(ecID_TEMPLATES_DIALOG_DETAILS, ecTemplatesDialog::OnDetails)
79 END_EVENT_TABLE()
80
81 // ----------------------------------------------------------------------------
82 // main frame
83 // ----------------------------------------------------------------------------
84
85 // Frame constructor
86 ecTemplatesDialog::ecTemplatesDialog(wxWindow* parent)
87 {
88     SetExtraStyle(wxDIALOG_EX_CONTEXTHELP);
89
90     ecDialog::Create(parent, ecID_TEMPLATES_DIALOG, _("Templates"),
91         wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER);
92
93     CreateControls(this);
94
95     Centre(wxBOTH);
96 }
97
98 ecTemplatesDialog::~ecTemplatesDialog()
99 {
100 }
101
102 void ecTemplatesDialog::CreateControls(wxWindow* parent)
103 {
104     wxSizer *item0 = new wxBoxSizer( wxVERTICAL );
105
106     wxStaticBox *item2 = new wxStaticBox( parent, -1, _("Hardware") );
107     wxSizer *item1 = new wxStaticBoxSizer( item2, wxVERTICAL );
108
109     wxString *strs3 = (wxString*) NULL;
110     wxComboBox *item3 = new wxComboBox( parent, ecID_TEMPLATES_DIALOG_HARDWARE_TEMPLATES, "", wxDefaultPosition, wxSize(360,-1), 0, strs3, wxCB_DROPDOWN|wxCB_READONLY|wxCB_SORT );
111     item1->Add( item3, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
112
113     wxTextCtrl *item4 = new wxTextCtrl( parent, ecID_TEMPLATES_DIALOG_HARDWARE_DESCRIPTION, _(""), wxDefaultPosition, wxSize(90,60), wxTE_MULTILINE|wxTE_READONLY );
114     item1->Add( item4, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
115
116     item0->Add( item1, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
117
118     wxSizer *item5 = new wxBoxSizer( wxHORIZONTAL );
119
120     wxStaticBox *item7 = new wxStaticBox( parent, -1, _("Packages") );
121     wxSizer *item6 = new wxStaticBoxSizer( item7, wxVERTICAL );
122
123     wxSizer *item8 = new wxBoxSizer( wxHORIZONTAL );
124
125     wxString *strs9 = (wxString*) NULL;
126     wxChoice *item9 = new wxChoice( parent, ecID_TEMPLATES_DIALOG_PACKAGE_TEMPLATES, wxDefaultPosition, wxSize(100,-1), 0, strs9, 0 );
127     item8->Add( item9, 20, wxALIGN_CENTRE|wxALL, 5 );
128
129     wxString *strs10 = (wxString*) NULL;
130     wxChoice *item10 = new wxChoice( parent, ecID_TEMPLATES_DIALOG_VERSION, wxDefaultPosition, wxSize(90,-1), 0, strs10, 0 );
131     item8->Add( item10, 0, wxALIGN_CENTRE|wxALL, 5 );
132
133     item6->Add( item8, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 0 );
134
135     wxTextCtrl *item11 = new wxTextCtrl( parent, ecID_TEMPLATES_DIALOG_PACKAGE_DESCRIPTION, _(""), wxDefaultPosition, wxSize(110,70), wxTE_MULTILINE|wxTE_READONLY );
136     item6->Add( item11, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
137
138     item5->Add( item6, 1, wxALIGN_CENTRE|wxLEFT|wxRIGHT|wxBOTTOM, 5 );
139
140     wxSizer *item12 = new wxBoxSizer( wxVERTICAL );
141
142     wxButton *item13 = new wxButton( parent, wxID_OK, _("&OK"), wxDefaultPosition, wxDefaultSize, 0 );
143     item12->Add( item13, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
144
145     wxButton *item14 = new wxButton( parent, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
146     item12->Add( item14, 0, wxALIGN_CENTRE|wxALL, 5 );
147
148     item12->Add( 10, 10, 0, wxALIGN_CENTRE|wxALL, 0 );
149
150     wxButton *item15 = new wxButton( parent, ecID_TEMPLATES_DIALOG_DETAILS, _("&Details >>"), wxDefaultPosition, wxDefaultSize, 0 );
151     item12->Add( item15, 0, wxALIGN_CENTRE|wxALL, 5 );
152
153     item5->Add( item12, 0, wxALIGN_CENTRE|wxALL, 5 );
154
155     item0->Add( item5, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 0 );
156
157     wxStaticText *item16 = new wxStaticText( parent, ecID_TEMPLATES_DIALOG_PACKAGES_MSG, _("&Packages in selected template:"), wxDefaultPosition, wxDefaultSize, 0 );
158
159     wxTextCtrl *item17 = new wxTextCtrl( parent, ecID_TEMPLATES_DIALOG_PACKAGES, _(""), wxDefaultPosition, wxSize(90,100), wxTE_MULTILINE|wxTE_READONLY );
160
161     // Don't add these yet (until press Details)
162     //item0->Add( item16, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
163     //item0->Add( item17, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
164     item16->Show(FALSE);
165     item17->Show(FALSE);
166
167 #ifdef __WXGTK__
168     wxButton *contextButton = new wxContextHelpButton( parent );
169     item12->Add( contextButton, 0, wxALIGN_CENTRE|wxALL, 5 );
170 #endif
171
172     parent->SetAutoLayout( TRUE );
173     parent->SetSizer( item0 );
174     parent->Layout();
175     item0->Fit( parent );
176     //item0->SetSizeHints( parent );
177
178     // Add context-sensitive help text
179     parent->FindWindow( ecID_TEMPLATES_DIALOG_HARDWARE_TEMPLATES )->SetHelpText(_("Selects from the set of available hardware templates."));
180     parent->FindWindow( ecID_TEMPLATES_DIALOG_HARDWARE_DESCRIPTION )->SetHelpText(_("Gives a brief description of the currently selected hardware template."));
181     parent->FindWindow( ecID_TEMPLATES_DIALOG_PACKAGE_TEMPLATES )->SetHelpText(_("Selects from the set of available package templates."));
182     parent->FindWindow( ecID_TEMPLATES_DIALOG_VERSION )->SetHelpText(_("Selects the version of the currently selected template."));
183     parent->FindWindow( ecID_TEMPLATES_DIALOG_PACKAGE_DESCRIPTION )->SetHelpText(_("Gives a brief description of the currently selected package template."));
184     parent->FindWindow( ecID_TEMPLATES_DIALOG_PACKAGES )->SetHelpText(_("Lists the packages contained in the currently selected template."));
185     parent->FindWindow( wxID_OK )->SetHelpText(_("Closes the dialog and saves any changes you have made."));
186     parent->FindWindow( wxID_CANCEL )->SetHelpText(_("Closes the dialog without saving any changes you have made."));
187     parent->FindWindow( ecID_TEMPLATES_DIALOG_DETAILS )->SetHelpText(_("Shows or hides a portion of the dialog that provides details of the contents of the currently selected template."));
188
189 #if __WXGTK__
190     parent->FindWindow( wxID_CONTEXT_HELP )->SetHelpText(_("Invokes context-sensitive help for the clicked-on window."));
191 #endif
192
193         // Add validators
194         parent->FindWindow( ecID_TEMPLATES_DIALOG_PACKAGE_DESCRIPTION )->SetValidator(wxGenericValidator(& m_strCdlTemplateDescription));
195         parent->FindWindow( ecID_TEMPLATES_DIALOG_HARDWARE_DESCRIPTION )->SetValidator(wxGenericValidator(& m_strCdlHardwareDescription));
196         parent->FindWindow( ecID_TEMPLATES_DIALOG_PACKAGES)->SetValidator(wxGenericValidator(& m_strCdlTemplatePackages));
197
198     PopulateControls();
199 }
200
201 // function which is called by quick sort
202 static int wxStringCompareFunction(const void *first, const void *second)
203 {
204   wxString *strFirst = (wxString *)first;
205   wxString *strSecond = (wxString *)second;
206
207   return wxStricmp(strFirst->c_str(), strSecond->c_str());
208 }
209
210 void ecTemplatesDialog::PopulateControls()
211 {
212     ecConfigToolDoc* doc = wxGetApp().GetConfigToolDoc();
213
214     m_hardware = doc->GetCdlConfig ()->get_hardware ().c_str();
215
216     wxComboBox* cdlHardwareCtrl = (wxComboBox*)  FindWindow( ecID_TEMPLATES_DIALOG_HARDWARE_TEMPLATES ) ;
217     wxChoice* cdlPackageCtrl = (wxChoice*)  FindWindow( ecID_TEMPLATES_DIALOG_PACKAGE_TEMPLATES ) ;
218
219
220         const std::vector<std::string> & targets = doc->GetCdlPkgData ()->get_targets ();
221         std::vector<std::string>::const_iterator target_i;
222
223     // Old code: let the combo box do the sorting. But not all platforms implement this.
224 #if 0
225     // populate the hardware combo box
226     int nIndex = 0;
227         for (target_i = targets.begin (); target_i != targets.end (); target_i++)
228         {
229                 const std::vector<std::string> & aliases = doc->GetCdlPkgData ()->get_target_aliases (* target_i);
230
231                 // use the first alias (if any) as the description
232                 wxString strTargetDescription = aliases.size () ? aliases [0].c_str () : target_i->c_str ();
233                 cdlHardwareCtrl->Append(strTargetDescription, (void*) &(*target_i)); // store the target iterator
234         std::string str(* (target_i));
235                 if (m_hardware == str.c_str())            // if current target...
236         {
237             int sel = 0;
238             int i;
239             for (i = 0; i <= nIndex; i++)
240                 if (cdlHardwareCtrl->GetClientData(i) == (void*) &(*target_i))
241                     sel = i;
242                         cdlHardwareCtrl->SetSelection (sel); // ...select the string
243         }
244         nIndex ++;
245         }
246 #else
247     // New code: sort, then add to combobox. How do we keep track of the target iterators?
248     // could use hash table, assuming that each string is unique
249     wxHashTable ht(wxKEY_STRING);
250     wxArrayString ar;
251
252         for (target_i = targets.begin (); target_i != targets.end (); target_i++)
253         {
254                 const std::vector<std::string> & aliases = doc->GetCdlPkgData ()->get_target_aliases (* target_i);
255
256                 // use the first alias (if any) as the description
257                 wxString strTargetDescription = aliases.size () ? aliases [0].c_str () : target_i->c_str ();
258
259         ar.Add(strTargetDescription);
260         ht.Put(strTargetDescription, (wxObject*) (void*) &(*target_i));
261     }
262
263     ar.Sort((wxArrayString::CompareFunction) & wxStringCompareFunction);
264
265     int nIndex = 0;
266
267     unsigned int i;
268     for (i = 0; i < ar.GetCount(); i ++)
269     {
270         wxString strTargetDescription = ar[i];
271
272         std::string *t_i = (std::string*) (void*) ht.Get(strTargetDescription);
273
274                 cdlHardwareCtrl->Append(strTargetDescription, (void*) t_i); // store the target iterator
275         std::string str(* (t_i));
276                 if (m_hardware == str.c_str())            // if current target...
277         {
278             int sel = 0;
279             int i;
280             for (i = 0; i <= nIndex; i++)
281                 if (cdlHardwareCtrl->GetClientData(i) == (void*) &(*t_i))
282                     sel = i;
283                         cdlHardwareCtrl->SetSelection (sel); // ...select the string
284         }
285         nIndex ++;
286         }
287
288 #endif
289
290         if (-1 == cdlHardwareCtrl->GetSelection ()) // if no target selected...
291                 cdlHardwareCtrl->SetSelection (0);          // ...select the first one
292
293         // populate the template combo box
294         m_template = doc->GetCdlConfig ()->get_template ().c_str();
295         const std::vector<std::string> & templates = doc->GetCdlPkgData ()->get_templates ();
296         std::vector<std::string>::const_iterator template_i;
297     nIndex = 0;
298         for (template_i = templates.begin (); template_i != templates.end (); template_i++)
299         {
300                 wxString strTemplateDescription = template_i->c_str ();
301                 cdlPackageCtrl->Append(strTemplateDescription, (void*) &(*template_i)); // store the template iterator
302                 /// m_cboCdlTemplate.SetItemData (nIndex, (DWORD) template_i); // store the template iterator
303                 std::string str(* (template_i));
304                 if (m_template == str.c_str())          // if current template...
305                         cdlPackageCtrl->SetSelection(nIndex); // ...select the string
306                 nIndex ++;
307         }
308
309         if (-1 == cdlPackageCtrl->GetSelection()) // if no template selected...
310                 cdlPackageCtrl->SetSelection(0);          // ...select the first one
311
312         // display initial target and template descriptions
313         wxCommandEvent dummyEvent;
314         OnSelHardwareTemplates(dummyEvent);
315         OnSelPackageTemplates(dummyEvent);
316
317         // populate the template version combo box
318         UpdateVersionList (doc->GetTemplateVersion ());
319 }
320
321 void ecTemplatesDialog::OnCancel(wxCommandEvent& event)
322 {
323     event.Skip();
324 }
325
326 void ecTemplatesDialog::OnOK(wxCommandEvent& event)
327 {
328     event.Skip();
329 }
330
331 void ecTemplatesDialog::OnDetails(wxCommandEvent& event)
332 {
333     wxWindow* win1 = FindWindow(ecID_TEMPLATES_DIALOG_PACKAGES);
334
335     wxASSERT( win1 != NULL );
336
337     bool show = !win1->IsShown();
338
339     ShowDetails(show);
340 }
341
342 void ecTemplatesDialog::ShowDetails(bool show)
343 {
344     wxWindow* win1 = FindWindow(ecID_TEMPLATES_DIALOG_PACKAGES);
345     wxWindow* win2 = FindWindow(ecID_TEMPLATES_DIALOG_PACKAGES_MSG);
346     wxButton* button = (wxButton*) FindWindow(ecID_TEMPLATES_DIALOG_DETAILS);
347
348     if (show)
349     {
350         GetSizer()->Add( win2, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
351         GetSizer()->Add( win1, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
352         button->SetLabel("&Details <<");
353     }
354     else
355     {
356         GetSizer()->Remove(win1);
357         GetSizer()->Remove(win2);
358         button->SetLabel("&Details >>");
359     }
360     win1->Show(show);
361     win2->Show(show);
362
363     Layout();
364     GetSizer()->Fit( this );
365 }
366
367 void ecTemplatesDialog::OnSelHardwareTemplates(wxCommandEvent& event)
368 {
369     wxComboBox* cdlHardwareCtrl = (wxComboBox*)  FindWindow( ecID_TEMPLATES_DIALOG_HARDWARE_TEMPLATES ) ;
370     wxChoice* cdlPackageCtrl = (wxChoice*)  FindWindow( ecID_TEMPLATES_DIALOG_PACKAGE_TEMPLATES ) ;
371
372     ecConfigToolDoc* doc = wxGetApp().GetConfigToolDoc();
373
374         // the target has changed so retrieve the new target description
375         const int nIndex = cdlHardwareCtrl->GetSelection ();
376         //std::vector<std::string>::const_iterator template_i = (std::vector<std::string>::const_iterator) cdlHardwareCtrl->GetClientData (nIndex);
377     std::string* template_i =  (std::string*) cdlHardwareCtrl->GetClientData (nIndex);
378         m_hardware = template_i->c_str();
379
380         m_strCdlHardwareDescription = doc->GetCdlPkgData ()->get_target_description ((const wxChar*) m_hardware).c_str ();
381         m_strCdlHardwareDescription = ecUtils::StripExtraWhitespace (m_strCdlHardwareDescription);
382
383     UpdateDetails (); // display new hardware packages in details box
384
385     TransferDataToWindow (); // display new target description
386 }
387
388 void ecTemplatesDialog::OnSelPackageTemplates(wxCommandEvent& event)
389 {
390     wxComboBox* cdlHardwareCtrl = (wxComboBox*)  FindWindow( ecID_TEMPLATES_DIALOG_HARDWARE_TEMPLATES ) ;
391     wxChoice* cdlPackageCtrl = (wxChoice*)  FindWindow( ecID_TEMPLATES_DIALOG_PACKAGE_TEMPLATES ) ;
392
393         // the template has changed so update the version combo box
394         int nIndex = cdlPackageCtrl->GetSelection ();
395
396         //std::vector<std::string>::const_iterator template_i = (std::vector<std::string>::const_iterator) cdlPackageCtrl->GetClientData (nIndex);
397     std::string *template_i = (std::string*) cdlPackageCtrl->GetClientData (nIndex);
398         m_template = template_i->c_str();
399         
400         UpdateVersionList (wxT("")); // repopulate template versions combo box and select most recent version
401 }
402
403 void ecTemplatesDialog::OnSelPackageVersion(wxCommandEvent& event)
404 {
405         wxString strVersion;
406     ecConfigToolDoc* doc = wxGetApp().GetConfigToolDoc();
407     wxChoice* cdlVersionCtrl = (wxChoice*)  FindWindow( ecID_TEMPLATES_DIALOG_VERSION ) ;
408
409         strVersion = cdlVersionCtrl->GetStringSelection ();
410
411         //TRACE (_T("Version '%s' selected\n"), strVersion);
412         m_template_version = ecUtils::UnicodeToStdStr (strVersion).c_str();
413         m_strCdlTemplateDescription = doc->GetCdlPkgData ()->get_template_description (m_template.c_str(), m_template_version.c_str()).c_str ();
414         m_strCdlTemplateDescription = ecUtils::StripExtraWhitespace (m_strCdlTemplateDescription);
415         
416         UpdateDetails (); // display new template packages in details box
417     TransferDataToWindow (); // display new template description
418 }
419
420 void ecTemplatesDialog::UpdateVersionList(const wxString& defaultVersion)
421 {
422     wxComboBox* cdlHardwareCtrl = (wxComboBox*)  FindWindow( ecID_TEMPLATES_DIALOG_HARDWARE_TEMPLATES ) ;
423     wxChoice* cdlPackageCtrl = (wxChoice*)  FindWindow( ecID_TEMPLATES_DIALOG_PACKAGE_TEMPLATES ) ;
424     wxChoice* cdlVersionCtrl = (wxChoice*)  FindWindow( ecID_TEMPLATES_DIALOG_VERSION ) ;
425
426     ecConfigToolDoc* doc = wxGetApp().GetConfigToolDoc();
427
428         // clear the version combo box
429         cdlVersionCtrl->Clear ();
430         
431         // get the template version information
432         const std::vector<std::string>& versions = doc->GetCdlPkgData ()->get_template_versions (m_template.c_str());
433         wxASSERT (versions.size () > 0);
434         
435         // add the template versions to the version combo box
436         for (unsigned int version = 0; version < versions.size (); version++) {
437                 // TRACE (_T("Adding version '%s'\n"), CString (versions [version].c_str ()));
438                 cdlVersionCtrl->Append (versions [version].c_str ());
439         }
440         
441         // select the appropriate version in the version combo box
442         if (defaultVersion.IsEmpty()) { // if no default version specified
443                 cdlVersionCtrl->SetSelection (versions.size () - 1); // select the most recent version
444         } else { // a default version was specified
445                 cdlVersionCtrl->SetStringSelection (defaultVersion);
446         }
447         wxCommandEvent dummyEvent;
448
449         OnSelPackageVersion(dummyEvent);
450         
451         // enable the version combo box only if there are multiple versions
452         cdlVersionCtrl->Enable (versions.size () > 1);
453 }
454
455 void ecTemplatesDialog::UpdateDetails()
456 {
457     ecConfigToolDoc* doc = wxGetApp().GetConfigToolDoc();
458
459         // retrieve the template and target package names
460         const std::vector<std::string> & template_packages = doc->GetCdlPkgData ()->get_template_packages (m_template.c_str(), m_template_version.c_str());
461         std::vector<std::string> packages = doc->GetCdlPkgData ()->get_target_packages (m_hardware.c_str());
462         packages.insert (packages.end (), template_packages.begin (), template_packages.end ());
463         
464         // retrieve the zeroth (verbose) package alias for each package
465         std::vector<std::string> aliases;
466         unsigned int i;
467         for (i = 0; i < packages.size (); i++)
468         {
469                 if (doc->GetCdlPkgData ()->is_known_package (packages [i])) // if the package is installed
470                 {
471                         aliases.push_back (doc->GetCdlPkgData ()->get_package_aliases (packages [i]) [0]);
472                 }
473                 else // package is not installed
474                 {
475                         aliases.push_back ("Unknown package " + packages [i]);
476                 }
477         }
478         
479         // sort the aliases into alphabetical order
480         std::sort (aliases.begin (), aliases.end ());
481         
482         // copy the aliases into the details box
483         m_strCdlTemplatePackages = wxT("");
484         for (i = 0; i < aliases.size (); i++)
485         {
486                 m_strCdlTemplatePackages += aliases [i].c_str ();
487 #ifdef __WXMSW__
488                 m_strCdlTemplatePackages += wxT("\r\n"); // add a CRLF between each alias
489 #else
490                 m_strCdlTemplatePackages += wxT("\n"); // add a LF between each alias
491 #endif
492         }
493         // TODO: does this work for CRLF?
494         m_strCdlTemplatePackages.Trim (TRUE); // remove the trailing CRLF
495 }