1 //####COPYRIGHTBEGIN####
3 // ----------------------------------------------------------------------------
4 // Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
6 // This program is part of the eCos host tools.
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)
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
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.
22 // ----------------------------------------------------------------------------
24 //####COPYRIGHTEND####
25 //===========================================================================
26 //#####DESCRIPTIONBEGIN####
33 // Description: Implementation of a the cell window view class
40 //####DESCRIPTIONEND####
42 //===========================================================================
45 #include "ConfigTool.h"
47 #include "ControlView.h"
48 #include "ConfigItem.h"
49 #include "IntegerEdit.h"
50 #include "DoubleEdit.h"
51 #include "StringEdit.h"
52 #include "ComboEdit.h"
55 #include "ConfigToolDoc.h"
60 #define INCLUDEFILE "ide.guicommon.h" // for ID_EDIT_FINDAGAIN
61 #include "IncludeSTL.h"
67 static char THIS_FILE[] = __FILE__;
70 /////////////////////////////////////////////////////////////////////////////
73 IMPLEMENT_DYNCREATE(CCellView, CView)
75 CCellView::CCellView():
76 m_bComboSellPending(false)
80 m_GrayPen.CreatePen(PS_SOLID,1,RGB(192,192,192));
81 CConfigTool::SetCellView(this);
84 CCellView::~CCellView()
87 CConfigTool::SetCellView(0);
91 BEGIN_MESSAGE_MAP(CCellView, CView)
92 //{{AFX_MSG_MAP(CCellView)
99 ON_COMMAND(ID_EDIT_FIND,OnEditFind)
100 ON_COMMAND(ID_EDIT_FINDAGAIN,OnEditFindAgain)
101 ON_UPDATE_COMMAND_UI(ID_EDIT_FINDAGAIN, OnUpdateEditFindAgain)
103 ON_UPDATE_COMMAND_UI(ID_EDIT_FIND, OnUpdateEditFind)
105 ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
106 ON_COMMAND(ID_EDIT_CUT, OnEditCut)
107 ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
108 ON_COMMAND(ID_EDIT_CLEAR, OnEditDelete)
109 ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateEditCopy)
110 ON_UPDATE_COMMAND_UI(ID_EDIT_CUT, OnUpdateEditCut)
111 ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, OnUpdateEditPaste)
112 ON_UPDATE_COMMAND_UI(ID_EDIT_CLEAR, OnUpdateEditDelete)
114 ON_MESSAGE(WM_CANCEL_EDIT,OnCancelEdit)
119 /////////////////////////////////////////////////////////////////////////////
122 void CCellView::OnInitialUpdate()
124 m_nFirstVisibleItem=0;
125 CView::OnInitialUpdate();
128 void CCellView::OnDraw(CDC* pDC)
130 CTreeCtrl &Tree=CConfigTool::GetControlView()->GetTreeCtrl();
132 CConfigToolDoc* pDoc=CConfigTool::GetConfigToolDoc();
133 if(pDoc->ItemCount()>0)
136 Tree.GetItemRect(Tree.GetRootItem(),rect,TRUE);
137 m_nFirstVisibleItem=rect.top;
140 GetClientRect(rcClient);
141 CPen *pOldPen=pDC->SelectObject(&m_GrayPen);
142 CFont *pOldFont=pDC->SelectObject(CConfigTool::GetControlView()->GetFont());
143 pDC->SetBkMode(TRANSPARENT);
146 pDC->GetClipBox(rcClip);
149 int dy=CConfigTool::GetControlView()->GetItemHeight();
151 for(HTREEITEM h=Tree.GetFirstVisibleItem();h;h=Tree.GetNextVisibleItem(h))
153 if(cy>rcClip.bottom){
157 CRect rcEdit(0,cy,rcClient.right,cy+dy);
160 pDC->MoveTo(rcClient.left,rcEdit.top);
161 pDC->LineTo(rcClient.right,rcEdit.top);
163 CConfigItem &ti=TI(h);
166 case CConfigItem::Enum:
171 case CConfigItem::Integer:
172 case CConfigItem::Double:
173 case CConfigItem::String:
178 CString str(ti.StringValue());
179 // cell contents is greyed if the option is not both active and modifiable
180 // or if a booldata item is not enabled
181 const CdlValuable valuable = ti.GetCdlValuable();
182 // check for a package explicitly because is_modifiable() returns true for a package
183 pDC->SetTextColor (GetSysColor ((! valuable) || (valuable->is_modifiable () && valuable->is_active () && ((! ti.HasBool ()) || ti.IsEnabled ()) && ! ti.IsPackage ()) ? COLOR_WINDOWTEXT : COLOR_GRAYTEXT));
184 pDC->TextOut(rcEdit.left,rcEdit.top,str);
192 pDC->MoveTo(rcClient.left,cy);
193 pDC->LineTo(rcClient.right,cy);
194 pDC->SelectObject(pOldPen);
195 pDC->SelectObject(pOldFont);
199 /////////////////////////////////////////////////////////////////////////////
200 // CCellView diagnostics
203 void CCellView::AssertValid() const
205 CView::AssertValid();
208 void CCellView::Dump(CDumpContext& dc) const
214 /////////////////////////////////////////////////////////////////////////////
215 // CCellView message handlers
217 void CCellView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
221 case CConfigToolDoc::IntFormatChanged:
223 for(HTREEITEM h=CConfigTool::GetControlView()->GetFirstVisibleItem();h;h=CConfigTool::GetControlView()->GetNextVisibleItem(h)){
224 CConfigItem &ti=TI(h);
225 if(ti.Type()==CConfigItem::Integer) {
228 InvalidateRect(rect);
231 if(m_pwndCell && TI(m_hInCell).Type()==CConfigItem::Integer) {
233 m_pwndCell->GetWindowText(strData);
235 CUtils::StrToItemIntegerType(strData,n);
236 m_pwndCell->SetWindowText(CUtils::IntToStr(n,CConfigTool::GetConfigToolDoc()->m_bHex));
240 case CConfigToolDoc::Clear:
243 UpdateWindow(); // This prevents cell view half of config pane still being displayed
245 case CConfigToolDoc::ValueChanged:
247 CConfigItem *pti=(CConfigItem *)pHint;
249 GetItemRect(pti->HItem(),rect);
250 InvalidateRect(rect);
259 UNUSED_ALWAYS(pSender);
262 void CCellView::GetItemRect(HTREEITEM h,CRect & rect) const
265 GetClientRect(rcClient);
267 CConfigTool::GetControlView()->GetItemRect( h, &rect, FALSE );
268 rect.left=rcClient.left;
269 rect.right=rcClient.right;
272 void CCellView::GetInCellRect(HTREEITEM h, CRect & rect, BOOL bDropped) const
274 CConfigItem &ti=TI(h);
277 case CConfigItem::Enum:
281 ti.EvalEnumStrings(arEnum);
282 rect.bottom += (2+(int)arEnum.GetSize()-1)*rect.Height();
285 case CConfigItem::Integer:
286 case CConfigItem::Double:
287 case CConfigItem::String:
290 //rect.DeflateRect(2,2); // To allow room for the border we draw ourselves
291 //rect.InflateRect(2,2);
298 ItemIntegerType CCellView::GetCellValue() const
300 // If the item is being edited in-cell, we'll get the data from the control
301 ItemIntegerType rc=0;
302 switch(TI(m_hInCell).Type()){
303 case CConfigItem::Integer:
306 m_pwndCell->GetWindowText(strData);
307 if(!CUtils::StrToItemIntegerType(strData,rc)){
312 case CConfigItem::Enum:
314 case CConfigItem::Boolean:
315 case CConfigItem::Radio:
316 //rc=((CTreeComboBox *)m_pwndCell)->GetCurSel();
317 rc=((CComboEdit *)m_pwndCell)->GetCurSel();
320 case CConfigItem::String:
322 int type=TI(m_hInCell).Type();
330 void CCellView::CancelCellEdit(bool bApplyChanges)
333 CConfigItem &ti=TI(m_hInCell);
336 m_pwndCell->GetWindowText(strValue);
337 // Ignore empty strings in integer or floating cells - these are legal as intermediate values but not now
338 if(strValue!=ti.StringValue() && (!strValue.IsEmpty() || (ti.Type()!=CConfigItem::Integer && ti.Type()!=CConfigItem::Double))){
339 CConfigTool::GetConfigToolDoc()->SetValue (ti, strValue);
348 BOOL CCellView::InCell(HTREEITEM h)
351 if(h && TI(h).IsEnabled()){
352 CConfigItem &ti=TI(h);
353 // edit cell only if option is both active and modifiable
354 const CdlValuable valuable = ti.GetCdlValuable();
355 // check packages explicitly because is_modifiable() returns true for a package
356 if ((! valuable) || (valuable->is_modifiable () && valuable->is_active () && ! ti.IsPackage ())){
358 GetItemRect(h,rcEdit);
361 case CConfigItem::Double:
364 CUtils::StrToDouble(ti.StringValue(),d);
365 m_pwndCell=new CDoubleEdit(d);
366 m_pwndCell->Create(WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL, rcEdit, this, IDC_CELL);
369 case CConfigItem::Integer:
372 CUtils::StrToItemIntegerType(ti.StringValue(),i);
373 m_pwndCell=new CIntegerEdit(i);
375 m_pwndCell->Create(WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL, rcEdit, this, IDC_CELL);
377 case CConfigItem::String:
379 CStringEdit *pStringEdit=new CStringEdit(ti.StringValue());
380 m_pwndCell=pStringEdit;
381 m_pwndCell->Create(WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL, rcEdit, this, IDC_CELL);
382 pStringEdit->EnableDoubleClickEdit(true,IDC_CT_EDIT);
386 case CConfigItem::Enum:
389 ti.EvalEnumStrings(arEnum);
390 rcEdit.bottom += (2+(int)arEnum.GetSize()-1)*rcEdit.Height();
391 m_pwndCell=new CComboEdit(ti.StringValue(),arEnum);
392 m_pwndCell->Create(WS_CHILD|WS_VISIBLE|CBS_DROPDOWNLIST, rcEdit, this, IDC_CELL);
400 m_pwndCell->SetFont(CFont::FromHandle((HFONT)GetStockObject(DEFAULT_GUI_FONT)));
401 m_pwndCell->SetFocus();
402 m_pwndCell->GetWindowText(m_strInitialCell);
405 return NULL!=m_hInCell;
408 void CCellView::OnLButtonDown(UINT nFlags, CPoint point)
410 UNUSED_ALWAYS(nFlags);
411 CTreeCtrl &Tree=CConfigTool::GetControlView()->GetTreeCtrl();
413 HTREEITEM h=HitTest();
419 // Relay to the splitter
420 ClientToScreen(&point);
421 GetParent()->ScreenToClient(&point);
422 GetParent()->SendMessage(WM_LBUTTONDOWN,(WPARAM)nFlags,MAKELPARAM(point.x,point.y));
425 void CCellView::OnSize(UINT nType, int cx, int cy)
427 CView::OnSize(nType, cx, cy);
429 //sdf1 UpdateWindow();
431 GetItemRect(m_hInCell,rect);
432 m_pwndCell->MoveWindow(rect,TRUE);
437 int CCellView::OnCreate(LPCREATESTRUCT lpCreateStruct)
439 if (CView::OnCreate(lpCreateStruct) == -1)
447 BOOL CCellView::PreCreateWindow(CREATESTRUCT& cs)
449 // TODO: Add your specialized code here and/or call the base class
450 cs.style &= (~WS_BORDER);
451 return CView::PreCreateWindow(cs);
454 void CCellView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
456 CView::OnVScroll(nSBCode, nPos, pScrollBar);
460 void CCellView::Sync()
462 CTreeCtrl &t=CConfigTool::GetControlView()->GetTreeCtrl();
464 t.GetItemRect(t.GetRootItem(),rect,TRUE);
467 if(pos!=m_nFirstVisibleItem){
468 ScrollWindow(0,pos-m_nFirstVisibleItem);
474 void CCellView::OnMouseMove(UINT nFlags, CPoint point)
476 // Relay the mouse event to the splitter
477 ClientToScreen(&point);
478 GetParent()->ScreenToClient(&point);
479 GetParent()->SendMessage(WM_MOUSEMOVE,(WPARAM)nFlags,MAKELPARAM(point.x,point.y));
483 BOOL CCellView::OnMouseWheel(UINT, short zDelta, CPoint)
485 UINT nScrollCode=((zDelta<0)?SB_LINEDOWN:SB_LINEUP);
486 LPARAM lParam=(LPARAM)GetScrollBarCtrl(SB_VERT)->GetSafeHwnd();
488 for(int i=0;i<abs(zDelta)/WHEEL_DELTA;i++){
489 CConfigTool::GetControlView()->SendMessage(WM_VSCROLL,MAKEWPARAM(nScrollCode,0),lParam);
496 void CCellView::OnEditFind()
498 CConfigTool::GetControlView()->OnEditFind();
501 void CCellView::OnEditFindAgain()
503 CConfigTool::GetControlView()->OnEditFindAgain();
506 void CCellView::OnUpdateEditFindAgain(CCmdUI* pCmdUI)
508 CConfigTool::GetControlView()->OnUpdateEditFindAgain(pCmdUI);
511 void CCellView::OnRButtonDown(UINT nFlags, CPoint point)
513 UNUSED_ALWAYS(nFlags);
514 // Make the r-click have an effect equivalent to that when on the control view part
515 CControlView *pv=CConfigTool::GetControlView();
516 HTREEITEM h=HitTest();
520 // point is in client coords
521 ClientToScreen(&point);
522 pv->ShowPopupMenu(h,point);
525 void CCellView::OnUpdateEditFind(CCmdUI* pCmdUI)
527 CConfigTool::GetControlView()->OnUpdateEditFind(pCmdUI);
530 BOOL CCellView::OnEraseBkgnd(CDC* pDC)
534 const MSG *pMsg=GetCurrentMessage();
536 if (::GetClassInfo(NULL, _T("AfxFrameOrView42ud"), &wndcls)){
537 TRACE(_T("proc=%08x hbrBackground=%08x "),wndcls.lpfnWndProc,wndcls.hbrBackground);
540 TRACE(_T("msg=%d hWnd=%08x wParam=%08x lParam=%08x m_pfnSuper=%08x super=%08x\n"),
541 pMsg->message,pMsg->hwnd, pMsg->lParam,pMsg->wParam,m_pfnSuper, GetSuperWndProcAddr());
543 return CView::OnEraseBkgnd(pDC);
547 // Work around bug apparently caused by SlickEdit
549 pDC->GetClipBox(rcClient);
550 pDC->FillSolidRect(rcClient,GetSysColor(COLOR_WINDOW));
555 BOOL CCellView::PreTranslateMessage(MSG* pMsg)
557 CTreeCtrl &Tree=CConfigTool::GetControlView()->GetTreeCtrl();
558 if(WM_KEYDOWN==pMsg->message){
559 switch(pMsg->wParam){
562 HTREEITEM h=Tree.GetSelectedItem();
564 if(0==(::GetKeyState(VK_SHIFT)&0x8000)){
565 // Shift key not down
566 h=Tree.GetNextVisibleItem(h);
573 MessageBeep (0xFFFFFFFF);
575 // Always handle this message to keep focus within the tree control
581 return CView::PreTranslateMessage(pMsg);
584 HTREEITEM CCellView::HitTest()
586 // Can use the control view's hittest because all it's interested in is the y coord
589 DWORD dwPos=GetMessagePos();
590 CTreeCtrl &Tree=CConfigTool::GetControlView()->GetTreeCtrl();
591 tvi.pt.y=GET_Y_LPARAM(dwPos);
592 Tree.ScreenToClient(&tvi.pt);
594 return Tree.HitTest(&tvi);
598 void CCellView::OnEditCopy()
601 m_pwndCell->OnEditCopy();
605 void CCellView::OnEditCut()
608 m_pwndCell->OnEditCut();
612 void CCellView::OnEditPaste()
615 m_pwndCell->OnEditPaste();
619 void CCellView::OnEditDelete()
622 m_pwndCell->OnEditDelete();
626 void CCellView::OnUpdateEditCopy(CCmdUI* pCmdUI)
629 m_pwndCell->OnUpdateEditCopy(pCmdUI);
631 pCmdUI->Enable(false);
635 void CCellView::OnUpdateEditCut(CCmdUI* pCmdUI)
638 m_pwndCell->OnUpdateEditCut(pCmdUI);
640 pCmdUI->Enable(false);
644 void CCellView::OnUpdateEditPaste(CCmdUI* pCmdUI)
647 m_pwndCell->OnUpdateEditPaste(pCmdUI);
649 pCmdUI->Enable(false);
653 void CCellView::OnUpdateEditDelete(CCmdUI* pCmdUI)
656 m_pwndCell->OnUpdateEditDelete(pCmdUI);
658 pCmdUI->Enable(false);
662 BOOL CCellView::OnHelpInfo(HELPINFO* pHelpInfo)
664 return CConfigTool::GetControlView()->OnHelpInfo(pHelpInfo);
667 LRESULT CCellView::OnCancelEdit(WPARAM wParam, LPARAM)
669 CancelCellEdit(wParam);