comparison host/tools/configtool/common/win32/ConfigItem.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
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 //
26 //===========================================================================
27 //===========================================================================
28 //#####DESCRIPTIONBEGIN####
29 //
30 // Author(s): sdf
31 // Contact(s): sdf
32 // Date: 1998/08/11
33 // Version: 0.01
34 // Purpose:
35 // Description: This is the implementation of the configuration item class
36 // Requires:
37 // Provides:
38 // See also:
39 // Known bugs:
40 // Usage:
41 //
42 //####DESCRIPTIONEND####
43 //
44 //===========================================================================
45 #include "stdafx.h"
46 #include "ConfigItem.h"
47 #include "ControlView.h"
48 #include "CTUtils.h"
49 #ifdef PLUGIN
50 #define INCLUDEFILE "ide.common.h" // for setEditLocation
51 #include "IncludeSTL.h"
52 #include "common/CodeCoordinate.h"
53 #endif
54 #include "ConfigToolDoc.h"
55 #include "ConfigTool.h"
56
57 LPCTSTR CConfigItem::TreeItemTypeImage[MaxTreeItemType + 1]={
58 _T("None"), _T("Integer"), _T("Enumeration"), _T("String"), _T("Double"), 0}; // Internationalization OK
59
60 const CFileName CConfigItem::FileName() const
61 {
62 CFileName strFile;
63 const CdlNode node = dynamic_cast<CdlNode> (m_CdlItem);
64 if (node){
65 // get the package which owns the configuration item
66 const CdlPackage package = GetOwnerPackage();
67 if (package){
68
69 // return the filename of the config header
70 strFile=CFileName(CConfigTool::GetConfigToolDoc()->InstallTree()+_T("include\\pkgconf"))+package->get_config_header ().c_str ();
71 }
72 }
73 return strFile;
74 }
75
76 CConfigItem::CConfigItem(CConfigItem *pParent, CdlUserVisible CdlItem):
77 m_CdlItem(CdlItem)
78 {
79 CTreeCtrl &tree=CConfigTool::GetControlView()->GetTreeCtrl();
80 HTREEITEM hParent;
81 if(NULL==CdlItem){
82 // This is the root item
83 hParent=TVI_ROOT;
84 m_Type=None;
85 } else {
86 hParent=pParent->HItem();
87
88 // FIXME: re-implement using CdlValuableBody::get_widget_hint()
89 if (IsPackage()) {
90 // If a package item, display the package version string
91 m_Type=String;
92 } else {
93 const CdlValuable valuable = dynamic_cast<CdlValuable> (CdlItem);
94 switch (valuable->get_flavor ()){
95 case CdlValueFlavor_None:
96 case CdlValueFlavor_Bool:
97 m_Type=None;
98 break;
99 case CdlValueFlavor_Data:
100 case CdlValueFlavor_BoolData:
101 if (! valuable->has_legal_values ()) {
102 m_Type=String;
103 } else if (0 == valuable->get_legal_values ()->ranges.size ()) {
104 m_Type=Enum;
105 } else {
106 CdlListValue list_value;
107 CdlEvalContext context (NULL, valuable, valuable->get_property (CdlPropertyId_LegalValues));
108 valuable->get_legal_values ()->eval (context, list_value);
109 m_Type=list_value.get_double_ranges ().size () ? Double : Integer;
110 }
111 break;
112 default:
113 ASSERT (0); // specified flavor not supported
114 break;
115 }
116 }
117 }
118 m_hItem=tree.InsertItem(ItemNameOrMacro(),hParent);
119 tree.SetItemData(m_hItem,(DWORD)this);
120 CConfigTool::GetControlView()->AdjustItemImage(m_hItem);
121 }
122
123 CConfigItem::~CConfigItem()
124 {
125 }
126
127 CString CConfigItem::GetURL() const
128 {
129 for(const CConfigItem *pItem=this;pItem;pItem=pItem->Parent()){
130 if(pItem->GetCdlItem()){
131 CString strURL;
132 strURL=pItem->GetCdlItem()->get_doc_url().c_str();
133 if(strURL.GetLength()){
134 return strURL;
135 }
136 strURL=pItem->GetCdlItem()->get_doc().c_str();
137 if(strURL.GetLength()){
138 return strURL;
139 }
140 }
141 }
142 return _T("ref/ecos-ref.html"); // the default URL
143 }
144
145 bool CConfigItem::SetValue(LPCTSTR pszValue, CdlTransaction transaction/*=NULL*/)
146 {
147 ASSERT ((m_Type == String) || (m_Type == Enum));
148 const CdlValuable valuable = GetCdlValuable();
149 ASSERT (valuable);
150 const std::string str=CUtils::UnicodeToStdStr (pszValue);
151 if(transaction){
152 if (CdlValueFlavor_BoolData == valuable->get_flavor ()){
153 // set the user bool to the current bool when changing a booldata
154 // value to avoid a possible change in the current bool
155 valuable->set_enabled_and_value (transaction, valuable->is_enabled (), str, CdlValueSource_User);
156 } else {// CdlValueFlavor_Data
157 valuable->set_value (transaction, str, CdlValueSource_User);
158 }
159 } else {
160 if (CdlValueFlavor_BoolData == valuable->get_flavor ()){
161 // set the user bool to the current bool when changing a booldata
162 // value to avoid a possible change in the current bool
163 valuable->set_enabled_and_value (valuable->is_enabled (), str, CdlValueSource_User);
164 } else {// CdlValueFlavor_Data
165 valuable->set_value (str, CdlValueSource_User);
166 }
167 }
168
169 return true;
170 }
171
172 bool CConfigItem::SetValue (double dValue, CdlTransaction transaction/*=NULL*/)
173 {
174 ASSERT (m_Type == Double);
175 const CdlValuable valuable = GetCdlValuable();
176 ASSERT (valuable);
177
178 if(transaction) {
179 if (CdlValueFlavor_BoolData == valuable->get_flavor ()) {
180 // set the user bool to the current bool when changing a booldata
181 // value to avoid a possible change in the current bool
182 valuable->set_enabled_and_value (transaction, valuable->is_enabled (), dValue, CdlValueSource_User);
183 } else {// CdlValueFlavor_Data
184 valuable->set_double_value (transaction, dValue, CdlValueSource_User);
185 }
186 } else {
187 if (CdlValueFlavor_BoolData == valuable->get_flavor ()) {
188 // set the user bool to the current bool when changing a booldata
189 // value to avoid a possible change in the current bool
190 valuable->set_enabled_and_value (valuable->is_enabled (), dValue, CdlValueSource_User);
191 } else {// CdlValueFlavor_Data
192 valuable->set_double_value (dValue, CdlValueSource_User);
193 }
194 }
195
196 return true;
197 }
198
199 CConfigItem *CConfigItem::FirstRadio() const
200 {
201 ASSERT(HasRadio ());
202
203 for(CConfigItem *h=Parent()->FirstChild();h;h=h->NextSibling()){
204 if(h->HasRadio ()){
205 return h;
206 }
207 }
208 // No radio buttons found
209 ASSERT(false);
210 return false;
211 }
212
213 bool CConfigItem::IsEnabled() const
214 {
215 const CdlValuable valuable = GetCdlValuable();
216 return NULL==valuable ||valuable->is_enabled();
217 }
218
219 bool CConfigItem::SetValue (ItemIntegerType nValue, CdlTransaction transaction/*=NULL*/)
220 {
221 ASSERT (m_Type == Integer);
222 const CdlValuable valuable = GetCdlValuable();
223 ASSERT (valuable);
224
225 if(transaction) {
226 if (CdlValueFlavor_BoolData == valuable->get_flavor ()) {
227 // set the user bool to the current bool when changing a booldata
228 // value to avoid a possible change in the current bool
229 valuable->set_enabled_and_value (transaction, valuable->is_enabled (), (cdl_int) nValue, CdlValueSource_User);
230 } else { // CdlValueFlavor_Data
231 valuable->set_integer_value (transaction, nValue, CdlValueSource_User);
232 }
233 } else {
234 if (CdlValueFlavor_BoolData == valuable->get_flavor ()) {
235 // set the user bool to the current bool when changing a booldata
236 // value to avoid a possible change in the current bool
237 valuable->set_enabled_and_value (valuable->is_enabled (), (cdl_int) nValue, CdlValueSource_User);
238 } else { // CdlValueFlavor_Data
239 valuable->set_integer_value (nValue, CdlValueSource_User);
240 }
241 }
242
243 return true;
244 }
245
246 bool CConfigItem::HasModifiedChildren() const
247 {
248 for(CConfigItem *pItem=FirstChild();pItem;pItem=pItem->NextSibling()){
249 if(pItem->Modified()||pItem->HasModifiedChildren()){
250 return true;
251 }
252 }
253 return false;
254 }
255
256 ItemIntegerType CConfigItem::Value () const
257 {
258 ASSERT (!IsPackage()); // not a package item
259 const CdlValuable valuable = GetCdlValuable();
260 ASSERT (valuable);
261 ItemIntegerType nValue (0);
262
263 switch (valuable->get_flavor ())
264 {
265 // case CdlValueFlavor_Bool:
266 // nValue = valuable->is_enabled (CdlValueSource_Current) ? 1 : 0;
267 // break;
268
269 case CdlValueFlavor_BoolData:
270 case CdlValueFlavor_Data:
271 nValue = (ItemIntegerType) valuable->get_integer_value (CdlValueSource_Current);
272 break;
273
274 default:
275 ASSERT (0); // specified flavor not supported
276 }
277
278 return nValue;
279 }
280
281 const double CConfigItem::DoubleValue (CdlValueSource source /* = CdlValueSource_Current */ ) const
282 {
283 ASSERT (!IsPackage()); // not a package item
284 const CdlValuable valuable = GetCdlValuable();
285 ASSERT (valuable);
286 ASSERT (valuable->has_double_value (source));
287 return valuable->get_double_value (source);
288 }
289
290 ItemIntegerType CConfigItem::DefaultValue () const
291 {
292 ItemIntegerType nValue;
293 return CUtils::StrToItemIntegerType (StringValue (CdlValueSource_Default), nValue) ? nValue : 0;
294 }
295
296 const CString CConfigItem::StringValue (CdlValueSource source /* = CdlValueSource_Current */ ) const
297 {
298 // ASSERT (!IsPackage()); // not a package item
299 const CdlValuable valuable = GetCdlValuable();
300 ASSERT (valuable);
301 CString strValue (_T(""));
302
303 switch (valuable->get_flavor ())
304 {
305 case CdlValueFlavor_Data:
306 case CdlValueFlavor_BoolData:
307 case CdlValueFlavor_None: // a package
308 if (m_Type == Integer)
309 strValue = CUtils::IntToStr (Value (), CConfigTool::GetConfigToolDoc ()->m_bHex);
310 else if (m_Type == Double)
311 strValue = CUtils::DoubleToStr (DoubleValue ());
312 else
313 strValue = valuable->get_value (source).c_str ();
314 break;
315
316 default:
317 ASSERT (0); // specified flavor not supported
318 }
319
320 return strValue;
321 }
322
323 const CString CConfigItem::StringValue(WhereType where) const
324 {
325 CString str;
326 switch(where){
327 case InName:
328 str=Name();
329 break;
330 case InMacro:
331 str=Macro();
332 break;
333 case InDesc:
334 str=Desc();
335 break;
336 case InCurrentValue:
337 str=CConfigItem::None==Type()?_T(""):StringValue(CdlValueSource_Current);
338 break;
339 case InDefaultValue:
340 str=CConfigItem::None==Type()?_T(""):StringValue(CdlValueSource_Default);
341 break;
342 default:
343 ASSERT(FALSE);
344 break;
345 }
346 return str;
347 }
348
349 void CConfigItem::DumpItem()
350 {
351 TRACE(_T("Item %08x\n\tDisplay Name='%s'\n\tMacro Name='%s'\n\tType=%s"),
352 this, Name(), Macro(), TreeItemTypeImage[m_Type]);
353 TRACE(_T("\n\tValue=%s\n\tURL=%s\n\tParent=%08x"),StringValue(), GetURL(), Parent());
354
355 TRACE(_T("\n"));
356 }
357
358 CConfigItem * CConfigItem::NextRadio() const
359 {
360 ASSERT(this->HasRadio ());
361 for(CConfigItem *pItem=NextSibling();pItem;pItem=pItem->NextSibling()){
362 if(pItem->HasRadio()){
363 return pItem;
364 }
365 }
366 return NULL;
367 }
368
369 bool CConfigItem::Modified () const
370 {
371 const CdlValuable valuable = GetCdlValuable();
372 return
373 valuable // accommodate the root config item which has no CDL item
374 && !IsPackage() // packages are never modified
375 && valuable->get_source () != CdlValueSource_Default;
376 }
377
378 CString CConfigItem::ItemNameOrMacro() const
379 {
380 CConfigToolDoc *pDoc=CConfigTool::GetConfigToolDoc();
381 return pDoc->m_bMacroNames&&!Macro().IsEmpty()?Macro():Name();
382 }
383
384 bool CConfigItem::IsDescendantOf(CConfigItem * pAncestor)
385 {
386 for(CConfigItem *pItem=Parent();pItem;pItem=pItem->Parent()){
387 if(pItem==pAncestor){
388 return true;
389 }
390 }
391 return false;
392 }
393
394 int CConfigItem::EvalEnumStrings (CStringArray &arEnumStrings) const
395 {
396 const CdlValuable valuable = GetCdlValuable();
397 ASSERT (valuable);
398 /*
399 if (m_Type == Boolean)
400 {
401 arEnumStrings.SetSize (2);
402 arEnumStrings.SetAt (0, _T("True"));
403 arEnumStrings.SetAt (1, _T("False"));
404 }
405 else
406 */
407 {
408 ASSERT (m_Type == Enum);
409 CdlListValue list_value;
410 CdlEvalContext context (NULL, m_CdlItem, m_CdlItem->get_property (CdlPropertyId_LegalValues));
411 valuable->get_legal_values ()->eval (context, list_value);
412 const std::vector<CdlSimpleValue> & table = list_value.get_table ();
413
414 // add legal values to the list
415 arEnumStrings.SetSize (table.size ());
416 for (unsigned int nValue = 0; nValue < table.size (); nValue++)
417 {
418 arEnumStrings.SetAt (nValue, table [nValue].get_value ().c_str ());
419 }
420 }
421 return arEnumStrings.GetSize();
422 }
423
424 bool CConfigItem::HasBool() const
425 {
426 if (!m_CdlItem) {
427 return false;
428 } else if (IsPackage()) {
429 return false;
430 } else {
431 const CdlValuable valuable = GetCdlValuable();
432 CdlValueFlavor flavor = valuable->get_flavor ();
433 return (flavor == CdlValueFlavor_Bool) || (flavor == CdlValueFlavor_BoolData);
434 }
435 }
436
437 bool CConfigItem::HasRadio() const
438 {
439 const CdlValuable valuable = GetCdlValuable();
440 if (! valuable)
441 return false;
442
443 CdlWidgetHint hint;
444 valuable->get_widget_hint (hint);
445 return (CdlBoolWidget_Radio == hint.bool_widget);
446 }
447
448 bool CConfigItem::SetEnabled(bool bEnabled, CdlTransaction current_transaction/*=NULL*/)
449 {
450 const CdlValuable valuable = GetCdlValuable();
451 ASSERT (valuable);
452
453 // use a transaction object to ensure that all config items are changed together
454 CdlTransaction transaction = current_transaction ? current_transaction : CdlTransactionBody::make (CConfigTool::GetConfigToolDoc ()->GetCdlConfig ());
455
456 if (HasRadio () && bEnabled) { // if a new radio button has been selected
457 for (CConfigItem *pItem = FirstRadio(); pItem; pItem = pItem->NextRadio ()) { // for each radio button in the group
458 if (pItem != this) { // if not the newly selected radio button
459 pItem->SetEnabled (false, transaction); // disable the radio button
460 }
461 }
462 }
463
464 if (CdlValueFlavor_BoolData == valuable->get_flavor ()) {
465 // set the user value to the current data value when enabling/disabling
466 // a booldata item to avoid a possible change in the current data value
467 CdlSimpleValue simple_value = valuable->get_simple_value ();
468 valuable->set_enabled_and_value (transaction, bEnabled, simple_value, CdlValueSource_User);
469 } else { // CdlValueFlavor_Bool
470 valuable->set_enabled (transaction, bEnabled, CdlValueSource_User);
471 }
472
473 if (! current_transaction) { // if not a recursive call to disable a radio button
474 transaction->body (); // commit the transaction
475 deleteZ(transaction);
476 }
477
478 return true;
479 }
480
481 bool CConfigItem::ViewHeader()
482 {
483 bool rc=false;
484 const CFileName strFile(FileName());
485 if(!strFile.IsEmpty()){
486 CConfigToolDoc *pDoc=CConfigTool::GetConfigToolDoc();
487 if(pDoc->BuildTree().IsEmpty()){
488 CUtils::MessageBoxF(_T("Cannot display header file until configuration is saved"));
489 } else {
490 #ifdef PLUGIN
491 // Load or activate window and leave
492 CodeCoordinate loc((LPCTSTR)strFile, 0, 0, CodeCoordinate::FILE_LINE);
493 rc=AppInstance::getAppManager()->getEditorController()->setEditLocation(loc);
494 #else
495 rc=CUtils::Launch(strFile,pDoc->m_strViewer);
496 #endif
497 }
498 }
499 return rc;
500 }
501
502 bool CConfigItem::ViewURL()
503 {
504 return CConfigTool::GetConfigToolDoc()->ShowURL(GetURL());
505 }
506
507 // Unload (a package)
508 bool CConfigItem::Unload()
509 {
510 bool rc=false;
511 CdlPackage package=dynamic_cast<CdlPackage>(GetCdlItem());
512 ASSERT(package);
513 CConfigToolDoc* pDoc=CConfigTool::GetConfigToolDoc();
514 // Remove its objects from the view to prevent any painting problems
515 CConfigTool::GetControlView()->GetTreeCtrl().DeleteItem(HItem());
516 for(int nItem=0;nItem<pDoc->ItemCount();nItem++){
517 CConfigItem *pItem=pDoc->Item(nItem);
518 if(package==pItem->GetOwnerPackage()){
519 //CConfigTool::GetControlView()->GetTreeCtrl().DeleteItem(pItem->HItem());
520 pItem->m_hItem=NULL; // Make sure we can't attempt to paint it
521 pItem->m_CdlItem=NULL; // Make sure we can't access stale data
522 }
523 }
524
525 const CString strMacroName(Macro());
526 TRACE (_T("Unloading package %s\n"), strMacroName);
527 try {
528 pDoc->GetCdlConfig()->unload_package (package);
529 rc=true;
530 }
531 catch (CdlStringException exception) {
532 CUtils::MessageBoxF(_T("Error unloading package %s:\n\n%s"), strMacroName, CString (exception.get_message ().c_str ()));
533 }
534 catch (...) {
535 CUtils::MessageBoxF(_T("Error unloading package %s"), strMacroName);
536 }
537 m_hItem=NULL; // Make sure we can't attempt to paint it
538 m_CdlItem=NULL; // Make sure we can't access stale data
539 return rc;
540 }
541
542 // Change version (of a package)
543 bool CConfigItem::ChangeVersion(const CString &strVersion)
544 {
545 bool rc=false;
546 CdlPackage package=dynamic_cast<CdlPackage>(GetCdlItem());
547 ASSERT(package);
548 const CdlValuable valuable = GetCdlValuable();
549 ASSERT (valuable);
550 const CString strMacroName(Macro());
551 if (strVersion != valuable->get_value ().c_str ()) { // if the wrong version is loaded
552 TRACE (_T("Changing package %s to version '%s'\n"), strMacroName, strVersion);
553 try {
554 CConfigTool::GetConfigToolDoc()->GetCdlConfig()->change_package_version (package, CUtils::UnicodeToStdStr (strVersion), CConfigToolDoc::CdlParseErrorHandler, CConfigToolDoc::CdlParseWarningHandler);
555 rc=true;
556 }
557 catch (CdlStringException exception) {
558 CUtils::MessageBoxF(_T("Error changing package %s to version '%s':\n\n%s"), strMacroName, strVersion, CString (exception.get_message ().c_str ()));
559 }
560 catch (...) {
561 CUtils::MessageBoxF(_T("Error changing package %s to version '%s'"), strMacroName, strVersion);
562 }
563 }
564 return rc;
565 }
566
567 CConfigItem *CConfigItem::Parent() const
568 {
569 CTreeCtrl &tree=CConfigTool::GetControlView()->GetTreeCtrl();
570 HTREEITEM hParent=tree.GetParentItem(HItem());
571 return (NULL==hParent||TVI_ROOT==hParent)?NULL:(CConfigItem *)tree.GetItemData(hParent);
572 }
573
574 CConfigItem *CConfigItem::FirstChild() const
575 {
576 CTreeCtrl &tree=CConfigTool::GetControlView()->GetTreeCtrl();
577 HTREEITEM hChild=tree.GetChildItem(HItem());
578 return hChild?(CConfigItem *)tree.GetItemData(hChild):NULL;
579 }
580
581 CConfigItem *CConfigItem::NextSibling() const
582 {
583 CTreeCtrl &tree=CConfigTool::GetControlView()->GetTreeCtrl();
584 HTREEITEM hSibling=tree.GetNextSiblingItem(HItem());
585 return hSibling?(CConfigItem *)tree.GetItemData(hSibling):NULL;
586 }