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.20 2009/06/18 18:05:50 herscher
21 <rdar://problem/4694554> Eliminate the first screen of Printer Wizard and maybe combine others ("I'm Feeling Lucky")
23 Revision 1.19 2006/08/14 23:24:09 cheshire
24 Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
26 Revision 1.18 2005/07/20 17:44:54 shersche
27 <rdar://problem/4124524> UI fixes for CUPS workaround
29 Revision 1.17 2005/07/11 20:17:15 shersche
30 <rdar://problem/4124524> UI fixes associated with CUPS printer workaround fix.
32 Revision 1.16 2005/07/07 17:53:20 shersche
33 Fix problems associated with the CUPS printer workaround fix.
35 Revision 1.15 2005/04/13 17:46:22 shersche
36 <rdar://problem/4082122> Generic PCL not selected when printers advertise multiple text records
38 Revision 1.14 2005/03/20 20:08:37 shersche
39 <rdar://problem/4055670> Second screen should not select a printer by default
41 Revision 1.13 2005/02/15 07:50:10 shersche
42 <rdar://problem/4007151> Update name
44 Revision 1.12 2005/02/10 22:35:11 cheshire
45 <rdar://problem/3727944> Update name
47 Revision 1.11 2005/01/31 23:54:30 shersche
48 <rdar://problem/3947508> Start browsing when printer wizard starts. Move browsing logic from CSecondPage object to CPrinterSetupWizardSheet object.
50 Revision 1.10 2005/01/20 19:54:38 shersche
51 Fix parse error when text record is NULL
53 Revision 1.9 2005/01/06 08:13:50 shersche
54 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
56 Revision 1.8 2005/01/04 21:09:14 shersche
57 Fix problems in parsing text records. Fix problems in remove event handling. Ensure that the same service can't be resolved more than once.
59 Revision 1.7 2004/12/31 07:25:27 shersche
60 Tidy up printer management, and fix memory leaks when hitting 'Cancel'
62 Revision 1.6 2004/12/30 01:24:02 shersche
63 <rdar://problem/3906182> Remove references to description key
66 Revision 1.5 2004/12/30 01:02:47 shersche
67 <rdar://problem/3734478> Add Printer information box that displays description and location information when printer name is selected
70 Revision 1.4 2004/12/29 18:53:38 shersche
71 <rdar://problem/3725106>
72 <rdar://problem/3737413> Added support for LPR and IPP protocols as well as support for obtaining multiple text records. Reorganized and simplified codebase.
73 Bug #: 3725106, 3737413
75 Revision 1.3 2004/09/13 21:26:15 shersche
76 <rdar://problem/3796483> Use the moreComing flag to determine whether drawing should take place in OnAddPrinter and OnRemovePrinter callbacks
79 Revision 1.2 2004/06/26 03:19:57 shersche
80 clean up warning messages
82 Submitted by: herscher
84 Revision 1.1 2004/06/18 04:36:57 rpantos
91 #include "PrinterSetupWizardApp.h"
92 #include "PrinterSetupWizardSheet.h"
93 #include "SecondPage.h"
94 #include "DebugServices.h"
95 #include "WinServices.h"
98 // local variable is initialize but not referenced
99 #pragma warning(disable:4189)
101 // CSecondPage dialog
103 IMPLEMENT_DYNAMIC(CSecondPage
, CPropertyPage
)
104 CSecondPage::CSecondPage()
105 : CPropertyPage(CSecondPage::IDD
)
107 m_psp
.dwFlags
&= ~(PSP_HASHELP
);
108 m_psp
.dwFlags
|= PSP_DEFAULT
|PSP_USEHEADERTITLE
|PSP_USEHEADERSUBTITLE
;
110 m_psp
.pszHeaderTitle
= MAKEINTRESOURCE(IDS_BROWSE_TITLE
);
111 m_psp
.pszHeaderSubTitle
= MAKEINTRESOURCE(IDS_BROWSE_SUBTITLE
);
113 m_emptyListItem
= NULL
;
114 m_initialized
= false;
119 CSecondPage::~CSecondPage()
125 CSecondPage::InitBrowseList()
127 CPrinterSetupWizardSheet
* psheet
;
130 psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
131 require_quiet( psheet
, exit
);
133 // Initialize so that nothing is selected when we add to the list
135 psheet
->SetSelectedPrinter( NULL
);
137 m_browseList
.Select( NULL
, TVGN_FIRSTVISIBLE
);
140 // load the no printers message until something shows up in the browse list
142 text
.LoadString(IDS_NO_PRINTERS
);
144 LoadTextAndDisableWindow( text
);
147 // disable the next button until there's a printer to select
149 psheet
->SetWizardButtons(PSWIZB_BACK
);
152 // disable the printer information box
154 SetPrinterInformationState( FALSE
);
155 m_descriptionField
.SetWindowText( L
"" );
156 m_locationField
.SetWindowText( L
"" );
164 void CSecondPage::DoDataExchange(CDataExchange
* pDX
)
166 CPropertyPage::DoDataExchange(pDX
);
167 DDX_Control(pDX
, IDC_BROWSE_LIST
, m_browseList
);
168 DDX_Control(pDX
, IDC_PRINTER_INFORMATION
, m_printerInformation
);
170 DDX_Control(pDX
, IDC_DESCRIPTION_LABEL
, m_descriptionLabel
);
172 DDX_Control(pDX
, IDC_DESCRIPTION_FIELD
, m_descriptionField
);
174 DDX_Control(pDX
, IDC_LOCATION_LABEL
, m_locationLabel
);
176 DDX_Control(pDX
, IDC_LOCATION_FIELD
, m_locationField
);
182 CSecondPage::OnSetCursor(CWnd
* pWnd
, UINT nHitTest
, UINT message
)
185 DEBUG_UNUSED(nHitTest
);
186 DEBUG_UNUSED(message
);
188 CPrinterSetupWizardSheet
* psheet
;
190 psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
191 require_quiet( psheet
, exit
);
193 SetCursor(psheet
->GetCursor());
202 CSecondPage::OnSetActive()
204 CPrinterSetupWizardSheet
* psheet
;
206 Printers::iterator it
;
207 OSStatus err
= kNoErr
;
210 b
= CPropertyPage::OnSetActive();
212 psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
213 require_action( psheet
, exit
, err
= kUnknownErr
);
215 // Stash the selected printer if any
217 printer
= psheet
->GetSelectedPrinter();
219 // initialize the browse list...this will remove everything currently
220 // in it, and add the no printers item
224 // Populate the list with any printers that we currently know about
226 for ( it
= psheet
->m_printers
.begin(); it
!= psheet
->m_printers
.end(); it
++ )
228 OnAddPrinter( *it
, false );
231 if ( ( !printer
&& ( psheet
->m_printers
.size() > 0 ) ) || ( printer
!= psheet
->GetSelectedPrinter() ) )
235 printer
= psheet
->m_printers
.front();
238 psheet
->SetSelectedPrinter( printer
);
243 m_browseList
.SelectItem( printer
->item
);
244 ::SetFocus( m_browseList
);
254 CSecondPage::OnKillActive()
256 CPrinterSetupWizardSheet
* psheet
;
258 psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
259 require_quiet( psheet
, exit
);
261 psheet
->SetLastPage(this);
265 return CPropertyPage::OnKillActive();
269 BEGIN_MESSAGE_MAP(CSecondPage
, CPropertyPage
)
270 ON_NOTIFY(TVN_SELCHANGED
, IDC_BROWSE_LIST
, OnTvnSelchangedBrowseList
)
271 ON_NOTIFY(NM_CLICK
, IDC_BROWSE_LIST
, OnNmClickBrowseList
)
272 ON_NOTIFY(TVN_KEYDOWN
, IDC_BROWSE_LIST
, OnTvnKeyDownBrowseList
)
277 // Printer::EventHandler implementation
279 CSecondPage::OnAddPrinter(
283 CPrinterSetupWizardSheet
* psheet
;
284 Printer
* selectedPrinter
;
285 OSStatus err
= kNoErr
;
287 check( IsWindow( m_hWnd
) );
289 m_browseList
.SetRedraw(FALSE
);
291 psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
292 require_quiet( psheet
, exit
);
294 selectedPrinter
= psheet
->GetSelectedPrinter();
296 printer
->item
= m_browseList
.InsertItem(printer
->displayName
);
298 m_browseList
.SetItemData( printer
->item
, (DWORD_PTR
) printer
);
300 m_browseList
.SortChildren(TVI_ROOT
);
303 // if the searching item is still in the list
306 // note that order is important here. Insert the printer
307 // item before removing the placeholder so we always have
308 // an item in the list to avoid experiencing the bug
309 // in Microsoft's implementation of CTreeCtrl
311 if (m_emptyListItem
!= NULL
)
313 m_browseList
.DeleteItem(m_emptyListItem
);
314 m_emptyListItem
= NULL
;
315 m_browseList
.EnableWindow(TRUE
);
318 if ( !selectedPrinter
)
320 psheet
->SetSelectedPrinter( printer
);
321 m_browseList
.SelectItem( printer
->item
);
322 ::SetFocus( m_browseList
);
329 m_browseList
.SetRedraw(TRUE
);
330 m_browseList
.Invalidate();
338 CSecondPage::OnRemovePrinter(
342 CPrinterSetupWizardSheet
* psheet
;
343 OSStatus err
= kNoErr
;
345 check( IsWindow( m_hWnd
) );
348 psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
349 require_quiet( psheet
, exit
);
351 m_browseList
.SetRedraw(FALSE
);
354 // check to make sure if we're the only item in the control...i.e.
355 // the list size is 1.
357 if (m_browseList
.GetCount() > 1)
360 // if we're not the only thing in the list, then
361 // simply remove it from the list
363 m_browseList
.DeleteItem( printer
->item
);
368 // if we're the only thing in the list, then redisplay
369 // it with the no printers message
378 m_browseList
.SetRedraw(TRUE
);
379 m_browseList
.Invalidate();
387 CSecondPage::OnResolveService( Service
* service
)
389 CPrinterSetupWizardSheet
* psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
390 require_quiet( psheet
, exit
);
394 Queue
* q
= service
->SelectedQueue();
400 // and set it to selected
403 m_selectedName
= service
->printer
->name
;
406 // and update the printer information box
408 SetPrinterInformationState( TRUE
);
410 m_descriptionField
.SetWindowText( q
->description
);
411 m_locationField
.SetWindowText( q
->location
);
417 SetCursor(psheet
->m_active
);
425 void CSecondPage::OnTvnSelchangedBrowseList(NMHDR
*pNMHDR
, LRESULT
*pResult
)
427 LPNMTREEVIEW pNMTreeView
= reinterpret_cast<LPNMTREEVIEW
>(pNMHDR
);
428 CPrinterSetupWizardSheet
* psheet
;
432 psheet
= reinterpret_cast<CPrinterSetupWizardSheet
*>(GetParent());
433 require_action( psheet
, exit
, err
= kUnknownErr
);
435 // The strange code here is to workaround a bug in the CTreeCtrl, whereupon the item
436 // we selected isn't passed through correctly to this callback routine.
440 printer
= psheet
->GetSelectedPrinter();
442 // If we really haven't selected a printer, then re-select NULL and exit
446 m_browseList
.SelectItem( NULL
);
451 // If we already have selected a printer, fake like we've clicked on it, but only
452 // if the CTreeCtrl hasn't already selected it
454 else if ( printer
->item
!= m_browseList
.GetSelectedItem() )
458 m_browseList
.SelectItem( printer
->item
);
464 HTREEITEM item
= m_browseList
.GetSelectedItem();
465 require_quiet( item
, exit
);
467 printer
= reinterpret_cast<Printer
*>(m_browseList
.GetItemData( item
) );
468 require_quiet( printer
, exit
);
471 // this call will trigger a resolve. When the resolve is complete,
472 // our OnResolve will be called.
474 err
= psheet
->StartResolve( printer
);
475 require_noerr( err
, exit
);
478 // And clear out the printer information box
480 SetPrinterInformationState( FALSE
);
481 m_descriptionField
.SetWindowText(L
"");
482 m_locationField
.SetWindowText(L
"");
491 text
.LoadString(IDS_ERROR_SELECTING_PRINTER_TEXT
);
492 caption
.LoadString(IDS_ERROR_SELECTING_PRINTER_CAPTION
);
494 MessageBox(text
, caption
, MB_OK
|MB_ICONEXCLAMATION
);
501 void CSecondPage::OnNmClickBrowseList(NMHDR
*pNMHDR
, LRESULT
*pResult
)
503 DEBUG_UNUSED( pNMHDR
);
511 void CSecondPage::OnTvnKeyDownBrowseList( NMHDR
* pNMHDR
, LRESULT
* pResult
)
513 DEBUG_UNUSED( pNMHDR
);
522 CSecondPage::LoadTextAndDisableWindow( CString
& text
)
524 m_emptyListItem
= m_browseList
.InsertItem( text
, 0, 0, NULL
, TVI_FIRST
);
525 m_browseList
.SelectItem( NULL
);
528 // this will remove everything else in the list...we might be navigating
529 // back to this window, and the browse list might have changed since
530 // we last displayed it.
532 if ( m_emptyListItem
)
534 HTREEITEM item
= m_browseList
.GetNextVisibleItem( m_emptyListItem
);
538 m_browseList
.DeleteItem( item
);
539 item
= m_browseList
.GetNextVisibleItem( m_emptyListItem
);
543 m_browseList
.EnableWindow( FALSE
);
548 CSecondPage::SetPrinterInformationState( BOOL state
)
550 m_printerInformation
.EnableWindow( state
);
552 m_descriptionLabel
.EnableWindow( state
);
554 m_descriptionField
.EnableWindow( state
);
556 m_locationLabel
.EnableWindow( state
);
558 m_locationField
.EnableWindow( state
);