GME  13
InspectorList.cpp
Go to the documentation of this file.
00001 // InspectorList.cpp : implementation file
00002 //
00003 
00004 #include "stdafx.h"
00005 #include "objectinspector.h"
00006 #include "InspectorList.h"
00007 #include "InspectorDlg.h"
00008 #include "ColourPopup.h"
00009 
00010 #ifdef _DEBUG
00011 #define new DEBUG_NEW
00012 #undef THIS_FILE
00013 static char THIS_FILE[] = __FILE__;
00014 #endif
00015 
00017 // CInspectorList
00018 
00019 CInspectorList::CInspectorList(bool bCategories):m_bCategories(bCategories),m_InPlaceManager(this)
00020 {
00021         m_bIsDividerDrag=FALSE;
00022         m_ItemHeight = 16;
00023         m_ComboboxLineHeight = 13;
00024         HDC hdc = ::GetDC(NULL);
00025         if (hdc)
00026         {
00027                 m_ItemHeight = m_ItemHeight * GetDeviceCaps(hdc, LOGPIXELSY) / 96;
00028                 m_ComboboxLineHeight = m_ComboboxLineHeight * GetDeviceCaps(hdc, LOGPIXELSY) / 96;
00029                 ::ReleaseDC(NULL, hdc);
00030         }
00031 }
00032 
00033 CInspectorList::~CInspectorList()
00034 {
00035 
00036 }
00037 
00038 
00039 BEGIN_MESSAGE_MAP(CInspectorList, CListBox)
00040         //{{AFX_MSG_MAP(CInspectorList)
00041         ON_WM_LBUTTONDOWN()
00042         ON_WM_LBUTTONDBLCLK()
00043         ON_WM_LBUTTONUP()
00044         ON_WM_MOUSEMOVE()
00045         ON_CONTROL_REFLECT(LBN_SELCHANGE, OnSelChange)
00046         ON_WM_LBUTTONDBLCLK()
00047         ON_WM_VSCROLL()
00048         ON_WM_MOUSEWHEEL()
00049         ON_WM_KEYDOWN()
00050         ON_WM_SIZE()
00051         ON_WM_RBUTTONDOWN()
00052         ON_BN_CLICKED(IDC_ARROW_BUTTON, OnArrowClicked)
00053         ON_BN_CLICKED(IDC_EDITOR_BUTTON, OnEditorClicked)
00054         ON_MESSAGE(MSG_EDIT_END_OK, OnEditEndOK)
00055         ON_COMMAND(ID_LISTCONTEXT_RESETTODEFAULT, OnListContextResetToDefault)
00056         //}}AFX_MSG_MAP
00057 END_MESSAGE_MAP()
00058 
00060 // CInspectorList message handlers
00061 
00062 BOOL CInspectorList::PreCreateWindow(CREATESTRUCT& cs)
00063 {
00064         // TODO: Add your specialized code here and/or call the base class
00065         cs.style |= WS_VSCROLL |LBS_OWNERDRAWVARIABLE | LBS_NOTIFY |
00066                                 LBS_NOINTEGRALHEIGHT | LBS_EXTENDEDSEL | LBS_HASSTRINGS;
00067         cs.style&=~LBS_SORT;
00068         cs.dwExStyle |= WS_EX_CLIENTEDGE;
00069         return CListBox::PreCreateWindow(cs);
00070 }
00071 
00072 void CInspectorList::PreSubclassWindow()
00073 {
00074         m_entryFont.CreatePointFont(INSP_ENTRY_FONT_PTSIZE, INSP_ENTRY_FONT_FACE);
00075 
00076 
00077         LOGFONT logFont;
00078         memset(&logFont, 0, sizeof(LOGFONT));
00079         logFont.lfCharSet = DEFAULT_CHARSET;
00080         logFont.lfHeight = INSP_ENTRY_FONT_PTSIZE;
00081         logFont.lfWeight = FW_BOLD;
00082         lstrcpyn(logFont.lfFaceName, INSP_ENTRY_FONT_FACE, sizeof(logFont.lfFaceName) / sizeof(TCHAR));
00083 
00084         VERIFY(m_entryBoldFont.CreatePointFontIndirect(&logFont, NULL));
00085 
00086 
00087         m_hCurArrow=AfxGetApp()->LoadStandardCursor(IDC_ARROW);
00088         m_hCurSize=AfxGetApp()->LoadStandardCursor(IDC_SIZEWE);
00089 
00090 
00091 
00092         CListBox::PreSubclassWindow();
00093 
00094 }
00095 
00096 void CInspectorList::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
00097 {
00098 
00099         UINT nIndex = lpDrawItemStruct->itemID;
00100         BOOL bIsSelected=lpDrawItemStruct->itemState & ODS_SELECTED;
00101         BOOL bIsDisabled=lpDrawItemStruct->itemState & ODS_DISABLED;
00102 
00103         // Obtaining the DeviceContext
00104         CDC dc;
00105         dc.Attach(lpDrawItemStruct->hDC);
00106         int savedDC = dc.SaveDC();
00107 
00108 
00109         // If the item exists
00110         if (nIndex != (UINT) -1)
00111         {
00112                 COLORREF crSelBackGround=::GetSysColor(COLOR_HIGHLIGHT);
00113                 COLORREF crNormBackGround=::GetSysColor(COLOR_WINDOW);
00114                 COLORREF crDisabledBackGround=::GetSysColor(COLOR_INACTIVEBORDER);
00115 
00116                 COLORREF crSelText=::GetSysColor(COLOR_HIGHLIGHTTEXT);
00117                 COLORREF crNormText=::GetSysColor(COLOR_WINDOWTEXT);
00118                 COLORREF crDisabledText=::GetSysColor(COLOR_GRAYTEXT);
00119 
00120                 COLORREF crText=bIsSelected?crSelText:crNormText;
00121                 COLORREF crBckGr=bIsSelected?crSelBackGround:crNormBackGround;
00122 
00123 
00124 
00125                 CListItem& ListItem=m_ListItemArray[nIndex];
00126 
00127 
00128 
00129                 // Getting the full rectangle for the item
00130                 CRect rectFull = lpDrawItemStruct->rcItem;
00131 
00132                 // Setting up one rectangle for each columns
00133                 CRect rectLeftMargin(rectFull),rectLeft(rectFull),rectRight(rectFull);
00134                 if(m_bCategories)
00135                 {
00136                         rectLeftMargin.right=INSP_LEFT_MARGIN;
00137                 }
00138                 else
00139                 {
00140                         rectLeftMargin.right=rectLeftMargin.left;
00141                 }
00142 
00143                 rectLeft.left=rectLeftMargin.right;
00144                 rectLeft.right=m_Settings.m_nDivider;
00145                 rectRight.left=m_Settings.m_nDivider;
00146 
00147 
00148 
00149                 // Repainting the background
00150 
00151                 // Left margin
00152                 if(m_bCategories)
00153                 {
00154                         dc.FillSolidRect(rectLeftMargin,crNormBackGround);
00155                 }
00156 
00157                 // Left side (name)
00158                 dc.FillSolidRect(rectLeft.left-1,rectLeft.top-1,rectLeft.Width()+1,rectLeft.Height()+1,crBckGr);
00159 
00160                 // Not selecting right panel side - only if it's default
00161                 if(ListItem.bIsDefault)
00162                 {
00163                         // crText=crDisabledText;     -- Modification by Volgyesi
00164                         crText=bIsSelected ? crText : crDisabledText;
00165                         //crBckGr=crDisabledBackGround;
00166                 }
00167 
00168                 if(ListItem.bIsDifferentValue)
00169                 {
00170                         dc.FillSolidRect(rectRight.left,rectRight.top-1,rectRight.Width(),rectRight.Height()+1,crDisabledBackGround);
00171                 }
00172                 else
00173                 {
00174                         dc.FillSolidRect(rectRight.left,rectRight.top-1,rectRight.Width(),rectRight.Height()+1,crNormBackGround);
00175                 }
00176 
00177                 static CBrush Brush(crNormText);
00178                 static CPen Pen(PS_SOLID,0,crNormText);
00179                 static CPen PenInactiveBorder(PS_SOLID,0,crDisabledBackGround);
00180 
00181 
00182                 // PlusMinus Button
00183                 if(m_bCategories)
00184                 {
00185 
00186                         if(ListItem.bIsContainer)
00187                         {
00188                                 int nXPlusMinusOffset=(rectLeftMargin.Width()-INSP_PLUS_MINUS_BUTTON_SIZE)/2;
00189                                 int nYPlusMinusOffset=(rectLeftMargin.Height()-INSP_PLUS_MINUS_BUTTON_SIZE)/2;
00190                                 CRect rectPlusMinus(rectLeftMargin.left+nXPlusMinusOffset,
00191                                                                         rectLeftMargin.top+nYPlusMinusOffset,
00192                                                                         rectLeftMargin.left+nXPlusMinusOffset+INSP_PLUS_MINUS_BUTTON_SIZE,
00193                                                                         rectLeftMargin.top+nYPlusMinusOffset+INSP_PLUS_MINUS_BUTTON_SIZE);
00194 
00195                                 CPoint ptCenter(rectPlusMinus.CenterPoint());
00196 
00197 
00198                                 dc.FrameRect(rectPlusMinus,&Brush);
00199 
00200                                 if(!ListItem.bIsContainerOpen)
00201                                 {
00202                                         // perpendicular component of + sign
00203                                         dc.MoveTo(ptCenter.x, ptCenter.y - 2);
00204                                         dc.LineTo(ptCenter.x, ptCenter.y + 3);
00205                                 }
00206                                 // - sign
00207                                 dc.MoveTo(ptCenter.x - 2, ptCenter.y);
00208                                 dc.LineTo(ptCenter.x + 3, ptCenter.y);
00209                         }
00210                 }
00211 
00212 
00213                 // Drawing edges - But we have to increase the rect
00214                 if(!rectLeft.IsRectEmpty())
00215                 {
00216                         dc.SelectObject(PenInactiveBorder);
00217                         rectLeft.InflateRect(2,1,0,0);
00218                         dc.DrawEdge(rectLeft,EDGE_SUNKEN,BF_BOTTOMRIGHT);
00219 
00220                         dc.MoveTo(rectLeft.TopLeft());
00221                         dc.LineTo(rectLeft.left,rectLeft.bottom);
00222 
00223                         rectLeft.DeflateRect(2,1,0,0);
00224                 }
00225 
00226                 if(!rectRight.IsRectEmpty())
00227                 {
00228                         rectRight.InflateRect(1,0,0,0);
00229                         dc.DrawEdge(rectRight,EDGE_SUNKEN,BF_BOTTOM);
00230                         rectRight.DeflateRect(1,0,0,0);
00231                 }
00232 
00233                 // Attribute name
00234                 CString strName=ListItem.strName;
00235                 CString strTxt;
00236                 ListItem.Value.toString(strTxt);
00237 
00238                 dc.SelectObject(&m_entryFont);
00239                 dc.SetBkMode(TRANSPARENT);
00240 
00241                 // Container
00242                 if(ListItem.bIsContainer)
00243                 {
00244                         dc.SelectObject(&m_entryBoldFont);
00245                 }
00246                 else // Normal data types
00247                 {
00248                         dc.SetTextColor(ListItem.bIsDefault?crDisabledText:crNormText);
00249 
00250                         if(ListItem.Value.dataType==ITEMDATA_COLOR) // Color
00251                         {
00252                                 CRect rectColorBox(rectRight);
00253                                 rectColorBox.left+=INSP_COLORBOX_MARGIN;
00254                                 rectColorBox.right=rectColorBox.left+INSP_COLORBOX_SIZE;
00255                                 rectColorBox.top=rectColorBox.top+(rectColorBox.Height()-INSP_COLORBOX_SIZE)/2-1;
00256                                 rectColorBox.bottom=rectColorBox.top+INSP_COLORBOX_SIZE;
00257 
00258                                 dc.FillSolidRect(rectColorBox,ListItem.Value.colorVal);
00259                                 dc.FrameRect(rectColorBox,&Brush);
00260 
00261                                 CRect rectText(rectRight);
00262                                 rectText.left=rectColorBox.right+2*INSP_COLORBOX_MARGIN;
00263 
00264                                 dc.DrawText(strTxt,CRect(rectText.left,rectText.top,
00265                                                                 rectText.right,rectText.bottom),
00266                                 DT_LEFT | DT_SINGLELINE);
00267                         }
00268                         else if(ListItem.Value.dataType==ITEMDATA_STRING&&ListItem.Value.cLineNum>1)
00269                         {
00270                                 // Multiline string
00271                                 CString strTxt;
00272                                 ListItem.Value.toString(strTxt);
00273                                 dc.DrawText(strTxt,CRect(rectRight.left,rectRight.top,
00274                                                                                 rectRight.right,rectRight.bottom),DT_LEFT | DT_NOPREFIX);
00275                                 //DT_NOPREFIX by zolmol: draw string as is, do not interpret the & character
00276                         }
00277                         else
00278                         {
00279                                 // Do not select the right hand side
00280 
00281                                 dc.DrawText(strTxt,CRect(rectRight.left,rectRight.top,
00282                                                                 rectRight.right,rectRight.bottom),
00283                                 DT_LEFT | DT_SINGLELINE | DT_NOPREFIX);
00284                                 //DT_NOPREFIX by zolmol: draw string as is, do not interpret the & character                    
00285                         }
00286                 }
00287                 dc.SetTextColor(crText);
00288                 dc.DrawText(strName,CRect(rectLeft.left,rectLeft.top,
00289                                                                                         rectLeft.right-2,rectLeft.bottom),
00290                                         DT_LEFT | DT_SINGLELINE);
00291         }
00292 
00293         dc.RestoreDC(savedDC);
00294         dc.Detach();
00295 
00296 
00297 }
00298 
00299 void CInspectorList::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
00300 {
00301         int nIndex=lpMeasureItemStruct->itemID;
00302         if(m_ListItemArray[nIndex].Value.dataType==ITEMDATA_STRING)
00303         {
00304                 int nLineNum=m_ListItemArray[nIndex].Value.cLineNum;
00305                 if(nLineNum==1)
00306                 {
00307                         lpMeasureItemStruct->itemHeight = m_ItemHeight;
00308                 }
00309                 else
00310                 {
00311                         lpMeasureItemStruct->itemHeight = min(255, nLineNum * m_ItemHeight);
00312                 }
00313 
00314         }
00315         else
00316         {
00317                 lpMeasureItemStruct->itemHeight = m_ItemHeight;
00318         }
00319 
00320 }
00321 
00322 void CInspectorList::DoCollapseExpand(int nIndex)
00323 {
00324         m_InPlaceManager.HideAllInPlace();
00325 
00326         CListItem &ListItem=m_ListItemArray.ElementAt(nIndex);
00327         if(!ListItem.bIsContainer) return;
00328 
00329         if(ListItem.bIsContainerOpen)
00330         {
00331                 int nChildIndex=nIndex+1;
00332                 ListItem.m_ContainedListItemArray.RemoveAll();
00333 
00334                 while(nChildIndex<=m_ListItemArray.GetUpperBound())
00335                 {
00336                         CListItem ChildListItem=m_ListItemArray.GetAt(nChildIndex);
00337 
00338                         if(ChildListItem.bIsContainer)break;
00339 
00340                         ListItem.m_ContainedListItemArray.Add(ChildListItem);
00341 
00342                         RemoveItem(nChildIndex);
00343                 }
00344 
00345                 // Setting the +/-sign
00346                 ListItem.bIsContainerOpen=FALSE;
00347         }
00348         else
00349         {
00350                 int nChildIndex=nIndex+1;
00351                 for(int i=0;i<=ListItem.m_ContainedListItemArray.GetUpperBound();i++)
00352                 {
00353                         CListItem ChildListItem=ListItem.m_ContainedListItemArray.GetAt(i);
00354                         m_ListItemArray.InsertAt(nChildIndex+i,ChildListItem);
00355                         InsertString(nChildIndex+i,_T(""));
00356 
00357                 }
00358 
00359                 ListItem.m_ContainedListItemArray.RemoveAll();
00360 
00361                 // Setting the +/-sign
00362                 ListItem.bIsContainerOpen=TRUE;
00363         }
00364         Invalidate();
00365 
00366 }
00367 
00368 
00369 void CInspectorList::OnLButtonDown(UINT nFlags, CPoint point)
00370 {
00371         if(GetCount()==0)return;
00372 
00373         if(m_bCategories)
00374         {
00375                 OnPlusMinusClick(point);
00376         }
00377         if (OnRightSideClick(point))
00378                 return;
00379 
00380         if(point.x>=(int)m_Settings.m_nDivider-INSP_MOUSE_RADIUS &&
00381                 point.x<=(int)m_Settings.m_nDivider+INSP_MOUSE_RADIUS)
00382         {
00383 
00384                 m_bIsDividerDrag=TRUE;
00385 
00386                 ::SetCursor(m_hCurSize);
00387 
00388                 CRect rectWnd;
00389                 GetWindowRect(rectWnd);
00390                 rectWnd.left += INSP_LEFT_MARGIN+3; rectWnd.right -= 20;
00391 
00392                 //Mouse within the listbox
00393                 ::ClipCursor(rectWnd);
00394 
00395                 //Capture the mouse
00396                 SetCapture();
00397 
00398 
00399                 CRect rectClient;
00400                 GetClientRect(rectClient);
00401 
00402                 m_ptOldTop.y=rectClient.top;
00403                 m_ptOldTop.x=point.x;
00404 
00405                 m_ptOldBottom.y=rectClient.bottom;
00406                 m_ptOldBottom.x=point.x;
00407 
00408                 CClientDC dc(this);
00409                 InvertLine(&dc,m_ptOldTop,m_ptOldBottom);
00410 
00411         }
00412         else
00413         {
00414                 CListBox::OnLButtonDown(nFlags, point);
00415         }
00416 }
00417 
00418 void CInspectorList::OnLButtonUp(UINT nFlags, CPoint point)
00419 {
00420         if(GetCount()==0)return;
00421 
00422         if(m_bIsDividerDrag)
00423         {
00424                 m_bIsDividerDrag=FALSE;
00425                 m_Settings.m_nDivider = point.x;
00426 
00427                 //Release the mouse
00428                 if (this==GetCapture())
00429                 {
00430                         ::ReleaseCapture();
00431                 }
00432 
00433                 // Allow the cursor to go outside
00434                 ::ClipCursor(NULL);
00435 
00436                 // Arrow cursor
00437                 ::SetCursor(m_hCurSize);
00438 
00439                 m_InPlaceManager.HideAllInPlace();
00440                 // Redraw listbox
00441                 Invalidate();
00442         }
00443         CListBox::OnLButtonUp(nFlags, point);
00444 }
00445 
00446 void CInspectorList::OnMouseMove(UINT nFlags, CPoint point)
00447 {
00448         if(GetCount()==0)return;
00449 
00450         if(m_bIsDividerDrag)
00451         {
00452                 // Deleting the previous line
00453                 CClientDC dc(this);
00454                 InvertLine(&dc,m_ptOldTop,m_ptOldBottom);
00455 
00456                 // Drawing a new one
00457                 m_ptOldTop.x=point.x;
00458                 m_ptOldBottom.x=point.x;
00459                 InvertLine(&dc,m_ptOldTop,m_ptOldBottom);
00460 
00461         }
00462         else
00463         {
00464                 if(point.x>=(int)m_Settings.m_nDivider-INSP_MOUSE_RADIUS &&
00465                         point.x<=(int)m_Settings.m_nDivider+INSP_MOUSE_RADIUS)
00466                 {
00467                         ::SetCursor(m_hCurSize);
00468                 }
00469                 else
00470                 {
00471                         ::SetCursor(m_hCurArrow);
00472                 }
00473 
00474         }
00475 
00476         CListBox::OnMouseMove(nFlags, point);
00477 }
00478 
00479 void CInspectorList::InvertLine(CDC *pDC, CPoint ptSrc, CPoint ptDst)
00480 {
00481 
00482         int nOldMode = pDC->SetROP2(R2_NOT);
00483 
00484         pDC->MoveTo(ptSrc);
00485         pDC->LineTo(ptDst);
00486 
00487         pDC->SetROP2(nOldMode);
00488 }
00489 
00490 void CInspectorList::OnSelChange()
00491 {
00492         int nSelCount=GetSelCount();
00493 
00494         if(nSelCount<1)
00495         {
00496                 SetHelp(-1);
00497         }
00498         else
00499         {
00500 
00501                 int nSelected;
00502                 CListBox::GetSelItems(1,&nSelected);
00503 
00504                 CRect rectItem;
00505                 GetItemRect(nSelected,rectItem);
00506 
00507                 SetHelp(nSelected);
00508                 rectItem.left=m_Settings.m_nDivider;
00509                 m_InPlaceManager.ShowInPlace(rectItem,nSelected);
00510         }
00511 
00512 }
00513 
00514 
00515 void CInspectorList::OnArrowClicked()
00516 {
00517 
00518         m_InPlaceManager.OnClickArrowButton(false);
00519 
00520 }
00521 
00522 void CInspectorList::OnEditorClicked()
00523 {
00524 
00525         m_InPlaceManager.OnClickEditorButton();
00526 
00527 }
00528 
00529 
00530 bool CInspectorList::InsertItem(CListItem ListItem, int nIndex)
00531 {
00532         int nUpperBound=m_ListItemArray.GetUpperBound();
00533 
00534         if(nIndex>nUpperBound)
00535         {
00536                 return AddItem(ListItem);
00537         }
00538 
00539         if(!m_bCategories||nUpperBound==-1)
00540         {
00541                 m_ListItemArray.InsertAt(nIndex,ListItem);
00542                 InsertString(nIndex,_T(""));
00543         }
00544         else
00545         {
00546                 int nLastCategoryIndex=nIndex;
00547                 bool bIsOpen;
00548                 do
00549                 {
00550                         const CListItem &LastCategoryListItem=m_ListItemArray.ElementAt(nLastCategoryIndex);
00551                         if(LastCategoryListItem.bIsContainer)
00552                         {
00553                                 bIsOpen=LastCategoryListItem.bIsContainerOpen;
00554                                 break;
00555                         }
00556                         nLastCategoryIndex--;
00557                 }while(nLastCategoryIndex>=0);
00558 
00559 
00560                 if(nLastCategoryIndex!=-1 && !bIsOpen)
00561                 {
00562                         CListItem & LastCategoryListItem =m_ListItemArray.ElementAt(nLastCategoryIndex);
00563                         LastCategoryListItem.m_ContainedListItemArray.Add(ListItem);
00564                 }
00565                 else
00566                 {
00567                         m_ListItemArray.InsertAt(nIndex,ListItem);
00568                         InsertString(nIndex,_T(""));
00569 
00570                 }
00571 
00572         }
00573 
00574 
00575         // Checking value
00576         if(!m_bCategories)
00577         {
00578                 ASSERT(ListItem.Value.dataType!=ITEMDATA_NULL);
00579                 return false;
00580         }
00581         else
00582         {
00583                 if(ListItem.Value.dataType==ITEMDATA_NULL && ListItem.bIsContainer==false)
00584                 {
00585                         // We should not add null items not containing any type
00586                         ASSERT(("ITEMDATA_NULL type data was to be inserted in the list",false));
00587                         return false;
00588                 }
00589                 else
00590                 {
00591                         return true;
00592                 }
00593         }
00594 }
00595 
00596 
00597 void CInspectorList::GetSelItems(CArray<int,int>&IndexArray,CArray<CListItem,CListItem&> &ListItemArray)
00598 {
00599         IndexArray.RemoveAll();
00600         ListItemArray.RemoveAll();
00601 
00602         int nSelCount=GetSelCount();
00603 
00604         if(nSelCount>0)
00605         {
00606                 IndexArray.SetSize(nSelCount);
00607                 CListBox::GetSelItems(nSelCount,IndexArray.GetData());
00608         }
00609 
00610         for(int i=0;i<=IndexArray.GetUpperBound();i++)
00611         {
00612                 ListItemArray.Add(m_ListItemArray.ElementAt(IndexArray[i]));
00613         }
00614 }
00615 
00616 
00617 bool CInspectorList::AddItem(CListItem ListItem)
00618 {
00619 
00620         int nUpperBound=m_ListItemArray.GetUpperBound();
00621 
00622         if(!m_bCategories||nUpperBound==-1)
00623         {
00624                 m_ListItemArray.Add(ListItem);
00625                 AddString(_T(""));
00626         }
00627         else
00628         {
00629                 int nLastCategoryIndex=nUpperBound;
00630                 bool bIsOpen;
00631                 do
00632                 {
00633                         const CListItem &LastCategoryListItem=m_ListItemArray.ElementAt(nLastCategoryIndex);
00634                         if(LastCategoryListItem.bIsContainer)
00635                         {
00636                                 bIsOpen=LastCategoryListItem.bIsContainerOpen;
00637                                 break;
00638                         }
00639                         nLastCategoryIndex--;
00640                 }while(nLastCategoryIndex>=0);
00641 
00642 
00643                 if(nLastCategoryIndex!=-1 && !bIsOpen)
00644                 {
00645                         CListItem & LastCategoryListItem =m_ListItemArray.ElementAt(nLastCategoryIndex);
00646                         LastCategoryListItem.m_ContainedListItemArray.Add(ListItem);
00647                 }
00648                 else
00649                 {
00650                         m_ListItemArray.Add(ListItem);
00651                         AddString(_T(""));
00652                 }
00653         }
00654 
00655         RefreshState();
00656         // Checking value
00657         if(!m_bCategories)
00658         {
00659                 ASSERT(ListItem.Value.dataType!=ITEMDATA_NULL);
00660                 return false;
00661         }
00662         else
00663         {
00664                 if(ListItem.Value.dataType==ITEMDATA_NULL && ListItem.bIsContainer==false)
00665                 {
00666                         // We should not add null items not containing any type
00667                         ASSERT(("ITEMDATA_NULL type data was to be inserted in the list",false));
00668                         return false;
00669                 }
00670                 else
00671                 {
00672                         return true;
00673                 }
00674         }
00675 }
00676 
00677 
00678 void CInspectorList::UpdateItems(CArray<CListItem,CListItem&> &ListItemArray)
00679 {
00680         int nUpperBound=ListItemArray.GetUpperBound();
00681         int nIndex=0;
00682 
00683         for(int i=0;i<=m_ListItemArray.GetUpperBound();i++)
00684         {
00685                 CListItem& ListItem=m_ListItemArray.ElementAt(i);
00686 
00687                 if(nIndex>nUpperBound)
00688                 {
00689                         CInspectorList::RemoveItem(i);
00690                         i--;
00691                         continue;
00692                 }
00693                 else
00694                 {
00695                         UpdateItem(ListItemArray.ElementAt(nIndex),ListItem, nIndex);
00696                         nIndex++;
00697                 }
00698 
00699                 if(ListItem.bIsContainer&&!ListItem.bIsContainerOpen)
00700                 {
00701                         for(int j=0;j<=ListItem.m_ContainedListItemArray.GetUpperBound();j++)
00702                         {
00703                                 CListItem & InnerListItem=ListItem.m_ContainedListItemArray.ElementAt(j);
00704                                 if(nIndex>nUpperBound)
00705                                 {
00706                                         ListItem.m_ContainedListItemArray.RemoveAt(j);
00707                                         j--;
00708                                         continue;
00709                                 }
00710                                 else
00711                                 {
00712                                         UpdateItem(ListItemArray.ElementAt(nIndex),InnerListItem, nIndex);
00713                                         nIndex++;
00714                                 }
00715                         }
00716                 }
00717         }
00718 
00719         int nLastElement=m_ListItemArray.GetUpperBound();
00720         if(nLastElement>=0)
00721         {
00722                 const CListItem& LastListItem=m_ListItemArray.ElementAt(nLastElement);
00723 
00724                 if(LastListItem.bIsContainer&& !LastListItem.bIsContainerOpen && nIndex<=nUpperBound)
00725                 {
00726                         DoCollapseExpand(nLastElement);
00727                 }
00728         }
00729         for(int k=nIndex;k<=nUpperBound;k++)
00730         {
00731                 CInspectorList::AddItem(ListItemArray.ElementAt(k));
00732         }
00733         if (m_InPlaceManager.m_ArrowButton.m_hWnd)
00734                 m_InPlaceManager.m_ArrowButton.ShowWindow(SW_HIDE);
00735 
00736         Invalidate();
00737 }
00738 
00739 
00740 void CInspectorList::UpdateItem(const CListItem &srcListItem, CListItem &dstListItem, int nIndex)
00741 {
00742         ASSERT(nIndex < GetCount());
00743         dstListItem.CopyWithNoState(srcListItem);
00744 
00745 
00746         // Unfortunately, Windows sends MeasureItem message only once - Volgyesi
00747         if(srcListItem.Value.dataType==ITEMDATA_STRING)
00748         {
00749                 int nLineNum=srcListItem.Value.cLineNum;
00750                 if(nLineNum==1)
00751                 {
00752                         SetItemHeight(nIndex, m_ItemHeight);
00753                 }
00754                 else
00755                 {
00756                         VERIFY(SetItemHeight(nIndex, min(255, nLineNum * m_ItemHeight)) == LB_OKAY);
00757                 }
00758 
00759         }
00760         else
00761         {
00762                 SetItemHeight(nIndex, m_ItemHeight);
00763         }
00764         // Modification End - Volgyesi
00765 }
00766 
00767 
00768 bool CInspectorList::RemoveItem(int nIndex)
00769 {
00770         if(nIndex<=m_ListItemArray.GetUpperBound())
00771         {
00772                 m_InPlaceManager.HideAllInPlace();
00773                 m_ListItemArray.RemoveAt(nIndex);
00774                 VERIFY(DeleteString(nIndex)!=LB_ERR);
00775                 return true;
00776         }
00777         return false;
00778 }
00779 
00780 
00781 void CInspectorList::RemoveAll()
00782 {
00783         m_ListItemArray.RemoveAll();
00784         CInspectorList::ResetContent();
00785 }
00786 
00787 
00788 void CInspectorList::ResetContent()
00789 {
00790         m_InPlaceManager.HideAllInPlace();
00791         CListBox::ResetContent();
00792 }
00793 
00794 
00795 void CInspectorList::OnLButtonDblClk(UINT nFlags, CPoint point)
00796 {
00797         if (!OnPlusMinusClick(point))
00798                 OnLButtonDown(nFlags, point);
00799 
00800         //CListBox::OnLButtonDblClk(nFlags, point);
00801 }
00802 
00803 
00804 bool CInspectorList::OnPlusMinusClick(CPoint point)
00805 {
00806         BOOL bOutside;
00807         int nIndex=ItemFromPoint(point,bOutside);
00808         if (nIndex==65535)
00809                 return false;
00810         if (bOutside)
00811                 return false;
00812 
00813         CListItem ListItem=m_ListItemArray.GetAt(nIndex);
00814         if(!ListItem.bIsContainer)
00815                 return false;
00816 
00817         CRect rectItem;
00818         GetItemRect(nIndex,rectItem);
00819         CRect rectLeftMargin(rectItem);
00820         rectLeftMargin.right=INSP_LEFT_MARGIN;
00821         int nXPlusMinusOffset=(rectLeftMargin.Width()-INSP_PLUS_MINUS_BUTTON_SIZE)/2;
00822         int nYPlusMinusOffset=(rectLeftMargin.Height()-INSP_PLUS_MINUS_BUTTON_SIZE)/2;
00823         CRect rectPlusMinus(rectLeftMargin.left+nXPlusMinusOffset,
00824                                                 rectLeftMargin.top+nYPlusMinusOffset,
00825                                                 rectLeftMargin.left+nXPlusMinusOffset+INSP_PLUS_MINUS_BUTTON_SIZE,
00826                                                 rectLeftMargin.top+nYPlusMinusOffset+INSP_PLUS_MINUS_BUTTON_SIZE);
00827         if(rectPlusMinus.PtInRect(point))
00828         {
00829                 // If it was a click on the correct place
00830                 DoCollapseExpand(nIndex);
00831                 return true;
00832         }
00833 
00834         return false;
00835 }
00836 
00837 
00838 bool CInspectorList::OnRightSideClick(CPoint point)
00839 {
00840         BOOL bOutside;
00841         int nIndex=ItemFromPoint(point,bOutside);
00842 
00843         if(!bOutside)
00844         {
00845                 CRect rectItem;
00846                 GetItemRect(nIndex,rectItem);
00847 
00848                 CRect rectRight(rectItem);
00849                 rectRight.left=m_Settings.m_nDivider;
00850 
00851                 if(rectRight.PtInRect(point))
00852                 {
00853                         return m_InPlaceManager.OnRightItemClick(nIndex, rectRight);
00854                 }
00855         }
00856 
00857         return false;
00858 }
00859 
00860 
00861 void CInspectorList::SetHelp(int nIndex)
00862 {
00863 
00864         CWnd* pParent=GetParent();
00865         CInspectorDlg*pInspectorDlg=(CInspectorDlg*)pParent->GetParent();
00866 
00867         if(nIndex==-1)
00868         {
00869                 pInspectorDlg->SetHelp(_T(""),_T(""));
00870                 return;
00871         }
00872 
00873 
00874         int nSelCount=GetSelCount();
00875         if(nSelCount>1)
00876         {
00877                 pInspectorDlg->SetHelp(_T("Multiple Selection"),_T("Select one item to edit its properties \r\nor press Ctrl+D to make selected items default."));
00878         }
00879         else
00880         {
00881                 CListItem ListItem=m_ListItemArray.GetAt(nIndex);
00882                 pInspectorDlg->SetHelp(ListItem.strName,ListItem.strToolTip);
00883         }
00884 }
00885 
00886 
00887 bool CInspectorList::SelectNextItem(BOOL reverse)
00888 {
00889         int nCount = GetCount();
00890         if (nCount > 1) {
00891                 int nCurSel = GetCurSel();      // In a multiple-selection list box, the index of the item that has the focus.
00892                 nCurSel = nCurSel + (reverse ? -1 : 1);
00893                 nCurSel = (nCurSel + nCount) % nCount;
00894                 // Clear current selections
00895                 // Get the indexes of all the selected items.
00896                 int nSelCount = GetSelCount();
00897                 CArray<int,int> arrListBoxSel;
00898                 arrListBoxSel.SetSize(nSelCount);
00899                 CListBox::GetSelItems(nSelCount, arrListBoxSel.GetData());
00900                 for(int i = 0; i < nSelCount; i++)
00901                         SetSel(arrListBoxSel.GetAt(i), FALSE);
00902 
00903                 // Select the next focused
00904                 SetSel(nCurSel, TRUE);
00905                 OnSelChange();
00906 
00907                 // TODO: pop up comboboxes (tricky because they're not really comboboxes)
00908                 //CListItem& ListItem=m_ListItemArray.ElementAt(nCurSel);
00909                 //if (ListItem.Value.dataType == ITEMDATA_BOOLEAN || ListItem.Value.dataType == ITEMDATA_FIXED_LIST) {
00910                 //      m_InPlaceManager.OnClickArrowButton(false);
00911                 //}
00912                 return true;
00913         }
00914         return false;
00915 }
00916 
00917 
00918 LRESULT CInspectorList::OnEditEndOK(WPARAM /*lParam*/, LPARAM /*wParam*/)
00919 {
00920 
00921         m_InPlaceManager.OnEditEnd();
00922 
00923         return TRUE;
00924 }
00925 
00926 
00927 void CInspectorList::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
00928 {
00929         m_InPlaceManager.HideAllInPlace();
00930 
00931         CListBox::OnVScroll(nSBCode, nPos, pScrollBar);
00932 }
00933 
00934 
00935 BOOL CInspectorList::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
00936 {
00937         m_InPlaceManager.HideAllInPlace();
00938         return CListBox::OnMouseWheel(nFlags, zDelta, pt);
00939 }
00940 
00941 
00942 
00943 void CInspectorList::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
00944 {
00945         switch(nChar)
00946         {
00947                 case 'D':       // That's all abaout Microsoft VK_ codes.
00948                         {
00949                                 if(::GetKeyState(VK_CONTROL) & 0x8000)
00950                                 {
00951                                         SetDefault();
00952                                         Invalidate();
00953 
00954                                 }
00955                         }
00956                         break;
00957                 case VK_DELETE:
00958                         {
00959                                 SetDefault();
00960                                 Invalidate();
00961                         }
00962                         break;
00963                 case VK_TAB:    // JIRA GME-178
00964                         {
00965                                 SelectNextItem(::GetKeyState(VK_SHIFT) & 0x8000);
00966                         }
00967                         break;
00968         }
00969 
00970         CListBox::OnKeyDown(nChar, nRepCnt, nFlags);
00971 }
00972 
00973 
00974 void CInspectorList::SetDefault()
00975 {
00976         int nSelCount=GetSelCount();
00977 
00978         CArray<int,int> SelItemArr;
00979         SelItemArr.SetSize(nSelCount);
00980 
00981         CListBox::GetSelItems(nSelCount,SelItemArr.GetData());
00982 
00983         for(int i=0;i<=SelItemArr.GetUpperBound();i++)
00984         {
00985                 int nCurr=SelItemArr.GetAt(i);
00986 
00987                 CListItem& ListItem=m_ListItemArray.ElementAt(nCurr);
00988                 ListItem.RestoreDefault();
00989 
00990                 NotifyParent(nCurr);
00991         }
00992 }
00993 
00994 void CInspectorList::OnSize(UINT nType, int cx, int cy)
00995 {
00996         m_InPlaceManager.HideAllInPlace();
00997         CListBox::OnSize(nType, cx, cy);
00998 
00999 }
01000 
01001 bool CInspectorList::FindByKey(DWORD dwKey,CListItem& FoundListItem )
01002 {
01003         for(int i=0;i<=m_ListItemArray.GetUpperBound();i++)
01004         {
01005                 CListItem& ListItem=m_ListItemArray.ElementAt(i);
01006                 if(ListItem.dwKeyValue==dwKey)
01007                 {
01008                         FoundListItem= ListItem;
01009                         return true;
01010                 }
01011                 else
01012                 {
01013                         if(ListItem.bIsContainer&&!ListItem.bIsContainerOpen)
01014                         {
01015                                 for(int j=0;j<=ListItem.m_ContainedListItemArray.GetUpperBound();j++)
01016                                 {
01017                                         CListItem & InnerListItem=ListItem.m_ContainedListItemArray.ElementAt(j);
01018                                         if(InnerListItem.dwKeyValue==dwKey)
01019                                         {
01020                                                 FoundListItem= InnerListItem;
01021                                                 return true;
01022                                         }
01023                                 }
01024                         }
01025                 }
01026         }
01027         return false;
01028 
01029 }
01030 
01031 
01032 bool CInspectorList::FindByKey(DWORD dwKey,DWORD dwUserData, CListItem& FoundListItem )
01033 {
01034         for(int i=0;i<=m_ListItemArray.GetUpperBound();i++)
01035         {
01036                 CListItem& ListItem=m_ListItemArray.ElementAt(i);
01037                 if(ListItem.dwKeyValue==dwKey && ListItem.dwUserData==dwUserData)
01038                 {
01039                         FoundListItem= ListItem;
01040                         return true;
01041                 }
01042                 else
01043                 {
01044                         if(ListItem.bIsContainer&&!ListItem.bIsContainerOpen)
01045                         {
01046                                 for(int j=0;j<=ListItem.m_ContainedListItemArray.GetUpperBound();j++)
01047                                 {
01048                                         CListItem & InnerListItem=ListItem.m_ContainedListItemArray.ElementAt(j);
01049                                         if(InnerListItem.dwKeyValue==dwKey && InnerListItem.dwUserData==dwUserData)
01050                                         {
01051                                                 FoundListItem= InnerListItem;
01052                                                 return true;
01053                                         }
01054                                 }
01055                         }
01056                 }
01057         }
01058         return false;
01059 
01060 }
01061 
01062 
01063 void CInspectorList::DeleteByKey(DWORD dwKey, DWORD dwUserData)
01064 {
01065         for(int i=0;i<=m_ListItemArray.GetUpperBound();i++)
01066         {
01067                 CListItem& ListItem=m_ListItemArray.ElementAt(i);
01068                 if(ListItem.dwKeyValue==dwKey && ListItem.dwUserData==dwUserData)
01069                 {
01070                         // Remove from array
01071                         m_ListItemArray.RemoveAt(i);
01072                         // Remove from listbox
01073                         DeleteString(i);
01074                         // Refresh listbox
01075                         Invalidate();
01076                         return;
01077 
01078                 }
01079                 else
01080                 {
01081                         if(ListItem.bIsContainer&&!ListItem.bIsContainerOpen)
01082                         {
01083                                 for(int j=0;j<=ListItem.m_ContainedListItemArray.GetUpperBound();j++)
01084                                 {
01085                                         CListItem & InnerListItem=ListItem.m_ContainedListItemArray.ElementAt(j);
01086                                         if(InnerListItem.dwKeyValue==dwKey && InnerListItem.dwUserData==dwUserData)
01087                                         {
01088                                                 // Remove from inner array
01089                                                 ListItem.m_ContainedListItemArray.RemoveAt(j);
01090                                                 return;
01091                                         }
01092                                 }
01093                         }
01094                 }
01095         }
01096 }
01097 
01098 
01099 void CInspectorList::DeleteByKey(DWORD dwKey)
01100 {
01101 
01102         for(int i=0;i<=m_ListItemArray.GetUpperBound();i++)
01103         {
01104                 CListItem& ListItem=m_ListItemArray.ElementAt(i);
01105                 if(ListItem.dwKeyValue==dwKey)
01106                 {
01107                         // Remove from array
01108                         m_ListItemArray.RemoveAt(i);
01109                         // Remove from listbox
01110                         DeleteString(i);
01111                         // Refresh listbox
01112                         Invalidate();
01113                         return;
01114 
01115                 }
01116                 else
01117                 {
01118                         if(ListItem.bIsContainer&&!ListItem.bIsContainerOpen)
01119                         {
01120                                 for(int j=0;j<=ListItem.m_ContainedListItemArray.GetUpperBound();j++)
01121                                 {
01122                                         CListItem & InnerListItem=ListItem.m_ContainedListItemArray.ElementAt(j);
01123                                         if(InnerListItem.dwKeyValue==dwKey)
01124                                         {
01125                                                 // Remove from inner array
01126                                                 ListItem.m_ContainedListItemArray.RemoveAt(j);
01127                                                 return;
01128                                         }
01129                                 }
01130                         }
01131                 }
01132         }
01133 }
01134 
01135 
01136 void CInspectorList::NotifyParent(UINT nSelItem)
01137 {
01138         GetParent()->SendMessage(LBN_ON_ITEM_CHANGED,nSelItem,0);
01139 }
01140 
01141 void CInspectorList::RefreshState()
01142 {
01143         SetHelp(-1);
01144         // PETER: Removed beacuse of JIRA #GME-64
01145         // OnSelChange();
01146 }
01147 
01148 
01149 void CInspectorList::GetItem(int nIndex, CListItem &ListItem)
01150 {
01151         ListItem=m_ListItemArray[nIndex];
01152 }
01153 
01154 
01155 void CInspectorList::OnRButtonDown(UINT nFlags, CPoint point)
01156 {
01157         bool bIsCustom = false;
01158 
01159         int nSelCount=GetSelCount();
01160 
01161         CArray<int,int> SelItemArr;
01162         SelItemArr.SetSize(nSelCount);
01163 
01164         CListBox::GetSelItems(nSelCount,SelItemArr.GetData());
01165 
01166         for(int i=0;i<=SelItemArr.GetUpperBound();i++)
01167         {
01168                 int nCurr=SelItemArr.GetAt(i);
01169 
01170                 CListItem& ListItem=m_ListItemArray.ElementAt(nCurr);
01171                 if (!ListItem.bIsDefault) {
01172                         bIsCustom = true;
01173                         break;
01174                 }
01175         }
01176 
01177         if (bIsCustom) {
01178                 CMenu menu;
01179                 menu.LoadMenu(IDR_LISTCNTX_MENU);
01180                 ClientToScreen(&point);
01181                 menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,
01182                                                                                                                 point.x, point.y, this);
01183         }
01184 
01185         CListBox::OnRButtonDown(nFlags, point);
01186 }
01187 
01188 void CInspectorList::OnListContextResetToDefault()
01189 {
01190         SetDefault();
01191         Invalidate();
01192 }