blob: 35bbefafa351dfbe5002eaf7ca2fd6780ea0f224 [file] [log] [blame]
/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 1997-2004 Apple Computer, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "stdafx.h"
#include "PrinterSetupWizardApp.h"
#include "PrinterSetupWizardSheet.h"
#include "SecondPage.h"
#include "DebugServices.h"
#include "WinServices.h"
#include <winspool.h>
// local variable is initialize but not referenced
#pragma warning(disable:4189)
// CSecondPage dialog
IMPLEMENT_DYNAMIC(CSecondPage, CPropertyPage)
CSecondPage::CSecondPage()
: CPropertyPage(CSecondPage::IDD)
{
m_psp.dwFlags &= ~(PSP_HASHELP);
m_psp.dwFlags |= PSP_DEFAULT|PSP_USEHEADERTITLE|PSP_USEHEADERSUBTITLE;
m_psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_BROWSE_TITLE);
m_psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_BROWSE_SUBTITLE);
m_emptyListItem = NULL;
m_initialized = false;
m_waiting = false;
}
CSecondPage::~CSecondPage()
{
}
void
CSecondPage::InitBrowseList()
{
CPrinterSetupWizardSheet * psheet;
CString text;
psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
require_quiet( psheet, exit );
// Initialize so that nothing is selected when we add to the list
psheet->SetSelectedPrinter( NULL );
m_gotChoice = false;
m_browseList.Select( NULL, TVGN_FIRSTVISIBLE );
//
// load the no printers message until something shows up in the browse list
//
text.LoadString(IDS_NO_PRINTERS);
LoadTextAndDisableWindow( text );
//
// disable the next button until there's a printer to select
//
psheet->SetWizardButtons(PSWIZB_BACK);
//
// disable the printer information box
//
SetPrinterInformationState( FALSE );
m_descriptionField.SetWindowText( L"" );
m_locationField.SetWindowText( L"" );
exit:
return;
}
void CSecondPage::DoDataExchange(CDataExchange* pDX)
{
CPropertyPage::DoDataExchange(pDX);
DDX_Control(pDX, IDC_BROWSE_LIST, m_browseList);
DDX_Control(pDX, IDC_PRINTER_INFORMATION, m_printerInformation);
DDX_Control(pDX, IDC_DESCRIPTION_LABEL, m_descriptionLabel);
DDX_Control(pDX, IDC_DESCRIPTION_FIELD, m_descriptionField);
DDX_Control(pDX, IDC_LOCATION_LABEL, m_locationLabel);
DDX_Control(pDX, IDC_LOCATION_FIELD, m_locationField);
}
afx_msg BOOL
CSecondPage::OnSetCursor(CWnd * pWnd, UINT nHitTest, UINT message)
{
DEBUG_UNUSED(pWnd);
DEBUG_UNUSED(nHitTest);
DEBUG_UNUSED(message);
CPrinterSetupWizardSheet * psheet;
psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
require_quiet( psheet, exit );
SetCursor(psheet->GetCursor());
exit:
return TRUE;
}
BOOL
CSecondPage::OnSetActive()
{
CPrinterSetupWizardSheet * psheet;
Printer * printer;
CWnd * pWnd;
Printers::iterator it;
OSStatus err = kNoErr;
BOOL b;
b = CPropertyPage::OnSetActive();
psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
require_action( psheet, exit, err = kUnknownErr );
// Stash the selected printer if any
printer = psheet->GetSelectedPrinter();
// initialize the browse list...this will remove everything currently
// in it, and add the no printers item
InitBrowseList();
// Populate the list with any printers that we currently know about
for ( it = psheet->m_printers.begin(); it != psheet->m_printers.end(); it++ )
{
OnAddPrinter( *it, false );
}
if ( ( !printer && ( psheet->m_printers.size() > 0 ) ) || ( printer != psheet->GetSelectedPrinter() ) )
{
if ( !printer )
{
printer = psheet->m_printers.front();
}
psheet->SetSelectedPrinter( printer );
}
if ( printer )
{
m_browseList.SelectItem( printer->item );
::SetFocus( m_browseList );
}
// Hide the back button
pWnd = ((CPropertySheet*)GetParent())->GetDlgItem(ID_WIZBACK);
if ( pWnd != NULL )
{
pWnd->ShowWindow(SW_HIDE);
}
exit:
return b;
}
BOOL
CSecondPage::OnKillActive()
{
CPrinterSetupWizardSheet * psheet;
CWnd * pWnd;
psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
require_quiet( psheet, exit );
psheet->SetLastPage(this);
// Show the back button
pWnd = ((CPropertySheet*)GetParent())->GetDlgItem(ID_WIZBACK);
if ( pWnd != NULL )
{
pWnd->ShowWindow(SW_SHOW);
}
exit:
return CPropertyPage::OnKillActive();
}
BEGIN_MESSAGE_MAP(CSecondPage, CPropertyPage)
ON_NOTIFY(TVN_SELCHANGED, IDC_BROWSE_LIST, OnTvnSelchangedBrowseList)
ON_NOTIFY(NM_CLICK, IDC_BROWSE_LIST, OnNmClickBrowseList)
ON_NOTIFY(TVN_KEYDOWN, IDC_BROWSE_LIST, OnTvnKeyDownBrowseList)
ON_WM_SETCURSOR()
END_MESSAGE_MAP()
// Printer::EventHandler implementation
OSStatus
CSecondPage::OnAddPrinter(
Printer * printer,
bool moreComing )
{
CPrinterSetupWizardSheet * psheet;
Printer * selectedPrinter;
OSStatus err = kNoErr;
check( IsWindow( m_hWnd ) );
m_browseList.SetRedraw(FALSE);
psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
require_quiet( psheet, exit );
if ( printer )
{
selectedPrinter = psheet->GetSelectedPrinter();
printer->item = m_browseList.InsertItem(printer->displayName);
m_browseList.SetItemData( printer->item, (DWORD_PTR) printer );
m_browseList.SortChildren(TVI_ROOT);
//
// if the searching item is still in the list
// get rid of it
//
// note that order is important here. Insert the printer
// item before removing the placeholder so we always have
// an item in the list to avoid experiencing the bug
// in Microsoft's implementation of CTreeCtrl
//
if (m_emptyListItem != NULL)
{
m_browseList.DeleteItem(m_emptyListItem);
m_emptyListItem = NULL;
m_browseList.EnableWindow(TRUE);
}
if ( !selectedPrinter )
{
psheet->SetSelectedPrinter( printer );
m_browseList.SelectItem( printer->item );
::SetFocus( m_browseList );
}
}
exit:
if (!moreComing)
{
m_browseList.SetRedraw(TRUE);
m_browseList.Invalidate();
}
return err;
}
OSStatus
CSecondPage::OnRemovePrinter(
Printer * printer,
bool moreComing)
{
CPrinterSetupWizardSheet * psheet;
OSStatus err = kNoErr;
check( IsWindow( m_hWnd ) );
check( printer );
psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
require_quiet( psheet, exit );
m_browseList.SetRedraw(FALSE);
if ( printer )
{
//
// check to make sure if we're the only item in the control...i.e.
// the list size is 1.
//
if (m_browseList.GetCount() > 1)
{
//
// if we're not the only thing in the list, then
// simply remove it from the list
//
m_browseList.DeleteItem( printer->item );
}
else
{
//
// if we're the only thing in the list, then redisplay
// it with the no printers message
//
InitBrowseList();
}
}
exit:
if ( !moreComing )
{
m_browseList.SetRedraw(TRUE);
m_browseList.Invalidate();
}
return err;
}
void
CSecondPage::OnResolveService( Service * service )
{
CPrinterSetupWizardSheet * psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
require_quiet( psheet, exit );
check( service );
Queue * q = service->SelectedQueue();
check( q );
//
// and set it to selected
//
m_selectedName = service->printer->name;
//
// and update the printer information box
//
SetPrinterInformationState( TRUE );
m_descriptionField.SetWindowText( q->description );
m_locationField.SetWindowText( q->location );
//
// reset the cursor
//
SetCursor(psheet->m_active);
exit:
return;
}
void CSecondPage::OnTvnSelchangedBrowseList(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
CPrinterSetupWizardSheet * psheet;
Printer * printer;
int err = 0;
psheet = reinterpret_cast<CPrinterSetupWizardSheet*>(GetParent());
require_action( psheet, exit, err = kUnknownErr );
// The strange code here is to workaround a bug in the CTreeCtrl, whereupon the item
// we selected isn't passed through correctly to this callback routine.
if ( !m_gotChoice )
{
printer = psheet->GetSelectedPrinter();
// If we really haven't selected a printer, then re-select NULL and exit
if ( !printer )
{
m_browseList.SelectItem( NULL );
goto exit;
}
// If we already have selected a printer, fake like we've clicked on it, but only
// if the CTreeCtrl hasn't already selected it
else if ( printer->item != m_browseList.GetSelectedItem() )
{
m_gotChoice = true;
m_browseList.SelectItem( printer->item );
goto exit;
}
}
HTREEITEM item = m_browseList.GetSelectedItem();
require_quiet( item, exit );
printer = reinterpret_cast<Printer*>(m_browseList.GetItemData( item ) );
require_quiet( printer, exit );
//
// this call will trigger a resolve. When the resolve is complete,
// our OnResolve will be called.
//
err = psheet->StartResolve( printer );
require_noerr( err, exit );
//
// And clear out the printer information box
//
SetPrinterInformationState( FALSE );
m_descriptionField.SetWindowText(L"");
m_locationField.SetWindowText(L"");
exit:
if (err != 0)
{
CString text;
CString caption;
text.LoadString(IDS_ERROR_SELECTING_PRINTER_TEXT);
caption.LoadString(IDS_ERROR_SELECTING_PRINTER_CAPTION);
MessageBox(text, caption, MB_OK|MB_ICONEXCLAMATION);
}
*pResult = 0;
}
void CSecondPage::OnNmClickBrowseList(NMHDR *pNMHDR, LRESULT *pResult)
{
DEBUG_UNUSED( pNMHDR );
m_gotChoice = true;
*pResult = 0;
}
void CSecondPage::OnTvnKeyDownBrowseList( NMHDR * pNMHDR, LRESULT * pResult)
{
DEBUG_UNUSED( pNMHDR );
m_gotChoice = true;
*pResult = 0;
}
void
CSecondPage::LoadTextAndDisableWindow( CString & text )
{
m_emptyListItem = m_browseList.InsertItem( text, 0, 0, NULL, TVI_FIRST );
m_browseList.SelectItem( NULL );
//
// this will remove everything else in the list...we might be navigating
// back to this window, and the browse list might have changed since
// we last displayed it.
//
if ( m_emptyListItem )
{
HTREEITEM item = m_browseList.GetNextVisibleItem( m_emptyListItem );
while ( item )
{
m_browseList.DeleteItem( item );
item = m_browseList.GetNextVisibleItem( m_emptyListItem );
}
}
m_browseList.EnableWindow( FALSE );
}
void
CSecondPage::SetPrinterInformationState( BOOL state )
{
m_printerInformation.EnableWindow( state );
m_descriptionLabel.EnableWindow( state );
m_descriptionField.EnableWindow( state );
m_locationLabel.EnableWindow( state );
m_locationField.EnableWindow( state );
}