]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - tools/src/tools/configtool/common/win32/AddRemoveDialog.cpp
Initial revision
[karo-tx-redboot.git] / tools / src / tools / configtool / common / win32 / AddRemoveDialog.cpp
1 //####COPYRIGHTBEGIN####
2 //                                                                          
3 // ----------------------------------------------------------------------------
4 // Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
5 //
6 // This program is part of the eCos host tools.
7 //
8 // This program is free software; you can redistribute it and/or modify it 
9 // under the terms of the GNU General Public License as published by the Free 
10 // Software Foundation; either version 2 of the License, or (at your option) 
11 // any later version.
12 // 
13 // This program is distributed in the hope that it will be useful, but WITHOUT 
14 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
15 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
16 // more details.
17 // 
18 // You should have received a copy of the GNU General Public License along with
19 // this program; if not, write to the Free Software Foundation, Inc., 
20 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21 //
22 // ----------------------------------------------------------------------------
23 //                                                                          
24 //####COPYRIGHTEND####
25 // AddRemoveDialog.cpp : implementation file
26 //
27
28 #include "stdafx.h"
29
30 #include "AddRemoveDialog.h"
31 #ifdef _DEBUG
32 #define new DEBUG_NEW
33 #undef THIS_FILE
34 static char THIS_FILE[] = __FILE__;
35 #endif
36
37 /////////////////////////////////////////////////////////////////////////////
38 // CAddRemoveDialog dialog
39
40 void CAddRemoveDialog::AfxDataInit()
41 {
42         //{{AFX_DATA_INIT(CAddRemoveDialog)
43                 // NOTE: the ClassWizard will add member initialization here
44         //}}AFX_DATA_INIT
45 }
46
47 CAddRemoveDialog::CAddRemoveDialog(CWnd* pParent /*=NULL*/)
48         : CeCosDialog(IDD, pParent),
49     m_bSort(false),
50     m_arbSel(NULL),
51     m_bHaveDescs(false),
52     m_nHorizontalResizingLimit(0)
53 {
54         AfxDataInit ();
55 }
56
57 CAddRemoveDialog::CAddRemoveDialog(UINT nIDTemplate, CWnd* pParent /*=NULL*/)
58         : CeCosDialog(nIDTemplate, pParent),
59     m_bSort(false),
60     m_arbSel(NULL),
61     m_nHorizontalResizingLimit(0)
62 {
63         AfxDataInit ();
64 }
65
66 void CAddRemoveDialog::DoDataExchange(CDataExchange* pDX)
67 {
68         CeCosDialog::DoDataExchange(pDX);
69         //{{AFX_DATA_MAP(CAddRemoveDialog)
70         DDX_Control(pDX, IDC_PACKAGE_DESC, m_wndDesc);
71         DDX_Control(pDX, IDC_ADDREMOVE_LIST2, m_List2);
72         DDX_Control(pDX, IDC_ADDREMOVE_LIST1, m_List1);
73         DDX_Control(pDX, IDC_ADDREMOVE_ADD,   m_Add);
74         DDX_Control(pDX, IDC_ADDREMOVE_REMOVE,m_Remove);
75         //}}AFX_DATA_MAP
76 }
77
78
79 BEGIN_MESSAGE_MAP(CAddRemoveDialog, CeCosDialog)
80         //{{AFX_MSG_MAP(CAddRemoveDialog)
81         ON_BN_CLICKED(IDC_ADDREMOVE_ADD, OnAdd)
82         ON_BN_CLICKED(IDC_ADDREMOVE_REMOVE, OnRemove)
83         ON_LBN_DBLCLK(IDC_ADDREMOVE_LIST1, OnDblclkList1)
84         ON_LBN_DBLCLK(IDC_ADDREMOVE_LIST2, OnDblclkList2)
85         ON_LBN_SELCHANGE(IDC_ADDREMOVE_LIST1, OnSelchangeList1)
86         ON_LBN_SELCHANGE(IDC_ADDREMOVE_LIST2, OnSelchangeList2)
87         ON_WM_DESTROY()
88         //}}AFX_MSG_MAP
89 END_MESSAGE_MAP()
90
91 /////////////////////////////////////////////////////////////////////////////
92 // CAddRemoveDialog message handlers
93
94 void CAddRemoveDialog::OnAdd() 
95 {
96     Add(m_List1,m_List2);
97     m_Add.EnableWindow(FALSE);
98     m_Remove.EnableWindow(TRUE);
99 }
100
101 void CAddRemoveDialog::OnRemove() 
102 {
103     Add(m_List2,m_List1);
104     m_Add.EnableWindow(TRUE);
105     m_Remove.EnableWindow(FALSE);
106 }
107
108 void CAddRemoveDialog::Insert(LPCTSTR pszItem, bool bAdded, LPCTSTR pszDesc/*=NULL*/)
109 {
110     m_bHaveDescs|=(NULL!=pszDesc);
111     m_arnItems.  Add(bAdded);
112     m_arstrItems.Add(pszItem);
113     m_arstrDescs.Add(pszDesc?pszDesc:_T(""));
114 }
115
116 BOOL CAddRemoveDialog::OnInitDialog() 
117 {
118         CeCosDialog::OnInitDialog();
119
120     m_arbSel=new int[GetCount()];
121     
122     SetWindowText(m_strCaption);
123     SetSortMode(m_List1);
124     SetSortMode(m_List2);
125
126         int cxExtent=0;
127     CDC *pDC=m_List1.GetDC();
128         CFont *pOldFont=pDC->SelectObject(m_List1.GetFont());
129     for(int i=GetCount()-1;i>=0;--i) {
130         const CString &str=m_arstrItems[i];
131                 cxExtent=max(cxExtent,pDC->GetTextExtent(str).cx);
132         CListBox &lb=m_arnItems[i]?m_List2:m_List1;
133         lb.SetItemData(lb.AddString(str),(DWORD)i);
134     }
135     pDC->SelectObject(pOldFont);
136
137     SetDlgItemText(IDC_ADDREMOVE_TEXT1,m_strMessage1);
138     SetDlgItemText(IDC_ADDREMOVE_TEXT2,m_strMessage2);
139
140         CRect rcLb1;
141         m_List1.GetWindowRect(rcLb1);
142     CRect rcDialog;
143     GetWindowRect(rcDialog);
144
145         int nExpand=cxExtent-(rcLb1.Width()-GetSystemMetrics(SM_CXVSCROLL)-2*GetSystemMetrics(SM_CXBORDER)-5);
146     nExpand=min(nExpand,m_nHorizontalResizingLimit);
147         if(nExpand>0){
148                 MoveChild(IDOK,2*nExpand,Move);
149                 MoveChild(IDCANCEL,2*nExpand,Move);
150                 MoveChild(IDC_ADDREMOVE_ADD,nExpand,Move);
151                 MoveChild(IDC_ADDREMOVE_REMOVE,nExpand,Move);
152                 MoveChild(IDC_ADDREMOVE_LIST1,nExpand,Stretch);
153                 MoveChild(IDC_ADDREMOVE_TEXT2,nExpand,Move);
154                 MoveChild(IDC_ADDREMOVE_LIST2,nExpand,Move);
155                 MoveChild(IDC_ADDREMOVE_LIST2,nExpand,Stretch);
156                 MoveChild(IDC_PACKAGE_DESC,2*nExpand,Stretch);
157             rcDialog.right+=2*nExpand; // MoveWindow call is below
158         }
159
160     // enable horizontal scrolling if necessary, assuming the
161         // listboxes have identical widths and accommodating a
162         // 2 pixel border at each side of each listbox
163         m_List1.SetHorizontalExtent (cxExtent + 4);
164         m_List2.SetHorizontalExtent (cxExtent + 4);
165
166     m_Add.EnableWindow(m_List1.GetCount()>0);
167     m_Remove.EnableWindow(m_List2.GetCount()>0);
168         
169     if(!m_bHaveDescs){
170         // Remove the description pane if not used:
171         CRect rcDesc;
172         m_wndDesc.GetWindowRect(rcDesc);
173         m_wndDesc.ShowWindow(SW_HIDE);
174             int delta=(rcDesc.Height()+(rcDesc.top-rcLb1.bottom));
175         MoveChild(IDOK,delta,Up);
176         MoveChild(IDCANCEL,delta,Up);
177         rcDialog.bottom-=delta;
178     }
179
180     // Finally, adjust dialog size according to calculations:
181     MoveWindow(rcDialog);
182
183         return TRUE;  // return TRUE unless you set the focus to a control
184                       // EXCEPTION: OCX Property Pages should return FALSE
185 }
186
187 void CAddRemoveDialog::OnDblclkList1() 
188 {
189     OnDblclk(m_List1,m_List2);
190     m_Add.EnableWindow(FALSE);
191     m_Remove.EnableWindow(TRUE);
192 }
193
194 void CAddRemoveDialog::OnDblclkList2() 
195 {
196     OnDblclk(m_List2,m_List1);
197     m_Add.EnableWindow(TRUE);
198     m_Remove.EnableWindow(FALSE);
199 }
200
201 int CAddRemoveDialog::Add(CListBox &lb1,CListBox &lb2)
202 {
203     int nSelCount=lb1.GetSelItems(lb1.GetCount(),m_arbSel);
204     for(int i=nSelCount-1;i>=0;--i){
205         Xfer(lb1,lb2,m_arbSel[i]);
206     }
207     ClearSel(lb1);
208     lb2.SetFocus();
209     return nSelCount;
210 }
211
212 void CAddRemoveDialog::OnDblclk(CListBox &lb1,CListBox &lb2)
213 {
214     BOOL bOutside;
215     DWORD dwPos=GetMessagePos();
216     POINTS pts=MAKEPOINTS(dwPos);
217     CRect rc(pts.x,pts.y,0,0);
218     lb1.ScreenToClient(rc);
219     CPoint pt(rc.left,rc.top);
220     int nItem=lb1.ItemFromPoint(pt,bOutside);
221     if(!bOutside){
222         Xfer(lb1,lb2,nItem);
223     }
224     ClearSel(lb1);
225     lb2.SetFocus();
226 }
227
228 void CAddRemoveDialog::ClearSel(CListBox &lb)
229 {
230     for(int i=lb.GetCount()-1;i>=0;--i){
231         lb.SetSel(i,FALSE);
232     }
233 }
234
235 void CAddRemoveDialog::OnSelchangeList1()
236 {
237     ClearSel(m_List2);
238     m_Add.EnableWindow(m_List1.GetSelCount()>0);
239     UpdateDescription(m_List1);
240     m_Remove.EnableWindow(FALSE);
241 }
242
243 void CAddRemoveDialog::OnSelchangeList2()
244 {
245     ClearSel(m_List1);
246     m_Remove.EnableWindow(m_List2.GetSelCount()>0);
247     UpdateDescription(m_List2);
248     m_Add.EnableWindow(FALSE);
249 }
250
251 void CAddRemoveDialog::Xfer(CListBox &lb1, CListBox &lb2, int nItem)
252 {
253     CString strItem;
254     lb1.GetText(nItem,strItem);
255     int nNewItem=lb2.AddString(strItem);
256     lb2.SetSel(nNewItem,TRUE);
257     DWORD nIndex=lb1.GetItemData(nItem);
258     lb2.SetItemData(nNewItem,nIndex);
259     m_arnItems[(int)nIndex]^=1;
260     lb1.DeleteString(nItem);
261 }
262
263 bool CAddRemoveDialog::IsAdded(LPCTSTR pszItem) const
264 {
265     for(int i=GetCount()-1;i>=0;--i){
266         if(m_arstrItems[i]==pszItem){
267             return 0!=m_arnItems[i];
268         }
269     }
270     ASSERT(false);
271     return false;
272 }
273
274
275 void CAddRemoveDialog::SetCaption(LPCTSTR pszCaption)
276 {
277     m_strCaption=pszCaption;
278 }
279
280 void CAddRemoveDialog::SetMessage(LPCTSTR pszText1,LPCTSTR pszText2)
281 {
282     m_strMessage1=pszText1;
283     m_strMessage2=pszText2;
284 }
285
286 void CAddRemoveDialog::OnDestroy() 
287 {
288         CeCosDialog::OnDestroy();
289     deleteZA(m_arbSel);
290 }
291
292 // Add the "sort" property to the listboxes.  Unfortunately this entails
293 // recreating them.
294 void CAddRemoveDialog::SetSortMode(CListBox &lb)
295 {
296     DWORD dwStyle=lb.GetStyle();
297     if(m_bSort!=(0!=(dwStyle&LBS_SORT))){
298         if(m_bSort){
299             dwStyle|=LBS_SORT;
300         } else {
301             dwStyle&=~LBS_SORT;
302         }
303         dwStyle|=WS_HSCROLL; // For some reason this doesn't come through GetStyle()
304         CRect rect;
305         lb.GetWindowRect(rect);
306         ScreenToClient(rect);
307         DWORD dwStyleEx=lb.GetExStyle();
308         CFont *pFont=lb.GetFont();
309         DWORD id=lb.GetDlgCtrlID();
310         lb.DestroyWindow();
311         lb.Detach();
312         // CreateEx not Create to get ourselves a 3D border
313         lb.CreateEx(dwStyleEx,_T("LISTBOX"),NULL,dwStyle,rect,this,id);
314         lb.SetFont(pFont);
315     }
316 }
317
318 // Implement ctrl/A on listboxes
319 BOOL CAddRemoveDialog::PreTranslateMessage(MSG* pMsg) 
320 {
321     if(WM_CHAR==pMsg->message && 1==pMsg->wParam){
322         if(pMsg->hwnd==m_List1.m_hWnd){
323             m_List1.SelItemRange(TRUE,0,m_List1.GetCount()-1);
324             ClearSel(m_List2);
325             m_Add.EnableWindow(m_List1.GetCount()>0);
326             m_Remove.EnableWindow(FALSE);
327             return TRUE;
328         } else if(pMsg->hwnd==m_List2.m_hWnd){
329             m_List2.SelItemRange(TRUE,0,m_List2.GetCount()-1);
330             ClearSel(m_List1);
331             m_Remove.EnableWindow(m_List2.GetCount()>0);
332             m_Add.EnableWindow(FALSE);
333             return TRUE;
334         }
335     }
336         
337         return CeCosDialog::PreTranslateMessage(pMsg);
338 }
339
340 void CAddRemoveDialog::MoveChild(UINT id,int delta,MoveType how)
341 {
342     CWnd *pWnd=GetDlgItem(id);
343     CRect rect;
344         pWnd->GetWindowRect(rect);
345         ScreenToClient(rect);
346     switch(how){
347         case Move:
348                 rect.left+=delta;
349                 rect.right+=delta;
350             break;
351         case Stretch:
352                 rect.right+=delta;
353             break;
354         case Up:
355             rect.top-=delta;
356             rect.bottom-=delta;
357             break;
358     }
359     pWnd->MoveWindow(rect);
360 }
361
362 void CAddRemoveDialog::UpdateDescription(CListBox &lb)
363 {
364     CString strDesc;
365     // Set the description if the listbox has exactly one item selected
366     if(1==lb.GetSelCount()){
367             int nIndex;
368             lb.GetSelItems(1,&nIndex);
369         strDesc=m_arstrDescs[lb.GetItemData(nIndex)];
370     }
371     m_wndDesc.SetWindowText(strDesc);
372 }
373
374 void CAddRemoveDialog::SetHorizontalResizingLimit(int nPercent)
375 {
376     m_nHorizontalResizingLimit=nPercent;
377 }