2 * Copyright (c) 1997-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
23 Change History (most recent first):
25 $Log: SecondPage.cpp,v $
26 Revision 1.15 2005/04/13 17:46:22 shersche
27 <rdar://problem/4082122> Generic PCL not selected when printers advertise multiple text records
29 Revision 1.14 2005/03/20 20:08:37 shersche
30 <rdar://problem/4055670> Second screen should not select a printer by default
32 Revision 1.13 2005/02/15 07:50:10 shersche
33 <rdar://problem/4007151> Update name
35 Revision 1.12 2005/02/10 22:35:11 cheshire
36 <rdar://problem/3727944> Update name
38 Revision 1.11 2005/01/31 23:54:30 shersche
39 <rdar://problem/3947508> Start browsing when printer wizard starts. Move browsing logic from CSecondPage object to CPrinterSetupWizardSheet object.
41 Revision 1.10 2005/01/20 19:54:38 shersche
42 Fix parse error when text record is NULL
44 Revision 1.9 2005/01/06 08:13:50 shersche
45 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
47 Revision 1.8 2005/01/04 21:09:14 shersche
48 Fix problems in parsing text records. Fix problems in remove event handling. Ensure that the same service can't be resolved more than once.
50 Revision 1.7 2004/12/31 07:25:27 shersche
51 Tidy up printer management, and fix memory leaks when hitting 'Cancel'
53 Revision 1.6 2004/12/30 01:24:02 shersche
54 <rdar://problem/3906182> Remove references to description key
57 Revision 1.5 2004/12/30 01:02:47 shersche
58 <rdar://problem/3734478> Add Printer information box that displays description and location information when printer name is selected
61 Revision 1.4 2004/12/29 18:53:38 shersche
62 <rdar://problem/3725106>
63 <rdar://problem/3737413> Added support for LPR and IPP protocols as well as support for obtaining multiple text records. Reorganized and simplified codebase.
64 Bug #: 3725106, 3737413
66 Revision 1.3 2004/09/13 21:26:15 shersche
67 <rdar://problem/3796483> Use the moreComing flag to determine whether drawing should take place in OnAddPrinter and OnRemovePrinter callbacks
70 Revision 1.2 2004/06/26 03:19:57 shersche
71 clean up warning messages
73 Submitted by: herscher
75 Revision 1.1 2004/06/18 04:36:57 rpantos
82 #include "PrinterSetupWizardApp.h"
83 #include "PrinterSetupWizardSheet.h"
84 #include "SecondPage.h"
85 #include "DebugServices.h"
86 #include "WinServices.h"
89 // local variable is initialize but not referenced
90 #pragma warning(disable:4189)
94 IMPLEMENT_DYNAMIC(CSecondPage
, CPropertyPage
)
95 CSecondPage::CSecondPage()
96 : CPropertyPage(CSecondPage::IDD
)
98 m_psp
.dwFlags
&= ~(PSP_HASHELP
);
99 m_psp
.dwFlags
|= PSP_DEFAULT
|PSP_USEHEADERTITLE
|PSP_USEHEADERSUBTITLE
;
101 m_psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_BROWSE_TITLE
);
102 m_psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_BROWSE_SUBTITLE
);
104 m_emptyListItem
= NULL
;
105 m_initialized
= false;
110 CSecondPage::~CSecondPage()
116 CSecondPage::InitBrowseList()
118 CPrinterSetupWizardSheet
* psheet
;
121 psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
122 require_quiet( psheet
, exit
);
125 // load the no printers message until something shows up in the browse list
127 text
.LoadString(IDS_NO_PRINTERS
);
129 LoadTextAndDisableWindow( text
);
132 // disable the next button until there's a printer to select
134 psheet
->SetWizardButtons(PSWIZB_BACK
);
137 // disable the printer information box
139 SetPrinterInformationState( FALSE
);
140 m_descriptionField
.SetWindowText( L
"" );
141 m_locationField
.SetWindowText( L
"" );
144 // and wait for the user to either hit the mouse or keyboard before selecting an item
154 void CSecondPage::DoDataExchange(CDataExchange
* pDX
)
156 CPropertyPage::DoDataExchange(pDX
);
157 DDX_Control(pDX
, IDC_BROWSE_LIST
, m_browseList
);
158 DDX_Control(pDX
, IDC_PRINTER_INFORMATION
, m_printerInformation
);
160 DDX_Control(pDX
, IDC_DESCRIPTION_LABEL
, m_descriptionLabel
);
162 DDX_Control(pDX
, IDC_DESCRIPTION_FIELD
, m_descriptionField
);
164 DDX_Control(pDX
, IDC_LOCATION_LABEL
, m_locationLabel
);
166 DDX_Control(pDX
, IDC_LOCATION_FIELD
, m_locationField
);
172 CSecondPage::OnSetCursor(CWnd
* pWnd
, UINT nHitTest
, UINT message
)
175 DEBUG_UNUSED(nHitTest
);
176 DEBUG_UNUSED(message
);
178 CPrinterSetupWizardSheet
* psheet
;
180 psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
181 require_quiet( psheet
, exit
);
183 SetCursor(psheet
->GetCursor());
192 CSecondPage::OnSetActive()
194 CPrinterSetupWizardSheet
* psheet
;
196 Printers::iterator it
;
197 OSStatus err
= kNoErr
;
200 b
= CPropertyPage::OnSetActive();
202 psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
203 require_action( psheet
, exit
, err
= kUnknownErr
);
205 // initialize the browse list...this will remove everything currently
206 // in it, and add the no printers item
210 // And populate the list with any printers that we currently know about
212 for ( it
= psheet
->m_printers
.begin(); it
!= psheet
->m_printers
.end(); it
++ )
214 OnAddPrinter( *it
, false );
217 printer
= psheet
->GetSelectedPrinter();
219 if ( printer
!= NULL
)
221 m_browseList
.Select( printer
->item
, TVGN_FIRSTVISIBLE
);
231 CSecondPage::OnKillActive()
233 return CPropertyPage::OnKillActive();
237 BEGIN_MESSAGE_MAP(CSecondPage
, CPropertyPage
)
238 ON_NOTIFY(TVN_SELCHANGED
, IDC_BROWSE_LIST
, OnTvnSelchangedBrowseList
)
239 ON_NOTIFY(NM_CLICK
, IDC_BROWSE_LIST
, OnNmClickBrowseList
)
240 ON_NOTIFY(TVN_KEYDOWN
, IDC_BROWSE_LIST
, OnTvnKeyDownBrowseList
)
245 // Printer::EventHandler implementation
247 CSecondPage::OnAddPrinter(
251 CPrinterSetupWizardSheet
* psheet
;
252 OSStatus err
= kNoErr
;
254 check( IsWindow( m_hWnd
) );
256 m_browseList
.SetRedraw(FALSE
);
258 psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
259 require_quiet( psheet
, exit
);
261 printer
->item
= m_browseList
.InsertItem(printer
->displayName
);
263 m_browseList
.SetItemData( printer
->item
, (DWORD_PTR
) printer
);
265 m_browseList
.SortChildren(TVI_ROOT
);
268 // if the searching item is still in the list
271 // note that order is important here. Insert the printer
272 // item before removing the placeholder so we always have
273 // an item in the list to avoid experiencing the bug
274 // in Microsoft's implementation of CTreeCtrl
276 if (m_emptyListItem
!= NULL
)
278 m_browseList
.DeleteItem(m_emptyListItem
);
279 m_emptyListItem
= NULL
;
280 m_browseList
.EnableWindow(TRUE
);
287 m_browseList
.SetRedraw(TRUE
);
288 m_browseList
.Invalidate();
296 CSecondPage::OnRemovePrinter(
300 CPrinterSetupWizardSheet
* psheet
;
301 OSStatus err
= kNoErr
;
303 check( IsWindow( m_hWnd
) );
306 psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
307 require_quiet( psheet
, exit
);
309 m_browseList
.SetRedraw(FALSE
);
312 // check to make sure if we're the only item in the control...i.e.
313 // the list size is 1.
315 if (m_browseList
.GetCount() > 1)
318 // if we're not the only thing in the list, then
319 // simply remove it from the list
321 m_browseList
.DeleteItem( printer
->item
);
326 // if we're the only thing in the list, then redisplay
327 // it with the no printers message
336 m_browseList
.SetRedraw(TRUE
);
337 m_browseList
.Invalidate();
345 CSecondPage::OnResolveService( Service
* service
)
347 CPrinterSetupWizardSheet
* psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
348 require_quiet( psheet
, exit
);
352 Queue
* q
= service
->SelectedQueue();
358 // and set it to selected
361 m_selectedName
= service
->printer
->name
;
364 // and update the printer information box
366 SetPrinterInformationState( TRUE
);
368 m_descriptionField
.SetWindowText( q
->description
);
369 m_locationField
.SetWindowText( q
->location
);
375 SetCursor(psheet
->m_active
);
383 void CSecondPage::OnTvnSelchangedBrowseList(NMHDR
*pNMHDR
, LRESULT
*pResult
)
385 LPNMTREEVIEW pNMTreeView
= reinterpret_cast<LPNMTREEVIEW
>(pNMHDR
);
386 CPrinterSetupWizardSheet
* psheet
;
390 psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
391 require_action( psheet
, exit
, err
= kUnknownErr
);
393 // The strange code here is to workaround a bug in the CTreeCtrl, whereupon the item
394 // we selected isn't passed through correctly to this callback routine.
398 printer
= psheet
->GetSelectedPrinter();
400 // If we really haven't selected a printer, then re-select NULL and exit
404 m_browseList
.SelectItem( NULL
);
409 // If we already have selected a printer, fake like we've clicked on it, but only
410 // if the CTreeCtrl hasn't already selected it
412 else if ( printer
->item
!= m_browseList
.GetSelectedItem() )
416 m_browseList
.SelectItem( printer
->item
);
422 HTREEITEM item
= m_browseList
.GetSelectedItem();
423 require_quiet( item
, exit
);
425 printer
= reinterpret_cast<Printer
*>(m_browseList
.GetItemData( item
) );
426 require_quiet( printer
, exit
);
429 // this call will trigger a resolve. When the resolve is complete,
430 // our OnResolve will be called.
432 err
= psheet
->StartResolve( printer
);
433 require_noerr( err
, exit
);
436 // And clear out the printer information box
438 SetPrinterInformationState( FALSE
);
439 m_descriptionField
.SetWindowText(L
"");
440 m_locationField
.SetWindowText(L
"");
449 text
.LoadString(IDS_ERROR_SELECTING_PRINTER_TEXT
);
450 caption
.LoadString(IDS_ERROR_SELECTING_PRINTER_CAPTION
);
452 MessageBox(text
, caption
, MB_OK
|MB_ICONEXCLAMATION
);
459 void CSecondPage::OnNmClickBrowseList(NMHDR
*pNMHDR
, LRESULT
*pResult
)
461 DEBUG_UNUSED( pNMHDR
);
469 void CSecondPage::OnTvnKeyDownBrowseList( NMHDR
* pNMHDR
, LRESULT
* pResult
)
471 DEBUG_UNUSED( pNMHDR
);
480 CSecondPage::LoadTextAndDisableWindow( CString
& text
)
482 m_emptyListItem
= m_browseList
.InsertItem( text
, 0, 0, NULL
, TVI_FIRST
);
483 m_browseList
.SelectItem( NULL
);
486 // this will remove everything else in the list...we might be navigating
487 // back to this window, and the browse list might have changed since
488 // we last displayed it.
490 if ( m_emptyListItem
)
492 HTREEITEM item
= m_browseList
.GetNextVisibleItem( m_emptyListItem
);
496 m_browseList
.DeleteItem( item
);
497 item
= m_browseList
.GetNextVisibleItem( m_emptyListItem
);
501 m_browseList
.EnableWindow( FALSE
);
506 CSecondPage::SetPrinterInformationState( BOOL state
)
508 m_printerInformation
.EnableWindow( state
);
510 m_descriptionLabel
.EnableWindow( state
);
512 m_descriptionField
.EnableWindow( state
);
514 m_locationLabel
.EnableWindow( state
);
516 m_locationField
.EnableWindow( state
);