--- /dev/null
+//####COPYRIGHTBEGIN####
+//
+// ----------------------------------------------------------------------------
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
+//
+// This program is part of the eCos host tools.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 of the License, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+// more details.
+//
+// You should have received a copy of the GNU General Public License along with
+// this program; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// ----------------------------------------------------------------------------
+//
+//####COPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): sdf
+// Contact(s): sdf
+// Date: 1998/08/11
+// Version: 0.01
+// Purpose:
+// Description: Implementation of a the cell window view class
+// Requires:
+// Provides:
+// See also:#include
+// Known bugs:
+// Usage:
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+#include "stdafx.h"
+#include "ConfigTool.h"
+#include "CellView.h"
+#include "ControlView.h"
+#include "ConfigItem.h"
+#include "IntegerEdit.h"
+#include "DoubleEdit.h"
+#include "StringEdit.h"
+#include "ComboEdit.h"
+
+#include "CTUtils.h"
+#include "ConfigToolDoc.h"
+
+#include "resource.h"
+
+#ifdef PLUGIN
+ #define INCLUDEFILE "ide.guicommon.h" // for ID_EDIT_FINDAGAIN
+ #include "IncludeSTL.h"
+#endif
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CCellView
+
+IMPLEMENT_DYNCREATE(CCellView, CView)
+
+CCellView::CCellView():
+ m_bComboSellPending(false)
+{
+ m_hInCell=NULL;
+ m_pwndCell=NULL;
+ m_GrayPen.CreatePen(PS_SOLID,1,RGB(192,192,192));
+ CConfigTool::SetCellView(this);
+}
+
+CCellView::~CCellView()
+{
+ deleteZ(m_pwndCell);
+ CConfigTool::SetCellView(0);
+}
+
+
+BEGIN_MESSAGE_MAP(CCellView, CView)
+ //{{AFX_MSG_MAP(CCellView)
+ ON_WM_LBUTTONDOWN()
+ ON_WM_SIZE()
+ ON_WM_CREATE()
+ ON_WM_VSCROLL()
+ ON_WM_MOUSEMOVE()
+ ON_WM_MOUSEWHEEL()
+ ON_COMMAND(ID_EDIT_FIND,OnEditFind)
+ ON_COMMAND(ID_EDIT_FINDAGAIN,OnEditFindAgain)
+ ON_UPDATE_COMMAND_UI(ID_EDIT_FINDAGAIN, OnUpdateEditFindAgain)
+ ON_WM_RBUTTONDOWN()
+ ON_UPDATE_COMMAND_UI(ID_EDIT_FIND, OnUpdateEditFind)
+ ON_WM_ERASEBKGND()
+ ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
+ ON_COMMAND(ID_EDIT_CUT, OnEditCut)
+ ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
+ ON_COMMAND(ID_EDIT_CLEAR, OnEditDelete)
+ ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateEditCopy)
+ ON_UPDATE_COMMAND_UI(ID_EDIT_CUT, OnUpdateEditCut)
+ ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, OnUpdateEditPaste)
+ ON_UPDATE_COMMAND_UI(ID_EDIT_CLEAR, OnUpdateEditDelete)
+ ON_WM_HELPINFO()
+ ON_MESSAGE(WM_CANCEL_EDIT,OnCancelEdit)
+
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CCellView drawing
+
+void CCellView::OnInitialUpdate()
+{
+ m_nFirstVisibleItem=0;
+ CView::OnInitialUpdate();
+}
+
+void CCellView::OnDraw(CDC* pDC)
+{
+ CTreeCtrl &Tree=CConfigTool::GetControlView()->GetTreeCtrl();
+
+ CConfigToolDoc* pDoc=CConfigTool::GetConfigToolDoc();
+ if(pDoc->ItemCount()>0)
+ {
+ CRect rect;
+ Tree.GetItemRect(Tree.GetRootItem(),rect,TRUE);
+ m_nFirstVisibleItem=rect.top;
+
+ CRect rcClient;
+ GetClientRect(rcClient);
+ CPen *pOldPen=pDC->SelectObject(&m_GrayPen);
+ CFont *pOldFont=pDC->SelectObject(CConfigTool::GetControlView()->GetFont());
+ pDC->SetBkMode(TRANSPARENT);
+
+ CRect rcClip;
+ pDC->GetClipBox(rcClip);
+
+ CPtrArray arItems;
+ int dy=CConfigTool::GetControlView()->GetItemHeight();
+ int cy=0;
+ for(HTREEITEM h=Tree.GetFirstVisibleItem();h;h=Tree.GetNextVisibleItem(h))
+ {
+ if(cy>rcClip.bottom){
+ break;
+ }
+
+ CRect rcEdit(0,cy,rcClient.right,cy+dy);
+ cy+=dy;
+
+ pDC->MoveTo(rcClient.left,rcEdit.top);
+ pDC->LineTo(rcClient.right,rcEdit.top);
+
+ CConfigItem &ti=TI(h);
+ if(h!=m_hInCell){
+ switch(ti.Type()){
+ case CConfigItem::Enum:
+ // Using combobox
+ rcEdit.left+=2;
+ rcEdit.top+=2;
+ // fall through
+ case CConfigItem::Integer:
+ case CConfigItem::Double:
+ case CConfigItem::String:
+ // Using editbox
+ rcEdit.top+=2;
+ rcEdit.left+=3;
+ {
+ CString str(ti.StringValue());
+ // cell contents is greyed if the option is not both active and modifiable
+ // or if a booldata item is not enabled
+ const CdlValuable valuable = ti.GetCdlValuable();
+ // check for a package explicitly because is_modifiable() returns true for a package
+ pDC->SetTextColor (GetSysColor ((! valuable) || (valuable->is_modifiable () && valuable->is_active () && ((! ti.HasBool ()) || ti.IsEnabled ()) && ! ti.IsPackage ()) ? COLOR_WINDOWTEXT : COLOR_GRAYTEXT));
+ pDC->TextOut(rcEdit.left,rcEdit.top,str);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ pDC->MoveTo(rcClient.left,cy);
+ pDC->LineTo(rcClient.right,cy);
+ pDC->SelectObject(pOldPen);
+ pDC->SelectObject(pOldFont);
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CCellView diagnostics
+
+#ifdef _DEBUG
+void CCellView::AssertValid() const
+{
+ CView::AssertValid();
+}
+
+void CCellView::Dump(CDumpContext& dc) const
+{
+ CView::Dump(dc);
+}
+#endif //_DEBUG
+
+/////////////////////////////////////////////////////////////////////////////
+// CCellView message handlers
+
+void CCellView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
+{
+ switch(lHint)
+ {
+ case CConfigToolDoc::IntFormatChanged:
+ {
+ for(HTREEITEM h=CConfigTool::GetControlView()->GetFirstVisibleItem();h;h=CConfigTool::GetControlView()->GetNextVisibleItem(h)){
+ CConfigItem &ti=TI(h);
+ if(ti.Type()==CConfigItem::Integer) {
+ CRect rect;
+ GetItemRect(h,rect);
+ InvalidateRect(rect);
+ }
+ }
+ if(m_pwndCell && TI(m_hInCell).Type()==CConfigItem::Integer) {
+ CString strData;
+ m_pwndCell->GetWindowText(strData);
+ ItemIntegerType n;
+ CUtils::StrToItemIntegerType(strData,n);
+ m_pwndCell->SetWindowText(CUtils::IntToStr(n,CConfigTool::GetConfigToolDoc()->m_bHex));
+ }
+ }
+ break;
+ case CConfigToolDoc::Clear:
+ deleteZ(m_pwndCell);
+ Invalidate();
+ UpdateWindow(); // This prevents cell view half of config pane still being displayed
+ break;
+ case CConfigToolDoc::ValueChanged:
+ {
+ CConfigItem *pti=(CConfigItem *)pHint;
+ CRect rect;
+ GetItemRect(pti->HItem(),rect);
+ InvalidateRect(rect);
+ }
+ break;
+ case 0:
+ Invalidate();
+ break;
+ default:
+ break;
+ }
+ UNUSED_ALWAYS(pSender);
+}
+
+void CCellView::GetItemRect(HTREEITEM h,CRect & rect) const
+{
+ CRect rcClient;
+ GetClientRect(rcClient);
+
+ CConfigTool::GetControlView()->GetItemRect( h, &rect, FALSE );
+ rect.left=rcClient.left;
+ rect.right=rcClient.right;
+}
+
+void CCellView::GetInCellRect(HTREEITEM h, CRect & rect, BOOL bDropped) const
+{
+ CConfigItem &ti=TI(h);
+ GetItemRect(h,rect);
+ switch(ti.Type()){
+ case CConfigItem::Enum:
+ // Using combobox
+ if(bDropped) {
+ CStringArray arEnum;
+ ti.EvalEnumStrings(arEnum);
+ rect.bottom += (2+(int)arEnum.GetSize()-1)*rect.Height();
+ }
+ break;
+ case CConfigItem::Integer:
+ case CConfigItem::Double:
+ case CConfigItem::String:
+ // Using editbox
+ //rect.bottom++;
+ //rect.DeflateRect(2,2); // To allow room for the border we draw ourselves
+ //rect.InflateRect(2,2);
+ break;
+ default:
+ return;
+ }
+}
+
+ItemIntegerType CCellView::GetCellValue() const
+{
+ // If the item is being edited in-cell, we'll get the data from the control
+ ItemIntegerType rc=0;
+ switch(TI(m_hInCell).Type()){
+ case CConfigItem::Integer:
+ {
+ CString strData;
+ m_pwndCell->GetWindowText(strData);
+ if(!CUtils::StrToItemIntegerType(strData,rc)){
+ rc=0;
+ }
+ }
+ break;
+ case CConfigItem::Enum:
+ /*
+ case CConfigItem::Boolean:
+ case CConfigItem::Radio:
+ //rc=((CTreeComboBox *)m_pwndCell)->GetCurSel();
+ rc=((CComboEdit *)m_pwndCell)->GetCurSel();
+ break;
+ */
+ case CConfigItem::String:
+ default:
+ int type=TI(m_hInCell).Type();
+ UNUSED_ALWAYS(type);
+ ASSERT(FALSE);
+ break;
+ }
+ return rc;
+}
+
+void CCellView::CancelCellEdit(bool bApplyChanges)
+{
+ if(m_hInCell){
+ CConfigItem &ti=TI(m_hInCell);
+ if(bApplyChanges){
+ CString strValue;
+ m_pwndCell->GetWindowText(strValue);
+ // Ignore empty strings in integer or floating cells - these are legal as intermediate values but not now
+ if(strValue!=ti.StringValue() && (!strValue.IsEmpty() || (ti.Type()!=CConfigItem::Integer && ti.Type()!=CConfigItem::Double))){
+ CConfigTool::GetConfigToolDoc()->SetValue (ti, strValue);
+ }
+ }
+
+ deleteZ(m_pwndCell);
+ m_hInCell=NULL;
+ }
+}
+
+BOOL CCellView::InCell(HTREEITEM h)
+{
+ CancelCellEdit();
+ if(h && TI(h).IsEnabled()){
+ CConfigItem &ti=TI(h);
+ // edit cell only if option is both active and modifiable
+ const CdlValuable valuable = ti.GetCdlValuable();
+ // check packages explicitly because is_modifiable() returns true for a package
+ if ((! valuable) || (valuable->is_modifiable () && valuable->is_active () && ! ti.IsPackage ())){
+ CRect rcEdit;
+ GetItemRect(h,rcEdit);
+ rcEdit.bottom++;
+ switch(ti.Type()){
+ case CConfigItem::Double:
+ {
+ double d;
+ CUtils::StrToDouble(ti.StringValue(),d);
+ m_pwndCell=new CDoubleEdit(d);
+ m_pwndCell->Create(WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL, rcEdit, this, IDC_CELL);
+ }
+ break;
+ case CConfigItem::Integer:
+ {
+ ItemIntegerType i;
+ CUtils::StrToItemIntegerType(ti.StringValue(),i);
+ m_pwndCell=new CIntegerEdit(i);
+ }
+ m_pwndCell->Create(WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL, rcEdit, this, IDC_CELL);
+ break;
+ case CConfigItem::String:
+ {
+ CStringEdit *pStringEdit=new CStringEdit(ti.StringValue());
+ m_pwndCell=pStringEdit;
+ m_pwndCell->Create(WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL, rcEdit, this, IDC_CELL);
+ pStringEdit->EnableDoubleClickEdit(true,IDC_CT_EDIT);
+ }
+
+ break;
+ case CConfigItem::Enum:
+ {
+ CStringArray arEnum;
+ ti.EvalEnumStrings(arEnum);
+ rcEdit.bottom += (2+(int)arEnum.GetSize()-1)*rcEdit.Height();
+ m_pwndCell=new CComboEdit(ti.StringValue(),arEnum);
+ m_pwndCell->Create(WS_CHILD|WS_VISIBLE|CBS_DROPDOWNLIST, rcEdit, this, IDC_CELL);
+ }
+ break;
+ default:
+ return 0;
+ break;
+ }
+ m_hInCell=h;
+ m_pwndCell->SetFont(CFont::FromHandle((HFONT)GetStockObject(DEFAULT_GUI_FONT)));
+ m_pwndCell->SetFocus();
+ m_pwndCell->GetWindowText(m_strInitialCell);
+ }
+ }
+ return NULL!=m_hInCell;
+}
+
+void CCellView::OnLButtonDown(UINT nFlags, CPoint point)
+{
+ UNUSED_ALWAYS(nFlags);
+ CTreeCtrl &Tree=CConfigTool::GetControlView()->GetTreeCtrl();
+ CancelCellEdit();
+ HTREEITEM h=HitTest();
+ if(h){
+ InCell(h);
+ Tree.SelectItem(h);
+ }
+
+ // Relay to the splitter
+ ClientToScreen(&point);
+ GetParent()->ScreenToClient(&point);
+ GetParent()->SendMessage(WM_LBUTTONDOWN,(WPARAM)nFlags,MAKELPARAM(point.x,point.y));
+}
+
+void CCellView::OnSize(UINT nType, int cx, int cy)
+{
+ CView::OnSize(nType, cx, cy);
+ if(m_hInCell){
+//sdf1 UpdateWindow();
+ CRect rect;
+ GetItemRect(m_hInCell,rect);
+ m_pwndCell->MoveWindow(rect,TRUE);
+ }
+
+}
+
+int CCellView::OnCreate(LPCREATESTRUCT lpCreateStruct)
+{
+ if (CView::OnCreate(lpCreateStruct) == -1)
+ return -1;
+
+ return 0;
+}
+
+
+
+BOOL CCellView::PreCreateWindow(CREATESTRUCT& cs)
+{
+ // TODO: Add your specialized code here and/or call the base class
+ cs.style &= (~WS_BORDER);
+ return CView::PreCreateWindow(cs);
+}
+
+void CCellView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
+{
+ CView::OnVScroll(nSBCode, nPos, pScrollBar);
+ Sync();
+}
+
+void CCellView::Sync()
+{
+ CTreeCtrl &t=CConfigTool::GetControlView()->GetTreeCtrl();
+ CRect rect;
+ t.GetItemRect(t.GetRootItem(),rect,TRUE);
+ int pos=rect.top;
+
+ if(pos!=m_nFirstVisibleItem){
+ ScrollWindow(0,pos-m_nFirstVisibleItem);
+ UpdateWindow();
+ }
+}
+
+
+void CCellView::OnMouseMove(UINT nFlags, CPoint point)
+{
+ // Relay the mouse event to the splitter
+ ClientToScreen(&point);
+ GetParent()->ScreenToClient(&point);
+ GetParent()->SendMessage(WM_MOUSEMOVE,(WPARAM)nFlags,MAKELPARAM(point.x,point.y));
+}
+
+
+BOOL CCellView::OnMouseWheel(UINT, short zDelta, CPoint)
+{
+ UINT nScrollCode=((zDelta<0)?SB_LINEDOWN:SB_LINEUP);
+ LPARAM lParam=(LPARAM)GetScrollBarCtrl(SB_VERT)->GetSafeHwnd();
+ if(lParam){
+ for(int i=0;i<abs(zDelta)/WHEEL_DELTA;i++){
+ CConfigTool::GetControlView()->SendMessage(WM_VSCROLL,MAKEWPARAM(nScrollCode,0),lParam);
+ Sync();
+ }
+ }
+ return TRUE;
+}
+
+void CCellView::OnEditFind()
+{
+ CConfigTool::GetControlView()->OnEditFind();
+}
+
+void CCellView::OnEditFindAgain()
+{
+ CConfigTool::GetControlView()->OnEditFindAgain();
+}
+
+void CCellView::OnUpdateEditFindAgain(CCmdUI* pCmdUI)
+{
+ CConfigTool::GetControlView()->OnUpdateEditFindAgain(pCmdUI);
+}
+
+void CCellView::OnRButtonDown(UINT nFlags, CPoint point)
+{
+ UNUSED_ALWAYS(nFlags);
+ // Make the r-click have an effect equivalent to that when on the control view part
+ CControlView *pv=CConfigTool::GetControlView();
+ HTREEITEM h=HitTest();
+ if(h){
+ pv->SelectItem(h);
+ }
+ // point is in client coords
+ ClientToScreen(&point);
+ pv->ShowPopupMenu(h,point);
+}
+
+void CCellView::OnUpdateEditFind(CCmdUI* pCmdUI)
+{
+ CConfigTool::GetControlView()->OnUpdateEditFind(pCmdUI);
+}
+
+BOOL CCellView::OnEraseBkgnd(CDC* pDC)
+{
+ /*
+ static int x=3;
+ const MSG *pMsg=GetCurrentMessage();
+ WNDCLASS wndcls;
+ if (::GetClassInfo(NULL, _T("AfxFrameOrView42ud"), &wndcls)){
+ TRACE(_T("proc=%08x hbrBackground=%08x "),wndcls.lpfnWndProc,wndcls.hbrBackground);
+ }
+
+ TRACE(_T("msg=%d hWnd=%08x wParam=%08x lParam=%08x m_pfnSuper=%08x super=%08x\n"),
+ pMsg->message,pMsg->hwnd, pMsg->lParam,pMsg->wParam,m_pfnSuper, GetSuperWndProcAddr());
+ if(x){
+ return CView::OnEraseBkgnd(pDC);
+ }
+ */
+
+ // Work around bug apparently caused by SlickEdit
+ CRect rcClient;
+ pDC->GetClipBox(rcClient);
+ pDC->FillSolidRect(rcClient,GetSysColor(COLOR_WINDOW));
+
+ return TRUE;
+}
+
+BOOL CCellView::PreTranslateMessage(MSG* pMsg)
+{
+ CTreeCtrl &Tree=CConfigTool::GetControlView()->GetTreeCtrl();
+ if(WM_KEYDOWN==pMsg->message){
+ switch(pMsg->wParam){
+ case VK_TAB:
+ {
+ HTREEITEM h=Tree.GetSelectedItem();
+ if(h){
+ if(0==(::GetKeyState(VK_SHIFT)&0x8000)){
+ // Shift key not down
+ h=Tree.GetNextVisibleItem(h);
+ }
+ if(h){
+ CancelCellEdit();
+ Tree.SelectItem(h);
+ Tree.SetFocus();
+ } else {
+ MessageBeep (0xFFFFFFFF);
+ }
+ // Always handle this message to keep focus within the tree control
+ return true;
+ }
+ }
+ }
+ }
+ return CView::PreTranslateMessage(pMsg);
+}
+
+HTREEITEM CCellView::HitTest()
+{
+ // Can use the control view's hittest because all it's interested in is the y coord
+
+ TVHITTESTINFO tvi;
+ DWORD dwPos=GetMessagePos();
+ CTreeCtrl &Tree=CConfigTool::GetControlView()->GetTreeCtrl();
+ tvi.pt.y=GET_Y_LPARAM(dwPos);
+ Tree.ScreenToClient(&tvi.pt);
+ tvi.pt.x=0;
+ return Tree.HitTest(&tvi);
+
+}
+
+void CCellView::OnEditCopy()
+{
+ if(m_pwndCell){
+ m_pwndCell->OnEditCopy();
+ }
+}
+
+void CCellView::OnEditCut()
+{
+ if(m_pwndCell){
+ m_pwndCell->OnEditCut();
+ }
+}
+
+void CCellView::OnEditPaste()
+{
+ if(m_pwndCell){
+ m_pwndCell->OnEditPaste();
+ }
+}
+
+void CCellView::OnEditDelete()
+{
+ if(m_pwndCell){
+ m_pwndCell->OnEditDelete();
+ }
+}
+
+void CCellView::OnUpdateEditCopy(CCmdUI* pCmdUI)
+{
+ if(m_pwndCell){
+ m_pwndCell->OnUpdateEditCopy(pCmdUI);
+ } else {
+ pCmdUI->Enable(false);
+ }
+}
+
+void CCellView::OnUpdateEditCut(CCmdUI* pCmdUI)
+{
+ if(m_pwndCell){
+ m_pwndCell->OnUpdateEditCut(pCmdUI);
+ } else {
+ pCmdUI->Enable(false);
+ }
+}
+
+void CCellView::OnUpdateEditPaste(CCmdUI* pCmdUI)
+{
+ if(m_pwndCell){
+ m_pwndCell->OnUpdateEditPaste(pCmdUI);
+ } else {
+ pCmdUI->Enable(false);
+ }
+}
+
+void CCellView::OnUpdateEditDelete(CCmdUI* pCmdUI)
+{
+ if(m_pwndCell){
+ m_pwndCell->OnUpdateEditDelete(pCmdUI);
+ } else {
+ pCmdUI->Enable(false);
+ }
+}
+
+BOOL CCellView::OnHelpInfo(HELPINFO* pHelpInfo)
+{
+ return CConfigTool::GetControlView()->OnHelpInfo(pHelpInfo);
+}
+
+LRESULT CCellView::OnCancelEdit(WPARAM wParam, LPARAM)
+{
+ CancelCellEdit(wParam);
+ return 0;
+}