comparison 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
comparison
equal deleted inserted replaced
75:41bf073c0c32 76:435cced73e2f
1 //####COPYRIGHTBEGIN####
2 //
3 // ----------------------------------------------------------------------------
4 // Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
5 //
6 // This program is part of the eCos host tools.
7 //
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)
11 // any later version.
12 //
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
16 // more details.
17 //
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.
21 //
22 // ----------------------------------------------------------------------------
23 //
24 //####COPYRIGHTEND####
25 // PropertiesView2.cpp : implementation file
26 //
27 //
28 //===========================================================================
29 //#####DESCRIPTIONBEGIN####
30 //
31 // Author(s): sdf
32 // Contact(s): sdf
33 // Date: 1998/08/11
34 // Version: 0.01
35 // Purpose:
36 // Description: This is the implementation of the properties window view.
37 // Requires:
38 // Provides:
39 // See also:
40 // Known bugs:
41 // Usage:
42 //
43 //####DESCRIPTIONEND####
44 //
45 //===========================================================================
46
47 #include "stdafx.h"
48 #include "PropertiesList.h"
49 #include "ConfigToolDoc.h"
50 #include "ConfigItem.H"
51
52 #include "CTUtils.h"
53 #include "ControlView.h"
54 #include "ConfigTool.h"
55
56 #define INCLUDEFILE <string>
57 #include "IncludeSTL.h"
58
59 #ifdef _DEBUG
60 #define new DEBUG_NEW
61 #undef THIS_FILE
62 static char THIS_FILE[] = __FILE__;
63 #endif
64
65
66 // specify the CDL properties which are to be visible in the properties view
67 const std::string CPropertiesList::visible_properties [] =
68 {
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,
78 CdlPropertyId_Define,
79 CdlPropertyId_DefineHeader,
80 CdlPropertyId_DefineProc,
81 // CdlPropertyId_Description,
82 CdlPropertyId_Dialog,
83 // CdlPropertyId_Display,
84 CdlPropertyId_DisplayProc,
85 CdlPropertyId_Doc,
86 CdlPropertyId_EntryProc,
87 CdlPropertyId_Flavor,
88 CdlPropertyId_DefineFormat,
89 CdlPropertyId_Group,
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,
100 CdlPropertyId_Make,
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,
110 CdlPropertyId_Wizard
111 };
112
113 /////////////////////////////////////////////////////////////////////////////
114 // CPropertiesList
115
116 CPropertiesList::CPropertiesList() :
117 m_pti(NULL),
118 m_nFirstProperty(0),
119 m_nOnSizeRecursionCount(0)
120 {
121 m_f[0]=0.25;
122 m_f[1]=0.75;
123 m_GrayPen.CreatePen(PS_SOLID,1,RGB(192,192,192));
124 }
125
126 CPropertiesList::~CPropertiesList()
127 {
128 }
129 //CListCtrl
130
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)
135 ON_WM_CREATE()
136 ON_WM_SIZE()
137 ON_WM_PAINT()
138 ON_NOTIFY_REFLECT(HDN_TRACK, OnTrack)
139 //}}AFX_MSG_MAP
140 END_MESSAGE_MAP()
141
142 const LPCTSTR CPropertiesList::FieldTypeImage[MAXFIELDTYPE]=
143 {_T("Type"), _T("Value"), _T("Default"), _T("Macro"), _T("File"), _T("URL"), _T("Enabled")};
144
145 /////////////////////////////////////////////////////////////////////////////
146 // CPropertiesList message handlers
147
148 void CPropertiesList::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult)
149 {
150
151 // Double-clicked the item
152
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.
155
156 int pos=GetMessagePos();
157 CPoint pt(GET_X_LPARAM(pos),GET_Y_LPARAM(pos));
158 ScreenToClient(&pt);
159 int nItem=HitTest(pt,NULL);
160
161 if(GetItemData(nItem)>1){
162 // This is a property row
163 const CdlGoalExpression goal = dynamic_cast<CdlGoalExpression> ((CdlProperty) GetItemData (nItem));
164 if (goal){
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
168 {
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
173 {
174 CConfigTool::GetControlView()->GetTreeCtrl().SelectItem(pItem->HItem());
175 }
176 }
177 }
178 } else {
179 const CString strText(GetItemText(nItem,0));
180 if(strText==FieldTypeImage[File]){
181 m_pti->ViewHeader();
182 } else if (strText==FieldTypeImage[URL]) {
183 m_pti->ViewURL();
184 }
185 }
186
187 UNUSED_ALWAYS(pResult);
188 UNUSED_ALWAYS(pNMHDR);
189 }
190 void CPropertiesList::OnPaint()
191 {
192 // Default painting
193 Default();
194
195 // Draw the grid
196 int nItems=GetItemCount();
197 if(nItems>0){
198 CDC &dc=*GetDC(); // device context for painting
199 CRect rcHeader;
200 GetHeaderCtrl()->GetClientRect(rcHeader);
201 dc.ExcludeClipRect(rcHeader);
202 CFont *pOldFont=dc.SelectObject(GetFont());
203 CPen *pOldPen=dc.SelectObject(&m_GrayPen);
204
205 CRect rect;
206 GetItemRect(0,rect,LVIR_BOUNDS);
207
208 int cy=rect.top-1;
209 int dy=rect.Height();
210
211 // This prevents the vertical line leaving shadows when column dragging occurs
212 rect.top--;
213 rect.bottom=rect.top+1;
214 dc.FillSolidRect(rect,GetSysColor(COLOR_WINDOW));
215
216 // Vertical line
217 GetItemRect(0,rect,LVIR_LABEL);
218
219 dc.MoveTo(rect.right-1,cy-1);
220 dc.LineTo(rect.right-1,cy+dy*nItems);
221
222 GetClientRect(rect);
223 int cx=rect.Width();
224
225 for(int i=0;i<nItems;i++){
226 cy+=dy;
227 dc.MoveTo(0,cy);
228 dc.LineTo(cx,cy);
229 }
230
231 dc.SelectObject(pOldPen);
232 dc.SelectObject(pOldFont);
233
234 ReleaseDC(&dc);
235 }
236 }
237
238 void CPropertiesList::Fill(CConfigItem *pti)
239 {
240 if(NULL==pti){
241 DeleteAllItems();
242 m_nFirstProperty=0;
243 m_pti=NULL;
244 } else if(pti!=m_pti){
245 m_pti=pti;
246 m_nMaxValueWidth=0;
247 CConfigItem::TreeItemType type=m_pti->Type();
248 int i;
249
250 // Initially flag all items as unnecessary - calls of SetItem or SetProperty will change this
251 for(i=GetItemCount()-1;i>=0;--i){
252 SetItemData(i,0);
253 }
254 if (m_pti->HasBool () || (CConfigItem::None!=type)){
255 SetItem(Macro, m_pti->Macro ());
256 }
257
258 if (m_pti->HasBool ()){
259 SetItem(Enabled,m_pti->IsEnabled() ? _T("True") : _T("False"));
260 }
261
262 if(!m_pti->FileName().IsEmpty()){
263 SetItem(File,m_pti->FileName());
264 }
265 SetItem(URL,m_pti->GetURL());
266
267 if(CConfigItem::None!=type){
268 switch(type){
269 case CConfigItem::String:
270 SetItem(Value,m_pti->StringValue());
271 SetItem(DefaultValue,m_pti->StringDefaultValue());
272 break;
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));
276 break;
277 case CConfigItem::Double:
278 SetItem(Value,CUtils::DoubleToStr(m_pti->DoubleValue()));
279 SetItem(DefaultValue,CUtils::DoubleToStr(m_pti->DoubleDefaultValue()));
280 break;
281 case CConfigItem::Enum:
282 SetItem(Value,m_pti->StringValue());
283 SetItem(DefaultValue,m_pti->StringDefaultValue());
284 break;
285 default:
286 ASSERT(FALSE);
287 break;
288 }
289 SetItem(Type,CConfigItem::TreeItemTypeImage[type]);
290 }
291
292 // List all the properties applicable to me
293 const std::string name = CUtils::UnicodeToStdStr (m_pti->Macro ());
294 if (name.size () > 0)
295 {
296 const CdlConfiguration config = CConfigTool::GetConfigToolDoc ()->GetCdlConfig ();
297 const CdlNode node = config->find_node (name, true);
298 ASSERT (node);
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 ();
311 void *p;
312 if(!map.Lookup(strName,p)){
313 p=0;
314 }
315
316 p=(void *)((int)p+1);
317 map.SetAt(strName,p);
318
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
325 }
326 strPropertyArgs += strArg; // add the argument to the string
327 strPropertyArgs += _T (" "); // separate arguments by a space character
328 }
329 }
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);
333
334 // display the exclamation icon if the property is in a conflicts list
335 bool bConflictItem =
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 );
339 }
340 }
341 }
342
343 for(i=GetItemCount()-1;i>=0;--i){
344 if(0==GetItemData(i)){
345 DeleteItem(i);
346 if(i<m_nFirstProperty){
347 m_nFirstProperty--;
348 }
349 }
350 }
351 CRect rect;
352 GetClientRect(rect);
353 int nAvailWidth=rect.Width()-GetColumnWidth(0);
354 int w=max(m_nMaxValueWidth,nAvailWidth);
355 m_f[1]=double(w)/double(rect.Width());
356 SetColumnWidth(1,w);
357 }
358 }
359
360
361 bool CPropertiesList::PropertyInConflictsList (CdlProperty property, const std::list<CdlConflict> & conflicts)
362 {
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 ())
366 return true;
367
368 return false;
369 }
370
371 // set item text in the properties list control, extending the list if necessary
372 int CPropertiesList::SetItemTextGrow(int nItem, LPCTSTR lpszItem)
373 {
374 while (GetItemCount () < nItem + 1)
375 {
376 int n=InsertItem (GetItemCount (), _T(""));
377 if (-1 == n){
378 return -1;
379 }
380 }
381 return SetItemText (nItem, 0, lpszItem);
382 }
383
384
385 int CPropertiesList::OnCreate(LPCREATESTRUCT lpCreateStruct)
386 {
387 lpCreateStruct->style|=WS_HSCROLL|WS_VSCROLL|LVS_REPORT|LVS_REPORT|LVS_SINGLESEL;
388 if (CListCtrl::OnCreate(lpCreateStruct) == -1)
389 return -1;
390
391 //GetHeaderCtrl()->ModifyStyle(HDS_FULLDRAG,0,0); // remove HDS_FULLDRAG style from header
392
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);
396
397 return 0;
398 }
399
400
401 void CPropertiesList::OnSize(UINT nType, int cx, int cy)
402 {
403 CListCtrl::OnSize(nType, cx, cy);
404 if(0==m_nOnSizeRecursionCount++){//prevent recursion
405 m_fWidth=cx;
406 for(int i=0;i<NCOLS;i++){
407 SetColumnWidth(i,int(cx*m_f[i]));
408 }
409 }
410 m_nOnSizeRecursionCount--;
411 }
412
413 void CPropertiesList::OnEndTrack(NMHEADER *pNMHeader, LRESULT*)
414 {
415 m_f[pNMHeader->iItem]=pNMHeader->pitem->cxy/m_fWidth;
416 }
417
418 void CPropertiesList::OnTrack(NMHEADER*, LRESULT*)
419 {
420 CRect rect;
421 GetItemRect(0,rect,LVIR_BOUNDS);
422 rect.bottom=rect.top+2;
423 InvalidateRect(rect);
424 }
425
426 void CPropertiesList::RefreshValue()
427 {
428 if (m_pti->HasBool ()){
429 SetItem(CPropertiesList::Enabled, m_pti->IsEnabled () ? _T("True") : _T("False"));
430 }
431 if (m_pti->Type () != CConfigItem::None){
432 SetItem(CPropertiesList::Value,m_pti->StringValue());
433 }
434 for (int nItem = m_nFirstProperty; nItem < GetItemCount (); nItem++)
435 {
436 CdlProperty property = (CdlProperty) GetItemData (nItem);
437 ASSERT (property);
438
439 // display the exclamation icon if the property is in a conflicts list
440 const CdlConfiguration config = CConfigTool::GetConfigToolDoc ()->GetCdlConfig ();
441 bool bConflictItem =
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 );
445 }
446
447 }
448
449 int CPropertiesList::SetItem(FieldType f, LPCTSTR pszValue)
450 {
451 int nIndex=SetItem(FieldTypeImage[f],pszValue,m_nFirstProperty);
452 if(nIndex==m_nFirstProperty){
453 m_nFirstProperty++;
454 }
455 SetItemData(nIndex,1);
456 return nIndex;
457 }
458
459 int CPropertiesList::SetItem(LPCTSTR pszItem, LPCTSTR pszValue, int nInsertAs,int nRepeat)
460 {
461 ASSERT(nInsertAs<=GetItemCount());
462 LVFINDINFO info;
463 info.flags =LVFI_STRING;
464 info.psz =pszItem;
465 info.vkDirection=VK_DOWN;
466 int nIndex=-1;
467 do {
468 nIndex=FindItem(&info,nIndex);
469 } while (--nRepeat>0 && nIndex!=-1);
470
471 if(-1==nIndex){
472 nIndex=InsertItem(nInsertAs,pszItem);
473 }
474
475 SetItemText(nIndex,1,pszValue);
476 CDC *pDC=GetDC();
477 CFont *pOldFont=pDC->SelectObject(GetFont());
478 m_nMaxValueWidth=max(m_nMaxValueWidth,pDC->GetTextExtent(pszValue).cx);
479 pDC->SelectObject(pOldFont);
480 ReleaseDC(pDC);
481 return nIndex;
482
483 }