1 /* -*- Mode: C; tab-width: 4 -*-
3 * Copyright (c) 1997-2004 Apple Computer, Inc. All rights reserved.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 Change History (most recent first):
19 $Log: SecondPage.cpp,v $
20 Revision 1.19 2006/08/14 23:24:09 cheshire
21 Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
23 Revision 1.18 2005/07/20 17:44:54 shersche
24 <rdar://problem/4124524> UI fixes for CUPS workaround
26 Revision 1.17 2005/07/11 20:17:15 shersche
27 <rdar://problem/4124524> UI fixes associated with CUPS printer workaround fix.
29 Revision 1.16 2005/07/07 17:53:20 shersche
30 Fix problems associated with the CUPS printer workaround fix.
32 Revision 1.15 2005/04/13 17:46:22 shersche
33 <rdar://problem/4082122> Generic PCL not selected when printers advertise multiple text records
35 Revision 1.14 2005/03/20 20:08:37 shersche
36 <rdar://problem/4055670> Second screen should not select a printer by default
38 Revision 1.13 2005/02/15 07:50:10 shersche
39 <rdar://problem/4007151> Update name
41 Revision 1.12 2005/02/10 22:35:11 cheshire
42 <rdar://problem/3727944> Update name
44 Revision 1.11 2005/01/31 23:54:30 shersche
45 <rdar://problem/3947508> Start browsing when printer wizard starts. Move browsing logic from CSecondPage object to CPrinterSetupWizardSheet object.
47 Revision 1.10 2005/01/20 19:54:38 shersche
48 Fix parse error when text record is NULL
50 Revision 1.9 2005/01/06 08:13:50 shersche
51 Don't use moreComing flag to determine number of text record, disregard queue name if qtotal isn't defined, don't disregard queue name if "rp" is the only key specified
53 Revision 1.8 2005/01/04 21:09:14 shersche
54 Fix problems in parsing text records. Fix problems in remove event handling. Ensure that the same service can't be resolved more than once.
56 Revision 1.7 2004/12/31 07:25:27 shersche
57 Tidy up printer management, and fix memory leaks when hitting 'Cancel'
59 Revision 1.6 2004/12/30 01:24:02 shersche
60 <rdar://problem/3906182> Remove references to description key
63 Revision 1.5 2004/12/30 01:02:47 shersche
64 <rdar://problem/3734478> Add Printer information box that displays description and location information when printer name is selected
67 Revision 1.4 2004/12/29 18:53:38 shersche
68 <rdar://problem/3725106>
69 <rdar://problem/3737413> Added support for LPR and IPP protocols as well as support for obtaining multiple text records. Reorganized and simplified codebase.
70 Bug #: 3725106, 3737413
72 Revision 1.3 2004/09/13 21:26:15 shersche
73 <rdar://problem/3796483> Use the moreComing flag to determine whether drawing should take place in OnAddPrinter and OnRemovePrinter callbacks
76 Revision 1.2 2004/06/26 03:19:57 shersche
77 clean up warning messages
79 Submitted by: herscher
81 Revision 1.1 2004/06/18 04:36:57 rpantos
88 #include "PrinterSetupWizardApp.h"
89 #include "PrinterSetupWizardSheet.h"
90 #include "SecondPage.h"
91 #include "DebugServices.h"
92 #include "WinServices.h"
95 // local variable is initialize but not referenced
96 #pragma warning(disable:4189)
100 IMPLEMENT_DYNAMIC(CSecondPage
, CPropertyPage
)
101 CSecondPage::CSecondPage()
102 : CPropertyPage(CSecondPage::IDD
)
104 m_psp
.dwFlags
&= ~(PSP_HASHELP
);
105 m_psp
.dwFlags
|= PSP_DEFAULT
|PSP_USEHEADERTITLE
|PSP_USEHEADERSUBTITLE
;
107 m_psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_BROWSE_TITLE
);
108 m_psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_BROWSE_SUBTITLE
);
110 m_emptyListItem
= NULL
;
111 m_initialized
= false;
116 CSecondPage::~CSecondPage()
122 CSecondPage::InitBrowseList()
124 CPrinterSetupWizardSheet
* psheet
;
127 psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
128 require_quiet( psheet
, exit
);
130 // Initialize so that nothing is selected when we add to the list
132 psheet
->SetSelectedPrinter( NULL
);
134 m_browseList
.Select( NULL
, TVGN_FIRSTVISIBLE
);
137 // load the no printers message until something shows up in the browse list
139 text
.LoadString(IDS_NO_PRINTERS
);
141 LoadTextAndDisableWindow( text
);
144 // disable the next button until there's a printer to select
146 psheet
->SetWizardButtons(PSWIZB_BACK
);
149 // disable the printer information box
151 SetPrinterInformationState( FALSE
);
152 m_descriptionField
.SetWindowText( L
"" );
153 m_locationField
.SetWindowText( L
"" );
161 void CSecondPage::DoDataExchange(CDataExchange
* pDX
)
163 CPropertyPage::DoDataExchange(pDX
);
164 DDX_Control(pDX
, IDC_BROWSE_LIST
, m_browseList
);
165 DDX_Control(pDX
, IDC_PRINTER_INFORMATION
, m_printerInformation
);
167 DDX_Control(pDX
, IDC_DESCRIPTION_LABEL
, m_descriptionLabel
);
169 DDX_Control(pDX
, IDC_DESCRIPTION_FIELD
, m_descriptionField
);
171 DDX_Control(pDX
, IDC_LOCATION_LABEL
, m_locationLabel
);
173 DDX_Control(pDX
, IDC_LOCATION_FIELD
, m_locationField
);
179 CSecondPage::OnSetCursor(CWnd
* pWnd
, UINT nHitTest
, UINT message
)
182 DEBUG_UNUSED(nHitTest
);
183 DEBUG_UNUSED(message
);
185 CPrinterSetupWizardSheet
* psheet
;
187 psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
188 require_quiet( psheet
, exit
);
190 SetCursor(psheet
->GetCursor());
199 CSecondPage::OnSetActive()
201 CPrinterSetupWizardSheet
* psheet
;
203 Printers::iterator it
;
204 OSStatus err
= kNoErr
;
207 b
= CPropertyPage::OnSetActive();
209 psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
210 require_action( psheet
, exit
, err
= kUnknownErr
);
212 // Stash the selected printer if any
214 printer
= psheet
->GetSelectedPrinter();
216 // initialize the browse list...this will remove everything currently
217 // in it, and add the no printers item
221 // Populate the list with any printers that we currently know about
223 for ( it
= psheet
->m_printers
.begin(); it
!= psheet
->m_printers
.end(); it
++ )
225 OnAddPrinter( *it
, false );
228 // And if we hit 'Back' from page 3, then re-select printer
230 if ( ( psheet
->GetLastPage() == psheet
->GetPage( 2 ) ) && printer
)
232 psheet
->SetSelectedPrinter( printer
);
233 m_browseList
.Select( printer
->item
, TVGN_FIRSTVISIBLE
);
243 CSecondPage::OnKillActive()
245 CPrinterSetupWizardSheet
* psheet
;
247 psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
248 require_quiet( psheet
, exit
);
250 psheet
->SetLastPage(this);
254 return CPropertyPage::OnKillActive();
258 BEGIN_MESSAGE_MAP(CSecondPage
, CPropertyPage
)
259 ON_NOTIFY(TVN_SELCHANGED
, IDC_BROWSE_LIST
, OnTvnSelchangedBrowseList
)
260 ON_NOTIFY(NM_CLICK
, IDC_BROWSE_LIST
, OnNmClickBrowseList
)
261 ON_NOTIFY(TVN_KEYDOWN
, IDC_BROWSE_LIST
, OnTvnKeyDownBrowseList
)
266 // Printer::EventHandler implementation
268 CSecondPage::OnAddPrinter(
272 CPrinterSetupWizardSheet
* psheet
;
273 OSStatus err
= kNoErr
;
275 check( IsWindow( m_hWnd
) );
277 m_browseList
.SetRedraw(FALSE
);
279 psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
280 require_quiet( psheet
, exit
);
282 printer
->item
= m_browseList
.InsertItem(printer
->displayName
);
284 m_browseList
.SetItemData( printer
->item
, (DWORD_PTR
) printer
);
286 m_browseList
.SortChildren(TVI_ROOT
);
289 // if the searching item is still in the list
292 // note that order is important here. Insert the printer
293 // item before removing the placeholder so we always have
294 // an item in the list to avoid experiencing the bug
295 // in Microsoft's implementation of CTreeCtrl
297 if (m_emptyListItem
!= NULL
)
299 m_browseList
.DeleteItem(m_emptyListItem
);
300 m_emptyListItem
= NULL
;
301 m_browseList
.EnableWindow(TRUE
);
308 m_browseList
.SetRedraw(TRUE
);
309 m_browseList
.Invalidate();
317 CSecondPage::OnRemovePrinter(
321 CPrinterSetupWizardSheet
* psheet
;
322 OSStatus err
= kNoErr
;
324 check( IsWindow( m_hWnd
) );
327 psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
328 require_quiet( psheet
, exit
);
330 m_browseList
.SetRedraw(FALSE
);
333 // check to make sure if we're the only item in the control...i.e.
334 // the list size is 1.
336 if (m_browseList
.GetCount() > 1)
339 // if we're not the only thing in the list, then
340 // simply remove it from the list
342 m_browseList
.DeleteItem( printer
->item
);
347 // if we're the only thing in the list, then redisplay
348 // it with the no printers message
357 m_browseList
.SetRedraw(TRUE
);
358 m_browseList
.Invalidate();
366 CSecondPage::OnResolveService( Service
* service
)
368 CPrinterSetupWizardSheet
* psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
369 require_quiet( psheet
, exit
);
373 Queue
* q
= service
->SelectedQueue();
379 // and set it to selected
382 m_selectedName
= service
->printer
->name
;
385 // and update the printer information box
387 SetPrinterInformationState( TRUE
);
389 m_descriptionField
.SetWindowText( q
->description
);
390 m_locationField
.SetWindowText( q
->location
);
396 SetCursor(psheet
->m_active
);
404 void CSecondPage::OnTvnSelchangedBrowseList(NMHDR
*pNMHDR
, LRESULT
*pResult
)
406 LPNMTREEVIEW pNMTreeView
= reinterpret_cast<LPNMTREEVIEW
>(pNMHDR
);
407 CPrinterSetupWizardSheet
* psheet
;
411 psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
412 require_action( psheet
, exit
, err
= kUnknownErr
);
414 // The strange code here is to workaround a bug in the CTreeCtrl, whereupon the item
415 // we selected isn't passed through correctly to this callback routine.
419 printer
= psheet
->GetSelectedPrinter();
421 // If we really haven't selected a printer, then re-select NULL and exit
425 m_browseList
.SelectItem( NULL
);
430 // If we already have selected a printer, fake like we've clicked on it, but only
431 // if the CTreeCtrl hasn't already selected it
433 else if ( printer
->item
!= m_browseList
.GetSelectedItem() )
437 m_browseList
.SelectItem( printer
->item
);
443 HTREEITEM item
= m_browseList
.GetSelectedItem();
444 require_quiet( item
, exit
);
446 printer
= reinterpret_cast<Printer
*>(m_browseList
.GetItemData( item
) );
447 require_quiet( printer
, exit
);
450 // this call will trigger a resolve. When the resolve is complete,
451 // our OnResolve will be called.
453 err
= psheet
->StartResolve( printer
);
454 require_noerr( err
, exit
);
457 // And clear out the printer information box
459 SetPrinterInformationState( FALSE
);
460 m_descriptionField
.SetWindowText(L
"");
461 m_locationField
.SetWindowText(L
"");
470 text
.LoadString(IDS_ERROR_SELECTING_PRINTER_TEXT
);
471 caption
.LoadString(IDS_ERROR_SELECTING_PRINTER_CAPTION
);
473 MessageBox(text
, caption
, MB_OK
|MB_ICONEXCLAMATION
);
480 void CSecondPage::OnNmClickBrowseList(NMHDR
*pNMHDR
, LRESULT
*pResult
)
482 DEBUG_UNUSED( pNMHDR
);
490 void CSecondPage::OnTvnKeyDownBrowseList( NMHDR
* pNMHDR
, LRESULT
* pResult
)
492 DEBUG_UNUSED( pNMHDR
);
501 CSecondPage::LoadTextAndDisableWindow( CString
& text
)
503 m_emptyListItem
= m_browseList
.InsertItem( text
, 0, 0, NULL
, TVI_FIRST
);
504 m_browseList
.SelectItem( NULL
);
507 // this will remove everything else in the list...we might be navigating
508 // back to this window, and the browse list might have changed since
509 // we last displayed it.
511 if ( m_emptyListItem
)
513 HTREEITEM item
= m_browseList
.GetNextVisibleItem( m_emptyListItem
);
517 m_browseList
.DeleteItem( item
);
518 item
= m_browseList
.GetNextVisibleItem( m_emptyListItem
);
522 m_browseList
.EnableWindow( FALSE
);
527 CSecondPage::SetPrinterInformationState( BOOL state
)
529 m_printerInformation
.EnableWindow( state
);
531 m_descriptionLabel
.EnableWindow( state
);
533 m_descriptionField
.EnableWindow( state
);
535 m_locationLabel
.EnableWindow( state
);
537 m_locationField
.EnableWindow( state
);