Mercurial > flash_v2
diff host/tools/configtool/common/win32/ConfigItem.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 |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/host/tools/configtool/common/win32/ConfigItem.cpp @@ -0,0 +1,586 @@ +//####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#### +// +//=========================================================================== +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): sdf +// Contact(s): sdf +// Date: 1998/08/11 +// Version: 0.01 +// Purpose: +// Description: This is the implementation of the configuration item class +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== +#include "stdafx.h" +#include "ConfigItem.h" +#include "ControlView.h" +#include "CTUtils.h" +#ifdef PLUGIN + #define INCLUDEFILE "ide.common.h" // for setEditLocation + #include "IncludeSTL.h" + #include "common/CodeCoordinate.h" +#endif +#include "ConfigToolDoc.h" +#include "ConfigTool.h" + +LPCTSTR CConfigItem::TreeItemTypeImage[MaxTreeItemType + 1]={ + _T("None"), _T("Integer"), _T("Enumeration"), _T("String"), _T("Double"), 0}; // Internationalization OK + +const CFileName CConfigItem::FileName() const +{ + CFileName strFile; + const CdlNode node = dynamic_cast<CdlNode> (m_CdlItem); + if (node){ + // get the package which owns the configuration item + const CdlPackage package = GetOwnerPackage(); + if (package){ + + // return the filename of the config header + strFile=CFileName(CConfigTool::GetConfigToolDoc()->InstallTree()+_T("include\\pkgconf"))+package->get_config_header ().c_str (); + } + } + return strFile; +} + +CConfigItem::CConfigItem(CConfigItem *pParent, CdlUserVisible CdlItem): + m_CdlItem(CdlItem) +{ + CTreeCtrl &tree=CConfigTool::GetControlView()->GetTreeCtrl(); + HTREEITEM hParent; + if(NULL==CdlItem){ + // This is the root item + hParent=TVI_ROOT; + m_Type=None; + } else { + hParent=pParent->HItem(); + + // FIXME: re-implement using CdlValuableBody::get_widget_hint() + if (IsPackage()) { + // If a package item, display the package version string + m_Type=String; + } else { + const CdlValuable valuable = dynamic_cast<CdlValuable> (CdlItem); + switch (valuable->get_flavor ()){ + case CdlValueFlavor_None: + case CdlValueFlavor_Bool: + m_Type=None; + break; + case CdlValueFlavor_Data: + case CdlValueFlavor_BoolData: + if (! valuable->has_legal_values ()) { + m_Type=String; + } else if (0 == valuable->get_legal_values ()->ranges.size ()) { + m_Type=Enum; + } else { + CdlListValue list_value; + CdlEvalContext context (NULL, valuable, valuable->get_property (CdlPropertyId_LegalValues)); + valuable->get_legal_values ()->eval (context, list_value); + m_Type=list_value.get_double_ranges ().size () ? Double : Integer; + } + break; + default: + ASSERT (0); // specified flavor not supported + break; + } + } + } + m_hItem=tree.InsertItem(ItemNameOrMacro(),hParent); + tree.SetItemData(m_hItem,(DWORD)this); + CConfigTool::GetControlView()->AdjustItemImage(m_hItem); +} + +CConfigItem::~CConfigItem() +{ +} + +CString CConfigItem::GetURL() const +{ + for(const CConfigItem *pItem=this;pItem;pItem=pItem->Parent()){ + if(pItem->GetCdlItem()){ + CString strURL; + strURL=pItem->GetCdlItem()->get_doc_url().c_str(); + if(strURL.GetLength()){ + return strURL; + } + strURL=pItem->GetCdlItem()->get_doc().c_str(); + if(strURL.GetLength()){ + return strURL; + } + } + } + return _T("ref/ecos-ref.html"); // the default URL +} + +bool CConfigItem::SetValue(LPCTSTR pszValue, CdlTransaction transaction/*=NULL*/) +{ + ASSERT ((m_Type == String) || (m_Type == Enum)); + const CdlValuable valuable = GetCdlValuable(); + ASSERT (valuable); + const std::string str=CUtils::UnicodeToStdStr (pszValue); + if(transaction){ + if (CdlValueFlavor_BoolData == valuable->get_flavor ()){ + // set the user bool to the current bool when changing a booldata + // value to avoid a possible change in the current bool + valuable->set_enabled_and_value (transaction, valuable->is_enabled (), str, CdlValueSource_User); + } else {// CdlValueFlavor_Data + valuable->set_value (transaction, str, CdlValueSource_User); + } + } else { + if (CdlValueFlavor_BoolData == valuable->get_flavor ()){ + // set the user bool to the current bool when changing a booldata + // value to avoid a possible change in the current bool + valuable->set_enabled_and_value (valuable->is_enabled (), str, CdlValueSource_User); + } else {// CdlValueFlavor_Data + valuable->set_value (str, CdlValueSource_User); + } + } + + return true; +} + +bool CConfigItem::SetValue (double dValue, CdlTransaction transaction/*=NULL*/) +{ + ASSERT (m_Type == Double); + const CdlValuable valuable = GetCdlValuable(); + ASSERT (valuable); + + if(transaction) { + if (CdlValueFlavor_BoolData == valuable->get_flavor ()) { + // set the user bool to the current bool when changing a booldata + // value to avoid a possible change in the current bool + valuable->set_enabled_and_value (transaction, valuable->is_enabled (), dValue, CdlValueSource_User); + } else {// CdlValueFlavor_Data + valuable->set_double_value (transaction, dValue, CdlValueSource_User); + } + } else { + if (CdlValueFlavor_BoolData == valuable->get_flavor ()) { + // set the user bool to the current bool when changing a booldata + // value to avoid a possible change in the current bool + valuable->set_enabled_and_value (valuable->is_enabled (), dValue, CdlValueSource_User); + } else {// CdlValueFlavor_Data + valuable->set_double_value (dValue, CdlValueSource_User); + } + } + + return true; +} + +CConfigItem *CConfigItem::FirstRadio() const +{ + ASSERT(HasRadio ()); + + for(CConfigItem *h=Parent()->FirstChild();h;h=h->NextSibling()){ + if(h->HasRadio ()){ + return h; + } + } + // No radio buttons found + ASSERT(false); + return false; +} + +bool CConfigItem::IsEnabled() const +{ + const CdlValuable valuable = GetCdlValuable(); + return NULL==valuable ||valuable->is_enabled(); +} + +bool CConfigItem::SetValue (ItemIntegerType nValue, CdlTransaction transaction/*=NULL*/) +{ + ASSERT (m_Type == Integer); + const CdlValuable valuable = GetCdlValuable(); + ASSERT (valuable); + + if(transaction) { + if (CdlValueFlavor_BoolData == valuable->get_flavor ()) { + // set the user bool to the current bool when changing a booldata + // value to avoid a possible change in the current bool + valuable->set_enabled_and_value (transaction, valuable->is_enabled (), (cdl_int) nValue, CdlValueSource_User); + } else { // CdlValueFlavor_Data + valuable->set_integer_value (transaction, nValue, CdlValueSource_User); + } + } else { + if (CdlValueFlavor_BoolData == valuable->get_flavor ()) { + // set the user bool to the current bool when changing a booldata + // value to avoid a possible change in the current bool + valuable->set_enabled_and_value (valuable->is_enabled (), (cdl_int) nValue, CdlValueSource_User); + } else { // CdlValueFlavor_Data + valuable->set_integer_value (nValue, CdlValueSource_User); + } + } + + return true; +} + +bool CConfigItem::HasModifiedChildren() const +{ + for(CConfigItem *pItem=FirstChild();pItem;pItem=pItem->NextSibling()){ + if(pItem->Modified()||pItem->HasModifiedChildren()){ + return true; + } + } + return false; +} + +ItemIntegerType CConfigItem::Value () const +{ + ASSERT (!IsPackage()); // not a package item + const CdlValuable valuable = GetCdlValuable(); + ASSERT (valuable); + ItemIntegerType nValue (0); + + switch (valuable->get_flavor ()) + { + // case CdlValueFlavor_Bool: + // nValue = valuable->is_enabled (CdlValueSource_Current) ? 1 : 0; + // break; + + case CdlValueFlavor_BoolData: + case CdlValueFlavor_Data: + nValue = (ItemIntegerType) valuable->get_integer_value (CdlValueSource_Current); + break; + + default: + ASSERT (0); // specified flavor not supported + } + + return nValue; +} + +const double CConfigItem::DoubleValue (CdlValueSource source /* = CdlValueSource_Current */ ) const +{ + ASSERT (!IsPackage()); // not a package item + const CdlValuable valuable = GetCdlValuable(); + ASSERT (valuable); + ASSERT (valuable->has_double_value (source)); + return valuable->get_double_value (source); +} + +ItemIntegerType CConfigItem::DefaultValue () const +{ + ItemIntegerType nValue; + return CUtils::StrToItemIntegerType (StringValue (CdlValueSource_Default), nValue) ? nValue : 0; +} + +const CString CConfigItem::StringValue (CdlValueSource source /* = CdlValueSource_Current */ ) const +{ + // ASSERT (!IsPackage()); // not a package item + const CdlValuable valuable = GetCdlValuable(); + ASSERT (valuable); + CString strValue (_T("")); + + switch (valuable->get_flavor ()) + { + case CdlValueFlavor_Data: + case CdlValueFlavor_BoolData: + case CdlValueFlavor_None: // a package + if (m_Type == Integer) + strValue = CUtils::IntToStr (Value (), CConfigTool::GetConfigToolDoc ()->m_bHex); + else if (m_Type == Double) + strValue = CUtils::DoubleToStr (DoubleValue ()); + else + strValue = valuable->get_value (source).c_str (); + break; + + default: + ASSERT (0); // specified flavor not supported + } + + return strValue; +} + +const CString CConfigItem::StringValue(WhereType where) const +{ + CString str; + switch(where){ + case InName: + str=Name(); + break; + case InMacro: + str=Macro(); + break; + case InDesc: + str=Desc(); + break; + case InCurrentValue: + str=CConfigItem::None==Type()?_T(""):StringValue(CdlValueSource_Current); + break; + case InDefaultValue: + str=CConfigItem::None==Type()?_T(""):StringValue(CdlValueSource_Default); + break; + default: + ASSERT(FALSE); + break; + } + return str; +} + +void CConfigItem::DumpItem() +{ + TRACE(_T("Item %08x\n\tDisplay Name='%s'\n\tMacro Name='%s'\n\tType=%s"), + this, Name(), Macro(), TreeItemTypeImage[m_Type]); + TRACE(_T("\n\tValue=%s\n\tURL=%s\n\tParent=%08x"),StringValue(), GetURL(), Parent()); + + TRACE(_T("\n")); +} + +CConfigItem * CConfigItem::NextRadio() const +{ + ASSERT(this->HasRadio ()); + for(CConfigItem *pItem=NextSibling();pItem;pItem=pItem->NextSibling()){ + if(pItem->HasRadio()){ + return pItem; + } + } + return NULL; +} + +bool CConfigItem::Modified () const +{ + const CdlValuable valuable = GetCdlValuable(); + return + valuable // accommodate the root config item which has no CDL item + && !IsPackage() // packages are never modified + && valuable->get_source () != CdlValueSource_Default; +} + +CString CConfigItem::ItemNameOrMacro() const +{ + CConfigToolDoc *pDoc=CConfigTool::GetConfigToolDoc(); + return pDoc->m_bMacroNames&&!Macro().IsEmpty()?Macro():Name(); +} + +bool CConfigItem::IsDescendantOf(CConfigItem * pAncestor) +{ + for(CConfigItem *pItem=Parent();pItem;pItem=pItem->Parent()){ + if(pItem==pAncestor){ + return true; + } + } + return false; +} + +int CConfigItem::EvalEnumStrings (CStringArray &arEnumStrings) const +{ + const CdlValuable valuable = GetCdlValuable(); + ASSERT (valuable); + /* + if (m_Type == Boolean) + { + arEnumStrings.SetSize (2); + arEnumStrings.SetAt (0, _T("True")); + arEnumStrings.SetAt (1, _T("False")); + } + else + */ + { + ASSERT (m_Type == Enum); + CdlListValue list_value; + CdlEvalContext context (NULL, m_CdlItem, m_CdlItem->get_property (CdlPropertyId_LegalValues)); + valuable->get_legal_values ()->eval (context, list_value); + const std::vector<CdlSimpleValue> & table = list_value.get_table (); + + // add legal values to the list + arEnumStrings.SetSize (table.size ()); + for (unsigned int nValue = 0; nValue < table.size (); nValue++) + { + arEnumStrings.SetAt (nValue, table [nValue].get_value ().c_str ()); + } + } + return arEnumStrings.GetSize(); +} + +bool CConfigItem::HasBool() const +{ + if (!m_CdlItem) { + return false; + } else if (IsPackage()) { + return false; + } else { + const CdlValuable valuable = GetCdlValuable(); + CdlValueFlavor flavor = valuable->get_flavor (); + return (flavor == CdlValueFlavor_Bool) || (flavor == CdlValueFlavor_BoolData); + } +} + +bool CConfigItem::HasRadio() const +{ + const CdlValuable valuable = GetCdlValuable(); + if (! valuable) + return false; + + CdlWidgetHint hint; + valuable->get_widget_hint (hint); + return (CdlBoolWidget_Radio == hint.bool_widget); +} + +bool CConfigItem::SetEnabled(bool bEnabled, CdlTransaction current_transaction/*=NULL*/) +{ + const CdlValuable valuable = GetCdlValuable(); + ASSERT (valuable); + + // use a transaction object to ensure that all config items are changed together + CdlTransaction transaction = current_transaction ? current_transaction : CdlTransactionBody::make (CConfigTool::GetConfigToolDoc ()->GetCdlConfig ()); + + if (HasRadio () && bEnabled) { // if a new radio button has been selected + for (CConfigItem *pItem = FirstRadio(); pItem; pItem = pItem->NextRadio ()) { // for each radio button in the group + if (pItem != this) { // if not the newly selected radio button + pItem->SetEnabled (false, transaction); // disable the radio button + } + } + } + + if (CdlValueFlavor_BoolData == valuable->get_flavor ()) { + // set the user value to the current data value when enabling/disabling + // a booldata item to avoid a possible change in the current data value + CdlSimpleValue simple_value = valuable->get_simple_value (); + valuable->set_enabled_and_value (transaction, bEnabled, simple_value, CdlValueSource_User); + } else { // CdlValueFlavor_Bool + valuable->set_enabled (transaction, bEnabled, CdlValueSource_User); + } + + if (! current_transaction) { // if not a recursive call to disable a radio button + transaction->body (); // commit the transaction + deleteZ(transaction); + } + + return true; +} + +bool CConfigItem::ViewHeader() +{ + bool rc=false; + const CFileName strFile(FileName()); + if(!strFile.IsEmpty()){ + CConfigToolDoc *pDoc=CConfigTool::GetConfigToolDoc(); + if(pDoc->BuildTree().IsEmpty()){ + CUtils::MessageBoxF(_T("Cannot display header file until configuration is saved")); + } else { +#ifdef PLUGIN + // Load or activate window and leave + CodeCoordinate loc((LPCTSTR)strFile, 0, 0, CodeCoordinate::FILE_LINE); + rc=AppInstance::getAppManager()->getEditorController()->setEditLocation(loc); +#else + rc=CUtils::Launch(strFile,pDoc->m_strViewer); +#endif + } + } + return rc; +} + +bool CConfigItem::ViewURL() +{ + return CConfigTool::GetConfigToolDoc()->ShowURL(GetURL()); +} + +// Unload (a package) +bool CConfigItem::Unload() +{ + bool rc=false; + CdlPackage package=dynamic_cast<CdlPackage>(GetCdlItem()); + ASSERT(package); + CConfigToolDoc* pDoc=CConfigTool::GetConfigToolDoc(); + // Remove its objects from the view to prevent any painting problems + CConfigTool::GetControlView()->GetTreeCtrl().DeleteItem(HItem()); + for(int nItem=0;nItem<pDoc->ItemCount();nItem++){ + CConfigItem *pItem=pDoc->Item(nItem); + if(package==pItem->GetOwnerPackage()){ + //CConfigTool::GetControlView()->GetTreeCtrl().DeleteItem(pItem->HItem()); + pItem->m_hItem=NULL; // Make sure we can't attempt to paint it + pItem->m_CdlItem=NULL; // Make sure we can't access stale data + } + } + + const CString strMacroName(Macro()); + TRACE (_T("Unloading package %s\n"), strMacroName); + try { + pDoc->GetCdlConfig()->unload_package (package); + rc=true; + } + catch (CdlStringException exception) { + CUtils::MessageBoxF(_T("Error unloading package %s:\n\n%s"), strMacroName, CString (exception.get_message ().c_str ())); + } + catch (...) { + CUtils::MessageBoxF(_T("Error unloading package %s"), strMacroName); + } + m_hItem=NULL; // Make sure we can't attempt to paint it + m_CdlItem=NULL; // Make sure we can't access stale data + return rc; +} + +// Change version (of a package) +bool CConfigItem::ChangeVersion(const CString &strVersion) +{ + bool rc=false; + CdlPackage package=dynamic_cast<CdlPackage>(GetCdlItem()); + ASSERT(package); + const CdlValuable valuable = GetCdlValuable(); + ASSERT (valuable); + const CString strMacroName(Macro()); + if (strVersion != valuable->get_value ().c_str ()) { // if the wrong version is loaded + TRACE (_T("Changing package %s to version '%s'\n"), strMacroName, strVersion); + try { + CConfigTool::GetConfigToolDoc()->GetCdlConfig()->change_package_version (package, CUtils::UnicodeToStdStr (strVersion), CConfigToolDoc::CdlParseErrorHandler, CConfigToolDoc::CdlParseWarningHandler); + rc=true; + } + catch (CdlStringException exception) { + CUtils::MessageBoxF(_T("Error changing package %s to version '%s':\n\n%s"), strMacroName, strVersion, CString (exception.get_message ().c_str ())); + } + catch (...) { + CUtils::MessageBoxF(_T("Error changing package %s to version '%s'"), strMacroName, strVersion); + } + } + return rc; +} + +CConfigItem *CConfigItem::Parent() const +{ + CTreeCtrl &tree=CConfigTool::GetControlView()->GetTreeCtrl(); + HTREEITEM hParent=tree.GetParentItem(HItem()); + return (NULL==hParent||TVI_ROOT==hParent)?NULL:(CConfigItem *)tree.GetItemData(hParent); +} + +CConfigItem *CConfigItem::FirstChild() const +{ + CTreeCtrl &tree=CConfigTool::GetControlView()->GetTreeCtrl(); + HTREEITEM hChild=tree.GetChildItem(HItem()); + return hChild?(CConfigItem *)tree.GetItemData(hChild):NULL; +} + +CConfigItem *CConfigItem::NextSibling() const +{ + CTreeCtrl &tree=CConfigTool::GetControlView()->GetTreeCtrl(); + HTREEITEM hSibling=tree.GetNextSiblingItem(HItem()); + return hSibling?(CConfigItem *)tree.GetItemData(hSibling):NULL; +}
