Hide the back button on the initial wizard screen.
[people/sha0/mDNSResponder.git] / Clients / PrinterSetupWizard / SecondPage.cpp
1 /* -*- Mode: C; tab-width: 4 -*-
2  *
3  * Copyright (c) 1997-2004 Apple Computer, Inc. All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  * 
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  * 
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include "stdafx.h"
19 #include "PrinterSetupWizardApp.h"
20 #include "PrinterSetupWizardSheet.h"
21 #include "SecondPage.h"
22 #include "DebugServices.h"
23 #include "WinServices.h"
24 #include <winspool.h>
25
26 // local variable is initialize but not referenced
27 #pragma warning(disable:4189)
28
29 // CSecondPage dialog
30
31 IMPLEMENT_DYNAMIC(CSecondPage, CPropertyPage)
32 CSecondPage::CSecondPage()
33         : CPropertyPage(CSecondPage::IDD)
34 {
35         m_psp.dwFlags &= ~(PSP_HASHELP);
36         m_psp.dwFlags |= PSP_DEFAULT|PSP_USEHEADERTITLE|PSP_USEHEADERSUBTITLE;
37
38         m_psp.pszHeaderTitle    = MAKEINTRESOURCE(IDS_BROWSE_TITLE);
39         m_psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_BROWSE_SUBTITLE);
40
41         m_emptyListItem         =       NULL;
42         m_initialized           =       false;
43         m_waiting                       =       false;
44 }
45
46
47 CSecondPage::~CSecondPage()
48 {
49 }
50
51
52 void
53 CSecondPage::InitBrowseList()
54 {
55         CPrinterSetupWizardSheet        *       psheet;
56         CString                                                 text;
57
58         psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
59         require_quiet( psheet, exit );
60
61         // Initialize so that nothing is selected when we add to the list
62
63         psheet->SetSelectedPrinter( NULL );
64         m_gotChoice = false;
65         m_browseList.Select( NULL, TVGN_FIRSTVISIBLE );
66
67         //
68         // load the no printers message until something shows up in the browse list
69         //
70         text.LoadString(IDS_NO_PRINTERS);
71
72         LoadTextAndDisableWindow( text );
73
74         //
75         // disable the next button until there's a printer to select
76         //
77         psheet->SetWizardButtons(PSWIZB_BACK);
78
79         //
80         // disable the printer information box
81         //
82         SetPrinterInformationState( FALSE );
83         m_descriptionField.SetWindowText( L"" );
84         m_locationField.SetWindowText( L"" );
85
86 exit:
87
88         return;
89 }
90
91
92 void CSecondPage::DoDataExchange(CDataExchange* pDX)
93 {
94         CPropertyPage::DoDataExchange(pDX);
95         DDX_Control(pDX, IDC_BROWSE_LIST, m_browseList);
96         DDX_Control(pDX, IDC_PRINTER_INFORMATION, m_printerInformation);
97
98         DDX_Control(pDX, IDC_DESCRIPTION_LABEL, m_descriptionLabel);
99
100         DDX_Control(pDX, IDC_DESCRIPTION_FIELD, m_descriptionField);
101
102         DDX_Control(pDX, IDC_LOCATION_LABEL, m_locationLabel);
103
104         DDX_Control(pDX, IDC_LOCATION_FIELD, m_locationField);
105
106 }
107
108
109 afx_msg BOOL
110 CSecondPage::OnSetCursor(CWnd * pWnd, UINT nHitTest, UINT message)
111 {
112         DEBUG_UNUSED(pWnd);
113         DEBUG_UNUSED(nHitTest);
114         DEBUG_UNUSED(message);
115
116         CPrinterSetupWizardSheet * psheet;
117
118         psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
119         require_quiet( psheet, exit );
120
121         SetCursor(psheet->GetCursor());
122
123 exit:
124
125         return TRUE;
126 }
127
128
129 BOOL
130 CSecondPage::OnSetActive()
131 {
132         CPrinterSetupWizardSheet        *       psheet;
133         Printer                                         *       printer;
134         CWnd                                            *       pWnd;
135         Printers::iterator                              it;
136         OSStatus                                                err = kNoErr;
137         BOOL                                                    b;
138
139         b = CPropertyPage::OnSetActive();
140
141         psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
142         require_action( psheet, exit, err = kUnknownErr );
143
144         // Stash the selected printer if any
145
146         printer = psheet->GetSelectedPrinter();
147
148         // initialize the browse list...this will remove everything currently
149         // in it, and add the no printers item
150
151         InitBrowseList();
152
153         // Populate the list with any printers that we currently know about
154
155         for ( it = psheet->m_printers.begin(); it != psheet->m_printers.end(); it++ )
156         {
157                 OnAddPrinter( *it, false );
158         }
159
160         if ( ( !printer && ( psheet->m_printers.size() > 0 ) ) || ( printer != psheet->GetSelectedPrinter() ) )
161         {
162                 if ( !printer )
163                 {
164                         printer = psheet->m_printers.front();
165                 }
166
167                 psheet->SetSelectedPrinter( printer );
168         }
169         
170         if ( printer )
171         {
172                 m_browseList.SelectItem( printer->item );
173                 ::SetFocus( m_browseList );
174         }
175
176         // Hide the back button
177         pWnd = ((CPropertySheet*)GetParent())->GetDlgItem(ID_WIZBACK);\r
178         if ( pWnd != NULL )\r
179         {\r
180                 pWnd->ShowWindow(SW_HIDE);\r
181         }
182
183 exit:
184
185         return b;
186 }
187
188
189 BOOL
190 CSecondPage::OnKillActive()
191 {
192         CPrinterSetupWizardSheet        * psheet;
193         CWnd                                            * pWnd;
194
195         psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
196         require_quiet( psheet, exit );   
197    
198         psheet->SetLastPage(this);
199
200         // Show the back button
201         pWnd = ((CPropertySheet*)GetParent())->GetDlgItem(ID_WIZBACK);\r
202         if ( pWnd != NULL )\r
203         {\r
204                 pWnd->ShowWindow(SW_SHOW);\r
205         }
206
207 exit:
208
209         return CPropertyPage::OnKillActive();
210 }
211
212
213 BEGIN_MESSAGE_MAP(CSecondPage, CPropertyPage)
214         ON_NOTIFY(TVN_SELCHANGED, IDC_BROWSE_LIST, OnTvnSelchangedBrowseList)
215         ON_NOTIFY(NM_CLICK, IDC_BROWSE_LIST, OnNmClickBrowseList)
216         ON_NOTIFY(TVN_KEYDOWN, IDC_BROWSE_LIST, OnTvnKeyDownBrowseList)
217         ON_WM_SETCURSOR()
218 END_MESSAGE_MAP()
219
220
221 // Printer::EventHandler implementation
222 OSStatus
223 CSecondPage::OnAddPrinter(
224                                         Printer *       printer,
225                                         bool            moreComing )
226 {
227         CPrinterSetupWizardSheet        *       psheet;
228         Printer                                         *       selectedPrinter;
229         OSStatus                                                err = kNoErr;
230
231         check( IsWindow( m_hWnd ) );
232
233         m_browseList.SetRedraw(FALSE);
234
235         psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
236         require_quiet( psheet, exit );
237         
238         selectedPrinter = psheet->GetSelectedPrinter();
239
240         printer->item = m_browseList.InsertItem(printer->displayName);
241
242         m_browseList.SetItemData( printer->item, (DWORD_PTR) printer );
243
244         m_browseList.SortChildren(TVI_ROOT);
245
246         //
247         // if the searching item is still in the list
248         // get rid of it
249         //
250         // note that order is important here.  Insert the printer
251         // item before removing the placeholder so we always have
252         // an item in the list to avoid experiencing the bug
253         // in Microsoft's implementation of CTreeCtrl
254         //
255         if (m_emptyListItem != NULL)
256         {
257                 m_browseList.DeleteItem(m_emptyListItem);
258                 m_emptyListItem = NULL;
259                 m_browseList.EnableWindow(TRUE);
260         }
261
262         if ( !selectedPrinter )
263         {
264                 psheet->SetSelectedPrinter( printer );
265                 m_browseList.SelectItem( printer->item );
266                 ::SetFocus( m_browseList );
267         }
268
269 exit:
270
271         if (!moreComing)
272         {
273                 m_browseList.SetRedraw(TRUE);
274                 m_browseList.Invalidate();
275         }
276
277         return err;
278 }
279
280
281 OSStatus
282 CSecondPage::OnRemovePrinter(
283                                 Printer *       printer,
284                                 bool            moreComing)
285 {
286         CPrinterSetupWizardSheet        *       psheet;
287         OSStatus                                                err = kNoErr;
288
289         check( IsWindow( m_hWnd ) );
290         check( printer );
291
292         psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
293         require_quiet( psheet, exit );
294
295         m_browseList.SetRedraw(FALSE);
296
297         //
298         // check to make sure if we're the only item in the control...i.e.
299         // the list size is 1.
300         //
301         if (m_browseList.GetCount() > 1)
302         {
303                 //
304                 // if we're not the only thing in the list, then
305                 // simply remove it from the list
306                 //
307                 m_browseList.DeleteItem( printer->item );
308         }
309         else
310         {
311                 //
312                 // if we're the only thing in the list, then redisplay
313                 // it with the no printers message
314                 //
315                 InitBrowseList();
316         }
317
318 exit:
319
320         if ( !moreComing )
321         {
322                 m_browseList.SetRedraw(TRUE);
323                 m_browseList.Invalidate();
324         }
325
326         return err;
327 }
328
329
330 void
331 CSecondPage::OnResolveService( Service * service )
332 {
333         CPrinterSetupWizardSheet * psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
334         require_quiet( psheet, exit );
335
336         check( service );
337
338         Queue * q = service->SelectedQueue();
339
340         check( q );
341         
342
343         //
344         // and set it to selected
345         //
346
347         m_selectedName  = service->printer->name;
348
349         //
350         // and update the printer information box
351         //
352         SetPrinterInformationState( TRUE );
353
354         m_descriptionField.SetWindowText( q->description );
355         m_locationField.SetWindowText( q->location );
356
357         //
358         // reset the cursor
359         //
360
361         SetCursor(psheet->m_active);
362
363 exit:
364
365         return;
366 }
367
368
369 void CSecondPage::OnTvnSelchangedBrowseList(NMHDR *pNMHDR, LRESULT *pResult)
370 {
371         LPNMTREEVIEW                                    pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
372         CPrinterSetupWizardSheet        *       psheet;
373         Printer                                         *       printer;
374         int                                                             err = 0;
375
376         psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
377         require_action( psheet, exit, err = kUnknownErr );
378
379         // The strange code here is to workaround a bug in the CTreeCtrl, whereupon the item
380         // we selected isn't passed through correctly to this callback routine.
381
382         if ( !m_gotChoice )
383         {
384                 printer = psheet->GetSelectedPrinter();
385
386                 // If we really haven't selected a printer, then re-select NULL and exit
387
388                 if ( !printer )
389                 {
390                         m_browseList.SelectItem( NULL );
391
392                         goto exit;
393                 }
394
395                 // If we already have selected a printer, fake like we've clicked on it, but only
396                 // if the CTreeCtrl hasn't already selected it
397                 
398                 else if ( printer->item != m_browseList.GetSelectedItem() )
399                 {
400                         m_gotChoice = true;
401
402                         m_browseList.SelectItem( printer->item );
403
404                         goto exit;
405                 }
406         }
407
408         HTREEITEM item = m_browseList.GetSelectedItem();
409         require_quiet( item, exit );
410
411         printer = reinterpret_cast<Printer*>(m_browseList.GetItemData( item ) );
412         require_quiet( printer, exit );
413
414         //
415         // this call will trigger a resolve.  When the resolve is complete,
416         // our OnResolve will be called.
417         //
418         err = psheet->StartResolve( printer );
419         require_noerr( err, exit );
420
421         //
422         // And clear out the printer information box
423         //
424         SetPrinterInformationState( FALSE );
425         m_descriptionField.SetWindowText(L"");
426         m_locationField.SetWindowText(L"");
427
428 exit:
429
430         if (err != 0)
431         {
432                 CString text;
433                 CString caption;
434
435                 text.LoadString(IDS_ERROR_SELECTING_PRINTER_TEXT);
436                 caption.LoadString(IDS_ERROR_SELECTING_PRINTER_CAPTION);
437
438                 MessageBox(text, caption, MB_OK|MB_ICONEXCLAMATION);
439         }
440
441         *pResult = 0;
442 }
443
444
445 void CSecondPage::OnNmClickBrowseList(NMHDR *pNMHDR, LRESULT *pResult)
446 {
447         DEBUG_UNUSED( pNMHDR );
448
449         m_gotChoice = true;
450
451         *pResult = 0;
452 }
453
454
455 void CSecondPage::OnTvnKeyDownBrowseList( NMHDR * pNMHDR, LRESULT * pResult)
456 {
457         DEBUG_UNUSED( pNMHDR );
458
459         m_gotChoice = true;
460
461         *pResult = 0;
462 }
463
464
465 void
466 CSecondPage::LoadTextAndDisableWindow( CString & text )
467 {
468         m_emptyListItem = m_browseList.InsertItem( text, 0, 0, NULL, TVI_FIRST );
469         m_browseList.SelectItem( NULL );
470
471         //
472         // this will remove everything else in the list...we might be navigating
473         // back to this window, and the browse list might have changed since
474         // we last displayed it.
475         //
476         if ( m_emptyListItem )
477         {
478                 HTREEITEM item = m_browseList.GetNextVisibleItem( m_emptyListItem );
479   
480                 while ( item )
481                 {
482                         m_browseList.DeleteItem( item );
483                         item = m_browseList.GetNextVisibleItem( m_emptyListItem );
484                 }
485         }
486
487         m_browseList.EnableWindow( FALSE );
488 }
489
490
491 void
492 CSecondPage::SetPrinterInformationState( BOOL state )
493 {
494         m_printerInformation.EnableWindow( state );
495
496         m_descriptionLabel.EnableWindow( state );
497
498         m_descriptionField.EnableWindow( state );
499
500         m_locationLabel.EnableWindow( state );
501
502         m_locationField.EnableWindow( state );
503
504 }
505
506
507