]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - tools/src/tools/configtool/common/win32/ControlView.cpp
Initial revision
[karo-tx-redboot.git] / tools / src / tools / configtool / common / win32 / ControlView.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 // ControlView.cpp : implementation file
26 //
27 //
28 //===========================================================================
29 //===========================================================================
30 //#####DESCRIPTIONBEGIN####
31 //
32 // Author(s):   sdf
33 // Contact(s):  sdf
34 // Date:                1998/08/11
35 // Version:             0.01
36 // Purpose:     
37 // Description: This is the implementation of the tree (control) view
38 // Requires:    
39 // Provides:    
40 // See also:    
41 // Known bugs:  
42 // Usage:       
43 //
44 //####DESCRIPTIONEND####
45 //
46 //===========================================================================
47
48 #include "stdafx.h"
49 #ifndef PLUGIN
50 #include "BCMenu.h"
51 #endif
52 #include "ControlView.h"
53 #include "ConfigTool.h"
54 #include "ConfigItem.h"
55 #include "ConfigToolDoc.h"
56 #include <stdlib.h>
57 #include "CTUtils.h"
58 #include "CellView.h"
59 #include "MessageBox.h"
60 #include "FindDialog.h"
61 #include "CTPropertiesDialog.h"
62 #include "ConfigViewOptionsDialog.h"
63 #ifdef PLUGIN
64   //#include "ide.common.h"
65   #define INCLUDEFILE "ide.guicommon.h"  // for ID_EDIT_FINDAGAIN
66   #include "IncludeSTL.h"
67   #include "CTMain.h"
68 #else
69   #include "MainFrm.h"
70 #endif
71
72 #include <afxpriv.h> // for WM_COMMANDHELP, WM_HITTEST
73 #include <htmlhelp.h>
74
75 #include "DescView.h" // for testing
76 #ifdef _DEBUG
77 #define new DEBUG_NEW
78 #undef THIS_FILE
79 static char THIS_FILE[] = __FILE__;
80 #endif
81
82 /////////////////////////////////////////////////////////////////////////////
83 // CControlView
84
85 IMPLEMENT_DYNCREATE(CControlView, CTreeView)
86
87 CControlView::CControlView()
88 {
89   m_bHasVScroll=-1;
90   m_nWorkspace=0;
91   m_dwDefaultStyle&=(~WS_VSCROLL);
92   m_hContext=NULL;
93   m_hExpandedForFind=NULL;
94   m_GrayPen.CreatePen(PS_SOLID,1,RGB(192,192,192));     
95   CConfigTool::SetControlView(this);
96 }
97
98 CControlView::~CControlView()
99 {
100   CConfigTool::SetControlView(0);
101 }
102
103 static UINT WM_FINDREPLACE = ::RegisterWindowMessage(FINDMSGSTRING);
104
105 BEGIN_MESSAGE_MAP(CControlView, CTreeView)
106 //{{AFX_MSG_MAP(CControlView)
107 ON_WM_PAINT()
108 ON_NOTIFY_REFLECT(TVN_ITEMEXPANDED, OnItemexpanded)
109 ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelchanged)
110 ON_WM_LBUTTONDOWN()
111 ON_WM_VSCROLL()
112 ON_WM_SIZE()
113 ON_COMMAND(ID_RESTORE_DEFAULTS, OnRestoreDefaults)
114 ON_COMMAND(ID_POPUP_PROPERTIES, OnPopupProperties)
115 ON_COMMAND(ID_UNLOAD_PACKAGE, OnUnload)
116 ON_WM_KEYDOWN()
117 ON_COMMAND(ID_VIEW_URL, OnViewUrl)
118 ON_WM_CREATE()
119 ON_WM_HSCROLL()
120 ON_WM_MOUSEMOVE()
121 ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING, OnItemexpanding)
122 ON_WM_MOUSEWHEEL()
123 ON_WM_RBUTTONDOWN()
124 ON_WM_SYSKEYDOWN()
125 ON_WM_SYSCHAR()
126 ON_COMMAND(ID_VIEW_HEADER, OnViewHeader)
127 ON_REGISTERED_MESSAGE( WM_FINDREPLACE, OnFind)
128 ON_COMMAND(ID_EDIT_FIND,OnEditFind)
129 ON_COMMAND(ID_EDIT_FINDAGAIN,OnEditFindAgain)
130 ON_UPDATE_COMMAND_UI(ID_EDIT_FINDAGAIN, OnUpdateEditFindAgain)
131 ON_UPDATE_COMMAND_UI(ID_EDIT_FIND, OnUpdateEditFind)
132 ON_WM_CHAR()
133         ON_NOTIFY_REFLECT(TVN_DELETEITEM, OnDeleteitem)
134         ON_COMMAND(ID_CV_WHATS_THIS, OnWhatsThis)
135 ON_MESSAGE(WM_SETFONT,OnSetFont)
136         ON_WM_HELPINFO()
137         ON_WM_MENUCHAR()
138         //}}AFX_MSG_MAP
139 END_MESSAGE_MAP()
140
141
142 /////////////////////////////////////////////////////////////////////////////
143 // CControlView drawing
144
145 void CControlView::OnDraw(CDC* pDC)
146 {
147   UNUSED_ALWAYS(pDC);
148 }
149
150 /////////////////////////////////////////////////////////////////////////////
151 // CControlView diagnostics
152
153 #ifdef _DEBUG
154 void CControlView::AssertValid() const
155 {
156   CTreeView::AssertValid();
157 }
158
159 void CControlView::Dump(CDumpContext& dc) const
160 {
161   CTreeView::Dump(dc);
162 }
163 #endif //_DEBUG
164
165
166 /////////////////////////////////////////////////////////////////////////////
167 // CControlView message handlers
168
169 void CControlView::OnPaint() 
170 {
171   CPaintDC dc(this); // device context for painting
172   
173   // First let the control do its default drawing.
174   CWnd::DefWindowProc( WM_PAINT, (WPARAM)dc.m_hDC, 0 );
175   
176   CConfigToolDoc* pDoc = CConfigTool::GetConfigToolDoc();
177   if(pDoc->ItemCount()>0)
178   {
179     // Redraw the disabled labels
180     CFont *pOldFont=dc.SelectObject(GetFont());
181     dc.SetTextColor(GetSysColor(COLOR_GRAYTEXT));
182     
183     for(HTREEITEM h=GetFirstVisibleItem();h;h=GetNextVisibleItem(h))
184     {
185       const UINT selflag = TVIS_DROPHILITED | TVIS_SELECTED;            
186       if(!IsActive(h)&&!(GetItemState( h, selflag ) & selflag )){
187         // Do not meddle with selected items or drop highlighted items
188         CRect rect;             
189         GetItemRect( h, &rect, TRUE );
190         dc.TextOut(m_TreeXOffsetAdjustment+rect.left+2, rect.top+1, GetItemText(h));                    
191       }
192     }
193     dc.SelectObject(pOldFont);
194     
195     // Now draw grid lines
196     
197     CRect rcClient;
198     GetClientRect(rcClient);
199     CPen *pOldPen=dc.SelectObject(&m_GrayPen);
200     int cy=0;
201     for(h=GetFirstVisibleItem();h;h=GetNextVisibleItem(h))
202     {
203       dc.MoveTo(rcClient.left,cy);
204       dc.LineTo(rcClient.right,cy);
205       cy+=m_nItemHeight;
206     }
207     dc.MoveTo(rcClient.left,cy);
208     dc.LineTo(rcClient.right,cy);
209     dc.SelectObject(pOldPen);
210     
211   }
212 }
213
214 void CControlView::OnItemexpanded(NMHDR* pNMHDR, LRESULT* pResult) 
215 {
216   //NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
217   SetScrollRangePos();
218   //SetHScrollRangePos();
219   if(CConfigTool::GetCellView()){
220     CConfigTool::GetCellView()->Invalidate();
221 //sdf1    CConfigTool::GetCellView()->UpdateWindow();
222   } 
223   
224   *pResult = 0;
225   UNUSED_ALWAYS(pNMHDR);
226 }
227
228 void CControlView::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult) 
229 {
230   //NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
231   
232   *pResult = 0;
233   UNUSED_ALWAYS(pNMHDR);
234 }
235
236 void CControlView::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult) 
237 {
238   CConfigToolDoc* pDoc = CConfigTool::GetConfigToolDoc();
239   if(pDoc->ItemCount()>0){
240     // Do nothing if in process of destroying configitems
241     NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
242     pDoc->UpdateAllViews (this, CConfigToolDoc::SelChanged, (CObject *)&TI(pNMTreeView->itemNew.hItem));
243     CConfigItem &ti=TI(pNMTreeView->itemNew.hItem);
244     
245     CString strDesc(ti.Desc());
246     if(strDesc.IsEmpty()){
247       strDesc=_T("No context help is available for this item");
248     }
249     //pMain->m_wndHelp.SetWindowText(strDesc);
250     //pMain->m_wndHelp.SetTitle(ti.ItemNameOrMacro());
251     SetScrollPos();
252     if(CConfigTool::GetCellView()){
253       CConfigTool::GetCellView()->Sync();
254     }
255   }
256   *pResult = 0;
257 }
258
259
260
261
262 void CControlView::OnLButtonDown(UINT nFlags, CPoint point) 
263 {
264   CConfigTool::GetCellView()->CancelCellEdit();
265   {
266     UINT nFlags;
267     HTREEITEM h=HitTest(point,&nFlags);
268     if(h && IsActive(h) && (nFlags&TVHT_ONITEMICON))
269     {
270       SelectItem(h);
271       BumpItem (h, TI (h).HasBool () ? 0 : 1); // toggle boolean or increment data
272     }
273     else
274     {
275       CTreeView::OnLButtonDown(nFlags,point);
276     }
277   }
278   
279   // Relay to the splitter
280   ClientToScreen(&point);
281   GetParent()->ScreenToClient(&point);
282   GetParent()->SendMessage(WM_LBUTTONDOWN,(WPARAM)nFlags,MAKELPARAM(point.x,point.y));  
283 }
284
285
286 void CControlView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
287
288   // Round to nearest item and express in units of items for the benefit of CTreeView
289   nPos=(nPos+m_nItemHeight/2)/m_nItemHeight;
290   DefWindowProc(WM_VSCROLL,MAKELONG(nSBCode, nPos), (LPARAM)pScrollBar->m_hWnd);
291   SetScrollPos();
292 }
293
294 /////////////////////////////////////////////////////////////////////////////
295 // CControlView message handlers
296
297 void CControlView::OnInitialUpdate() 
298 {
299   CTreeView::OnInitialUpdate();
300 #ifdef IE4
301   SetItemHeight(20);
302 #endif
303   /*
304   #ifndef PLUGIN
305   // Do this here, because the framework resets the title after calling OnOpenDocument()
306   CConfigToolDoc* pDoc = CConfigTool::GetConfigToolDoc();
307   CString strTitle(pDoc->BuildTree());
308   if(strTitle.IsEmpty())
309   {
310                 strTitle+=_T("Repository ");
311     strTitle+=pDoc->Repository();
312     }
313     pDoc->SetTitle(strTitle);
314     #endif
315   */
316 }
317
318 void CControlView::OnSize(UINT nType, int cx, int cy) 
319 {
320   //m_nInOnSize++;
321   CScrollBar *cv=GetScrollBarCtrl(SB_VERT);
322   //int dx=cx-m_Size.cx;
323   //int dy=cy-m_Size.cy;
324   /*
325   TRACE("WM_SIZE[%d] dx=%d dy=%d depth=%d ch=%08x cv=%08x",
326                 0,
327     dx,dy,
328     m_nInOnSize,
329     ch,cv);
330                 */
331   int bIsHScrollBarDelta=(cv==NULL);
332   //int bIsVScrollBarDelta=(ch==NULL);
333   if(bIsHScrollBarDelta/*dx==-16*/){
334     cx=m_Size.cx;
335   }
336   //    if(bIsVScrollBarDelta/*dy==-16*/){
337   //            cy=m_Size.cy;
338   //    }
339   if(cx!=m_Size.cx || cy!=m_Size.cy){
340     m_Size=CSize(cx,cy);
341     DefWindowProc(WM_SIZE,(WPARAM)nType,MAKELPARAM(cx,cy));
342   }
343   KillScrollBars();
344   SetScrollRangePos();
345   //SetHScrollRangePos();
346   //m_nInOnSize--;
347 }
348
349 BOOL CControlView::PreCreateWindow(CREATESTRUCT& cs) 
350 {
351   cs.style=TVS_HASBUTTONS | TVS_LINESATROOT | TVS_SHOWSELALWAYS |
352     WS_CHILD | WS_VISIBLE /*| WS_BORDER*/ | WS_TABSTOP;
353   cs.style&=(~WS_VSCROLL);
354   m_dwDefaultStyle&=(~WS_VSCROLL);
355   return CTreeView::PreCreateWindow(cs);
356 }
357
358 void CControlView::OnRButtonDown(UINT nFlags, CPoint point) 
359 {
360   UNUSED_ALWAYS(nFlags);
361   UINT Flags;
362   HTREEITEM h=HitTest(point,&Flags);
363   if(h){
364     SelectItem(h);
365   }
366   // point is in client coords
367   ClientToScreen(&point);
368   ShowPopupMenu(h,point);
369 }
370
371 // Button functionality
372
373 void CControlView::Refresh (HTREEITEM h) // was Enable()
374 {
375   if(h){
376     AdjustItemImage(h);
377     // Invalidate the labels of the affected items
378     CRect rect;         
379     GetItemRect(h, rect, TRUE );
380     rect.left+=m_TreeXOffsetAdjustment;
381     InvalidateRect(rect);
382     // Do the same for the cell view
383     CRect rcBuddyClient;
384     CConfigTool::GetCellView()->GetClientRect(rcBuddyClient);
385     rect.left=rcBuddyClient.left;
386     rect.right=rcBuddyClient.right;
387     CConfigTool::GetCellView()->InvalidateRect(rect);
388   }
389 }
390
391 BOOL CControlView::IsActive(HTREEITEM h) const
392 {
393   const CdlUserVisible vitem = TI (h).GetCdlItem ();
394   return vitem ? vitem->is_active () : true; 
395 }
396
397 void CControlView::AdjustItemImage(HTREEITEM h)
398 {
399   CConfigItem &ti=TI(h);
400   CString str(ti.ItemNameOrMacro());
401   if(ti.Modified()){
402     str+=_TCHAR('*');
403   }
404   //#ifndef PLUGIN
405   //    CConfigTool::GetConfigToolDoc()->SetTitle(_T("rt")); // Parameter is ignored
406   //#endif
407   SetItemText(h,str);
408   
409   int nImage=0;
410   enum {FolderIcon=0, CheckBoxIcon=2, RadioIcon=6, IntegerIcon=10, StringIcon=12, EnumIcon=14, PackageIcon=16, DoubleIcon=20};
411   if (ti.HasBool ())
412   {
413     if (ti.IsPackage ())
414       nImage = PackageIcon;
415     else
416       nImage = ti.HasRadio () ? RadioIcon : CheckBoxIcon;
417     
418     if (ti.IsEnabled ())
419       nImage += 2;
420   }
421   else
422   {
423     switch(ti.Type())
424     {
425     /*
426     case CConfigItem::Boolean:
427     nImage=ti.IsPackage()?PackageIcon:CheckBoxIcon;
428     // These images have all four states
429     if(ti.Value())
430     {
431                                 nImage+=2;
432         }
433         break;
434         case CConfigItem::Radio:
435         nImage=RadioIcon;
436         // Has four states
437         if(ti.Value())
438         {
439         nImage+=2;
440         }
441         break;
442       */
443     case CConfigItem::Double:
444       nImage=DoubleIcon;
445       break;
446     case CConfigItem::Integer:
447       nImage=IntegerIcon;
448       break;
449     case CConfigItem::Enum:
450       nImage=EnumIcon;
451       break;
452     case CConfigItem::None:
453       nImage = FolderIcon;
454       break;
455     case CConfigItem::String:
456       // if a package use the enabled package icon else use the string icon
457       nImage = ti.IsPackage () ? PackageIcon + 2 : StringIcon;
458       break;
459     default:
460       ASSERT(FALSE);
461       break;
462     }
463   }
464   // All items have an enabled alternative
465   if(!IsActive(h))
466   {
467     nImage+=1;
468   }
469   //    else if (ti.Type () == CConfigItem::Boolean)
470   else if ((ti.Type () != CConfigItem::None) || ti.HasBool ())
471   {
472     // grey icon if the option is not modifiable or is inactive
473     const CdlValuable valuable = ti.GetCdlValuable();
474     if (valuable && ! (valuable->is_modifiable () && valuable->is_active ()))
475       nImage++;
476   }
477   BOOL b=SetItemImage(h,nImage,nImage);
478   ASSERT(b);
479 }
480
481 ItemIntegerType CControlView::Value(HTREEITEM h) const
482 {
483   ItemIntegerType rc;
484   CConfigItem &ti=TI(h);
485   if(CConfigTool::GetCellView()->ActiveCell()==h){
486     rc=CConfigTool::GetCellView()->GetCellValue();
487   } else 
488   {
489     rc=ti.Value();
490   }
491   return rc;
492 }
493
494 void CControlView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) 
495 {
496   CConfigToolDoc* pDoc = CConfigTool::GetConfigToolDoc();
497   switch(lHint)
498   {
499                 case CConfigToolDoc::AllSaved:
500       
501       {
502         for(int nItem=0;nItem<pDoc->ItemCount();nItem++)
503         {
504           CConfigItem *pItem=pDoc->Item(nItem);
505           HTREEITEM h=pItem->HItem();
506           if(h){
507             SetItemText(h,pItem->ItemNameOrMacro());
508             InvalidateItem(h);
509           }
510         }
511       }
512       break;
513     case CConfigToolDoc::NameFormatChanged:
514       {
515         for(int nItem=0;nItem<pDoc->ItemCount();nItem++)
516         {
517           CConfigItem *pItem=pDoc->Item(nItem);
518           CString strName(pItem->ItemNameOrMacro());
519           if(pItem->Modified()){
520             strName+=_TCHAR('*');
521           }
522           SetItemText(pItem->HItem(),strName);
523         }
524         
525         Invalidate();
526       }
527       break;
528     case CConfigToolDoc::IntFormatChanged:
529       break;
530     case CConfigToolDoc::Clear:         
531       m_hExpandedForFind=NULL;
532       m_hContext=NULL;
533       DeleteAllItems();
534       break;
535     case CConfigToolDoc::ValueChanged:
536       {
537         CConfigItem &ti=*(CConfigItem *)pHint;
538         HTREEITEM h=ti.HItem();
539         AdjustItemImage(h);
540         switch(ti.Type()){
541         case CConfigItem::Integer:
542           //                        case CConfigItem::Boolean:
543           //                        case CConfigItem::Radio:
544           {
545             ItemIntegerType n=ti.Value();
546             Refresh (h);
547             for(HTREEITEM hc=GetChildItem(h);hc;hc=GetNextSiblingItem (hc)){
548               Refresh (hc);
549             }
550             /*
551             // In the case of radio buttons, do the same thing to my siblings:
552             if(ti.Type()==CConfigItem::Radio && n==1){
553             for(HTREEITEM hs=ti.FirstRadio()->HItem();hs;hs=GetNextSiblingItem(hs)){
554             if(TI(hs).Type()==CConfigItem::Radio && hs!=h){
555             AdjustItemImage(hs);
556             // Enable or disable their children
557             for(HTREEITEM hn=GetChildItem(hs);hn;hn=GetNextSiblingItem(hn)){
558             Refresh (hn);
559             }
560             }
561             }
562             }
563             */
564             if(pDoc->m_bAutoExpand){
565               if ( (0==(GetItemState(h,TVIS_EXPANDED) & TVIS_EXPANDED)) != (0==n) ){
566                 Expand(h,n?TVE_EXPAND:TVE_COLLAPSE);
567                 SetScrollRangePos();
568               }
569               
570               //SetHScrollRangePos();
571               if(CConfigTool::GetCellView()){
572                 CConfigTool::GetCellView()->Invalidate();
573               }
574             }
575           }
576           break;
577         default:
578           break;
579         }
580         CRect rect;
581         GetItemRect(h,rect,FALSE);
582         InvalidateRect(rect);
583       }                 
584       break;
585     case CConfigToolDoc::ExternallyChanged:
586       {
587         for(int nItem=0;nItem<pDoc->ItemCount();nItem++){
588           CConfigItem *pItem=pDoc->Item(nItem);
589           AdjustItemImage(pItem->HItem());
590         }
591       }
592       break;
593     case 0:
594       if(pDoc->ItemCount()>0)
595       {
596         CRect rect;
597         GetItemRect(GetFirstVisibleItem(),rect,FALSE);
598         m_nItemHeight=rect.Height();
599         m_nWorkspace=m_nItemHeight;
600         SetScrollRangePos();
601         SetHScrollRangePos(); 
602 #ifdef _DEBUG
603         int nCP=0;
604         for(int nItem=0;nItem<pDoc->ItemCount();nItem++)
605         {
606           CConfigItem *pItem=pDoc->Item(nItem);
607           ASSERT(pItem->HItem());
608           switch(pItem->Type()){
609           case CConfigItem::None:
610             break;
611           case CConfigItem::String:
612           case CConfigItem::Enum:
613           case CConfigItem::Integer:
614           case CConfigItem::Double:
615             //          case CConfigItem::Boolean:
616             nCP++;
617             break;
618             //          case CConfigItem::Radio:
619             //                  nCP+=(pItem==pItem->FirstRadio());
620             //                  break;
621           default:
622             ASSERT(FALSE);
623             break;
624           }
625         }
626         TRACE(_T("### done creating - %d config items created: %d configuration points\n"),GetCount(),nCP);
627 #endif
628         
629         SetScrollRangePos();
630         
631       }
632     default:
633       break; // not for us, apparently
634   }
635   UNUSED_ALWAYS(pSender);
636 }
637
638 void CControlView::OnRestoreDefaults() 
639 {
640   if(TI(m_hContext).HasModifiedChildren())
641   {
642     switch(CUtils::MessageBoxFT(MB_YESNOCANCEL,_T("Restore defaults for nested items?")))
643     {
644     case IDYES:
645       RestoreDefault(m_hContext,TRUE);
646       break;
647     case IDNO:
648       RestoreDefault(m_hContext,FALSE);
649       break;
650     case IDCANCEL:
651       break;
652     default:
653       ASSERT(FALSE);
654       break;
655     }
656   } else 
657   {
658     RestoreDefault(m_hContext,FALSE);
659   }
660   
661   // current values may have changed so refresh the other views
662   //CConfigTool::GetConfigToolDoc ()->UpdateFailingRuleCount ();
663   if (TI (m_hContext).Type () != CConfigItem::None)
664     CConfigTool::GetConfigToolDoc ()->UpdateAllViews (NULL, CConfigToolDoc::ValueChanged, (CObject *) GetItemData (m_hContext));
665 }
666
667 void CControlView::OnPopupProperties() 
668 {
669   if(NULL==m_hContext){
670     m_hContext=GetSelectedItem();
671   }
672   if(NULL!=m_hContext){
673     CCTPropertiesDialog dlg(TI(m_hContext));
674     dlg.DoModal();
675     m_hContext=NULL;
676   }
677 }
678
679
680 void CControlView::RestoreDefault(HTREEITEM h, BOOL bRecurse /* = FALSE */, BOOL bTopLevel /* = TRUE */)
681 {
682   CConfigItem &ti = TI (h);
683   const CdlValuable valuable = ti.GetCdlValuable();
684   if (valuable && (CdlValueFlavor_None != valuable->get_flavor ())) // skip the root node and nodes without a value
685     valuable->set_source (CdlValueSource_Default);
686   SetItemText (h, ti.ItemNameOrMacro ()); // remove asterisk in control view
687   
688   if (bTopLevel && ti.HasRadio ()) // if user-specified item is a radio button
689   {
690     for (CConfigItem * pItem = ti.FirstRadio (); pItem; pItem = pItem->NextRadio ())
691     {
692       if (&ti != pItem)
693       {
694         const CdlValuable valuable = pItem->GetCdlValuable();
695         ASSERT (valuable);
696         valuable->set_source (CdlValueSource_Default); // restore default for each sibling radio button
697         SetItemText (pItem->HItem (), pItem->ItemNameOrMacro ()); // remove asterisk in control view
698       }
699       
700     }
701   }
702   
703   if (bRecurse)
704   {
705     for (h = GetChildItem (h); h; h = GetNextSiblingItem (h))
706     {
707       RestoreDefault (h, TRUE, FALSE);
708     }
709   }
710 }
711
712 BOOL CControlView::IsChanged(HTREEITEM h, BOOL bRecurse)
713 {
714   BOOL rc = TI (h).Modified ();
715   //    CConfigItem &ti=TI(h);
716   //    BOOL rc=(0!=ti.StringDefaultValue().Compare(ti.StringValue()));         
717   if(!rc && bRecurse)
718   {
719     for(h=GetChildItem(h);h;h=GetNextSiblingItem(h))
720     {
721       if(IsChanged(h,TRUE))
722       {
723         rc=TRUE;
724         break;
725       }
726     }
727   }
728   return rc;
729 }
730
731
732 void CControlView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
733 {
734   if(nChar==VK_APPS){
735     HTREEITEM h=GetSelectedItem();
736     ShowPopupMenu(h);
737     return;
738   }
739   CTreeView::OnKeyDown(nChar, nRepCnt, nFlags);
740 }
741
742 void CControlView::InvalidateItem(HTREEITEM h)
743 {
744   if(CConfigTool::GetCellView()->ActiveCell()==h)
745   {
746     //m_pwndCell->Invalidate();
747   } 
748   else 
749   {
750     CRect rect;
751     GetItemRect(h,rect,FALSE);
752     InvalidateRect(rect);
753   }
754 }
755
756 /*
757 void CControlView::OnViewSwitches() 
758 {
759 m_bSwitches ^= 1;       
760 CConfigToolDoc* pDoc = CConfigTool::GetConfigToolDoc();
761 for(int nItem=0;nItem<pDoc->ItemCount();nItem++)
762 {
763 CConfigItem *pItem=pDoc->Item(nItem);
764 HTREEITEM h=pItem->HItem();
765 if(pItem->m_Icon==CConfigItem::IconCheckbox)
766 {
767 pItem->m_Icon=CConfigItem::IconSwitch;
768 } else if(pItem->m_Icon==CConfigItem::IconSwitch)
769 {
770 pItem->m_Icon=CConfigItem::IconCheckbox;
771 }
772 AdjustItemImage(h);
773 }
774
775   Invalidate();
776   
777     }
778     
779       void CControlView::OnUpdateViewSwitches(CCmdUI* pCmdUI) 
780       {
781       pCmdUI->SetCheck(m_bSwitches);
782       }
783       
784         void CControlView::OnViewCheckboxes() 
785         {
786         OnViewSwitches();
787         }
788         void CControlView::OnUpdateViewCheckboxes(CCmdUI* pCmdUI) 
789         {
790         pCmdUI->SetCheck(!m_bSwitches);
791         }
792 */
793 void CControlView::OnViewUrl() 
794 {
795   TI(m_hContext).ViewURL();
796 }
797
798 bool CControlView::BumpItem(HTREEITEM h,int nInc)
799 {
800   bool rc=false;
801   // Take an action for clicking on the icon
802   CConfigToolDoc* pDoc = CConfigTool::GetConfigToolDoc();
803   CConfigItem &ti=TI(h);
804   
805   // do not modify the option value if it is inactive or not modifiable
806   const CdlValuable valuable = ti.GetCdlValuable();
807   if (!valuable || (valuable->is_modifiable () && valuable->is_active ())) {
808     if (0 == nInc) // if a toggle request
809     {
810       if (ti.HasBool () && ! (ti.HasRadio () && ti.IsEnabled ())) { // only enable (not disable) a radio button
811         rc=pDoc->SetEnabled (ti, ! ti.IsEnabled ()); // toggle enabled/disabled state
812       }
813     } else if (ti.IsEnabled ()) { // the item is enabled...
814       switch(ti.Type())
815       {
816       case CConfigItem::None:
817       case CConfigItem::String:
818       case CConfigItem::Double:
819         break;
820       case CConfigItem::Enum:
821         {
822           CStringArray arEnum;
823           ti.EvalEnumStrings (arEnum); // calculate legal values just in time
824           if (0==arEnum.GetSize()) // if no legal values...
825             break;           // ...do nothing
826           int nIndex = -1;
827           const CString strCurrent = ti.StringValue ();
828           for (int nEnum = 0; (nEnum < arEnum.GetSize()) && (nIndex == -1); nEnum++)
829             if (0 == arEnum[nEnum].Compare (strCurrent))
830                                                         nIndex = nEnum; // the index of the current value
831             
832                                         if (nIndex != -1) // if the current value is still legal
833                   nIndex += (nInc < 0 ? -1 : 1); // increment/decrement the index
834                 else
835                   nIndex = 0; // otherwise select the first enum
836                 
837                 if (nIndex < 0) // if the new index is negative
838                   nIndex = arEnum.GetSize()-1; // make it positive
839                 
840                 rc=pDoc->SetValue (ti, arEnum[nIndex % arEnum.GetSize()]);
841         }
842         break;
843       case CConfigItem::Integer:
844         {
845           ItemIntegerType nOldValue=Value(h);
846           if(nInc==1 && nOldValue==ItemIntegerType (-1)){
847             nOldValue=0;
848           } else if(nInc==-1 && nOldValue==0){
849             nOldValue=ItemIntegerType (-1);
850           } else {
851             nOldValue+=nInc;
852           }
853           rc=pDoc->SetValue(ti,nOldValue);
854           break;
855         }
856         
857         break;
858         /*
859         case CConfigItem::Boolean:
860         
861           {
862           ItemIntegerType nOldValue=Value(h);
863           pDoc->SetValue(ti,nOldValue^1);
864           }
865           break;
866                         case CConfigItem::Radio:
867             
868               if(0==Value(h)){
869               pDoc->SetValue(ti, (ItemIntegerType) 1);
870               }
871               break;
872         */
873       default:
874         ASSERT(FALSE);
875         break;
876       }
877     }
878   }
879   return rc;
880 }
881
882 int CControlView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
883 {
884   if (CTreeView::OnCreate(lpCreateStruct) == -1)
885     return -1;
886   
887   BOOL b=m_il.Create(IDB_BITMAP2,16,1,RGB(0,128,128));
888   
889   // This code is necessary because of what appears to be an inconsistency between
890   // different versions of the common control dll.  In some the text rectangles seem
891   // not to take into account the offset introduced by the item image of the root item.
892   // The offset is used in the OnPaint handler to make sure the greyed text is in the
893   // right place.
894   
895   // Begin hack
896   {
897     HTREEITEM h=InsertItem(_T("Foo"));
898     CRect rect1,rect2;
899     GetItemRect(h,rect1,TRUE);
900     
901     SetImageList(&m_il,TVSIL_NORMAL);
902     GetItemRect(h,rect2,TRUE);
903     m_TreeXOffsetAdjustment=rect1.left==0?(rect2.left-rect1.left):0;
904     DeleteItem(h);
905   }
906   // End hack
907   
908   ASSERT(b);
909   
910   CRect rcClient;
911   GetClientRect(rcClient);      
912   CSplitterWnd *pSplitter=(CSplitterWnd*)GetParent();
913   pSplitter->SetColumnInfo(1,rcClient.Width()/4,0);
914   
915   return 0;
916 }
917
918 void CControlView::KillScrollBars()
919 {
920   CSplitterWnd *pSplit=(CSplitterWnd *)GetParent();
921   int min,curX,curY;
922   const int col=0;
923   pSplit->GetColumnInfo(col,curX,min);
924   if(-1==curX){
925     return;
926   }
927   pSplit->GetRowInfo   (0,curY,min);
928   if(-1==curY){
929     return;
930   }
931   CRect rcClient;
932   GetClientRect(rcClient);
933   /*
934   TRACE("splitter[%d]=(%d,%d) view=(%d,%d)",
935                 col,
936     curX,curY,
937     rcClient.Width(),rcClient.Height());
938                 */
939   if(curX>rcClient.Width()&&curY>rcClient.Height()){
940     //sdf ShowScrollBar(SB_BOTH,FALSE);
941     ShowScrollBar(SB_VERT,FALSE);
942   } else {
943     if(curX>rcClient.Width()){
944       //TRACE(" -VERT\n");
945       ShowScrollBar(SB_VERT,FALSE);
946     }
947     if(curY>rcClient.Height()){
948       //TRACE(" -HORZ\n");
949       //sdf ShowScrollBar(SB_HORZ,FALSE);
950     }
951   }
952   //TRACE("\n");
953 }
954
955 void CControlView::SetScrollPos()
956 {
957   if(m_bHasVScroll==1){
958     CRect rect;
959     GetTreeCtrl().GetItemRect(GetTreeCtrl().GetRootItem(),rect,FALSE);
960     CScrollBar *cv=(CScrollBar *)(GetParent()->GetDlgItem(AFX_IDW_VSCROLL_FIRST));
961     //BOOL cv=TRUE;
962     if(cv && m_bHasVScroll){
963       //TRACE("SetScrollPos %d\n",-rect.top);
964       cv->SetScrollPos(-rect.top);
965       //SetScrollInfo(SB_VERT,&si,SIF_POS);
966     }
967   }
968 }
969
970 void CControlView::SetScrollRangePos()
971 {
972   RecalcWorkSpaceSize();
973   if(m_nWorkspace>0){
974     CScrollBar *cv=(CScrollBar *)(GetParent()->GetDlgItem(AFX_IDW_VSCROLL_FIRST));
975     //BOOL cv=TRUE;
976     
977     if(cv){
978       CRect rcClient;
979       GetClientRect(rcClient);
980       SCROLLINFO si;
981       si.cbSize=sizeof SCROLLINFO;
982       memset(&si,0,sizeof SCROLLINFO);
983       si.nPage=rcClient.Height();
984       si.fMask=SIF_PAGE|SIF_RANGE|SIF_POS;
985       si.nMin=0;
986       CRect rect;
987       GetTreeCtrl().GetItemRect(GetTreeCtrl().GetRootItem(),rect,FALSE);
988       si.nPos=-rect.top;
989       BOOL bHasVScroll=(si.nPage<(unsigned)m_nWorkspace);
990       if(bHasVScroll){
991         si.nMax=m_nWorkspace/*-si.nPage*/;
992         cv->SetScrollInfo(&si,SIF_PAGE|SIF_RANGE|SIF_POS);
993         //TRACE("SetScrollInfo range=(%d,%d) pos=%d page=%d\n",si.nMin,si.nMax,si.nPos,si.nPage);
994       }
995       if(bHasVScroll!=m_bHasVScroll){
996         CSplitterWnd *pSplitter=(CSplitterWnd *)GetParent();
997         DWORD style=(pSplitter->GetScrollStyle()&(~WS_VSCROLL))
998           |(bHasVScroll*WS_VSCROLL);
999         pSplitter->SetScrollStyle(style);
1000         pSplitter->RecalcLayout();
1001         m_bHasVScroll=bHasVScroll;
1002       }
1003     }
1004   }
1005 }
1006
1007 void CControlView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
1008 {
1009   CTreeView::OnHScroll(nSBCode, nPos, pScrollBar);
1010   SetHScrollPos();
1011 }
1012
1013 void CControlView::SetHScrollRangePos()
1014 {
1015   return;//sdf
1016 }
1017
1018 void CControlView::SetHScrollPos()
1019 {
1020   return;//sdf
1021   CRect rcClient;
1022   GetClientRect(rcClient);
1023   SCROLLINFO si;
1024   si.cbSize=sizeof SCROLLINFO;
1025   memset(&si,0,sizeof SCROLLINFO);
1026   si.fMask=SIF_POS;
1027   CRect rect;
1028   GetTreeCtrl().GetItemRect(GetTreeCtrl().GetRootItem(),rect,FALSE);
1029   si.nPos=-rect.left;
1030   const int nCol=0;
1031   CScrollBar *cv=(CScrollBar *)(GetParent()->GetDlgItem(AFX_IDW_HSCROLL_FIRST+nCol));
1032   //BOOL cv=TRUE;
1033   if(cv && m_bHasHScroll){
1034     cv->SetScrollInfo(&si,SIF_POS);
1035     //SetScrollInfo(SB_HORZ,&si,SIF_POS);
1036   }
1037   
1038 }
1039
1040 void CControlView::OnMouseMove(UINT nFlags, CPoint point) 
1041 {
1042   CTreeView::OnMouseMove(nFlags, point) ;
1043   
1044   // Relay the mouse event to the splitter
1045   ClientToScreen(&point);
1046   GetParent()->ScreenToClient(&point);
1047   GetParent()->SendMessage(WM_MOUSEMOVE,(WPARAM)nFlags,MAKELPARAM(point.x,point.y));    
1048 }
1049
1050 BOOL CControlView::OnMouseWheel(UINT, short zDelta, CPoint) 
1051 {
1052   UINT nScrollCode=((zDelta<0)?SB_LINEDOWN:SB_LINEUP);
1053   LPARAM lParam=(LPARAM)GetScrollBarCtrl(SB_VERT)->GetSafeHwnd();
1054   if(lParam){
1055     for(int i=0;i<abs(zDelta)/WHEEL_DELTA;i++){
1056       SendMessage(WM_VSCROLL,MAKEWPARAM(nScrollCode,0),lParam);
1057       CConfigTool::GetCellView()->Sync();
1058     }
1059   }
1060   return TRUE;
1061 }
1062
1063 void CControlView::RecalcWorkSpaceSize()
1064 {
1065   //TRACE("Control view recalcworkspace\n");
1066   CRect rcFirst,rcLast;
1067   CConfigToolDoc* pDoc = CConfigTool::GetConfigToolDoc();
1068   if(pDoc->ItemCount()>0){
1069     HTREEITEM h=pDoc->FirstItem()->HItem();
1070     if(h){
1071       GetItemRect(h,rcFirst,FALSE);
1072       if(pDoc->ItemCount()>0 && pDoc->Item(pDoc->ItemCount()-1)->HItem()){
1073         for(HTREEITEM h=pDoc->Item(pDoc->ItemCount()-1)->HItem();h;h=GetPrevVisibleItem(h)){
1074           if(GetItemRect(h,rcLast,FALSE)){
1075             m_nWorkspace=rcLast.bottom-rcFirst.top;
1076             break;
1077           }
1078         }
1079       }
1080     }
1081   }
1082 }
1083
1084 void CControlView::OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
1085 {
1086   switch(nChar){
1087                 case VK_F10:
1088       if(::GetKeyState(VK_SHIFT)&0x8000){
1089         // Shift key down
1090         ShowPopupMenu(GetSelectedItem());
1091       }
1092       break;
1093     case VK_RETURN:
1094       if(nFlags&(1<<13)){
1095         // Alt key down
1096         m_hContext=GetSelectedItem();
1097         OnPopupProperties();
1098       }
1099       break;
1100   }
1101   CTreeView::OnSysKeyDown(nChar, nRepCnt, nFlags);
1102 }
1103
1104 void CControlView::ShowPopupMenu(HTREEITEM h,CPoint point/*=CPoint(-1,-1)*/)
1105 {
1106   // Display a context menu
1107   if(NULL!=h){
1108     Menu menu;
1109     menu.LoadMenu(IDR_CONTROLVIEW_POPUP);
1110     Menu *pPopup=(Menu *)menu.GetSubMenu(0);
1111
1112     if(point.x<0){
1113       CRect rcItem;
1114       GetItemRect(h,rcItem,TRUE);
1115       point=rcItem.CenterPoint();
1116       ClientToScreen(&point);
1117     }
1118     m_hContext=h;
1119     CConfigItem &ti=TI(m_hContext);
1120     CConfigItem::TreeItemType type=ti.Type();
1121
1122     #ifndef PLUGIN
1123     menu.LoadToolbar(IDR_MISCBAR);
1124     #endif
1125     if(!IsChanged(m_hContext,true)){
1126       pPopup->EnableMenuItem(ID_RESTORE_DEFAULTS,MF_BYCOMMAND|MF_GRAYED);
1127     }
1128
1129     if((CConfigItem::None!=type) || ti.HasBool ()){
1130                 const CString strURL(ti.GetURL());
1131         if(strURL.IsEmpty()){
1132           pPopup->EnableMenuItem(ID_VIEW_URL,MF_BYCOMMAND|MF_GRAYED);
1133         }
1134     }
1135
1136     const CFileName strFile(TI(h).FileName());
1137     if(strFile.IsEmpty() || CConfigTool::GetConfigToolDoc()->BuildTree().IsEmpty()){
1138        pPopup->EnableMenuItem(ID_VIEW_HEADER,MF_BYCOMMAND|MF_GRAYED);
1139     }
1140
1141     if(!TI(h).IsPackage()){
1142       int n=pPopup->GetMenuItemCount();
1143       pPopup->RemoveMenu(n-1,MF_BYPOSITION);
1144       pPopup->RemoveMenu(n-2,MF_BYPOSITION);
1145     }
1146     pPopup->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON, point.x,point.y,this);
1147   }
1148 }
1149
1150 void CControlView::OnSysChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
1151 {
1152   // TODO: Add your message handler code here and/or call default
1153   
1154   CTreeView::OnSysChar(nChar, nRepCnt, nFlags);
1155 }
1156
1157 CConfigToolDoc * CControlView::GetDocument()
1158 {
1159   return CConfigTool::GetConfigToolDoc();
1160 }
1161
1162 void CControlView::OnViewHeader() 
1163 {
1164   TI(m_hContext).ViewHeader();
1165 }
1166
1167 void CControlView::OnEditFind() 
1168 {
1169   CConfigToolDoc *pDoc=CConfigTool::GetConfigToolDoc();
1170   if(!CConfigTool::GetMain()->m_bFindInProgress){
1171     (new CFindDialog())->Create(pDoc->m_strFind,pDoc->m_nFindFlags&(FR_WHOLEWORD|FR_MATCHCASE|FR_DOWN),pDoc->m_nFindWhere, this);
1172     CConfigTool::GetMain()->m_bFindInProgress=true;
1173   }
1174 }
1175
1176 void CControlView::OnEditFindAgain() 
1177 {
1178   CConfigToolDoc *pDoc=CConfigTool::GetConfigToolDoc();
1179   DoFind(pDoc->m_strFind,pDoc->m_nFindFlags,pDoc->m_nFindWhere);
1180 }
1181
1182 LONG CControlView::OnFind(WPARAM wParam, LPARAM lParam)
1183 {
1184   UNUSED_ALWAYS(wParam);
1185   CFindDialog *pDlg=(CFindDialog *)CFindDialog::GetNotifier(lParam);
1186   FINDREPLACE &fr=pDlg->m_fr;
1187   CConfigToolDoc *pDoc=CConfigTool::GetConfigToolDoc();
1188   if(0==(fr.Flags&FR_DIALOGTERM)){
1189     pDoc->m_strFind=fr.lpstrFindWhat;
1190     pDoc->m_nFindFlags=fr.Flags;
1191     pDoc->m_nFindWhere=pDlg->m_nFindPos;
1192     
1193     CConfigItem *pItem=DoFind(pDoc->m_strFind,pDoc->m_nFindFlags,pDoc->m_nFindWhere);
1194     if(pItem){
1195                     // Is the find window on top of the item?
1196                     CRect rect1,rect2;
1197         GetItemRect(pItem->HItem(),rect1,TRUE);
1198         ClientToScreen(rect1);
1199         pDlg->GetWindowRect(rect2); // screen coords
1200         rect1=rect1 & rect2;
1201         if(rect1.Height()|rect1.Width()){
1202           int nWidth=rect2.Width();
1203           rect2.left=rect1.right;
1204           rect2.right=rect2.left+nWidth;
1205           pDlg->MoveWindow(rect2);
1206         }
1207     }
1208   } else {
1209     CConfigTool::GetMain()->m_bFindInProgress=false;
1210   }
1211   
1212   return 0;
1213 }
1214
1215 CConfigItem * CControlView::DoFind(LPCTSTR pszWhat,DWORD dwFlags,WhereType where)
1216 {
1217   CConfigToolDoc *pDoc=CConfigTool::GetConfigToolDoc();
1218   int nCount=pDoc->ItemCount();
1219   static LPCTSTR arWhereImage[]={_T("name"),_T("macro"),_T("description string"),_T("current value"),_T("default value")};
1220   
1221   CString strFind(pszWhat);
1222   if(!(dwFlags&FR_MATCHCASE)){
1223     strFind.MakeLower();
1224   }
1225   
1226   HTREEITEM h=GetSelectedItem();
1227   int nItem;  
1228   if(!h){
1229     nItem=0;
1230   } else {
1231     for(nItem=nCount-1;nItem>=0;--nItem) {
1232       if(h==pDoc->Item(nItem)->HItem()){
1233         break;
1234       }
1235     }
1236     ASSERT(nItem>=0);
1237   }
1238
1239   CConfigItem *pItem=NULL;
1240   for(int i=0;i<nCount;i++){
1241     if(dwFlags&FR_DOWN){
1242       nItem=(nItem+1)%nCount;
1243     } else {
1244       nItem=(nCount+nItem-1)%nCount;
1245     }
1246     pItem=pDoc->Item(nItem);
1247     
1248     CString strName(pItem->StringValue(where));
1249     if(0==(dwFlags&FR_MATCHCASE)){
1250       strName.MakeLower();
1251     }
1252     int nIndex=strName.Find(strFind);
1253     if(-1!=nIndex){
1254       if(dwFlags&FR_WHOLEWORD){
1255         // Enforce whole-word semantics: to left and right
1256         if(nIndex>0 && IsWordChar(strName[nIndex-1])){
1257           continue;
1258         }
1259         nIndex+=strFind.GetLength();
1260         if(nIndex<strName.GetLength() && IsWordChar(strName[nIndex])){
1261           continue;
1262         }
1263       }         
1264       break;
1265     }
1266   }
1267   
1268   if(i<nCount){
1269     if(m_hExpandedForFind){
1270       Expand(m_hExpandedForFind,TVE_COLLAPSE);
1271     }
1272     HTREEITEM h=pItem->HItem();
1273     // Is h visible?
1274     for(HTREEITEM hv=GetFirstVisibleItem();hv;hv=GetNextVisibleItem(hv)){
1275       if(hv==h){
1276         break;
1277       }
1278     }
1279     if(NULL==hv){
1280       // we want to record the highest unexpanded item
1281       for(HTREEITEM hv=GetParentItem(h);hv;hv=GetParentItem(hv)){
1282         const UINT selflag = TVIS_EXPANDED;             
1283         if(0==(GetItemState( hv, selflag ) & selflag )){
1284           m_hExpandedForFind=hv;
1285         }
1286       }
1287     }
1288     EnsureVisible(h);
1289     SelectItem(h);
1290     
1291   } else {
1292     CUtils::MessageBoxF(_T("Cannot find the %s '%s'"),arWhereImage[where],pszWhat);
1293   }
1294   return pItem;
1295 }
1296
1297 bool CControlView::IsWordChar(TCHAR c)
1298 {
1299   return _istalnum(c) || _TCHAR('_')==c;
1300 }
1301
1302 void CControlView::OnUpdateEditFindAgain(CCmdUI* pCmdUI) 
1303 {
1304   pCmdUI->Enable(!CConfigTool::GetMain()->m_bFindInProgress && !CConfigTool::GetConfigToolDoc()->m_strFind.IsEmpty() && CWnd::GetFocus() && m_hWnd==CWnd::GetFocus()->m_hWnd);  
1305 }
1306
1307 bool CControlView::SelectItem(const CConfigItem *pItem)
1308 {
1309 #ifdef PLUGIN
1310   CConfigTool::GetMain()->ShoweCosBar();
1311 #else
1312 #endif
1313   return SelectItem(pItem->HItem());
1314 }
1315
1316 void CControlView::OnUpdateEditFind(CCmdUI* pCmdUI) 
1317 {
1318   pCmdUI->Enable(!CConfigTool::GetMain()->m_bFindInProgress);   
1319 }
1320
1321 BOOL CControlView::PreTranslateMessage(MSG* pMsg) 
1322 {
1323   // We handle WM_KEYDOWN here to avoid the problem of the keyboard buffer not being emptied
1324   if(WM_KEYDOWN==pMsg->message){
1325     HTREEITEM h=GetSelectedItem();
1326     if(h){
1327                     switch(pMsg->wParam){
1328         case VK_SPACE:
1329           if(BumpItem(h,0)){ // toggle boolean
1330                                         return true;
1331           }
1332           break;
1333         case VK_TAB:
1334           {
1335             bool bShift=(::GetKeyState(VK_SHIFT)&0x8000);// Shift key down
1336             if(bShift){
1337               h=GetPrevVisibleItem(h);
1338             }
1339             if(h){
1340               SelectItem(h);
1341               if(!CConfigTool::GetCellView()->InCell(h) && !bShift){
1342                 h=GetNextVisibleItem(h);
1343                 if(h){
1344                   SelectItem(h);
1345                 }
1346               }
1347             }
1348             if(NULL==h){
1349               MessageBeep (0xFFFFFFFF);
1350             }
1351             // Always handle this message to keep focus within the tree control
1352             return true;
1353           }
1354         }
1355     }
1356   }
1357   return CTreeView::PreTranslateMessage(pMsg);
1358 }
1359
1360 void CControlView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
1361 {
1362   HTREEITEM h=GetSelectedItem();
1363   if(h){
1364     switch(nChar){
1365     case _TCHAR('>'):
1366       if(!BumpItem(h,+1)){
1367         MessageBeep(0xffff);
1368       }
1369       return;
1370     case _TCHAR('<'):
1371       if(!BumpItem(h,-1)){
1372         MessageBeep(0xffff);
1373       }
1374       return;
1375     }
1376   }
1377   
1378   CTreeView::OnChar(nChar, nRepCnt, nFlags);
1379 }
1380
1381 LRESULT CControlView::OnSetFont(WPARAM, LPARAM)
1382 {
1383   LRESULT rc=Default();
1384   CRect rect;
1385   GetItemRect(GetFirstVisibleItem(),rect,FALSE);
1386   m_nItemHeight=rect.Height();
1387   RecalcWorkSpaceSize();
1388   return rc;
1389 }
1390
1391 void CControlView::OnUnload()
1392 {
1393   if(IDYES==CUtils::MessageBoxFT(MB_YESNO|MB_DEFBUTTON2,_T("Are you sure you wish to unload this package?"))){
1394     TI(m_hContext).Unload();
1395     CConfigTool::GetConfigToolDoc()->RegenerateData();
1396   }
1397 }
1398
1399 void CControlView::OnDeleteitem(NMHDR*, LRESULT* pResult) 
1400 {
1401   if(CConfigTool::GetCellView()){
1402     CConfigTool::GetCellView()->Invalidate();
1403   } 
1404         *pResult = 0;
1405 }
1406
1407 void CControlView::OnWhatsThis() 
1408 {
1409   DWORD dwPos=GetMessagePos();
1410   
1411   HH_POPUP hhp;
1412   hhp.cbStruct=sizeof(hhp);
1413   hhp.idString=0;
1414   hhp.hinst=AfxGetInstanceHandle();
1415   hhp.pszText=TI(m_hContext).Desc();
1416   hhp.pt.x=GET_X_LPARAM(dwPos);
1417   hhp.pt.y=GET_Y_LPARAM(dwPos);
1418   hhp.clrForeground=(COLORREF)-1; //default 
1419   hhp.clrBackground=GetSysColor(COLOR_INFOBK); 
1420   hhp.rcMargins=CRect(-1,-1,-1,-1);
1421   hhp.pszFont=NULL;
1422
1423   HtmlHelp( 
1424     m_hWnd,
1425     NULL,
1426     HH_DISPLAY_TEXT_POPUP, //HH_TP_HELP_CONTEXTMENU, 
1427     (DWORD)&hhp
1428     ); 
1429         
1430 }
1431
1432 void CControlView::Refresh(LPCTSTR pszMacroName)
1433 {
1434   const CConfigItem * pItem=CConfigTool::GetConfigToolDoc()->Find(pszMacroName);
1435   if(pItem){ // will be NULL if item has been removed
1436     Refresh(pItem->HItem());
1437   }
1438 }
1439
1440 BOOL CControlView::OnHelpInfo(HELPINFO*) 
1441 {
1442   return CConfigTool::GetConfigToolDoc()->ShowURL(CUtils::LoadString(IDS_CONTROL_VIEW_HELP));   
1443 }
1444
1445 LRESULT CControlView::OnMenuChar(UINT, UINT, CMenu*)
1446 {
1447   const MSG *pMsg=GetCurrentMessage();
1448   // punt to the mainframe to deal with shortcuts in popups
1449   return AfxGetMainWnd()->SendMessage(pMsg->message,pMsg->wParam,pMsg->lParam);
1450 }