]> git.saurik.com Git - apple/mdnsresponder.git/blob - Clients/PrinterSetupWizard/SecondPage.cpp
mDNSResponder-107.5.tar.gz
[apple/mdnsresponder.git] / Clients / PrinterSetupWizard / SecondPage.cpp
1 /*
2 * Copyright (c) 1997-2004 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22
23 Change History (most recent first):
24
25 $Log: SecondPage.cpp,v $
26 Revision 1.18 2005/07/20 17:44:54 shersche
27 <rdar://problem/4124524> UI fixes for CUPS workaround
28
29 Revision 1.17 2005/07/11 20:17:15 shersche
30 <rdar://problem/4124524> UI fixes associated with CUPS printer workaround fix.
31
32 Revision 1.16 2005/07/07 17:53:20 shersche
33 Fix problems associated with the CUPS printer workaround fix.
34
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
37
38 Revision 1.14 2005/03/20 20:08:37 shersche
39 <rdar://problem/4055670> Second screen should not select a printer by default
40
41 Revision 1.13 2005/02/15 07:50:10 shersche
42 <rdar://problem/4007151> Update name
43
44 Revision 1.12 2005/02/10 22:35:11 cheshire
45 <rdar://problem/3727944> Update name
46
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.
49
50 Revision 1.10 2005/01/20 19:54:38 shersche
51 Fix parse error when text record is NULL
52
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
55
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.
58
59 Revision 1.7 2004/12/31 07:25:27 shersche
60 Tidy up printer management, and fix memory leaks when hitting 'Cancel'
61
62 Revision 1.6 2004/12/30 01:24:02 shersche
63 <rdar://problem/3906182> Remove references to description key
64 Bug #: 3906182
65
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
68 Bug #: 3734478
69
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
74
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
77 Bug #: 3796483
78
79 Revision 1.2 2004/06/26 03:19:57 shersche
80 clean up warning messages
81
82 Submitted by: herscher
83
84 Revision 1.1 2004/06/18 04:36:57 rpantos
85 First checked in
86
87
88 */
89
90 #include "stdafx.h"
91 #include "PrinterSetupWizardApp.h"
92 #include "PrinterSetupWizardSheet.h"
93 #include "SecondPage.h"
94 #include "DebugServices.h"
95 #include "WinServices.h"
96 #include <winspool.h>
97
98 // local variable is initialize but not referenced
99 #pragma warning(disable:4189)
100
101 // CSecondPage dialog
102
103 IMPLEMENT_DYNAMIC(CSecondPage, CPropertyPage)
104 CSecondPage::CSecondPage()
105 : CPropertyPage(CSecondPage::IDD)
106 {
107 m_psp.dwFlags &= ~(PSP_HASHELP);
108 m_psp.dwFlags |= PSP_DEFAULT|PSP_USEHEADERTITLE|PSP_USEHEADERSUBTITLE;
109
110 m_psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_BROWSE_TITLE);
111 m_psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_BROWSE_SUBTITLE);
112
113 m_emptyListItem = NULL;
114 m_initialized = false;
115 m_waiting = false;
116 }
117
118
119 CSecondPage::~CSecondPage()
120 {
121 }
122
123
124 void
125 CSecondPage::InitBrowseList()
126 {
127 CPrinterSetupWizardSheet * psheet;
128 CString text;
129
130 psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
131 require_quiet( psheet, exit );
132
133 // Initialize so that nothing is selected when we add to the list
134
135 psheet->SetSelectedPrinter( NULL );
136 m_gotChoice = false;
137 m_browseList.Select( NULL, TVGN_FIRSTVISIBLE );
138
139 //
140 // load the no printers message until something shows up in the browse list
141 //
142 text.LoadString(IDS_NO_PRINTERS);
143
144 LoadTextAndDisableWindow( text );
145
146 //
147 // disable the next button until there's a printer to select
148 //
149 psheet->SetWizardButtons(PSWIZB_BACK);
150
151 //
152 // disable the printer information box
153 //
154 SetPrinterInformationState( FALSE );
155 m_descriptionField.SetWindowText( L"" );
156 m_locationField.SetWindowText( L"" );
157
158 exit:
159
160 return;
161 }
162
163
164 void CSecondPage::DoDataExchange(CDataExchange* pDX)
165 {
166 CPropertyPage::DoDataExchange(pDX);
167 DDX_Control(pDX, IDC_BROWSE_LIST, m_browseList);
168 DDX_Control(pDX, IDC_PRINTER_INFORMATION, m_printerInformation);
169
170 DDX_Control(pDX, IDC_DESCRIPTION_LABEL, m_descriptionLabel);
171
172 DDX_Control(pDX, IDC_DESCRIPTION_FIELD, m_descriptionField);
173
174 DDX_Control(pDX, IDC_LOCATION_LABEL, m_locationLabel);
175
176 DDX_Control(pDX, IDC_LOCATION_FIELD, m_locationField);
177
178 }
179
180
181 afx_msg BOOL
182 CSecondPage::OnSetCursor(CWnd * pWnd, UINT nHitTest, UINT message)
183 {
184 DEBUG_UNUSED(pWnd);
185 DEBUG_UNUSED(nHitTest);
186 DEBUG_UNUSED(message);
187
188 CPrinterSetupWizardSheet * psheet;
189
190 psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
191 require_quiet( psheet, exit );
192
193 SetCursor(psheet->GetCursor());
194
195 exit:
196
197 return TRUE;
198 }
199
200
201 BOOL
202 CSecondPage::OnSetActive()
203 {
204 CPrinterSetupWizardSheet * psheet;
205 Printer * printer;
206 Printers::iterator it;
207 OSStatus err = kNoErr;
208 BOOL b;
209
210 b = CPropertyPage::OnSetActive();
211
212 psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
213 require_action( psheet, exit, err = kUnknownErr );
214
215 // Stash the selected printer if any
216
217 printer = psheet->GetSelectedPrinter();
218
219 // initialize the browse list...this will remove everything currently
220 // in it, and add the no printers item
221
222 InitBrowseList();
223
224 // Populate the list with any printers that we currently know about
225
226 for ( it = psheet->m_printers.begin(); it != psheet->m_printers.end(); it++ )
227 {
228 OnAddPrinter( *it, false );
229 }
230
231 // And if we hit 'Back' from page 3, then re-select printer
232
233 if ( ( psheet->GetLastPage() == psheet->GetPage( 2 ) ) && printer )
234 {
235 psheet->SetSelectedPrinter( printer );
236 m_browseList.Select( printer->item, TVGN_FIRSTVISIBLE );
237 }
238
239 exit:
240
241 return b;
242 }
243
244
245 BOOL
246 CSecondPage::OnKillActive()
247 {
248 CPrinterSetupWizardSheet * psheet;
249
250 psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
251 require_quiet( psheet, exit );
252
253 psheet->SetLastPage(this);
254
255 exit:
256
257 return CPropertyPage::OnKillActive();
258 }
259
260
261 BEGIN_MESSAGE_MAP(CSecondPage, CPropertyPage)
262 ON_NOTIFY(TVN_SELCHANGED, IDC_BROWSE_LIST, OnTvnSelchangedBrowseList)
263 ON_NOTIFY(NM_CLICK, IDC_BROWSE_LIST, OnNmClickBrowseList)
264 ON_NOTIFY(TVN_KEYDOWN, IDC_BROWSE_LIST, OnTvnKeyDownBrowseList)
265 ON_WM_SETCURSOR()
266 END_MESSAGE_MAP()
267
268
269 // Printer::EventHandler implementation
270 OSStatus
271 CSecondPage::OnAddPrinter(
272 Printer * printer,
273 bool moreComing )
274 {
275 CPrinterSetupWizardSheet * psheet;
276 OSStatus err = kNoErr;
277
278 check( IsWindow( m_hWnd ) );
279
280 m_browseList.SetRedraw(FALSE);
281
282 psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
283 require_quiet( psheet, exit );
284
285 printer->item = m_browseList.InsertItem(printer->displayName);
286
287 m_browseList.SetItemData( printer->item, (DWORD_PTR) printer );
288
289 m_browseList.SortChildren(TVI_ROOT);
290
291 //
292 // if the searching item is still in the list
293 // get rid of it
294 //
295 // note that order is important here. Insert the printer
296 // item before removing the placeholder so we always have
297 // an item in the list to avoid experiencing the bug
298 // in Microsoft's implementation of CTreeCtrl
299 //
300 if (m_emptyListItem != NULL)
301 {
302 m_browseList.DeleteItem(m_emptyListItem);
303 m_emptyListItem = NULL;
304 m_browseList.EnableWindow(TRUE);
305 }
306
307 exit:
308
309 if (!moreComing)
310 {
311 m_browseList.SetRedraw(TRUE);
312 m_browseList.Invalidate();
313 }
314
315 return err;
316 }
317
318
319 OSStatus
320 CSecondPage::OnRemovePrinter(
321 Printer * printer,
322 bool moreComing)
323 {
324 CPrinterSetupWizardSheet * psheet;
325 OSStatus err = kNoErr;
326
327 check( IsWindow( m_hWnd ) );
328 check( printer );
329
330 psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
331 require_quiet( psheet, exit );
332
333 m_browseList.SetRedraw(FALSE);
334
335 //
336 // check to make sure if we're the only item in the control...i.e.
337 // the list size is 1.
338 //
339 if (m_browseList.GetCount() > 1)
340 {
341 //
342 // if we're not the only thing in the list, then
343 // simply remove it from the list
344 //
345 m_browseList.DeleteItem( printer->item );
346 }
347 else
348 {
349 //
350 // if we're the only thing in the list, then redisplay
351 // it with the no printers message
352 //
353 InitBrowseList();
354 }
355
356 exit:
357
358 if ( !moreComing )
359 {
360 m_browseList.SetRedraw(TRUE);
361 m_browseList.Invalidate();
362 }
363
364 return err;
365 }
366
367
368 void
369 CSecondPage::OnResolveService( Service * service )
370 {
371 CPrinterSetupWizardSheet * psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
372 require_quiet( psheet, exit );
373
374 check( service );
375
376 Queue * q = service->SelectedQueue();
377
378 check( q );
379
380
381 //
382 // and set it to selected
383 //
384
385 m_selectedName = service->printer->name;
386
387 //
388 // and update the printer information box
389 //
390 SetPrinterInformationState( TRUE );
391
392 m_descriptionField.SetWindowText( q->description );
393 m_locationField.SetWindowText( q->location );
394
395 //
396 // reset the cursor
397 //
398
399 SetCursor(psheet->m_active);
400
401 exit:
402
403 return;
404 }
405
406
407 void CSecondPage::OnTvnSelchangedBrowseList(NMHDR *pNMHDR, LRESULT *pResult)
408 {
409 LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
410 CPrinterSetupWizardSheet * psheet;
411 Printer * printer;
412 int err = 0;
413
414 psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
415 require_action( psheet, exit, err = kUnknownErr );
416
417 // The strange code here is to workaround a bug in the CTreeCtrl, whereupon the item
418 // we selected isn't passed through correctly to this callback routine.
419
420 if ( !m_gotChoice )
421 {
422 printer = psheet->GetSelectedPrinter();
423
424 // If we really haven't selected a printer, then re-select NULL and exit
425
426 if ( !printer )
427 {
428 m_browseList.SelectItem( NULL );
429
430 goto exit;
431 }
432
433 // If we already have selected a printer, fake like we've clicked on it, but only
434 // if the CTreeCtrl hasn't already selected it
435
436 else if ( printer->item != m_browseList.GetSelectedItem() )
437 {
438 m_gotChoice = true;
439
440 m_browseList.SelectItem( printer->item );
441
442 goto exit;
443 }
444 }
445
446 HTREEITEM item = m_browseList.GetSelectedItem();
447 require_quiet( item, exit );
448
449 printer = reinterpret_cast<Printer*>(m_browseList.GetItemData( item ) );
450 require_quiet( printer, exit );
451
452 //
453 // this call will trigger a resolve. When the resolve is complete,
454 // our OnResolve will be called.
455 //
456 err = psheet->StartResolve( printer );
457 require_noerr( err, exit );
458
459 //
460 // And clear out the printer information box
461 //
462 SetPrinterInformationState( FALSE );
463 m_descriptionField.SetWindowText(L"");
464 m_locationField.SetWindowText(L"");
465
466 exit:
467
468 if (err != 0)
469 {
470 CString text;
471 CString caption;
472
473 text.LoadString(IDS_ERROR_SELECTING_PRINTER_TEXT);
474 caption.LoadString(IDS_ERROR_SELECTING_PRINTER_CAPTION);
475
476 MessageBox(text, caption, MB_OK|MB_ICONEXCLAMATION);
477 }
478
479 *pResult = 0;
480 }
481
482
483 void CSecondPage::OnNmClickBrowseList(NMHDR *pNMHDR, LRESULT *pResult)
484 {
485 DEBUG_UNUSED( pNMHDR );
486
487 m_gotChoice = true;
488
489 *pResult = 0;
490 }
491
492
493 void CSecondPage::OnTvnKeyDownBrowseList( NMHDR * pNMHDR, LRESULT * pResult)
494 {
495 DEBUG_UNUSED( pNMHDR );
496
497 m_gotChoice = true;
498
499 *pResult = 0;
500 }
501
502
503 void
504 CSecondPage::LoadTextAndDisableWindow( CString & text )
505 {
506 m_emptyListItem = m_browseList.InsertItem( text, 0, 0, NULL, TVI_FIRST );
507 m_browseList.SelectItem( NULL );
508
509 //
510 // this will remove everything else in the list...we might be navigating
511 // back to this window, and the browse list might have changed since
512 // we last displayed it.
513 //
514 if ( m_emptyListItem )
515 {
516 HTREEITEM item = m_browseList.GetNextVisibleItem( m_emptyListItem );
517
518 while ( item )
519 {
520 m_browseList.DeleteItem( item );
521 item = m_browseList.GetNextVisibleItem( m_emptyListItem );
522 }
523 }
524
525 m_browseList.EnableWindow( FALSE );
526 }
527
528
529 void
530 CSecondPage::SetPrinterInformationState( BOOL state )
531 {
532 m_printerInformation.EnableWindow( state );
533
534 m_descriptionLabel.EnableWindow( state );
535
536 m_descriptionField.EnableWindow( state );
537
538 m_locationLabel.EnableWindow( state );
539
540 m_locationField.EnableWindow( state );
541
542 }
543
544
545