Mercurial > flash_v2
diff host/tools/pkgadmin/win32/PkgAdminDlg.cpp @ 76:435cced73e2f ecos-v1_3_1-release
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
| author | jlarmour |
|---|---|
| date | Tue, 28 Mar 2000 14:10:45 +0000 |
| parents | |
| children | d397fc472bcf |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/host/tools/pkgadmin/win32/PkgAdminDlg.cpp @@ -0,0 +1,604 @@ +//####COPYRIGHTBEGIN#### +// +// ---------------------------------------------------------------------------- +// Copyright (C) 1998, 1999, 2000 Red Hat, Inc. +// +// 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#### +// PkgAdminDlg.cpp : implementation file +// + +#include "stdafx.h" + +#include "PkgAdmin.h" +#include "PkgAdminDlg.h" +#include "PkgAdminLicenseDlg.h" +#include "PkgAdminTclWaitDlg.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CPkgadminAboutDlg dialog used for App About + +class CPkgadminAboutDlg : public CDialog +{ +public: + CPkgadminAboutDlg(); + +// Dialog Data + //{{AFX_DATA(CPkgadminAboutDlg) + enum { IDD = IDD_PKGADMIN_ABOUTBOX }; + //}}AFX_DATA + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CPkgadminAboutDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + //{{AFX_MSG(CPkgadminAboutDlg) + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +CPkgadminAboutDlg::CPkgadminAboutDlg() : CDialog(CPkgadminAboutDlg::IDD) +{ + //{{AFX_DATA_INIT(CPkgadminAboutDlg) + //}}AFX_DATA_INIT +} + +void CPkgadminAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CPkgadminAboutDlg) + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CPkgadminAboutDlg, CDialog) + //{{AFX_MSG_MAP(CPkgadminAboutDlg) + // No message handlers + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CPkgAdminDlg dialog + +CPkgAdminDlg::CPkgAdminDlg(LPCTSTR pszRepository,LPCTSTR pszUserTools) + : CeCosDialog(CPkgAdminDlg::IDD, NULL) +{ + //{{AFX_DATA_INIT(CPkgAdminDlg) + // NOTE: the ClassWizard will add member initialization here + //}}AFX_DATA_INIT + // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 + if(pszRepository){ + m_strRepository=pszRepository; + } + if(pszUserTools){ + m_strUserTools=pszUserTools; + } + m_CdlPkgData = NULL; +} + +void CPkgAdminDlg::DoDataExchange(CDataExchange* pDX) +{ + CeCosDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CPkgAdminDlg) + DDX_Control(pDX, IDC_PKGADMIN_REMOVE, m_btnRemove); + DDX_Control(pDX, IDC_PKGADMIN_TREE, m_ctrlPackageTree); + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CPkgAdminDlg, CeCosDialog) + //{{AFX_MSG_MAP(CPkgAdminDlg) + ON_WM_SYSCOMMAND() + ON_WM_PAINT() + ON_WM_QUERYDRAGICON() + ON_BN_CLICKED(IDC_PKGADMIN_REMOVE, OnPkgadminRemove) + ON_WM_DESTROY() + ON_BN_CLICKED(IDC_PKGADMIN_ADD, OnPkgadminAdd) + ON_BN_CLICKED(IDCLOSE, OnClose) + ON_BN_CLICKED(IDC_PKGADMIN_REPOSITORY, OnPkgadminRepository) + ON_NOTIFY(TVN_SELCHANGED, IDC_PKGADMIN_TREE, OnSelchangedPkgadminTree) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CPkgAdminDlg message handlers + +BOOL CPkgAdminDlg::OnInitDialog() +{ + CeCosDialog::OnInitDialog(); + + if(this==AfxGetApp()->m_pMainWnd){ // only if the dialog is the application + // Add "About..." menu item to system menu. + + // IDM_ABOUTBOX must be in the system command range. + ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); + ASSERT(IDM_ABOUTBOX < 0xF000); + + CMenu* pSysMenu = GetSystemMenu(FALSE); + if (pSysMenu != NULL) + { + CString strAboutMenu; + strAboutMenu.LoadString(IDS_ABOUTBOX); + if (!strAboutMenu.IsEmpty()) + { + pSysMenu->AppendMenu(MF_SEPARATOR); + pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); + } + } + + // Set the icon for this dialog. The framework does this automatically + // when the application's main window is not a dialog + SetIcon(m_hIcon, TRUE); // Set big icon + + // The following AppWizard-generated call was causing the 32x32 icon to + // be resized for use as a 16x16 icon. Removing the call causes the + // correct 16x16 icon to be displayed. +// SetIcon(m_hIcon, FALSE); // Set small icon + + // TODO: Add extra initialization here + + // setup the repsoitory location + + if (m_strRepository.IsEmpty()) // if the repository cannot be located + { + OnPkgadminRepository (); // prompt the user for the repository location + if (m_strRepository.IsEmpty ()) + { + PostMessage (WM_COMMAND,IDCANCEL); + return TRUE; + } + } + } else { + GetDlgItem(IDC_PKGADMIN_REPOSITORY)->ShowWindow(SW_HIDE); + } + + // setup the path to the user tools (tar and gunzip) + + if ((! m_strUserTools.IsEmpty()) || FindUserToolsPath ()) // if the user tools can be located + { + // add the user tools to the PATH environment variable + const DWORD nLength = GetEnvironmentVariable (_T("PATH"), NULL, 0) + 1; + TCHAR * pszOldPath = new TCHAR [nLength]; + GetEnvironmentVariable (_T("PATH"), pszOldPath, nLength); + SetEnvironmentVariable (_T("PATH"), CString (pszOldPath) + _T(";") + m_strUserTools); + delete [] pszOldPath; + } + + // setup the package tree image list + + m_ilTreeIcons.Create (IDB_PKGADMIN_TREEICONS, 16, 1, RGB (0,128,128)); + m_ctrlPackageTree.SetImageList (&m_ilTreeIcons, TVSIL_NORMAL); + + // populate the package tree + + while (! PopulatePackageTree (m_strRepository)) + { + m_strRepository = _T(""); + OnPkgadminRepository (); // prompt the user for the repository location + if (m_strRepository.IsEmpty ()) // if dialog was cancelled + { + PostQuitMessage (1); + return TRUE; + } + } + + return TRUE; // return TRUE unless you set the focus to a control +} + +void CPkgAdminDlg::OnSysCommand(UINT nID, LPARAM lParam) +{ + if ((nID & 0xFFF0) == IDM_ABOUTBOX) + { + CPkgadminAboutDlg dlgAbout; + dlgAbout.DoModal(); + } + else + { + CeCosDialog::OnSysCommand(nID, lParam); + } +} + +// If you add a minimize button to your dialog, you will need the code below +// to draw the icon. For MFC applications using the document/view model, +// this is automatically done for you by the framework. + +void CPkgAdminDlg::OnPaint() +{ + if (IsIconic()) + { + CPaintDC dc(this); // device context for painting + + SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); + + // Center icon in client rectangle + int cxIcon = GetSystemMetrics(SM_CXICON); + int cyIcon = GetSystemMetrics(SM_CYICON); + CRect rect; + GetClientRect(&rect); + int x = (rect.Width() - cxIcon + 1) / 2; + int y = (rect.Height() - cyIcon + 1) / 2; + + // Draw the icon + dc.DrawIcon(x, y, m_hIcon); + } + else + { + CeCosDialog::OnPaint(); + } +} + +// The system calls this to obtain the cursor to display while the user drags +// the minimized window. +HCURSOR CPkgAdminDlg::OnQueryDragIcon() +{ + return (HCURSOR) m_hIcon; +} + +bool CPkgAdminDlg::PopulatePackageTree(LPCTSTR pszPackagesPath) +{ + // delete any existing CDL database + + if (m_CdlPkgData) + { + delete m_CdlPkgData; + m_CdlPkgData = NULL; + } + + // load the package database + + try + { + m_CdlPkgData = CdlPackagesDatabaseBody::make (UnicodeToStdStr (pszPackagesPath)); + } + catch (CdlStringException exception) + { + CString strMessage; + strMessage.Format (_T("Error loading database:\n\n%s"), CString (exception.get_message ().c_str ())); + AfxMessageBox (strMessage); + return false; + } + catch (...) + { + AfxMessageBox (_T("Error loading database")); + return false; + } + + // clear the old package tree + + ClearPackageTree (); + + // 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 + + TRACE (_T("Adding package %s:"), CString (package->c_str ())); + HTREEITEM hPackage = m_ctrlPackageTree.InsertItem (CString (m_CdlPkgData->get_package_aliases (*package) [0].c_str ())); + m_ctrlPackageTree.SetItemData (hPackage, (DWORD) new CString (package->c_str ())); + m_ctrlPackageTree.SetItemImage (hPackage, 0, 0); + + 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 + + TRACE (_T(" %s"), CString (version->c_str ())); + const HTREEITEM hVersion = m_ctrlPackageTree.InsertItem (CString (version->c_str ()), hPackage); + m_ctrlPackageTree.SetItemImage (hVersion, 1, 1); + } + TRACE (_T("\n")); + m_ctrlPackageTree.SortChildren (hPackage); // sort the version nodes + } + + m_ctrlPackageTree.SortChildren (NULL); // sort the package nodes + + if(this==AfxGetApp()->m_pMainWnd){ // if the dialog is the application + // update the caption bar + CString strCaption (m_strRepository); + strCaption.Replace (_TCHAR('/'), _TCHAR('\\')); + strCaption += _T(" - eCos Package Administration Tool"); + SetWindowText (strCaption); + } + + return true; +} + +void CPkgAdminDlg::OnPkgadminRemove() +{ + const HTREEITEM hTreeItem = m_ctrlPackageTree.GetSelectedItem (); + if (! hTreeItem) + return; + + if (IDYES != CWnd::MessageBox (_T("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?"), + _T("Remove Package"), MB_YESNO | MB_ICONEXCLAMATION)) + return; + + const CString * pstrPackage = (const CString *) m_ctrlPackageTree.GetItemData (hTreeItem); + if (pstrPackage) // if a package node is selected + { + // remove all package version nodes + + bool bStatus = true; + HTREEITEM hChildItem = m_ctrlPackageTree.GetChildItem (hTreeItem); + while (hChildItem && bStatus) + { + const HTREEITEM hNextChildItem = m_ctrlPackageTree.GetNextSiblingItem (hChildItem); + bStatus = RemovePackageVersion (hChildItem); + hChildItem = hNextChildItem; + } + + // remove the package node + + if (bStatus) + { + delete pstrPackage; + m_ctrlPackageTree.DeleteItem (hTreeItem); + } + } + else // a version node is selected + { + // remove the version node + + const HTREEITEM hParentItem = m_ctrlPackageTree.GetParentItem (hTreeItem); + ASSERT (hParentItem); + if (RemovePackageVersion (hTreeItem) && ! m_ctrlPackageTree.ItemHasChildren (hParentItem)) // if the only version was deleted + { + // remove the package node + + delete pstrPackage; + m_ctrlPackageTree.DeleteItem (hParentItem); + } + } +} + +void CPkgAdminDlg::ClearPackageTree() +{ + HTREEITEM hPackage = m_ctrlPackageTree.GetRootItem (); + if (! hPackage) // if no packages in the tree... + return; // ...nothing to do + + while (hPackage) + { + const HTREEITEM hNextPackage = m_ctrlPackageTree.GetNextSiblingItem (hPackage); + TRACE (_T("Deleting package %s\n"), * ((CString *) m_ctrlPackageTree.GetItemData (hPackage))); + delete (CString *) m_ctrlPackageTree.GetItemData (hPackage); + m_ctrlPackageTree.DeleteItem (hPackage); + hPackage = hNextPackage; + } +} + +void CPkgAdminDlg::OnDestroy() +{ + CeCosDialog::OnDestroy(); + + // free memory allocated to the tree item data CStrings + + ClearPackageTree (); + + // free memory allocated to the CDL database + + if (m_CdlPkgData) + delete m_CdlPkgData; + +} + +void CPkgAdminDlg::OnPkgadminAdd() +{ + CFileDialog dlg (TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_ALLOWMULTISELECT, _T("eCos Package Files (*.epk)|*.epk||"), GetParent ()); + TCHAR szBuffer [MAX_PATH * 16] = _T(""); + dlg.m_ofn.lpstrFile = szBuffer; + dlg.m_ofn.nMaxFile = MAX_PATH * 16; + dlg.m_ofn.lpstrTitle = _T("Open eCos Package Files"); + if (IDOK == dlg.DoModal ()) + { + bool bRepositoryChanged = false; + POSITION posPathName = dlg.GetStartPosition (); + while (posPathName) + { + // get an eCos package distribution file + + CString strPathName = dlg.GetNextPathName (posPathName); + + // extract the licence file + + CString strCommand; + strCommand.Format (_T("add %s --extract_license"), strPathName); + strCommand.Replace (_TCHAR('\\'), _TCHAR('/')); // backslashes -> forward slashes for Tcl_EvalFile + EvalTclFile (3, strCommand); + CString strLicenseFile = m_strRepository + _T("/pkgadd.txt"); + strLicenseFile.Replace (_TCHAR('/'), _TCHAR('\\')); // forward slashes -> backslashes for Win32 + + // read the license file + + CFile fileLicenseFile; + if (fileLicenseFile.Open (strLicenseFile, CFile::modeRead)) + { + TRACE (_T("License file found at %s\n"), strLicenseFile); + const DWORD dwLicenseLength = fileLicenseFile.GetLength (); + char * pszBuffer = new char [dwLicenseLength + 1]; // allocate a buffer + fileLicenseFile.Read (pszBuffer, dwLicenseLength); + fileLicenseFile.Close (); + CFile::Remove (strLicenseFile); // delete the license file when read + pszBuffer [dwLicenseLength] = NULL; // terminate the string in the buffer + CString strLicenseText (pszBuffer); // copy into a CString to convert to Unicode + delete [] pszBuffer; + if (-1 == strLicenseText.Find (_T("\r\n"))) // if the file has LF line endings... + strLicenseText.Replace (_T("\n"), _T("\r\n")); // ... replace with CRLF line endings + + // display the license text + + CPkgAdminLicenseDlg dlgLicense (this); + dlgLicense.m_strLicense = strLicenseText; + dlgLicense.SetCaption (strPathName + _T(" - Add Packages")); + if (IDOK != dlgLicense.DoModal ()) // if license not accepted by user + continue; // try the next file + } + + // add the contents of the package distribution file + + strCommand.Format (_T("add %s --accept_license"), strPathName); + strCommand.Replace (_TCHAR('\\'), _TCHAR('/')); // backslashes -> forward slashes for Tcl_EvalFile + if (! EvalTclFile (3, strCommand)) // if not successful + continue; // try the next file + + bRepositoryChanged = true; + } + + // refresh the package tree only if necessary + + if (bRepositoryChanged && ! PopulatePackageTree (m_strRepository)) + DestroyWindow (); + } +} + +bool CPkgAdminDlg::EvalTclFile(int nArgc, LPCTSTR pszArgv) +{ + CPkgAdminTclWaitDlg dlgWait; + + TRACE (_T("Evaluating ecosadmin.tcl %s\n"), pszArgv); + + // set up the data structure which is passed to the Tcl thread + + CString strArgc; + strArgc.Format (_T("%d"), nArgc); + std::string argv0 = UnicodeToStdStr (m_strRepository) + "/ecosadmin.tcl"; + std::string argv = UnicodeToStdStr (pszArgv); + std::string argc = UnicodeToStdStr (strArgc); + dlgWait.etsInfo.argv0 = (char *) argv0.c_str (); + dlgWait.etsInfo.argv = (char *) argv.c_str (); + dlgWait.etsInfo.argc = (char *) argc.c_str (); + + // display the 'please wait' dialog + // the Tcl command is invoked from CPkgAdminTclWaitDlg::OnCreate() + + CWaitCursor curWait; + dlgWait.DoModal (); + curWait.Restore (); + + // retrieve status information from the data structure + + int nStatus = dlgWait.etsInfo.status; + CString strErrorMessage (dlgWait.etsInfo.result); + + // report any error + + if (! strErrorMessage.IsEmpty ()) + { + AfxMessageBox (_T("Command execution error:\n\n") + strErrorMessage); + return false; + } + else if (TCL_OK != nStatus) + { + AfxMessageBox (_T("Command execution error")); + return false; + } + + return true; +} + +bool CPkgAdminDlg::RemovePackageVersion(HTREEITEM hTreeItem) +{ + const HTREEITEM hParentItem = m_ctrlPackageTree.GetParentItem (hTreeItem); + ASSERT (hParentItem); + CString * pstrPackage = (CString *) m_ctrlPackageTree.GetItemData (hParentItem); + ASSERT (pstrPackage); + CString strCommand; + strCommand.Format (_T("remove %s --version %s"), * pstrPackage, m_ctrlPackageTree.GetItemText (hTreeItem)); + if (! EvalTclFile (3, strCommand)) // if not successful + return false; + + m_ctrlPackageTree.DeleteItem (hTreeItem); // remove the selected item from the tree + return true; +} + +void CPkgAdminDlg::OnPkgadminRepository() +{ + CFileDialog dlg (TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, _T("eCos Package Database Files (ecos.db)|ecos.db||"), GetParent ()); + dlg.m_ofn.lpstrTitle = _T("Open eCos Package Database File"); + + int nStatus; + do + { + nStatus = dlg.DoModal (); + if (IDOK == nStatus) + { + const CString strPathName = dlg.GetPathName (); + const int nPathNameIndex = strPathName.ReverseFind (_TCHAR('\\')); + ASSERT (nPathNameIndex != -1); + m_strRepository = strPathName.Mid (0, nPathNameIndex); + m_strRepository.Replace (_TCHAR('\\'), _TCHAR('/')); + } + } + while ((IDOK == nStatus) && ! PopulatePackageTree (m_strRepository)); +} + +void CPkgAdminDlg::OnSelchangedPkgadminTree(NMHDR*, LRESULT* pResult) +{ + //NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; + + // enable the remove button only if a node is selected + m_btnRemove.EnableWindow (NULL != m_ctrlPackageTree.GetSelectedItem ()); + + *pResult = 0; +} + +std::string CPkgAdminDlg::UnicodeToStdStr(LPCTSTR str) +{ + int nLength = 1 + _tcslen (str); + char * pszString = new char [nLength]; + + #ifdef _UNICODE + WideCharToMultiByte (CP_ACP, 0, str, -1, pszString, nLength, NULL, NULL); + #else + strcpy (pszString, str); + #endif + + std::string stdstr = std::string (pszString); + delete [] pszString; + return stdstr; +} + +bool CPkgAdminDlg::FindUserToolsPath() +{ + HKEY hKey; + if (ERROR_SUCCESS != RegOpenKeyEx (HKEY_CURRENT_USER, _T("Software\\Red Hat\\eCos\\Configuration Tool\\User Tools"), 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 (); +}
