1 //####COPYRIGHTBEGIN####
3 // ----------------------------------------------------------------------------
4 // Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
6 // This program is part of the eCos host tools.
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)
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
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.
22 // ----------------------------------------------------------------------------
24 //####COPYRIGHTEND####
25 // PropertiesView2.cpp : implementation file
28 //===========================================================================
29 //#####DESCRIPTIONBEGIN####
36 // Description: This is the implementation of the properties window view.
43 //####DESCRIPTIONEND####
45 //===========================================================================
48 #include "PropertiesList.h"
49 #include "ConfigToolDoc.h"
50 #include "ConfigItem.H"
53 #include "ControlView.h"
54 #include "ConfigTool.h"
56 #define INCLUDEFILE <string>
57 #include "IncludeSTL.h"
62 static char THIS_FILE[] = __FILE__;
66 // specify the CDL properties which are to be visible in the properties view
67 const std::string CPropertiesList::visible_properties [] =
69 CdlPropertyId_ActiveIf,
70 CdlPropertyId_BuildProc,
71 CdlPropertyId_Calculated,
72 CdlPropertyId_CancelProc,
73 CdlPropertyId_CheckProc,
74 CdlPropertyId_Compile,
75 CdlPropertyId_ConfirmProc,
76 CdlPropertyId_DecorationProc,
77 CdlPropertyId_DefaultValue,
79 CdlPropertyId_DefineHeader,
80 CdlPropertyId_DefineProc,
81 // CdlPropertyId_Description,
83 // CdlPropertyId_Display,
84 CdlPropertyId_DisplayProc,
86 CdlPropertyId_EntryProc,
88 CdlPropertyId_DefineFormat,
90 CdlPropertyId_Hardware,
91 CdlPropertyId_IfDefine,
92 CdlPropertyId_Implements,
93 CdlPropertyId_IncludeDir,
94 CdlPropertyId_IncludeFiles,
95 CdlPropertyId_InitProc,
96 CdlPropertyId_InstallProc,
97 CdlPropertyId_LegalValues,
98 CdlPropertyId_Library,
99 CdlPropertyId_LicenseProc,
101 CdlPropertyId_Makefile,
102 CdlPropertyId_MakeObject,
103 CdlPropertyId_NoDefine,
104 CdlPropertyId_Object,
105 CdlPropertyId_Parent,
106 CdlPropertyId_Requires,
107 CdlPropertyId_Screen,
108 CdlPropertyId_Script,
109 CdlPropertyId_UpdateProc,
113 /////////////////////////////////////////////////////////////////////////////
116 CPropertiesList::CPropertiesList() :
119 m_nOnSizeRecursionCount(0)
123 m_GrayPen.CreatePen(PS_SOLID,1,RGB(192,192,192));
126 CPropertiesList::~CPropertiesList()
131 BEGIN_MESSAGE_MAP(CPropertiesList, CListCtrl)
132 //{{AFX_MSG_MAP(CPropertiesList)
133 ON_NOTIFY(HDN_ENDTRACKW, 0, OnEndTrack)
134 ON_NOTIFY_REFLECT(NM_DBLCLK, OnDblclk)
138 ON_NOTIFY_REFLECT(HDN_TRACK, OnTrack)
142 const LPCTSTR CPropertiesList::FieldTypeImage[MAXFIELDTYPE]=
143 {_T("Type"), _T("Value"), _T("Default"), _T("Macro"), _T("File"), _T("URL"), _T("Enabled")};
145 /////////////////////////////////////////////////////////////////////////////
146 // CPropertiesList message handlers
148 void CPropertiesList::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult)
151 // Double-clicked the item
153 // We do not use the parameters on the OnDblClk handlers in order to preserve compatibility
154 // between pre- and post-4.71 comctrl32.dll versions.
156 int pos=GetMessagePos();
157 CPoint pt(GET_X_LPARAM(pos),GET_Y_LPARAM(pos));
159 int nItem=HitTest(pt,NULL);
161 if(GetItemData(nItem)>1){
162 // This is a property row
163 const CdlGoalExpression goal = dynamic_cast<CdlGoalExpression> ((CdlProperty) GetItemData (nItem));
165 // This is a rule row
166 const CdlExpression expression = goal->get_expression ();
167 if (1 == expression->references.size ()) // if the property contains a single reference
169 // assume that the reference is to another user visible node and try to find it
170 std::string macro_name = expression->references [0].get_destination_name ();
171 CConfigItem * pItem = CConfigTool::GetConfigToolDoc ()->Find (CString (macro_name.c_str ()));
172 if (pItem) // the referenced node was found so select it
174 CConfigTool::GetControlView()->GetTreeCtrl().SelectItem(pItem->HItem());
179 const CString strText(GetItemText(nItem,0));
180 if(strText==FieldTypeImage[File]){
182 } else if (strText==FieldTypeImage[URL]) {
187 UNUSED_ALWAYS(pResult);
188 UNUSED_ALWAYS(pNMHDR);
190 void CPropertiesList::OnPaint()
196 int nItems=GetItemCount();
198 CDC &dc=*GetDC(); // device context for painting
200 GetHeaderCtrl()->GetClientRect(rcHeader);
201 dc.ExcludeClipRect(rcHeader);
202 CFont *pOldFont=dc.SelectObject(GetFont());
203 CPen *pOldPen=dc.SelectObject(&m_GrayPen);
206 GetItemRect(0,rect,LVIR_BOUNDS);
209 int dy=rect.Height();
211 // This prevents the vertical line leaving shadows when column dragging occurs
213 rect.bottom=rect.top+1;
214 dc.FillSolidRect(rect,GetSysColor(COLOR_WINDOW));
217 GetItemRect(0,rect,LVIR_LABEL);
219 dc.MoveTo(rect.right-1,cy-1);
220 dc.LineTo(rect.right-1,cy+dy*nItems);
225 for(int i=0;i<nItems;i++){
231 dc.SelectObject(pOldPen);
232 dc.SelectObject(pOldFont);
238 void CPropertiesList::Fill(CConfigItem *pti)
244 } else if(pti!=m_pti){
247 CConfigItem::TreeItemType type=m_pti->Type();
250 // Initially flag all items as unnecessary - calls of SetItem or SetProperty will change this
251 for(i=GetItemCount()-1;i>=0;--i){
254 if (m_pti->HasBool () || (CConfigItem::None!=type)){
255 SetItem(Macro, m_pti->Macro ());
258 if (m_pti->HasBool ()){
259 SetItem(Enabled,m_pti->IsEnabled() ? _T("True") : _T("False"));
262 if(!m_pti->FileName().IsEmpty()){
263 SetItem(File,m_pti->FileName());
265 SetItem(URL,m_pti->GetURL());
267 if(CConfigItem::None!=type){
269 case CConfigItem::String:
270 SetItem(Value,m_pti->StringValue());
271 SetItem(DefaultValue,m_pti->StringDefaultValue());
273 case CConfigItem::Integer:
274 SetItem(Value,CUtils::IntToStr(m_pti->Value(),CConfigTool::GetConfigToolDoc()->m_bHex));
275 SetItem(DefaultValue,CUtils::IntToStr(m_pti->DefaultValue(),CConfigTool::GetConfigToolDoc()->m_bHex));
277 case CConfigItem::Double:
278 SetItem(Value,CUtils::DoubleToStr(m_pti->DoubleValue()));
279 SetItem(DefaultValue,CUtils::DoubleToStr(m_pti->DoubleDefaultValue()));
281 case CConfigItem::Enum:
282 SetItem(Value,m_pti->StringValue());
283 SetItem(DefaultValue,m_pti->StringDefaultValue());
289 SetItem(Type,CConfigItem::TreeItemTypeImage[type]);
292 // List all the properties applicable to me
293 const std::string name = CUtils::UnicodeToStdStr (m_pti->Macro ());
294 if (name.size () > 0)
296 const CdlConfiguration config = CConfigTool::GetConfigToolDoc ()->GetCdlConfig ();
297 const CdlNode node = config->find_node (name, true);
299 const std::vector<CdlProperty> & properties = node->get_properties ();
300 std::vector<CdlProperty>::const_iterator property_i;
301 CMapStringToPtr map; // count of each property name
302 for (property_i = properties.begin (); property_i != properties.end (); property_i++) {// for each property
303 // get the property name
304 const CdlProperty &prop=*property_i;
305 const CString strName(prop->get_property_name ().c_str());
306 enum {VISIBLE_PROPERTIES_COUNT=sizeof visible_properties/sizeof visible_properties[0]};
307 if (std::find (visible_properties, visible_properties + VISIBLE_PROPERTIES_COUNT, CUtils::UnicodeToStdStr(strName)) != visible_properties + VISIBLE_PROPERTIES_COUNT) {// if the property should be displayed
308 // set the property arguments
309 CString strPropertyArgs;
310 const std::vector<std::string> & argv = prop->get_argv ();
312 if(!map.Lookup(strName,p)){
316 p=(void *)((int)p+1);
317 map.SetAt(strName,p);
319 std::vector<std::string>::const_iterator argv_i;
320 for (argv_i = argv.begin (); argv_i != argv.end (); argv_i++){ // for each property argument...
321 if (argv_i != argv.begin ()){ // ...except the first (the property name)
322 CString strArg(CUtils::StripExtraWhitespace (CString(argv_i->c_str())));
323 if (strPropertyArgs.GetLength () + strArg.GetLength() + 1 > 256) {// if the string is too long for the list control
324 break; // no need to add any further arguments
326 strPropertyArgs += strArg; // add the argument to the string
327 strPropertyArgs += _T (" "); // separate arguments by a space character
330 // the list control appears to display a maximum of 256 characters
331 int nIndex=SetItem(strName,strPropertyArgs,GetItemCount(),(int)p);
332 SetItemData(nIndex,(DWORD)prop);
334 // display the exclamation icon if the property is in a conflicts list
336 // PropertyInConflictsList (* property_i, config->get_structural_conflicts ()) || ignore for now
337 PropertyInConflictsList (prop, config->get_all_conflicts ());
338 CListCtrl::SetItem (nIndex, 0, LVIF_IMAGE, NULL, bConflictItem ? 1 : 0, 0, 0, 0 );
343 for(i=GetItemCount()-1;i>=0;--i){
344 if(0==GetItemData(i)){
346 if(i<m_nFirstProperty){
353 int nAvailWidth=rect.Width()-GetColumnWidth(0);
354 int w=max(m_nMaxValueWidth,nAvailWidth);
355 m_f[1]=double(w)/double(rect.Width());
361 bool CPropertiesList::PropertyInConflictsList (CdlProperty property, const std::list<CdlConflict> & conflicts)
363 std::list<CdlConflict>::const_iterator conf_i;
364 for (conf_i = conflicts.begin (); conf_i != conflicts.end (); conf_i++) // for each conflict
365 if (property == (* conf_i)->get_property ())
371 // set item text in the properties list control, extending the list if necessary
372 int CPropertiesList::SetItemTextGrow(int nItem, LPCTSTR lpszItem)
374 while (GetItemCount () < nItem + 1)
376 int n=InsertItem (GetItemCount (), _T(""));
381 return SetItemText (nItem, 0, lpszItem);
385 int CPropertiesList::OnCreate(LPCREATESTRUCT lpCreateStruct)
387 lpCreateStruct->style|=WS_HSCROLL|WS_VSCROLL|LVS_REPORT|LVS_REPORT|LVS_SINGLESEL;
388 if (CListCtrl::OnCreate(lpCreateStruct) == -1)
391 //GetHeaderCtrl()->ModifyStyle(HDS_FULLDRAG,0,0); // remove HDS_FULLDRAG style from header
393 ListView_SetExtendedListViewStyle(GetSafeHwnd(),/*LVS_EX_GRIDLINES|*/LVS_EX_FULLROWSELECT/*|LVS_EX_ONECLICKACTIVATE*//*|LVS_EX_TRACKSELECT*/);
394 InsertColumn(0,_T("Property"),LVCFMT_LEFT,0,0);
395 InsertColumn(1,_T("Value"),LVCFMT_LEFT,0,1);
401 void CPropertiesList::OnSize(UINT nType, int cx, int cy)
403 CListCtrl::OnSize(nType, cx, cy);
404 if(0==m_nOnSizeRecursionCount++){//prevent recursion
406 for(int i=0;i<NCOLS;i++){
407 SetColumnWidth(i,int(cx*m_f[i]));
410 m_nOnSizeRecursionCount--;
413 void CPropertiesList::OnEndTrack(NMHEADER *pNMHeader, LRESULT*)
415 m_f[pNMHeader->iItem]=pNMHeader->pitem->cxy/m_fWidth;
418 void CPropertiesList::OnTrack(NMHEADER*, LRESULT*)
421 GetItemRect(0,rect,LVIR_BOUNDS);
422 rect.bottom=rect.top+2;
423 InvalidateRect(rect);
426 void CPropertiesList::RefreshValue()
428 if (m_pti->HasBool ()){
429 SetItem(CPropertiesList::Enabled, m_pti->IsEnabled () ? _T("True") : _T("False"));
431 if (m_pti->Type () != CConfigItem::None){
432 SetItem(CPropertiesList::Value,m_pti->StringValue());
434 for (int nItem = m_nFirstProperty; nItem < GetItemCount (); nItem++)
436 CdlProperty property = (CdlProperty) GetItemData (nItem);
439 // display the exclamation icon if the property is in a conflicts list
440 const CdlConfiguration config = CConfigTool::GetConfigToolDoc ()->GetCdlConfig ();
442 // PropertyInConflictsList (property, config->get_structural_conflicts ()) || ignore for now
443 PropertyInConflictsList (property, config->get_all_conflicts ());
444 CListCtrl::SetItem (nItem, 0, LVIF_IMAGE, NULL, bConflictItem ? 1 : 0, 0, 0, 0 );
449 int CPropertiesList::SetItem(FieldType f, LPCTSTR pszValue)
451 int nIndex=SetItem(FieldTypeImage[f],pszValue,m_nFirstProperty);
452 if(nIndex==m_nFirstProperty){
455 SetItemData(nIndex,1);
459 int CPropertiesList::SetItem(LPCTSTR pszItem, LPCTSTR pszValue, int nInsertAs,int nRepeat)
461 ASSERT(nInsertAs<=GetItemCount());
463 info.flags =LVFI_STRING;
465 info.vkDirection=VK_DOWN;
468 nIndex=FindItem(&info,nIndex);
469 } while (--nRepeat>0 && nIndex!=-1);
472 nIndex=InsertItem(nInsertAs,pszItem);
475 SetItemText(nIndex,1,pszValue);
477 CFont *pOldFont=pDC->SelectObject(GetFont());
478 m_nMaxValueWidth=max(m_nMaxValueWidth,pDC->GetTextExtent(pszValue).cx);
479 pDC->SelectObject(pOldFont);