]> git.kernelconcepts.de Git - karo-tx-redboot.git/blobdiff - tools/src/tools/configtool/standalone/wxwin/admindlg.cpp
Initial revision
[karo-tx-redboot.git] / tools / src / tools / configtool / standalone / wxwin / admindlg.cpp
diff --git a/tools/src/tools/configtool/standalone/wxwin/admindlg.cpp b/tools/src/tools/configtool/standalone/wxwin/admindlg.cpp
new file mode 100644 (file)
index 0000000..281d30b
--- /dev/null
@@ -0,0 +1,565 @@
+//####COPYRIGHTBEGIN####
+//
+// ----------------------------------------------------------------------------
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
+// Copyright (C) 2003 John Dallaway
+//
+// This program is part of the eCos host tools.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 of the License, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+// more details.
+//
+// You should have received a copy of the GNU General Public License along with
+// this program; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+//
+// ----------------------------------------------------------------------------
+//
+//####COPYRIGHTEND####
+// admindlg.cpp :
+//
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   julians,jld
+// Contact(s):  julians
+// Date:        2000/09/28
+// Version:     $Id$
+// Purpose:
+// Description: Implementation file for ecAdminDialog
+// Requires:
+// Provides:
+// See also:
+// Known bugs:
+// Usage:
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+#ifdef __GNUG__
+#pragma implementation "admindlg.h"
+#endif
+
+// Includes other headers for precompiled compilation
+#include "ecpch.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+// For registry access functions in GetUserToolsPath
+#ifdef __WXMSW__
+#include <windows.h>
+#include "wx/msw/winundef.h"
+#endif
+
+#include "wx/cshelp.h"
+#include "wx/filedlg.h"
+#include "wx/file.h"
+#include "wx/filefn.h"
+#include "wx/progdlg.h"
+
+#include "configtool.h"
+#include "admindlg.h"
+#include "configtooldoc.h"
+#include "licensedlg.h"
+#include "ecutils.h"
+
+#ifdef __WXGTK__
+#include "bitmaps/package_open.xpm"
+#include "bitmaps/package_version.xpm"
+#endif
+
+BEGIN_EVENT_TABLE(ecAdminDialog, ecDialog)
+    EVT_BUTTON(wxID_OK, ecAdminDialog::OnClose)
+    EVT_BUTTON(ecID_ADMIN_DIALOG_ADD, ecAdminDialog::OnAdd)
+    EVT_BUTTON(ecID_ADMIN_DIALOG_REMOVE, ecAdminDialog::OnRemove)
+    EVT_INIT_DIALOG(ecAdminDialog::OnInitDialog)
+END_EVENT_TABLE()
+
+// ----------------------------------------------------------------------------
+// main frame
+// ----------------------------------------------------------------------------
+
+// Frame constructor
+ecAdminDialog::ecAdminDialog(wxWindow* parent, const wxString& repository, const wxString& userTools):
+    m_imageList(16, 16, 1)
+{
+    m_strRepository = repository;
+    m_strUserTools = userTools;
+       m_CdlPkgData = NULL;
+
+    SetExtraStyle(wxDIALOG_EX_CONTEXTHELP);
+
+    ecDialog::Create(parent, ecID_ADMIN_DIALOG, _("Administration"),
+        wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER);
+
+    CreateControls(this);
+
+    m_imageList.Add(wxICON(package_open));
+    m_imageList.Add(wxICON(package_version));
+    m_treeCtrl->SetImageList(& m_imageList);
+
+    Centre(wxBOTH);
+}
+
+ecAdminDialog::~ecAdminDialog()
+{
+       ClearPackageTree ();
+
+       // free memory allocated to the CDL database
+
+       if (m_CdlPkgData)
+               delete m_CdlPkgData;
+
+    m_treeCtrl->SetImageList(NULL);
+}
+
+void ecAdminDialog::OnInitDialog(wxInitDialogEvent& event)
+{
+    // setup the path to the user tools (tar and gunzip)
+    
+    if ((! m_strUserTools.IsEmpty()) || FindUserToolsPath ()) // if the user tools can be located
+    {
+        wxString path;
+        wxGetEnv(wxT("PATH"), & path);
+        
+        // TODO: this may not work on all platforms
+        path = path + wxString(wxPATH_SEP) + m_strUserTools;
+        wxSetEnv(wxT("PATH"), path);
+    }
+    
+    // populate the package tree
+
+    if (!PopulatePackageTree (m_strRepository))
+    {
+        m_strRepository = wxT("");
+        // TODO
+        // OnPkgadminRepository (); // prompt the user for the repository location
+    }
+}
+
+void ecAdminDialog::CreateControls(wxWindow* parent)
+{
+    m_treeCtrl = new wxTreeCtrl(parent, ecID_ADMIN_DIALOG_TREE,
+        wxDefaultPosition, wxSize(380, 290), wxTR_HAS_BUTTONS | wxSUNKEN_BORDER);
+
+    wxSizer *item0 = new wxBoxSizer( wxHORIZONTAL );
+
+    wxSizer *item1 = new wxBoxSizer( wxVERTICAL );
+
+    wxStaticText *item2 = new wxStaticText( parent, wxID_STATIC, _("&Installed packages:"), wxDefaultPosition, wxDefaultSize, 0 );
+    item1->Add( item2, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+    wxWindow *item3 = parent->FindWindow( ecID_ADMIN_DIALOG_TREE );
+    wxASSERT( item3 );
+    item1->Add( item3, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+    item0->Add( item1, 1, wxGROW|wxALIGN_CENTER_HORIZONTAL|wxALL, 5 );
+
+    wxSizer *item4 = new wxBoxSizer( wxVERTICAL );
+
+    wxButton *item5 = new wxButton( parent, ecID_ADMIN_DIALOG_ADD, _("&Add..."), wxDefaultPosition, wxDefaultSize, 0 );
+    item4->Add( item5, 0, wxALIGN_CENTRE|wxALL, 5 );
+
+    wxButton *item6 = new wxButton( parent, ecID_ADMIN_DIALOG_REMOVE, _("&Remove"), wxDefaultPosition, wxDefaultSize, 0 );
+    item4->Add( item6, 0, wxALIGN_CENTRE|wxALL, 5 );
+
+    item4->Add( 20, 20, 1, wxALIGN_CENTRE|wxALL, 5 );
+
+    wxButton *item7 = new wxButton( parent, wxID_OK, _("&Close"), wxDefaultPosition, wxDefaultSize, 0 );
+    item4->Add( item7, 0, wxALIGN_CENTRE|wxALL, 5 );
+
+#ifdef __WXGTK__
+    wxButton *contextButton = new wxContextHelpButton( parent );
+    item4->Add( contextButton, 0, wxALIGN_CENTRE|wxALL, 5 );
+#endif
+
+    item0->Add( item4, 0, wxGROW|wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxTOP|wxBOTTOM, 5 );
+    
+    item7->SetDefault(); // Make Close the default button
+
+    parent->SetAutoLayout( TRUE );
+    parent->SetSizer( item0 );
+    parent->Layout();
+    item0->Fit( parent );
+    //item0->SetSizeHints( parent );
+
+    // Add context-sensitive help text
+    parent->FindWindow( ecID_ADMIN_DIALOG_TREE)->SetHelpText(_("Displays the set of packages currently in the eCos component repository."));
+    parent->FindWindow( ecID_ADMIN_DIALOG_ADD)->SetHelpText(_("Adds the contents of an eCos package file to the eCos component repository."));
+    parent->FindWindow( ecID_ADMIN_DIALOG_REMOVE)->SetHelpText(_("Removes the currently selected package from the eCos component repository."));
+    parent->FindWindow( wxID_OK )->SetHelpText(_("Closes the dialog and saves any changes you have made."));
+
+#if __WXGTK__
+    parent->FindWindow( wxID_CONTEXT_HELP )->SetHelpText(_("Invokes context-sensitive help for the clicked-on window."));
+#endif
+
+}
+
+void ecAdminDialog::OnAdd(wxCommandEvent& event)
+{
+    wxString defaultDir; // TODO
+    wxString defaultFile;
+    wxString wildcard = wxT("eCos Package Files (*.epk)|*.epk");
+    wxFileDialog dlg(this, _("Open eCos Package Files"), defaultDir, defaultFile, wildcard, wxOPEN|wxMULTIPLE);
+
+    if (wxID_OK == dlg.ShowModal ())
+    {
+        bool bRepositoryChanged = FALSE;
+        //POSITION posPathName = dlg.GetStartPosition ();
+        wxArrayString filenames;
+        dlg.GetPaths(filenames);
+        size_t i;
+        for (i = (size_t) 0; i < filenames.GetCount(); i++)
+        {
+            wxString strPathName(filenames[i]);
+
+            if (!wxFileExists(strPathName))
+            {
+                wxString msg;
+                msg.Printf(_("Cannot open %s"), (const wxChar*) strPathName);
+                wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK);
+            }
+            else
+            {
+                
+                // get an eCos package distribution file
+                
+                // extract the licence file
+
+                wxString strCommand;
+                strCommand.Printf(wxT("add %s --extract_license"), (const wxChar*) strPathName);
+                strCommand.Replace(wxT("\\"), wxT("/")); // backslashes -> forward slashes for Tcl_EvalFile
+                EvalTclFile (3, strCommand, _("Adding package"));
+
+                wxString strLicenseFile = m_strRepository + wxString(wxFILE_SEP_PATH) + wxT("pkgadd.txt");
+#ifdef __WXMSW__
+                strLicenseFile.Replace (wxT("/"), wxT("\\")); // forward slashes -> backslashes for Win32
+#endif
+                // read the license file
+
+                wxFile fileLicenseFile;
+                if (fileLicenseFile.Exists (strLicenseFile) && fileLicenseFile.Open (strLicenseFile, wxFile::read))
+                {
+                    //TRACE (_T("License file found at %s\n"), strLicenseFile);
+                    const off_t dwLicenseLength = fileLicenseFile.Length ();
+                    char* pszBuffer = new char [dwLicenseLength + 1]; // allocate a buffer
+                    fileLicenseFile.Read ((void*) pszBuffer, dwLicenseLength);
+                    fileLicenseFile.Close ();
+                    wxRemoveFile (strLicenseFile); // delete the license file when read
+                    pszBuffer [dwLicenseLength] = 0; // terminate the string in the buffer
+                    wxString strLicenseText (pszBuffer); // copy into a wxString to convert to Unicode
+                    delete [] pszBuffer;
+#ifdef __WXMSW__
+                    if (-1 == strLicenseText.Find (wxT("\r\n"))) // if the file has LF line endings...
+                        strLicenseText.Replace (_T("\n"), _T("\r\n")); // ... replace with CRLF line endings
+#else
+                    strLicenseText.Replace (_T("\r"), wxEmptyString); // remove CR characters
+#endif
+                    // display the license text
+
+                    ecLicenseDialog dlgLicense (strLicenseText, this, ecID_LICENSE_DIALOG, strPathName + _(" - Add Packages"));
+                    if (wxID_OK != dlgLicense.ShowModal ()) // if license not accepted by user
+                        continue; // try the next file
+                }
+                
+                // add the contents of the package distribution file
+                
+                strCommand.Printf (wxT("add %s --accept_license"), (const wxChar*) strPathName);
+                strCommand.Replace (wxT("\\"), wxT("/")); // backslashes -> forward slashes for Tcl_EvalFile
+                if (! EvalTclFile (3, strCommand, _("Adding package")))  // if not successful
+                {
+                    // try the next file
+                }
+                else
+                {                
+                    bRepositoryChanged = TRUE;
+                }
+            }
+        }
+        
+        // refresh the package tree only if necessary
+        
+        if (bRepositoryChanged && ! PopulatePackageTree (m_strRepository))
+        {
+        }
+    }
+}
+
+void ecAdminDialog::OnRemove(wxCommandEvent& event)
+{
+    wxTreeCtrl* treeCtrl = (wxTreeCtrl*) FindWindow( ecID_ADMIN_DIALOG_TREE) ;
+
+    const wxTreeItemId hTreeItem = treeCtrl->GetSelection ();
+    if (! hTreeItem || !hTreeItem.IsOk())
+        return;
+    
+    if (wxYES != wxMessageBox (_("The selected package will be deleted from the repository. Core eCos packages may be restored only by reinstalling eCos.\n\nDo you wish to continue?"),
+        _("Remove Package"), wxYES_NO | wxICON_EXCLAMATION))
+        return;
+
+    ecAdminItemData* data = (ecAdminItemData*) treeCtrl->GetItemData (hTreeItem);
+
+    if (data) // if a package node is selected
+    {
+        // remove all package version nodes
+
+        wxString pstrPackage(data->m_string);
+        
+        bool bStatus = TRUE;
+        long cookie;
+        wxTreeItemId hChildItem = treeCtrl->GetFirstChild (hTreeItem, cookie);
+        while (hChildItem && bStatus)
+        {
+            const wxTreeItemId hNextChildItem = treeCtrl->GetNextSibling (hChildItem);                 
+            bStatus = RemovePackageVersion (hChildItem);
+            hChildItem = hNextChildItem;
+        }
+        
+        // remove the package node
+        
+        if (bStatus)
+        {
+            treeCtrl->Delete (hTreeItem);
+        }
+    }
+    else // a version node is selected
+    {
+        // remove the version node
+        
+        const wxTreeItemId hParentItem = treeCtrl->GetParent (hTreeItem);
+        wxASSERT (hParentItem && hParentItem.IsOk() );
+        if (RemovePackageVersion (hTreeItem) && ! treeCtrl->ItemHasChildren (hParentItem)) // if the only version was deleted
+        {
+            // remove the package node
+            
+            treeCtrl->Delete (hParentItem); 
+        }
+    }
+}
+
+void ecAdminDialog::OnClose(wxCommandEvent& event)
+{
+    event.Skip();
+}
+
+bool ecAdminDialog::FindUserToolsPath()
+{
+#ifdef __WXMSW__
+    HKEY hKey;
+    if (ERROR_SUCCESS != RegOpenKeyEx (HKEY_CURRENT_USER, _T("Software\\eCos Configuration Tool\\Paths\\UserToolsDir"), 0, KEY_READ, &hKey))
+        return FALSE;
+    
+    TCHAR szBuffer [MAX_PATH + 1];
+    DWORD dwBufferLength = MAX_PATH + 1;
+    LONG lStatus = RegQueryValueEx (hKey, _T("Folder"), NULL, NULL, (LPBYTE) szBuffer, &dwBufferLength);
+    RegCloseKey (hKey);
+    if (ERROR_SUCCESS != lStatus)
+        return FALSE;
+    
+    m_strUserTools = szBuffer;
+    // TRACE (_T("User tools found at %s\n"), m_strUserTools);
+    return ! m_strUserTools.IsEmpty ();
+#else
+    // wxMessageBox("Sorry, ecAdminDialog::FindUserToolsPath not implemented for this platform.");
+    return FALSE;
+#endif
+}
+
+bool ecAdminDialog::RemovePackageVersion (wxTreeItemId hTreeItem)
+{
+    wxTreeCtrl* treeCtrl = (wxTreeCtrl*) FindWindow( ecID_ADMIN_DIALOG_TREE) ;
+
+    const wxTreeItemId hParentItem = treeCtrl->GetParent (hTreeItem);
+    wxASSERT (hParentItem);
+
+    ecAdminItemData* data = (ecAdminItemData*) treeCtrl->GetItemData (hParentItem);
+
+    wxASSERT( data );
+
+    if (!data)
+        return FALSE;
+
+    wxString pstrPackage = data->m_string ;
+
+    wxString strCommand;
+    wxString itemText(treeCtrl->GetItemText (hTreeItem));
+    strCommand.Printf (wxT("remove %s --version %s"), (const wxChar*) pstrPackage, (const wxChar*) itemText);
+    if (! EvalTclFile (3, strCommand, wxT("Removing package"))) // if not successful
+        return false;
+    
+    treeCtrl->Delete (hTreeItem); // remove the selected item from the tree
+
+    return TRUE;
+}
+
+void ecAdminDialog::ClearPackageTree ()
+{
+    wxTreeCtrl* treeCtrl = (wxTreeCtrl*) FindWindow( ecID_ADMIN_DIALOG_TREE) ;
+
+    wxTreeItemId hPackage = treeCtrl->GetRootItem ();
+    if (! hPackage.IsOk()) // if no packages in the tree...
+        return;     // ...nothing to do
+    
+    while (hPackage.IsOk())
+    {
+        const wxTreeItemId hNextPackage = treeCtrl->GetNextSibling(hPackage);
+        treeCtrl->Delete (hPackage);
+        hPackage = hNextPackage;
+    }
+}
+
+// Trivial handlers; otherwise CdlPackagesDatabaseBody::make asserts.
+static void CdlErrorHandler (std::string message)
+{
+};
+
+static void CdlWarningHandler (std::string message)
+{
+};
+
+
+bool ecAdminDialog::PopulatePackageTree (const wxString& packageDatabase)
+{
+    wxTreeCtrl* treeCtrl = (wxTreeCtrl*) FindWindow( ecID_ADMIN_DIALOG_TREE) ;
+
+    // delete any existing CDL database
+    
+    if (m_CdlPkgData)
+    {
+        delete m_CdlPkgData;
+        m_CdlPkgData = NULL;
+    }
+    
+    // load the package database
+    
+    try
+    {
+        // Cdl asserts unless the handlers are present.
+        m_CdlPkgData = CdlPackagesDatabaseBody::make (ecUtils::UnicodeToStdStr (packageDatabase), &CdlErrorHandler, &CdlWarningHandler);
+    }
+    catch (CdlStringException exception)
+    {
+        wxString strMessage;
+        strMessage.Printf (_("Error loading database:\n\n%s"), (const wxChar*) wxString (exception.get_message ().c_str ()));
+        wxMessageBox(strMessage, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK);
+        return FALSE;
+    }
+    catch (...)
+    {
+        wxMessageBox(_("Error loading database"), (const wxChar*) wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK);
+        return FALSE;
+    }
+    
+    // clear the old package tree
+    
+    ClearPackageTree ();
+    
+    // Add a root item
+    wxTreeItemId rootId = m_treeCtrl->AddRoot(_("Packages"), 0, -1);
+
+    // populate the new package tree
+    
+    const std::vector<std::string>& packages = m_CdlPkgData->get_packages ();
+    for (std::vector<std::string>::const_iterator package = packages.begin (); package != packages.end (); package++)
+    {
+        // add a package node
+        
+        wxTreeItemId hPackage = treeCtrl->AppendItem (treeCtrl->GetRootItem(), wxString (m_CdlPkgData->get_package_aliases (*package) [0].c_str ()));
+        treeCtrl->SetItemData (hPackage, new ecAdminItemData(wxString (package->c_str ())));
+        treeCtrl->SetItemImage (hPackage, 0, wxTreeItemIcon_Normal);
+        treeCtrl->SetItemImage (hPackage, 0, wxTreeItemIcon_Selected);
+        treeCtrl->SetItemImage (hPackage, 0, wxTreeItemIcon_Expanded);
+        treeCtrl->SetItemImage (hPackage, 0, wxTreeItemIcon_SelectedExpanded);
+        
+        const std::vector<std::string>& versions = m_CdlPkgData->get_package_versions (* package);
+        for (std::vector<std::string>::const_iterator version = versions.begin (); version != versions.end (); version++)
+        {
+            // add a version node
+            const wxTreeItemId hVersion = treeCtrl->AppendItem ( hPackage, wxString (version->c_str ()));
+            treeCtrl->SetItemImage (hVersion, 1, wxTreeItemIcon_Normal);
+            treeCtrl->SetItemImage (hVersion, 1, wxTreeItemIcon_Selected);
+            treeCtrl->SetItemImage (hVersion, 1, wxTreeItemIcon_Expanded);
+            treeCtrl->SetItemImage (hVersion, 1, wxTreeItemIcon_SelectedExpanded);
+        }
+        treeCtrl->SortChildren (hPackage); // sort the version nodes
+    }
+    
+    treeCtrl->SortChildren (treeCtrl->GetRootItem()); // sort the package nodes
+    treeCtrl->Expand(treeCtrl->GetRootItem());
+    
+    return TRUE;
+}
+
+
+bool ecAdminDialog::EvalTclFile(int nargc, const wxString& Argv, const wxString& msg)
+{
+    wxProgressDialog dlgWait(msg, _("Please wait..."), 100, this);
+
+    dlgWait.Update(50);
+
+//TRACE (_T("Evaluating ecosadmin.tcl %s\n"), pszArgv);
+
+    // set up the data structure which is passed to the Tcl thread
+
+    wxString strArgc;
+    strArgc.Printf (wxT("%d"), nargc);
+    std::string argv0 = ecUtils::UnicodeToStdStr (m_strRepository) + "/ecosadmin.tcl";
+    std::string argv = ecUtils::UnicodeToStdStr (Argv);
+    std::string argc = ecUtils::UnicodeToStdStr (strArgc);
+
+    Tcl_Interp * interp = Tcl_CreateInterp ();
+
+#ifdef __WXMSW__
+    Tcl_Channel outchan = Tcl_OpenFileChannel (interp, "nul", "a+", 777);
+    Tcl_SetStdChannel (outchan, TCL_STDOUT); // direct standard output to NUL:
+#endif
+
+    const char * pszStatus = Tcl_SetVar (interp, "argv0", (char*) argv0.c_str(), 0);
+    pszStatus = Tcl_SetVar (interp, "argv", (char*) argv.c_str(), 0);
+    pszStatus = Tcl_SetVar (interp, "argc", (char*) argc.c_str(), 0);
+    pszStatus = Tcl_SetVar (interp, "gui_mode", "1", 0); // return errors in result string
+    int nStatus = Tcl_EvalFile (interp, (char*) argv0.c_str());
+    const char* result = Tcl_GetStringResult (interp);
+
+#ifdef __WXMSW__
+    Tcl_SetStdChannel (NULL, TCL_STDOUT);
+    Tcl_UnregisterChannel (interp, outchan);
+#endif
+
+    Tcl_DeleteInterp (interp);
+
+    wxString strErrorMessage (result);
+
+    // report any error
+    if (! strErrorMessage.IsEmpty ())
+    {
+        wxString msg (_("Command execution error:\n\n") + strErrorMessage);
+        wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK);
+       return FALSE;
+    }
+    else if (TCL_OK != nStatus)
+    {
+        wxString msg (_("Command execution error"));
+        wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK);
+    return FALSE;
+    }
+
+    return TRUE;
+}