]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - tools/src/tools/configtool/common/win32/PropertiesList.cpp
Initial revision
[karo-tx-redboot.git] / tools / src / tools / configtool / common / win32 / PropertiesList.cpp
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 }