]> git.saurik.com Git - apple/mdnsresponder.git/blob - Clients/PrinterSetupWizard/SecondPage.cpp
mDNSResponder-107.3.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.13 2005/02/15 07:50:10 shersche
27 <rdar://problem/4007151> Update name
28
29 Revision 1.12 2005/02/10 22:35:11 cheshire
30 <rdar://problem/3727944> Update name
31
32 Revision 1.11 2005/01/31 23:54:30 shersche
33 <rdar://problem/3947508> Start browsing when printer wizard starts. Move browsing logic from CSecondPage object to CPrinterSetupWizardSheet object.
34
35 Revision 1.10 2005/01/20 19:54:38 shersche
36 Fix parse error when text record is NULL
37
38 Revision 1.9 2005/01/06 08:13:50 shersche
39 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
40
41 Revision 1.8 2005/01/04 21:09:14 shersche
42 Fix problems in parsing text records. Fix problems in remove event handling. Ensure that the same service can't be resolved more than once.
43
44 Revision 1.7 2004/12/31 07:25:27 shersche
45 Tidy up printer management, and fix memory leaks when hitting 'Cancel'
46
47 Revision 1.6 2004/12/30 01:24:02 shersche
48 <rdar://problem/3906182> Remove references to description key
49 Bug #: 3906182
50
51 Revision 1.5 2004/12/30 01:02:47 shersche
52 <rdar://problem/3734478> Add Printer information box that displays description and location information when printer name is selected
53 Bug #: 3734478
54
55 Revision 1.4 2004/12/29 18:53:38 shersche
56 <rdar://problem/3725106>
57 <rdar://problem/3737413> Added support for LPR and IPP protocols as well as support for obtaining multiple text records. Reorganized and simplified codebase.
58 Bug #: 3725106, 3737413
59
60 Revision 1.3 2004/09/13 21:26:15 shersche
61 <rdar://problem/3796483> Use the moreComing flag to determine whether drawing should take place in OnAddPrinter and OnRemovePrinter callbacks
62 Bug #: 3796483
63
64 Revision 1.2 2004/06/26 03:19:57 shersche
65 clean up warning messages
66
67 Submitted by: herscher
68
69 Revision 1.1 2004/06/18 04:36:57 rpantos
70 First checked in
71
72
73 */
74
75 #include "stdafx.h"
76 #include "PrinterSetupWizardApp.h"
77 #include "PrinterSetupWizardSheet.h"
78 #include "SecondPage.h"
79 #include "DebugServices.h"
80 #include "WinServices.h"
81 #include <winspool.h>
82
83 // local variable is initialize but not referenced
84 #pragma warning(disable:4189)
85
86 // CSecondPage dialog
87
88 IMPLEMENT_DYNAMIC(CSecondPage, CPropertyPage)
89 CSecondPage::CSecondPage()
90 : CPropertyPage(CSecondPage::IDD)
91 {
92 m_psp.dwFlags &= ~(PSP_HASHELP);
93 m_psp.dwFlags |= PSP_DEFAULT|PSP_USEHEADERTITLE|PSP_USEHEADERSUBTITLE;
94
95 m_psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_BROWSE_TITLE);
96 m_psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_BROWSE_SUBTITLE);
97
98 m_emptyListItem = NULL;
99 m_initialized = false;
100 m_waiting = false;
101 }
102
103
104 CSecondPage::~CSecondPage()
105 {
106 }
107
108
109 void
110 CSecondPage::InitBrowseList()
111 {
112 CPrinterSetupWizardSheet * psheet;
113 CString text;
114
115 psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
116 require_quiet( psheet, exit );
117
118 //
119 // load the no printers message until something shows up in the browse list
120 //
121 text.LoadString(IDS_NO_PRINTERS);
122
123 LoadTextAndDisableWindow( text );
124
125 //
126 // disable the next button until there's a printer to select
127 //
128 psheet->SetWizardButtons(PSWIZB_BACK);
129
130 //
131 // disable the printer information box
132 //
133 SetPrinterInformationState( FALSE );
134
135 exit:
136
137 return;
138 }
139
140
141 void CSecondPage::DoDataExchange(CDataExchange* pDX)
142 {
143 CPropertyPage::DoDataExchange(pDX);
144 DDX_Control(pDX, IDC_BROWSE_LIST, m_browseList);
145 DDX_Control(pDX, IDC_PRINTER_INFORMATION, m_printerInformation);
146
147 DDX_Control(pDX, IDC_DESCRIPTION_LABEL, m_descriptionLabel);
148
149 DDX_Control(pDX, IDC_DESCRIPTION_FIELD, m_descriptionField);
150
151 DDX_Control(pDX, IDC_LOCATION_LABEL, m_locationLabel);
152
153 DDX_Control(pDX, IDC_LOCATION_FIELD, m_locationField);
154
155 }
156
157
158 afx_msg BOOL
159 CSecondPage::OnSetCursor(CWnd * pWnd, UINT nHitTest, UINT message)
160 {
161 DEBUG_UNUSED(pWnd);
162 DEBUG_UNUSED(nHitTest);
163 DEBUG_UNUSED(message);
164
165 CPrinterSetupWizardSheet * psheet;
166
167 psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
168 require_quiet( psheet, exit );
169
170 SetCursor(psheet->GetCursor());
171
172 exit:
173
174 return TRUE;
175 }
176
177
178 BOOL
179 CSecondPage::OnSetActive()
180 {
181 CPrinterSetupWizardSheet * psheet;
182 Printer * printer;
183 Printers::iterator it;
184 OSStatus err = kNoErr;
185
186 psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
187 require_action( psheet, exit, err = kUnknownErr );
188
189 // initialize the browse list...this will remove everything currently
190 // in it, and add the no printers item
191
192 InitBrowseList();
193
194 // And populate the list with any printers that we currently know about
195
196 for ( it = psheet->m_printers.begin(); it != psheet->m_printers.end(); it++ )
197 {
198 OnAddPrinter( *it, false );
199 }
200
201 printer = psheet->GetSelectedPrinter();
202
203 if ( printer != NULL )
204 {
205 m_browseList.Select( printer->item, TVGN_FIRSTVISIBLE );
206 }
207
208 exit:
209
210 return CPropertyPage::OnSetActive();
211 }
212
213
214 BOOL
215 CSecondPage::OnKillActive()
216 {
217 return CPropertyPage::OnKillActive();
218 }
219
220
221 BEGIN_MESSAGE_MAP(CSecondPage, CPropertyPage)
222 ON_NOTIFY(TVN_SELCHANGED, IDC_BROWSE_LIST, OnTvnSelchangedBrowseList)
223 ON_WM_SETCURSOR()
224 END_MESSAGE_MAP()
225
226
227 // Printer::EventHandler implementation
228 OSStatus
229 CSecondPage::OnAddPrinter(
230 Printer * printer,
231 bool moreComing )
232 {
233 CPrinterSetupWizardSheet * psheet;
234 OSStatus err = kNoErr;
235
236 check( IsWindow( m_hWnd ) );
237
238 m_browseList.SetRedraw(FALSE);
239
240 psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
241 require_quiet( psheet, exit );
242
243 printer->item = m_browseList.InsertItem(printer->displayName);
244
245 m_browseList.SetItemData( printer->item, (DWORD_PTR) printer );
246
247 m_browseList.SortChildren(TVI_ROOT);
248
249 if ( printer->name == m_selectedName )
250 {
251 m_browseList.SelectItem( printer->item );
252 }
253
254 //
255 // if the searching item is still in the list
256 // get rid of it
257 //
258 // note that order is important here. Insert the printer
259 // item before removing the placeholder so we always have
260 // an item in the list to avoid experiencing the bug
261 // in Microsoft's implementation of CTreeCtrl
262 //
263 if (m_emptyListItem != NULL)
264 {
265 m_browseList.DeleteItem(m_emptyListItem);
266 m_emptyListItem = NULL;
267 m_browseList.EnableWindow(TRUE);
268 }
269
270 exit:
271
272 if (!moreComing)
273 {
274 m_browseList.SetRedraw(TRUE);
275 m_browseList.Invalidate();
276 }
277
278 return err;
279 }
280
281
282 OSStatus
283 CSecondPage::OnRemovePrinter(
284 Printer * printer,
285 bool moreComing)
286 {
287 CPrinterSetupWizardSheet * psheet;
288 OSStatus err = kNoErr;
289
290 check( IsWindow( m_hWnd ) );
291 check( printer );
292
293 psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
294 require_quiet( psheet, exit );
295
296 m_browseList.SetRedraw(FALSE);
297
298 //
299 // check to make sure if we're the only item in the control...i.e.
300 // the list size is 1.
301 //
302 if (m_browseList.GetCount() > 1)
303 {
304 //
305 // if we're not the only thing in the list, then
306 // simply remove it from the list
307 //
308 m_browseList.DeleteItem( printer->item );
309 }
310 else
311 {
312 //
313 // if we're the only thing in the list, then redisplay
314 // it with the no printers message
315 //
316 InitBrowseList();
317 }
318
319 exit:
320
321 if ( !moreComing )
322 {
323 m_browseList.SetRedraw(TRUE);
324 m_browseList.Invalidate();
325 }
326
327 return err;
328 }
329
330
331 void
332 CSecondPage::OnResolveService( Service * service )
333 {
334 CPrinterSetupWizardSheet * psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
335 require_quiet( psheet, exit );
336
337 check( service );
338
339 //
340 // and set it to selected
341 //
342
343 m_selectedName = service->printer->name;
344
345 //
346 // and update the printer information box
347 //
348 SetPrinterInformationState( TRUE );
349
350 m_descriptionField.SetWindowText( service->description );
351 m_locationField.SetWindowText( service->location );
352
353 //
354 // reset the cursor
355 //
356
357 SetCursor(psheet->m_active);
358
359 exit:
360
361 return;
362 }
363
364
365 void CSecondPage::OnTvnSelchangedBrowseList(NMHDR *pNMHDR, LRESULT *pResult)
366 {
367 LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
368 CPrinterSetupWizardSheet * psheet;
369 int err = 0;
370
371 HTREEITEM item = m_browseList.GetSelectedItem();
372 require_quiet( item, exit );
373
374 psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
375 require_action( psheet, exit, err = kUnknownErr );
376
377 Printer * printer;
378
379 printer = reinterpret_cast<Printer*>(m_browseList.GetItemData( item ) );
380 require_quiet( printer, exit );
381
382 //
383 // this call will trigger a resolve. When the resolve is complete,
384 // our OnResolve will be called.
385 //
386 err = psheet->StartResolve( printer );
387 require_noerr( err, exit );
388
389 //
390 // And clear out the printer information box
391 //
392 SetPrinterInformationState( FALSE );
393 m_descriptionField.SetWindowText(L"");
394 m_locationField.SetWindowText(L"");
395
396 exit:
397
398 if (err != 0)
399 {
400 CString text;
401 CString caption;
402
403 text.LoadString(IDS_ERROR_SELECTING_PRINTER_TEXT);
404 caption.LoadString(IDS_ERROR_SELECTING_PRINTER_CAPTION);
405
406 MessageBox(text, caption, MB_OK|MB_ICONEXCLAMATION);
407 }
408
409 *pResult = 0;
410 }
411
412
413 void
414 CSecondPage::LoadTextAndDisableWindow( CString & text )
415 {
416 m_emptyListItem = m_browseList.InsertItem( text, 0, 0, NULL, TVI_FIRST );
417 m_browseList.SelectItem( NULL );
418
419 //
420 // this will remove everything else in the list...we might be navigating
421 // back to this window, and the browse list might have changed since
422 // we last displayed it.
423 //
424 if ( m_emptyListItem )
425 {
426 HTREEITEM item = m_browseList.GetNextVisibleItem( m_emptyListItem );
427
428 while ( item )
429 {
430 m_browseList.DeleteItem( item );
431 item = m_browseList.GetNextVisibleItem( m_emptyListItem );
432 }
433 }
434
435 m_browseList.EnableWindow( FALSE );
436 }
437
438
439 void
440 CSecondPage::SetPrinterInformationState( BOOL state )
441 {
442 m_printerInformation.EnableWindow( state );
443
444 m_descriptionLabel.EnableWindow( state );
445
446 m_descriptionField.EnableWindow( state );
447
448 m_locationLabel.EnableWindow( state );
449
450 m_locationField.EnableWindow( state );
451
452 }
453
454
455