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