]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - tools/src/tools/configtool/standalone/wxwin/propertywin.cpp
unified MX27, MX25, MX37 trees
[karo-tx-redboot.git] / tools / src / tools / configtool / standalone / wxwin / propertywin.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 // propertywin.cpp :
26 //
27 //===========================================================================
28 //#####DESCRIPTIONBEGIN####
29 //
30 // Author(s):   julians
31 // Contact(s):  julians
32 // Date:        2000/09/04
33 // Version:     $Id$
34 // Purpose:
35 // Description: Implementation file for ecPropertyListCtrl
36 // Requires:
37 // Provides:
38 // See also:
39 // Known bugs:
40 // Usage:
41 //
42 //####DESCRIPTIONEND####
43 //
44 //===========================================================================
45
46 // ============================================================================
47 // declarations
48 // ============================================================================
49
50 // ----------------------------------------------------------------------------
51 // headers
52 // ----------------------------------------------------------------------------
53 #ifdef __GNUG__
54     #pragma implementation "propertywin.h"
55 #endif
56
57 // Includes other headers for precompiled compilation
58 #include "ecpch.h"
59
60 #ifdef __BORLANDC__
61     #pragma hdrstop
62 #endif
63
64 #include "propertywin.h"
65 #include "configtool.h"
66 #include "configitem.h"
67 #include "configtooldoc.h"
68 #include "ecutils.h"
69
70 // specify the CDL properties which are to be visible in the properties view
71 const std::string ecPropertyListCtrl::visible_properties [] =
72 {
73         CdlPropertyId_ActiveIf,
74         CdlPropertyId_BuildProc,
75         CdlPropertyId_Calculated,
76         CdlPropertyId_CancelProc,
77         CdlPropertyId_CheckProc,
78         CdlPropertyId_Compile,
79         CdlPropertyId_ConfirmProc,
80         CdlPropertyId_DecorationProc,
81         CdlPropertyId_DefaultValue,
82         CdlPropertyId_Define,
83         CdlPropertyId_DefineHeader,
84         CdlPropertyId_DefineProc,
85 //      CdlPropertyId_Description,
86         CdlPropertyId_Dialog,
87 //      CdlPropertyId_Display,
88         CdlPropertyId_DisplayProc,
89         CdlPropertyId_Doc,
90         CdlPropertyId_EntryProc,
91         CdlPropertyId_Flavor,
92         CdlPropertyId_DefineFormat,
93         CdlPropertyId_Group,
94         CdlPropertyId_Hardware,
95         CdlPropertyId_IfDefine,
96         CdlPropertyId_Implements,
97         CdlPropertyId_IncludeDir,
98         CdlPropertyId_IncludeFiles,
99         CdlPropertyId_InitProc,
100         CdlPropertyId_InstallProc,
101         CdlPropertyId_LegalValues,
102         CdlPropertyId_Library,
103         CdlPropertyId_LicenseProc,
104         CdlPropertyId_Make,
105         CdlPropertyId_Makefile,
106         CdlPropertyId_MakeObject,
107         CdlPropertyId_NoDefine,
108         CdlPropertyId_Object,
109         CdlPropertyId_Parent,
110         CdlPropertyId_Requires,
111         CdlPropertyId_Screen,
112         CdlPropertyId_Script,
113         CdlPropertyId_UpdateProc,
114         CdlPropertyId_Wizard
115 };
116
117 const wxChar* ecPropertyListCtrl::sm_fieldTypeImage[ecMAXFIELDTYPE]=
118         {wxT("Type"), wxT("Value"), wxT("Default"), wxT("Macro"), wxT("File"), wxT("URL"), wxT("Enabled")};
119
120
121 /*
122  * ecPropertyListCtrl
123  */
124
125 IMPLEMENT_CLASS(ecPropertyListCtrl, wxListCtrl)
126
127 BEGIN_EVENT_TABLE(ecPropertyListCtrl, wxListCtrl)
128     EVT_RIGHT_DOWN(ecPropertyListCtrl::OnRightClick)
129     EVT_LEFT_DCLICK(ecPropertyListCtrl::OnDoubleClick)
130 END_EVENT_TABLE()
131
132 ecPropertyListCtrl::ecPropertyListCtrl(wxWindow* parent, wxWindowID id, const wxPoint& pt,
133         const wxSize& sz, long style):
134         wxListCtrl(parent, id, pt, sz, style)
135 {
136     if (!wxGetApp().GetSettings().GetWindowSettings().GetUseDefaults() &&
137          wxGetApp().GetSettings().GetWindowSettings().GetFont(wxT("Properties")).Ok())
138     {
139         SetFont(wxGetApp().GetSettings().GetWindowSettings().GetFont(wxT("Properties")));
140     }
141
142     m_f[0]=0.25;
143     m_f[1]=0.75;
144     m_pti = NULL;
145     m_nFirstProperty = 0;
146     m_nOnSizeRecursionCount = 0;
147
148     AddColumns();
149
150 #if 0
151     int j;
152     int i = 0;
153     for (j = 0; j < 4; j++)
154     {
155         
156         // Insert some dummy items
157         
158         wxListItem info;
159         info.m_text = _("URL");
160         info.m_mask = wxLIST_MASK_TEXT ; // | wxLIST_MASK_IMAGE | wxLIST_MASK_DATA;
161         info.m_itemId = i;
162         info.m_image = -1;
163         //info.m_data = (long) doc;
164         
165         long item = InsertItem(info);
166         
167         SetItem(i, 1, _("redirects/interrupts.html"));   
168         i ++;
169         
170         info.m_text = _("Enabled");
171         info.m_mask = wxLIST_MASK_TEXT ; // | wxLIST_MASK_IMAGE | wxLIST_MASK_DATA;
172         info.m_itemId = i;
173         info.m_image = -1;
174         //info.m_data = (long) doc;
175         
176         item = InsertItem(info);
177         
178         SetItem(i, 1, _("True"));
179         i ++;
180     }
181 #endif
182
183 }
184
185 void ecPropertyListCtrl::OnRightClick(wxMouseEvent& event)
186 {
187     PopupMenu(wxGetApp().GetWhatsThisMenu(), event.GetX(), event.GetY());
188 }
189
190 void ecPropertyListCtrl::AddColumns()
191 {
192     InsertColumn(0, "Property", wxLIST_FORMAT_LEFT, 100);
193     InsertColumn(1, "Value", wxLIST_FORMAT_LEFT, 300);
194 }
195
196 void ecPropertyListCtrl::Fill(ecConfigItem *pti)
197 {
198     if(NULL==pti){
199         ClearAll();
200         AddColumns();
201         m_nFirstProperty=0;
202         m_pti=NULL;
203     } else /* if(pti!=m_pti) */ {
204         m_pti=pti;
205         m_nMaxValueWidth=0;
206         ecOptionType type=m_pti->GetOptionType();
207         int i;  
208         
209         // Initially flag all items as unnecessary - calls of SetItem or SetProperty will change this
210         for(i=GetItemCount()-1;i>=0;--i){
211             SetItemData(i,0);
212         }
213         if (m_pti->HasBool () || (ecOptionTypeNone!=type)){
214             SetItem(ecMacro, m_pti->GetMacro ());
215         }
216         
217         if (m_pti->HasBool ()){
218             SetItem(ecEnabled, m_pti->IsEnabled() ? wxT("True") : wxT("False"));
219         }
220         
221         if(!m_pti->GetFilename().IsEmpty()){
222             SetItem(ecFile, m_pti->GetFilename());
223         }
224         SetItem(ecURL, m_pti->GetURL());
225         
226         if (ecOptionTypeNone!=type){
227
228             switch(type){
229             case ecString:
230                 SetItem(ecValue, m_pti->StringValue());
231                 SetItem(ecDefaultValue, m_pti->StringDefaultValue());
232                 break;
233             case ecLong:
234                 SetItem(ecValue, ecUtils::IntToStr(m_pti->Value(), wxGetApp().GetSettings().m_bHex));
235                 SetItem(ecDefaultValue, ecUtils::IntToStr(m_pti->DefaultValue(), wxGetApp().GetSettings().m_bHex));
236                 break;
237             case ecDouble:
238                 SetItem(ecValue, ecUtils::DoubleToStr(m_pti->DoubleValue()));
239                 SetItem(ecDefaultValue, ecUtils::DoubleToStr(m_pti->DoubleDefaultValue()));
240                 break;
241             case ecEnumerated:
242                 SetItem(ecValue,m_pti->StringValue());
243                 SetItem(ecDefaultValue,m_pti->StringDefaultValue());
244                 break;
245             default:
246                 wxASSERT( FALSE );
247                 break;
248             }
249             // TODO: set image
250             // SetItem(ecType, ecConfigItem::TreeItemTypeImage[type]);
251         }
252
253         // List all the properties applicable to me
254         const std::string name = ecUtils::UnicodeToStdStr (m_pti->GetMacro ());
255         if (name.size () > 0)
256         {
257             const CdlConfiguration config = wxGetApp().GetConfigToolDoc ()->GetCdlConfig ();
258             const CdlNode node = config->find_node (name, true);
259             wxASSERT (node);
260             const std::vector<CdlProperty> & properties = node->get_properties ();
261             std::vector<CdlProperty>::const_iterator property_i;
262             // CMapStringToPtr map; // count of each property name
263             wxHashTable map(wxKEY_STRING);  // count of each property name
264
265             for (property_i = properties.begin (); property_i != properties.end (); property_i++) {// for each property
266                 // get the property name
267                 const CdlProperty &prop=*property_i;
268                 const wxString strName(prop->get_property_name ().c_str());
269                 enum {VISIBLE_PROPERTIES_COUNT=sizeof visible_properties/sizeof visible_properties[0]};
270                 if (std::find (visible_properties, visible_properties + VISIBLE_PROPERTIES_COUNT, ecUtils::UnicodeToStdStr(strName)) != visible_properties + VISIBLE_PROPERTIES_COUNT) {// if the property should be displayed
271                     // set the property arguments
272                     wxString strPropertyArgs;
273                     const std::vector<std::string> & argv = prop->get_argv ();
274                     void *p;
275                     p = (void*) map.Delete(strName);
276                     
277                     p=(void *)((int)p+1);
278                     map.Put(strName, (wxObject*) p);
279                     
280                     std::vector<std::string>::const_iterator argv_i;
281                     for (argv_i = argv.begin (); argv_i != argv.end (); argv_i++){ // for each property argument...
282                         if (argv_i != argv.begin ()){                              // ...except the first (the property name)
283                             wxString strArg(ecUtils::StripExtraWhitespace (wxString(argv_i->c_str())));
284                             if (strPropertyArgs.Len() + strArg.Len() + 1 > 256) {// if the string is too long for the list control
285                                 break; // no need to add any further arguments
286                             }
287                             strPropertyArgs += strArg; // add the argument to the string
288                             strPropertyArgs += wxT (" "); // separate arguments by a space character
289                         }
290                     }
291                     // the list control appears to display a maximum of 256 characters
292                     int nIndex=SetItem(strName, strPropertyArgs, GetItemCount(), (int)p);
293                     SetItemData(nIndex, (long) prop);
294                     
295                     // display the exclamation icon if the property is in a conflicts list
296                     bool bConflictItem =
297                         //                                      PropertyInConflictsList (* property_i, config->get_structural_conflicts ()) || ignore for now
298                         PropertyInConflictsList (prop, config->get_all_conflicts ());
299
300                     // TODO: set the image for a conflict item
301                     // CListCtrl::SetItem (nIndex, 0, LVIF_IMAGE, NULL, bConflictItem ? 1 : 0, 0, 0, 0 );
302                 }
303             }
304         }
305
306         for(i=GetItemCount()-1;i>=0;--i){
307             if(0==GetItemData(i)){
308                 DeleteItem(i);
309                 if(i<m_nFirstProperty){
310                     m_nFirstProperty--;
311                 }
312             }
313         }
314         // TODO
315 #if 0
316         CRect rect;
317         GetClientRect(rect);
318         int nAvailWidth=rect.Width()-GetColumnWidth(0);
319         int w=max(m_nMaxValueWidth,nAvailWidth);
320         m_f[1]=double(w)/double(rect.Width());
321         SetColumnWidth(1,w); 
322 #endif
323     }
324
325     Refresh();
326 }
327
328 bool ecPropertyListCtrl::PropertyInConflictsList (CdlProperty property, const std::list<CdlConflict> & conflicts)
329 {
330     std::list<CdlConflict>::const_iterator conf_i;
331     for (conf_i = conflicts.begin (); conf_i != conflicts.end (); conf_i++) // for each conflict
332         if (property == (* conf_i)->get_property ())
333             return true;
334         
335         return false;
336 }
337
338 void ecPropertyListCtrl::RefreshValue()
339 {
340     if (!m_pti)
341         return;
342
343     if (m_pti->HasBool ()){
344         SetItem(ecEnabled, m_pti->IsEnabled () ? wxT("True") : wxT("False"));
345     }
346     if (m_pti->GetOptionType () != ecOptionTypeNone){
347         SetItem(ecValue, m_pti->StringValue());
348     }
349     for (int nItem = m_nFirstProperty; nItem < GetItemCount (); nItem++)
350     {
351         CdlProperty property = (CdlProperty) GetItemData (nItem);
352         wxASSERT (property);
353         
354         // display the exclamation icon if the property is in a conflicts list
355         const CdlConfiguration config = wxGetApp().GetConfigToolDoc ()->GetCdlConfig ();
356         bool bConflictItem =
357             //                                          PropertyInConflictsList (property, config->get_structural_conflicts ()) || ignore for now
358             PropertyInConflictsList (property, config->get_all_conflicts ());
359         
360         // TODO
361         // CListCtrl::SetItem (nItem, 0, LVIF_IMAGE, NULL, bConflictItem ? 1 : 0, 0, 0, 0 );
362     }
363     
364 }
365
366 int ecPropertyListCtrl::SetItem(ecFieldType f, const wxString& value)
367 {
368     int nIndex=SetItem(sm_fieldTypeImage[f], value, m_nFirstProperty);
369     if(nIndex==m_nFirstProperty){
370         m_nFirstProperty++;
371     }
372     SetItemData(nIndex,1);
373     return nIndex;
374 }
375
376 int ecPropertyListCtrl::SetItem(const wxString& item, const wxString& value, int nInsertAs, int nRepeat)
377 {
378     wxASSERT( nInsertAs <= GetItemCount() );
379
380 /*
381     LVFINDINFO info;
382     info.flags =LVFI_STRING;
383     info.psz   =pszItem;
384     info.vkDirection=VK_DOWN;
385     int nIndex=-1;
386     do {
387         nIndex=FindItem(&info,nIndex);
388     } while (--nRepeat>0 && nIndex!=-1);
389 */
390     // NB: wxListCtrl doesn't support reverse search, so could do it explicitly
391     // by iterating through the items.
392     // But for now, just ignore the nRepeat flag and find the first one.
393     int nIndex = -1;
394     nIndex = FindItem(0, /* nIndex */ item);
395     
396     if(-1==nIndex){
397         nIndex = InsertItem(nInsertAs, item);
398     }
399     
400     wxListCtrl::SetItem(nIndex, 1, value);
401
402     // TODO
403 #if 0
404     CDC *pDC=GetDC();
405     CFont *pOldFont=pDC->SelectObject(GetFont());
406     m_nMaxValueWidth=max(m_nMaxValueWidth,pDC->GetTextExtent(pszValue).cx);
407     pDC->SelectObject(pOldFont);
408     ReleaseDC(pDC);
409 #endif
410
411     return nIndex;
412 }
413
414 void ecPropertyListCtrl::OnDoubleClick(wxMouseEvent& event)
415 {
416     // Double-clicked the item
417
418     int flags;
419     long item = HitTest(event.GetPosition(), flags);
420     if (item > -1)
421     {
422         const wxString strText = wxListCtrlGetItemTextColumn(*this, item,0);
423         if(strText == wxT("File")){
424             m_pti->ViewHeader();
425         } else if (strText == wxT("URL")) {
426             m_pti->ViewURL();
427         }
428     }
429
430     // TODO
431 #if 0    
432     int pos=GetMessagePos();
433     CPoint pt(GET_X_LPARAM(pos),GET_Y_LPARAM(pos));
434     ScreenToClient(&pt);
435     int nItem=HitTest(pt,NULL);
436     
437     if(GetItemData(nItem)>1){
438         // This is a property row
439         const CdlGoalExpression goal = dynamic_cast<CdlGoalExpression> ((CdlProperty) GetItemData (nItem));
440         if (goal){
441             // This is a rule row
442             const CdlExpression expression = goal->get_expression ();
443             if (1 == expression->references.size ()) // if the property contains a single reference
444             {
445                 // assume that the reference is to another user visible node and try to find it
446                 std::string macro_name = expression->references [0].get_destination_name ();
447                 CConfigItem * pItem = CConfigTool::GetConfigToolDoc ()->Find (CString (macro_name.c_str ()));
448                 if (pItem) // the referenced node was found so select it
449                 {
450                     CConfigTool::GetControlView()->GetTreeCtrl().SelectItem(pItem->HItem());
451                 }
452             }
453         }
454     } else {
455         const CString strText(GetItemText(nItem,0));
456         if(strText==FieldTypeImage[File]){
457             m_pti->ViewHeader();
458         } else if (strText==FieldTypeImage[URL]) {
459             m_pti->ViewURL();
460         }
461     }
462 #endif
463     event.Skip();
464 }