Mercurial > ecos
diff host/tools/configtool/common/win32/PropertiesList.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 | 74dbf4c3f2e1 |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/host/tools/configtool/common/win32/PropertiesList.cpp @@ -0,0 +1,483 @@ +//####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#### +// PropertiesView2.cpp : implementation file +// +// +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): sdf +// Contact(s): sdf +// Date: 1998/08/11 +// Version: 0.01 +// Purpose: +// Description: This is the implementation of the properties window view. +// Requires: +// Provides: +// See also: +// Known bugs: +// Usage: +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +#include "stdafx.h" +#include "PropertiesList.h" +#include "ConfigToolDoc.h" +#include "ConfigItem.H" + +#include "CTUtils.h" +#include "ControlView.h" +#include "ConfigTool.h" + +#define INCLUDEFILE <string> +#include "IncludeSTL.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + + +// specify the CDL properties which are to be visible in the properties view +const std::string CPropertiesList::visible_properties [] = +{ + CdlPropertyId_ActiveIf, + CdlPropertyId_BuildProc, + CdlPropertyId_Calculated, + CdlPropertyId_CancelProc, + CdlPropertyId_CheckProc, + CdlPropertyId_Compile, + CdlPropertyId_ConfirmProc, + CdlPropertyId_DecorationProc, + CdlPropertyId_DefaultValue, + CdlPropertyId_Define, + CdlPropertyId_DefineHeader, + CdlPropertyId_DefineProc, +// CdlPropertyId_Description, + CdlPropertyId_Dialog, +// CdlPropertyId_Display, + CdlPropertyId_DisplayProc, + CdlPropertyId_Doc, + CdlPropertyId_EntryProc, + CdlPropertyId_Flavor, + CdlPropertyId_DefineFormat, + CdlPropertyId_Group, + CdlPropertyId_Hardware, + CdlPropertyId_IfDefine, + CdlPropertyId_Implements, + CdlPropertyId_IncludeDir, + CdlPropertyId_IncludeFiles, + CdlPropertyId_InitProc, + CdlPropertyId_InstallProc, + CdlPropertyId_LegalValues, + CdlPropertyId_Library, + CdlPropertyId_LicenseProc, + CdlPropertyId_Make, + CdlPropertyId_Makefile, + CdlPropertyId_MakeObject, + CdlPropertyId_NoDefine, + CdlPropertyId_Object, + CdlPropertyId_Parent, + CdlPropertyId_Requires, + CdlPropertyId_Screen, + CdlPropertyId_Script, + CdlPropertyId_UpdateProc, + CdlPropertyId_Wizard +}; + +///////////////////////////////////////////////////////////////////////////// +// CPropertiesList + +CPropertiesList::CPropertiesList() : + m_pti(NULL), + m_nFirstProperty(0), + m_nOnSizeRecursionCount(0) +{ + m_f[0]=0.25; + m_f[1]=0.75; + m_GrayPen.CreatePen(PS_SOLID,1,RGB(192,192,192)); +} + +CPropertiesList::~CPropertiesList() +{ +} +//CListCtrl + +BEGIN_MESSAGE_MAP(CPropertiesList, CListCtrl) + //{{AFX_MSG_MAP(CPropertiesList) + ON_NOTIFY(HDN_ENDTRACKW, 0, OnEndTrack) + ON_NOTIFY_REFLECT(NM_DBLCLK, OnDblclk) + ON_WM_CREATE() + ON_WM_SIZE() + ON_WM_PAINT() + ON_NOTIFY_REFLECT(HDN_TRACK, OnTrack) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +const LPCTSTR CPropertiesList::FieldTypeImage[MAXFIELDTYPE]= + {_T("Type"), _T("Value"), _T("Default"), _T("Macro"), _T("File"), _T("URL"), _T("Enabled")}; + +///////////////////////////////////////////////////////////////////////////// +// CPropertiesList message handlers + +void CPropertiesList::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult) +{ + + // Double-clicked the item + + // We do not use the parameters on the OnDblClk handlers in order to preserve compatibility + // between pre- and post-4.71 comctrl32.dll versions. + + int pos=GetMessagePos(); + CPoint pt(GET_X_LPARAM(pos),GET_Y_LPARAM(pos)); + ScreenToClient(&pt); + int nItem=HitTest(pt,NULL); + + if(GetItemData(nItem)>1){ + // This is a property row + const CdlGoalExpression goal = dynamic_cast<CdlGoalExpression> ((CdlProperty) GetItemData (nItem)); + if (goal){ + // This is a rule row + const CdlExpression expression = goal->get_expression (); + if (1 == expression->references.size ()) // if the property contains a single reference + { + // assume that the reference is to another user visible node and try to find it + std::string macro_name = expression->references [0].get_destination_name (); + CConfigItem * pItem = CConfigTool::GetConfigToolDoc ()->Find (CString (macro_name.c_str ())); + if (pItem) // the referenced node was found so select it + { + CConfigTool::GetControlView()->GetTreeCtrl().SelectItem(pItem->HItem()); + } + } + } + } else { + const CString strText(GetItemText(nItem,0)); + if(strText==FieldTypeImage[File]){ + m_pti->ViewHeader(); + } else if (strText==FieldTypeImage[URL]) { + m_pti->ViewURL(); + } + } + + UNUSED_ALWAYS(pResult); + UNUSED_ALWAYS(pNMHDR); +} +void CPropertiesList::OnPaint() +{ + // Default painting + Default(); + + // Draw the grid + int nItems=GetItemCount(); + if(nItems>0){ + CDC &dc=*GetDC(); // device context for painting + CRect rcHeader; + GetHeaderCtrl()->GetClientRect(rcHeader); + dc.ExcludeClipRect(rcHeader); + CFont *pOldFont=dc.SelectObject(GetFont()); + CPen *pOldPen=dc.SelectObject(&m_GrayPen); + + CRect rect; + GetItemRect(0,rect,LVIR_BOUNDS); + + int cy=rect.top-1; + int dy=rect.Height(); + + // This prevents the vertical line leaving shadows when column dragging occurs + rect.top--; + rect.bottom=rect.top+1; + dc.FillSolidRect(rect,GetSysColor(COLOR_WINDOW)); + + // Vertical line + GetItemRect(0,rect,LVIR_LABEL); + + dc.MoveTo(rect.right-1,cy-1); + dc.LineTo(rect.right-1,cy+dy*nItems); + + GetClientRect(rect); + int cx=rect.Width(); + + for(int i=0;i<nItems;i++){ + cy+=dy; + dc.MoveTo(0,cy); + dc.LineTo(cx,cy); + } + + dc.SelectObject(pOldPen); + dc.SelectObject(pOldFont); + + ReleaseDC(&dc); + } +} + +void CPropertiesList::Fill(CConfigItem *pti) +{ + if(NULL==pti){ + DeleteAllItems(); + m_nFirstProperty=0; + m_pti=NULL; + } else if(pti!=m_pti){ + m_pti=pti; + m_nMaxValueWidth=0; + CConfigItem::TreeItemType type=m_pti->Type(); + int i; + + // Initially flag all items as unnecessary - calls of SetItem or SetProperty will change this + for(i=GetItemCount()-1;i>=0;--i){ + SetItemData(i,0); + } + if (m_pti->HasBool () || (CConfigItem::None!=type)){ + SetItem(Macro, m_pti->Macro ()); + } + + if (m_pti->HasBool ()){ + SetItem(Enabled,m_pti->IsEnabled() ? _T("True") : _T("False")); + } + + if(!m_pti->FileName().IsEmpty()){ + SetItem(File,m_pti->FileName()); + } + SetItem(URL,m_pti->GetURL()); + + if(CConfigItem::None!=type){ + switch(type){ + case CConfigItem::String: + SetItem(Value,m_pti->StringValue()); + SetItem(DefaultValue,m_pti->StringDefaultValue()); + break; + case CConfigItem::Integer: + SetItem(Value,CUtils::IntToStr(m_pti->Value(),CConfigTool::GetConfigToolDoc()->m_bHex)); + SetItem(DefaultValue,CUtils::IntToStr(m_pti->DefaultValue(),CConfigTool::GetConfigToolDoc()->m_bHex)); + break; + case CConfigItem::Double: + SetItem(Value,CUtils::DoubleToStr(m_pti->DoubleValue())); + SetItem(DefaultValue,CUtils::DoubleToStr(m_pti->DoubleDefaultValue())); + break; + case CConfigItem::Enum: + SetItem(Value,m_pti->StringValue()); + SetItem(DefaultValue,m_pti->StringDefaultValue()); + break; + default: + ASSERT(FALSE); + break; + } + SetItem(Type,CConfigItem::TreeItemTypeImage[type]); + } + + // List all the properties applicable to me + const std::string name = CUtils::UnicodeToStdStr (m_pti->Macro ()); + if (name.size () > 0) + { + const CdlConfiguration config = CConfigTool::GetConfigToolDoc ()->GetCdlConfig (); + const CdlNode node = config->find_node (name, true); + ASSERT (node); + const std::vector<CdlProperty> & properties = node->get_properties (); + std::vector<CdlProperty>::const_iterator property_i; + CMapStringToPtr map; // count of each property name + for (property_i = properties.begin (); property_i != properties.end (); property_i++) {// for each property + // get the property name + const CdlProperty &prop=*property_i; + const CString strName(prop->get_property_name ().c_str()); + enum {VISIBLE_PROPERTIES_COUNT=sizeof visible_properties/sizeof visible_properties[0]}; + if (std::find (visible_properties, visible_properties + VISIBLE_PROPERTIES_COUNT, CUtils::UnicodeToStdStr(strName)) != visible_properties + VISIBLE_PROPERTIES_COUNT) {// if the property should be displayed + // set the property arguments + CString strPropertyArgs; + const std::vector<std::string> & argv = prop->get_argv (); + void *p; + if(!map.Lookup(strName,p)){ + p=0; + } + + p=(void *)((int)p+1); + map.SetAt(strName,p); + + std::vector<std::string>::const_iterator argv_i; + for (argv_i = argv.begin (); argv_i != argv.end (); argv_i++){ // for each property argument... + if (argv_i != argv.begin ()){ // ...except the first (the property name) + CString strArg(CUtils::StripExtraWhitespace (CString(argv_i->c_str()))); + if (strPropertyArgs.GetLength () + strArg.GetLength() + 1 > 256) {// if the string is too long for the list control + break; // no need to add any further arguments + } + strPropertyArgs += strArg; // add the argument to the string + strPropertyArgs += _T (" "); // separate arguments by a space character + } + } + // the list control appears to display a maximum of 256 characters + int nIndex=SetItem(strName,strPropertyArgs,GetItemCount(),(int)p); + SetItemData(nIndex,(DWORD)prop); + + // display the exclamation icon if the property is in a conflicts list + bool bConflictItem = + // PropertyInConflictsList (* property_i, config->get_structural_conflicts ()) || ignore for now + PropertyInConflictsList (prop, config->get_all_conflicts ()); + CListCtrl::SetItem (nIndex, 0, LVIF_IMAGE, NULL, bConflictItem ? 1 : 0, 0, 0, 0 ); + } + } + } + + for(i=GetItemCount()-1;i>=0;--i){ + if(0==GetItemData(i)){ + DeleteItem(i); + if(i<m_nFirstProperty){ + m_nFirstProperty--; + } + } + } + CRect rect; + GetClientRect(rect); + int nAvailWidth=rect.Width()-GetColumnWidth(0); + int w=max(m_nMaxValueWidth,nAvailWidth); + m_f[1]=double(w)/double(rect.Width()); + SetColumnWidth(1,w); + } +} + + +bool CPropertiesList::PropertyInConflictsList (CdlProperty property, const std::list<CdlConflict> & conflicts) +{ + std::list<CdlConflict>::const_iterator conf_i; + for (conf_i = conflicts.begin (); conf_i != conflicts.end (); conf_i++) // for each conflict + if (property == (* conf_i)->get_property ()) + return true; + + return false; +} + +// set item text in the properties list control, extending the list if necessary +int CPropertiesList::SetItemTextGrow(int nItem, LPCTSTR lpszItem) +{ + while (GetItemCount () < nItem + 1) + { + int n=InsertItem (GetItemCount (), _T("")); + if (-1 == n){ + return -1; + } + } + return SetItemText (nItem, 0, lpszItem); +} + + +int CPropertiesList::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + lpCreateStruct->style|=WS_HSCROLL|WS_VSCROLL|LVS_REPORT|LVS_REPORT|LVS_SINGLESEL; + if (CListCtrl::OnCreate(lpCreateStruct) == -1) + return -1; + + //GetHeaderCtrl()->ModifyStyle(HDS_FULLDRAG,0,0); // remove HDS_FULLDRAG style from header + + ListView_SetExtendedListViewStyle(GetSafeHwnd(),/*LVS_EX_GRIDLINES|*/LVS_EX_FULLROWSELECT/*|LVS_EX_ONECLICKACTIVATE*//*|LVS_EX_TRACKSELECT*/); + InsertColumn(0,_T("Property"),LVCFMT_LEFT,0,0); + InsertColumn(1,_T("Value"),LVCFMT_LEFT,0,1); + + return 0; +} + + +void CPropertiesList::OnSize(UINT nType, int cx, int cy) +{ + CListCtrl::OnSize(nType, cx, cy); + if(0==m_nOnSizeRecursionCount++){//prevent recursion + m_fWidth=cx; + for(int i=0;i<NCOLS;i++){ + SetColumnWidth(i,int(cx*m_f[i])); + } + } + m_nOnSizeRecursionCount--; +} + +void CPropertiesList::OnEndTrack(NMHEADER *pNMHeader, LRESULT*) +{ + m_f[pNMHeader->iItem]=pNMHeader->pitem->cxy/m_fWidth; +} + +void CPropertiesList::OnTrack(NMHEADER*, LRESULT*) +{ + CRect rect; + GetItemRect(0,rect,LVIR_BOUNDS); + rect.bottom=rect.top+2; + InvalidateRect(rect); +} + +void CPropertiesList::RefreshValue() +{ + if (m_pti->HasBool ()){ + SetItem(CPropertiesList::Enabled, m_pti->IsEnabled () ? _T("True") : _T("False")); + } + if (m_pti->Type () != CConfigItem::None){ + SetItem(CPropertiesList::Value,m_pti->StringValue()); + } + for (int nItem = m_nFirstProperty; nItem < GetItemCount (); nItem++) + { + CdlProperty property = (CdlProperty) GetItemData (nItem); + ASSERT (property); + + // display the exclamation icon if the property is in a conflicts list + const CdlConfiguration config = CConfigTool::GetConfigToolDoc ()->GetCdlConfig (); + bool bConflictItem = +// PropertyInConflictsList (property, config->get_structural_conflicts ()) || ignore for now + PropertyInConflictsList (property, config->get_all_conflicts ()); + CListCtrl::SetItem (nItem, 0, LVIF_IMAGE, NULL, bConflictItem ? 1 : 0, 0, 0, 0 ); + } + +} + +int CPropertiesList::SetItem(FieldType f, LPCTSTR pszValue) +{ + int nIndex=SetItem(FieldTypeImage[f],pszValue,m_nFirstProperty); + if(nIndex==m_nFirstProperty){ + m_nFirstProperty++; + } + SetItemData(nIndex,1); + return nIndex; +} + +int CPropertiesList::SetItem(LPCTSTR pszItem, LPCTSTR pszValue, int nInsertAs,int nRepeat) +{ + ASSERT(nInsertAs<=GetItemCount()); + LVFINDINFO info; + info.flags =LVFI_STRING; + info.psz =pszItem; + info.vkDirection=VK_DOWN; + int nIndex=-1; + do { + nIndex=FindItem(&info,nIndex); + } while (--nRepeat>0 && nIndex!=-1); + + if(-1==nIndex){ + nIndex=InsertItem(nInsertAs,pszItem); + } + + SetItemText(nIndex,1,pszValue); + CDC *pDC=GetDC(); + CFont *pOldFont=pDC->SelectObject(GetFont()); + m_nMaxValueWidth=max(m_nMaxValueWidth,pDC->GetTextExtent(pszValue).cx); + pDC->SelectObject(pOldFont); + ReleaseDC(pDC); + return nIndex; + +}
