1 // PropertyList.cpp : implementation file
6 #include "CMakeSetup.h"
7 #include "CMakeSetupDialog.h"
8 #include "PathDialog.h"
9 #include "../cmCacheManager.h"
10 #include "../cmSystemTools.h"
12 #define IDC_PROPCMBBOX 712
13 #define IDC_PROPEDITBOX 713
14 #define IDC_PROPBTNCTRL 714
15 #define IDC_PROPCHECKBOXCTRL 715
17 /////////////////////////////////////////////////////////////////////////////
20 CPropertyList::CPropertyList()
23 m_ShowAdvanced
= false;
27 CPropertyList::~CPropertyList()
29 for(std::set
<CPropertyItem
*>::iterator i
= m_PropertyItems
.begin();
30 i
!= m_PropertyItems
.end(); ++i
)
37 BEGIN_MESSAGE_MAP(CPropertyList
, CListBox
)
38 //{{AFX_MSG_MAP(CPropertyList)
41 ON_CONTROL_REFLECT(LBN_SELCHANGE
, OnSelchange
)
48 ON_CBN_KILLFOCUS(IDC_PROPCMBBOX
, OnKillfocusCmbBox
)
49 ON_CBN_SELCHANGE(IDC_PROPCMBBOX
, OnSelchangeCmbBox
)
50 ON_EN_KILLFOCUS(IDC_PROPEDITBOX
, OnKillfocusEditBox
)
51 ON_EN_CHANGE(IDC_PROPEDITBOX
, OnChangeEditBox
)
52 ON_BN_CLICKED(IDC_PROPBTNCTRL
, OnButton
)
53 ON_BN_CLICKED(IDC_PROPCHECKBOXCTRL
, OnCheckBox
)
54 ON_COMMAND(42, OnDelete
)
55 ON_COMMAND(43, OnHelp
)
56 ON_COMMAND(44, OnIgnore
)
59 /////////////////////////////////////////////////////////////////////////////
60 // CPropertyList message handlers
62 BOOL
CPropertyList::PreCreateWindow(CREATESTRUCT
& cs
)
64 if (!CListBox::PreCreateWindow(cs
))
67 cs
.style
&= ~(LBS_OWNERDRAWVARIABLE
| LBS_SORT
);
68 cs
.style
|= LBS_OWNERDRAWFIXED
;
77 void CPropertyList::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct
)
79 lpMeasureItemStruct
->itemHeight
= 20; //pixels
83 void CPropertyList::DrawItem(LPDRAWITEMSTRUCT lpDIS
)
86 dc
.Attach(lpDIS
->hDC
);
87 CRect rectFull
= lpDIS
->rcItem
;
88 CRect rect
= rectFull
;
90 m_nDivider
= rect
.Width() / 2;
91 rect
.left
= m_nDivider
;
92 CRect rect2
= rectFull
;
93 rect2
.right
= rect
.left
- 1;
94 UINT nIndex
= lpDIS
->itemID
;
96 if (nIndex
!= (UINT
) -1)
98 //get the CPropertyItem for the current row
99 CPropertyItem
* pItem
= (CPropertyItem
*) GetItemDataPtr(nIndex
);
100 //draw two rectangles, one for each row column
101 if(pItem
->m_NewValue
)
103 dc
.FillSolidRect(rect2
,RGB(255,100, 100));
107 dc
.FillSolidRect(rect2
,RGB(192,192,192));
110 dc
.DrawEdge(rect2
,EDGE_SUNKEN
,BF_BOTTOMRIGHT
);
111 dc
.DrawEdge(rect
,EDGE_SUNKEN
,BF_BOTTOM
);
114 //write the property name in the first rectangle
115 dc
.SetBkMode(TRANSPARENT
);
116 dc
.DrawText(pItem
->m_propName
,CRect(rect2
.left
+3,rect2
.top
+3,
117 rect2
.right
-3,rect2
.bottom
+3),
118 DT_LEFT
| DT_SINGLELINE
);
120 //write the initial property value in the second rectangle
121 dc
.DrawText(pItem
->m_curValue
,CRect(rect
.left
+3,rect
.top
+3,
122 rect
.right
+3,rect
.bottom
+3),
123 DT_LEFT
| DT_SINGLELINE
);
128 int CPropertyList::AddItem(CString txt
)
130 int nIndex
= AddString(txt
);
134 // order = 1 add to top
135 // order = 2 add to bottom
136 int CPropertyList::AddPropItem(CPropertyItem
* pItem
, int order
)
138 if(pItem
->m_Advanced
&& ! m_ShowAdvanced
)
140 m_PropertyItems
.insert(pItem
);
143 this->HideControls();
155 nIndex
= InsertString(order
, _T(""));
159 nIndex
= AddString(pItem
->m_propName
);
161 SetItemDataPtr(nIndex
,pItem
);
162 m_PropertyItems
.insert(pItem
);
166 void CPropertyList::AddProperty(const char* name
,
168 const char* helpString
,
170 const char* comboItems
,
174 CPropertyItem
* pItem
= 0;
175 for(std::set
<CPropertyItem
*>::iterator i
= m_PropertyItems
.begin();
176 i
!= m_PropertyItems
.end(); ++i
)
178 CPropertyItem
* item
= *i
;
179 if(item
->m_propName
== name
)
182 if(pItem
->m_curValue
!= value
)
184 pItem
->m_curValue
= value
;
185 pItem
->m_HelpString
= helpString
;
188 pItem
->m_Advanced
= advanced
;
192 // if it is not found, then create a new one
195 pItem
= new CPropertyItem(name
, value
, helpString
, type
, comboItems
);
196 pItem
->m_NewValue
= true;
198 pItem
->m_Advanced
= advanced
;
204 this->AddPropItem(pItem
, order
);
208 int CPropertyList::OnCreate(LPCREATESTRUCT lpCreateStruct
)
210 if (CListBox::OnCreate(lpCreateStruct
) == -1)
217 m_hCursorSize
= AfxGetApp()->LoadStandardCursor(IDC_SIZEWE
);
218 m_hCursorArrow
= AfxGetApp()->LoadStandardCursor(IDC_ARROW
);
220 m_SSerif8Font
.CreatePointFont(80,_T("MS Sans Serif"));
225 void CPropertyList::OnSelchange()
230 GetItemRect(m_curSel
,rect
);
231 rect
.left
= m_nDivider
;
233 CPropertyItem
* pItem
= (CPropertyItem
*) GetItemDataPtr(m_curSel
);
236 m_btnCtrl
.ShowWindow(SW_HIDE
);
237 if (m_CheckBoxControl
)
238 m_CheckBoxControl
.ShowWindow(SW_HIDE
);
240 if (pItem
->m_nItemType
==CPropertyList::COMBO
)
242 //display the combo box. If the combo box has already been
243 //created then simply move it to the new location, else create it
246 m_cmbBox
.MoveWindow(rect
);
250 m_cmbBox
.Create(CBS_DROPDOWNLIST
251 | CBS_NOINTEGRALHEIGHT
| WS_VISIBLE
252 | WS_CHILD
| WS_BORDER
,
253 rect
,this,IDC_PROPCMBBOX
);
254 m_cmbBox
.SetFont(&m_SSerif8Font
);
257 //add the choices for this particular property
258 CString cmbItems
= pItem
->m_cmbItems
;
259 lBoxSelText
= pItem
->m_curValue
;
261 m_cmbBox
.ResetContent();
264 while ((i2
=cmbItems
.Find('|',i
)) != -1)
266 m_cmbBox
.AddString(cmbItems
.Mid(i
,i2
-i
));
270 m_cmbBox
.AddString(cmbItems
.Mid(i
));
272 m_cmbBox
.ShowWindow(SW_SHOW
);
275 //jump to the property's current value in the combo box
276 int j
= m_cmbBox
.FindStringExact(0,lBoxSelText
);
278 m_cmbBox
.SetCurSel(j
);
280 m_cmbBox
.SetCurSel(0);
282 else if (pItem
->m_nItemType
==CPropertyList::EDIT
)
286 m_prevSel
= m_curSel
;
289 m_editBox
.MoveWindow(rect
);
292 m_editBox
.Create(ES_LEFT
| ES_AUTOHSCROLL
| WS_VISIBLE
293 | WS_CHILD
| WS_BORDER
,
294 rect
,this,IDC_PROPEDITBOX
);
295 m_editBox
.SetFont(&m_SSerif8Font
);
298 lBoxSelText
= pItem
->m_curValue
;
300 m_editBox
.ShowWindow(SW_SHOW
);
301 m_editBox
.SetFocus();
302 //set the text in the edit box to the property's current value
303 m_editBox
.SetWindowText(lBoxSelText
);
305 else if (pItem
->m_nItemType
== CPropertyList::CHECKBOX
)
308 if (m_CheckBoxControl
)
309 m_CheckBoxControl
.MoveWindow(rect
);
312 m_CheckBoxControl
.Create("check",BS_CHECKBOX
313 | BM_SETCHECK
|BS_LEFTTEXT
314 | WS_VISIBLE
| WS_CHILD
,
315 rect
,this,IDC_PROPCHECKBOXCTRL
);
316 m_CheckBoxControl
.SetFont(&m_SSerif8Font
);
319 lBoxSelText
= pItem
->m_curValue
;
321 m_CheckBoxControl
.ShowWindow(SW_SHOW
);
322 m_CheckBoxControl
.SetFocus();
323 //set the text in the edit box to the property's current value
324 if(lBoxSelText
== "ON")
326 m_CheckBoxControl
.SetCheck(1);
330 m_CheckBoxControl
.SetCheck(0);
338 m_prevSel
= m_curSel
;
343 m_editBox
.MoveWindow(rect
);
347 m_editBox
.Create(ES_LEFT
| ES_AUTOHSCROLL
| WS_VISIBLE
348 | WS_CHILD
| WS_BORDER
,
349 rect
,this,IDC_PROPEDITBOX
);
350 m_editBox
.SetFont(&m_SSerif8Font
);
353 lBoxSelText
= pItem
->m_curValue
;
355 m_editBox
.ShowWindow(SW_SHOW
);
356 m_editBox
.SetFocus();
357 //set the text in the edit box to the property's current value
358 m_editBox
.SetWindowText(lBoxSelText
);
362 void CPropertyList::DisplayButton(CRect region
)
364 //displays a button if the property is a file/color/font chooser
366 m_prevSel
= m_curSel
;
368 if (region
.Width() > 25)
369 region
.left
= region
.right
- 25;
373 m_btnCtrl
.MoveWindow(region
);
376 m_btnCtrl
.Create("...",BS_PUSHBUTTON
| WS_VISIBLE
| WS_CHILD
,
377 region
,this,IDC_PROPBTNCTRL
);
378 m_btnCtrl
.SetFont(&m_SSerif8Font
);
381 m_btnCtrl
.ShowWindow(SW_SHOW
);
382 m_btnCtrl
.SetFocus();
385 void CPropertyList::OnKillFocus(CWnd
* pNewWnd
)
387 //m_btnCtrl.ShowWindow(SW_HIDE);
389 CListBox::OnKillFocus(pNewWnd
);
392 void CPropertyList::OnKillfocusCmbBox()
394 m_cmbBox
.ShowWindow(SW_HIDE
);
399 void CPropertyList::OnKillfocusEditBox()
402 m_editBox
.ShowWindow(SW_HIDE
);
407 void CPropertyList::OnSelchangeCmbBox()
412 m_cmbBox
.GetLBText(m_cmbBox
.GetCurSel(),selStr
);
413 CPropertyItem
* pItem
= (CPropertyItem
*) GetItemDataPtr(m_curSel
);
414 pItem
->m_curValue
= selStr
;
419 void CPropertyList::OnChangeEditBox()
422 m_editBox
.GetWindowText(newStr
);
424 CPropertyItem
* pItem
= (CPropertyItem
*) GetItemDataPtr(m_curSel
);
425 if(pItem
->m_curValue
!= newStr
)
427 pItem
->m_curValue
= newStr
;
432 void CPropertyList::HideControls()
436 m_editBox
.ShowWindow(SW_HIDE
);
440 m_cmbBox
.ShowWindow(SW_HIDE
);
442 if(m_CheckBoxControl
)
444 m_CheckBoxControl
.ShowWindow(SW_HIDE
);
448 m_btnCtrl
.ShowWindow(SW_HIDE
);
452 void CPropertyList::OnVScroll( UINT nSBCode
, UINT nPos
, CScrollBar
* pScrollBar
)
454 this->HideControls();
455 CListBox::OnVScroll(nSBCode
, nPos
, pScrollBar
);
458 void CPropertyList::OnCheckBox()
460 CPropertyItem
* pItem
= (CPropertyItem
*) GetItemDataPtr(m_curSel
);
461 if(m_CheckBoxControl
.GetCheck())
463 pItem
->m_curValue
= "ON";
467 pItem
->m_curValue
= "OFF";
473 void CPropertyList::OnButton()
475 if(m_PropertyItems
.size() == 0)
480 CPropertyItem
* pItem
= (CPropertyItem
*) GetItemDataPtr(m_curSel
);
482 // The dialogs might change the working directory. Save it.
483 std::string cwd
= cmSystemTools::GetCurrentWorkingDirectory();
485 //display the appropriate common dialog depending on what type
486 //of chooser is associated with the property
488 if (pItem
->m_nItemType
== CPropertyList::FILE)
490 CString SelectedFile
;
491 CString
Filter("All Files (*.*)||");
493 CFileDialog
FileDlg(TRUE
, NULL
, NULL
, NULL
,
496 CString currPath
= pItem
->m_curValue
;
497 if (currPath
.Right(9) == "-NOTFOUND" || currPath
== "NOTFOUND")
501 if (currPath
.GetLength() > 0)
503 int endSlash
= currPath
.ReverseFind('\\');
506 endSlash
= currPath
.ReverseFind('/');
508 initialDir
= currPath
.Left(endSlash
);
510 initialDir
.Replace("/", "\\");
511 FileDlg
.m_ofn
.lpstrTitle
= "Select file";
512 if (currPath
.GetLength() > 0)
513 FileDlg
.m_ofn
.lpstrInitialDir
= initialDir
;
515 if(IDOK
== FileDlg
.DoModal())
517 SelectedFile
= FileDlg
.GetPathName();
519 m_btnCtrl
.ShowWindow(SW_HIDE
);
520 std::string path
= SelectedFile
;
521 cmSystemTools::ConvertToUnixSlashes(path
);
522 pItem
->m_curValue
= path
.c_str();
527 else if (pItem
->m_nItemType
== CPropertyList::PATH
)
529 CString initialDir
= pItem
->m_curValue
;
530 // convert back to windos style path
531 initialDir
.Replace("/", "\\");
532 CString title
= "Setting Cache Value: ";
533 title
+= pItem
->m_propName
;
534 CPathDialog
dlg("Select Path", title
, initialDir
);
535 if(dlg
.DoModal()==IDOK
)
537 CString SelectedFile
= dlg
.GetPathName();
538 m_btnCtrl
.ShowWindow(SW_HIDE
);
539 std::string path
= SelectedFile
;
540 cmSystemTools::ConvertToUnixSlashes(path
);
541 pItem
->m_curValue
= path
.c_str();
547 cmSystemTools::ChangeDirectory(cwd
.c_str());
550 void CPropertyList::OnLButtonUp(UINT nFlags
, CPoint point
)
554 //if columns were being resized then this indicates
555 //that mouse is up so resizing is done. Need to redraw
556 //columns to reflect their new widths.
559 //if mouse was captured then release it
560 if (GetCapture()==this)
566 InvertLine(&dc
,CPoint(point
.x
,m_nDivTop
),CPoint(point
.x
,m_nDivBtm
));
567 //set the divider position to the new value
568 m_nDivider
= point
.x
;
576 int i
= ItemFromPoint(point
,loc
);
578 CListBox::OnLButtonUp(nFlags
, point
);
582 void CPropertyList::OnLButtonDown(UINT nFlags
, CPoint point
)
584 if ((point
.x
>=m_nDivider
-5) && (point
.x
<=m_nDivider
+5))
586 //if mouse clicked on divider line, then start resizing
588 ::SetCursor(m_hCursorSize
);
591 GetWindowRect(windowRect
);
592 windowRect
.left
+= 10; windowRect
.right
-= 10;
593 //do not let mouse leave the list box boundary
594 ::ClipCursor(windowRect
);
597 m_cmbBox
.ShowWindow(SW_HIDE
);
599 m_editBox
.ShowWindow(SW_HIDE
);
602 GetClientRect(clientRect
);
605 m_nDivTop
= clientRect
.top
;
606 m_nDivBtm
= clientRect
.bottom
;
607 m_nOldDivX
= point
.x
;
610 InvertLine(&dc
,CPoint(m_nOldDivX
,m_nDivTop
),CPoint(m_nOldDivX
,m_nDivBtm
));
618 CListBox::OnLButtonDown(nFlags
, point
);
622 void CPropertyList::OnMouseMove(UINT nFlags
, CPoint point
)
626 //move divider line to the mouse pos. if columns are
627 //currently being resized
629 //remove old divider line
630 InvertLine(&dc
,CPoint(m_nOldDivX
,m_nDivTop
),CPoint(m_nOldDivX
,m_nDivBtm
));
631 //draw new divider line
632 InvertLine(&dc
,CPoint(point
.x
,m_nDivTop
),CPoint(point
.x
,m_nDivBtm
));
633 m_nOldDivX
= point
.x
;
635 else if ((point
.x
>= m_nDivider
-5) && (point
.x
<= m_nDivider
+5))
636 //set the cursor to a sizing cursor if the cursor is over the row divider
637 ::SetCursor(m_hCursorSize
);
641 int curSel
= ItemFromPoint(point
,loc
);
642 if(!loc
&& curSel
< 65535)
644 CPropertyItem
* pItem
= (CPropertyItem
*) GetItemDataPtr(curSel
);
645 m_CMakeSetupDialog
->SetDlgItemText(IDC_PROGRESS
, pItem
->m_HelpString
);
647 CListBox::OnMouseMove(nFlags
, point
);
652 void CPropertyList::InvertLine(CDC
* pDC
,CPoint ptFrom
,CPoint ptTo
)
654 int nOldMode
= pDC
->SetROP2(R2_NOT
);
659 pDC
->SetROP2(nOldMode
);
662 void CPropertyList::PreSubclassWindow()
669 m_hCursorSize
= AfxGetApp()->LoadStandardCursor(IDC_SIZEWE
);
670 m_hCursorArrow
= AfxGetApp()->LoadStandardCursor(IDC_ARROW
);
672 m_SSerif8Font
.CreatePointFont(80,_T("MS Sans Serif"));
675 CPropertyItem
* CPropertyList::GetItem(int index
)
677 return (CPropertyItem
*)GetItemDataPtr(index
);
680 void CPropertyList::OnRButtonUp( UINT
/* nFlags */, CPoint point
)
684 this->GetWindowRect(&rect
);
686 m_curSel
= ItemFromPoint(point
,loc
);
687 menu
.CreatePopupMenu();
688 menu
.AppendMenu(MF_STRING
| MF_ENABLED
, 44, "Ignore Cache Entry");
689 menu
.AppendMenu(MF_STRING
| MF_ENABLED
, 42, "Delete Cache Entry");
690 menu
.AppendMenu(MF_STRING
| MF_ENABLED
, 43, "Help For Cache Entry");
691 menu
.TrackPopupMenu(TPM_LEFTALIGN
| TPM_RIGHTBUTTON
,
692 rect
.TopLeft().x
+ point
.x
,
693 rect
.TopLeft().y
+ point
.y
, this, NULL
);
696 void CPropertyList::RemoveProperty(const char* name
)
698 this->HideControls();
699 for(int i
=0; i
< this->GetCount(); ++i
)
701 CPropertyItem
* pItem
= (CPropertyItem
*) GetItemDataPtr(i
);
702 if(pItem
->m_propName
== name
)
704 m_PropertyItems
.erase(pItem
);
706 this->DeleteString(i
);
712 void CPropertyList::OnIgnore()
714 if(m_curSel
== -1 || this->GetCount() <= 0)
718 CPropertyItem
* pItem
= (CPropertyItem
*) GetItemDataPtr(m_curSel
);
719 pItem
->m_curValue
= "IGNORE";
725 void CPropertyList::OnDelete()
727 if(m_curSel
== -1 || this->GetCount() <= 0)
731 CPropertyItem
* pItem
= (CPropertyItem
*) GetItemDataPtr(m_curSel
);
732 m_CMakeSetupDialog
->GetCMakeInstance()->GetCacheManager()->RemoveCacheEntry(pItem
->m_propName
);
733 m_PropertyItems
.erase(pItem
);
735 this->DeleteString(m_curSel
);
736 this->HideControls();
737 this->SetTopIndex(0);
740 if(m_curSel
> this->GetCount())
742 m_curSel
= this->GetCount();
744 this->SetCurSel(m_curSel
);
747 void CPropertyList::OnHelp()
749 if(m_curSel
== -1 || this->GetCount() <= 0)
753 CPropertyItem
* pItem
= (CPropertyItem
*) GetItemDataPtr(m_curSel
);
754 MessageBox(pItem
->m_HelpString
, pItem
->m_propName
, MB_OK
|MB_ICONINFORMATION
);
757 void CPropertyList::RemoveAll()
759 int c
= this->GetCount();
760 for(int i
=0; i
< c
; ++i
)
762 this->DeleteString(0);
764 for(std::set
<CPropertyItem
*>::iterator ii
= m_PropertyItems
.begin();
765 ii
!= m_PropertyItems
.end(); ++ii
)
769 m_PropertyItems
.clear();
771 this->HideControls();
775 void CPropertyList::InvalidateList()
781 void CPropertyList::ShowAdvanced()
783 this->SetRedraw(FALSE
);
784 this->ResetContent();
785 m_ShowAdvanced
= true;
786 std::map
<std::string
, CPropertyItem
*> sortProps
;
787 for(std::set
<CPropertyItem
*>::iterator i
= m_PropertyItems
.begin();
788 i
!= m_PropertyItems
.end(); ++i
)
790 sortProps
[(const char*)(*i
)->m_propName
] = *i
;
792 for(std::map
<std::string
, CPropertyItem
*>::iterator i
= sortProps
.begin();
793 i
!= sortProps
.end(); ++i
)
795 CPropertyItem
* item
= i
->second
;
798 this->AddPropItem(item
, 2);
801 for(std::map
<std::string
, CPropertyItem
*>::iterator i
= sortProps
.begin();
802 i
!= sortProps
.end(); ++i
)
804 CPropertyItem
* item
= i
->second
;
805 if(!item
->m_NewValue
)
807 this->AddPropItem(item
, 2);
810 this->SetRedraw(TRUE
);
811 this->InvalidateList();
815 void CPropertyList::HideAdvanced()
817 this->SetRedraw(FALSE
);
818 this->ResetContent();
819 m_ShowAdvanced
= false;
820 std::map
<std::string
, CPropertyItem
*> sortProps
;
821 for(std::set
<CPropertyItem
*>::iterator i
= m_PropertyItems
.begin();
822 i
!= m_PropertyItems
.end(); ++i
)
824 sortProps
[(const char*)(*i
)->m_propName
] = *i
;
826 for(std::map
<std::string
, CPropertyItem
*>::iterator i
= sortProps
.begin();
827 i
!= sortProps
.end(); ++i
)
829 CPropertyItem
* item
= i
->second
;
830 if(item
->m_NewValue
&& !item
->m_Advanced
)
832 this->AddPropItem(item
, 2);
835 for(std::map
<std::string
, CPropertyItem
*>::iterator i
= sortProps
.begin();
836 i
!= sortProps
.end(); ++i
)
838 CPropertyItem
* item
= i
->second
;
839 if(!item
->m_Advanced
&& !item
->m_NewValue
)
841 this->AddPropItem(item
, 2);
844 this->SetRedraw(TRUE
);
845 this->InvalidateList();