/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Netscape Public License * Version 1.0 (the "NPL"); you may not use this file except in * compliance with the NPL. You may obtain a copy of the NPL at * http://www.mozilla.org/NPL/ * * Software distributed under the NPL is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL * for the specific language governing rights and limitations under the * NPL. * * The Initial Developer of this code under the NPL is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All Rights * Reserved. */ #include "LMUCHandler.h" #include "LMUCDialog.h" #include #include #include #include #include #include #include #include "muc.h" //#include "profile.h" #include "ListUtils.h" extern "C" { #include "ppp.interface.h" } #define MODEM_SECTION "[Modem]" #define MODEM_KEY "Modem" #define ACCOUNT_SECTION "[Account]" #define ACCOUNT_KEY "Account" #define LOCATION_SECTION "[Location]" #define LOCATION_KEY "Location" const MessageT msg_RunAccountSetup = 1025; const MessageT cmd_AdvancedSettings = 4009; const LStr255 kEmptyString( "" ); LMUCHandler::LMUCHandler(): LListener() { mIniFile = NULL; mDirty = false; mAutoConfigCheck = NULL; mConfigSettings = NULL; mAdvancedButton = NULL; mConfigHelp = NULL; mLocationPopup = NULL; mAccountName = NULL; mModemName = NULL; mShowingHelp = false; } LMUCHandler::~LMUCHandler() { } void LMUCHandler::GetDefaultConfiguration() { GetCurrentAccountName( &mConfiguration.mAccountName ); GetCurrentModemName( &mConfiguration.mModemName ); GetCurrentLocationName( &mConfiguration.mLocationName ); } void LMUCHandler::ClearConfiguration() { mConfiguration.mAccountName[ 0 ] = 0; mConfiguration.mModemName[ 0 ] = 0; mConfiguration.mLocationName[ 0 ] = 0; } // ¥ makes sure all the settings read from the configuration exist inside PPP, // displays alerts for those that don't and resets them void LMUCHandler::SetCurrentConfiguration() { LStr255 temp; temp = mConfiguration.mModemName; this->SetupEntry( temp, GetModemsList, 130 ); LString::CopyPStr( temp, mConfiguration.mModemName ); temp = mConfiguration.mAccountName; this->SetupEntry( temp, GetAccountsList, 129 ); LString::CopyPStr( temp, mConfiguration.mAccountName ); temp = mConfiguration.mLocationName; this->SetupEntry( temp, GetLocationsList, 131 ); LString::CopyPStr( temp, mConfiguration.mLocationName ); } // ¥Êdisplays the edit dialog and allows editing of the settings ExceptionCode LMUCHandler::EditProfile( FSSpec* profileParSpec ) { MessageT ret; Try_ { FSSpec profile; this->GetDialConfigurationFile( *profileParSpec, profile ); if ( mIniFile ) delete mIniFile; mIniFile = new LWinIniFile; mIniFile->SetSpecifier( profile ); LString::CopyPStr( profile.name, mConfiguration.mProfileName ); StDialogHandler handler( 133, NULL ); LMUCEditDialog* dlog = (LMUCEditDialog*)handler.GetDialog(); dlog->UpdateLists(); Try_ { this->ReadConfiguration(); } Catch_( inErr ) { // ¥Êif we get an fnfErr, it means we don't have an configuration // file and we should create one if ( inErr == fnfErr ) { mIniFile->CreateNewDataFile( 'MOSS', 'TEXT', smSystemScript ); this->GetDefaultConfiguration(); } } EndCatch_ dlog->SetInitialValue( mConfiguration.mModemName, mConfiguration.mAccountName, mConfiguration.mLocationName ); top: ret = handler.DoDialog(); switch ( ret ) { case msg_OK: { LStr255 modemName; LStr255 accountName; LStr255 locationName; dlog->GetNewValues( modemName, accountName, locationName ); LString::CopyPStr( modemName, mConfiguration.mModemName ); LString::CopyPStr( accountName, mConfiguration.mAccountName ); LString::CopyPStr( locationName, mConfiguration.mLocationName ); this->WriteConfiguration(); return noErr; } break; case msg_Cancel: return errUserCancelledLaunch; break; case msg_RunAccountSetup: return errNeedToRunAccountSetup; break; default: goto top; } } Catch_( inErr ) { return inErr; } EndCatch_ return noErr; } // ¥ this happens when the user clicks "ok" from the profile selector ExceptionCode LMUCHandler::SelectProfile( FSSpec* profileParSpec, Boolean autoSelect ) { Try_ { FSSpec profile; if ( !autoSelect && mAutoConfigCheck && mAutoConfigCheck->GetValue() ) return noErr; this->GetDialConfigurationFile( *profileParSpec, profile ); ThrowIfNot_( this->ConnectionExists() == noErr ); if ( mIniFile ) delete mIniFile; mIniFile = new LWinIniFile; mIniFile->SetSpecifier( profile ); LString::CopyPStr( profile.name, mConfiguration.mProfileName ); this->ReadConfiguration(); if ( !autoSelect && mLocationPopup ) mLocationPopup->GetCurrentItemTitle( mConfiguration.mLocationName ); this->SetCurrentConfiguration(); if ( mConfiguration.mAccountName != kEmptyString ) this->UpdateConfiguration(); if ( mDirty ) this->WriteConfiguration(); } Catch_( inErr ) { switch ( inErr ) { case errProfileNotFound: case errNeedToRunAccountSetup: case errCannotSwitchDialSettings: case errUserCancelledLaunch: return inErr; case fnfErr: { mIniFile->CreateNewDataFile( 'MOSS', 'TEXT', smSystemScript ); this->GetDefaultConfiguration(); this->WriteConfiguration(); } default: return errProfileNotFound; } } EndCatch_ return noErr; } // ¥Êread the configuration in "profileParSpec" into a configuration struct ExceptionCode LMUCHandler::GetProfile( const FSSpec* profileParSpec, FreePPPInfo* buffer ) { Try_ { FSSpec profile; this->GetDialConfigurationFile( *profileParSpec, profile ); if ( mIniFile ) delete mIniFile; mIniFile = new LWinIniFile; mIniFile->SetSpecifier( profile ); this->ReadConfiguration(); *buffer = mConfiguration; } Catch_( inErr ) { } EndCatch_ return noErr; } ExceptionCode LMUCHandler::SetProfile( const FSSpec* /*profileParSpec*/, const FreePPPInfo* /*buffer*/) { /* Try_ { FSSpec profile; this->GetDialConfigurationFile( *profileParSpec, profile ); if ( mIniFile ) delete mIniFile; mIniFile = new LWinIniFile; mIniFile->SetSpecifier( profile ); this->ReadConfiguration(); mConfiguration = *buffer; this->WriteConfiguration(); } Catch_( inErr ) { } EndCatch_ return noErr; */ } // ¥ configure's PPP void LMUCHandler::UpdateConfiguration() { Str255 current; // ¥ go set the PPP prefs GetCurrentAccountName( ¤t ); if ( !::IdenticalString( current, mConfiguration.mAccountName, NULL ) ) SetCurrentAccountName( &mConfiguration.mAccountName ); GetCurrentModemName( ¤t ); if ( !::IdenticalString( current, mConfiguration.mModemName, NULL ) ) SetCurrentModemName( &mConfiguration.mModemName ); GetCurrentLocationName( ¤t ); if ( !::IdenticalString( current, mConfiguration.mLocationName, NULL ) ) SetCurrentLocationName( &mConfiguration.mLocationName ); } ExceptionCode LMUCHandler::HandleDialog( TraversePPPListFunc inFunc, ResIDT inDlogID, LStr255& outListItemPicked ) { MessageT ret; StDialogHandler handler( inDlogID, NULL ); LMUCDialog* dlog = (LMUCDialog*)handler.GetDialog(); dlog->SetPPPFunction( inFunc ); dlog->UpdateList(); top: ret = handler.DoDialog(); switch ( ret ) { case msg_OK: dlog->GetNewValue( outListItemPicked ); return noErr; break; case msg_Cancel: return errUserCancelledLaunch; break; case msg_RunAccountSetup: return errNeedToRunAccountSetup; break; default: goto top; } return noErr; } // ¥Êreads the settings from the configuration file void LMUCHandler::ReadConfiguration() { this->ClearConfiguration(); ThrowIfNot_( mIniFile ); // ¥ÊOpenDataFile will throw if the file isn't foundÉ mIniFile->OpenDataFork( fsRdPerm ); LStr255 temp; this->GetEntry( temp, ACCOUNT_SECTION, ACCOUNT_KEY ); LString::CopyPStr( temp, mConfiguration.mAccountName ); this->GetEntry( temp, MODEM_SECTION, MODEM_KEY ); LString::CopyPStr( temp, mConfiguration.mModemName ); this->GetEntry( temp, LOCATION_SECTION, LOCATION_KEY ); LString::CopyPStr( temp, mConfiguration.mLocationName ); mIniFile->CloseDataFork(); } ExceptionCode LMUCHandler::WriteConfiguration() { if ( !mIniFile ) return -1; Try_ { mIniFile->CloseDataFork(); } Catch_( inErr ) { // ¥ don't need to do anything } Try_ { mIniFile->OpenDataFork( fsWrPerm ); mIniFile->SetLength( 0 ); *mIniFile << ACCOUNT_SECTION"\r" << ACCOUNT_KEY << "=" << (StringPtr)mConfiguration.mAccountName << "\r"; *mIniFile << MODEM_SECTION << "\r" << MODEM_KEY << "=" << (StringPtr)mConfiguration.mModemName << "\r"; *mIniFile << LOCATION_SECTION << "\r" << LOCATION_KEY << "=" << (StringPtr)mConfiguration.mLocationName << "\r"; mIniFile->CloseDataFork(); mDirty = false; } Catch_( inErr ) { mIniFile->CloseDataFork(); return errCannotSwitchDialSettings; } return noErr; } // ¥Êcall this when you want to get the value for an entry out of the configuration file ExceptionCode LMUCHandler::GetEntry( LStr255& outValue, const LStr255& inSectionName, const LStr255& inKeyName ) { ExceptionCode err; ThrowIfNot_( mIniFile && ( mIniFile->GetDataForkRefNum() != refNum_Undefined ) ); err = mIniFile->FindSection( inSectionName ); if ( err != noErr ) return err; err = mIniFile->GetValueForName( inKeyName, outValue ); return err; } // ¥Êcall this when you want to make sure an entry exists inside PPP ExceptionCode LMUCHandler::SetupEntry( LStr255& inOutEntry, TraversePPPListFunc inFunc, ResIDT inDlogID ) { if ( inOutEntry == kEmptyString ) { mDirty = true; return noErr; } if ( this->FindName( inFunc, inOutEntry ) != noErr ) { // ¥ the user's Config file specifies a configuration entry that // doesn't existÉÊtry to update it by showing the existing // entries and let them pick one OSErr err; LStr255 newString; err = this->HandleDialog( inFunc, inDlogID, newString ); // ¥ err can be: noErr, errUserCancelled, errNeedToRunAS if ( err != noErr ) Throw_( err ); inOutEntry = newString; mDirty = true; } return noErr; } ExceptionCode LMUCHandler::ConnectionExists() { if ( IsFreePPPOpen() ) { // ¥Êalert the user LStr255 name; LCaption* caption; MessageT ret; StDialogHandler handler( 132, NULL ); LDialogBox* dlog = (LDialogBox*)handler.GetDialog(); GetCurrentAccountName( (Str255*)&name ); caption = (LCaption*)dlog->FindPaneByID( 'anam' ); if ( caption ) caption->SetDescriptor( name ); GetCurrentModemName( (Str255*)&name ); caption = (LCaption*)dlog->FindPaneByID( 'mnam' ); if ( caption ) caption->SetDescriptor( name ); GetCurrentLocationName( (Str255*)&name ); caption = (LCaption*)dlog->FindPaneByID( 'lnam' ); if ( caption ) caption->SetDescriptor( name ); do { ret = handler.DoDialog(); if ( ret == msg_OK ) return noErr; else if ( ret == msg_Cancel ) return errCannotSwitchDialSettings; } while ( 1 ); } return noErr; } ExceptionCode LMUCHandler::FindName( TraversePPPListFunc p, const LStr255& value ) { Str255* list; int number; OSErr err; err = (*p)( &list ); number = ::GetPtrSize( (Ptr)list ) / sizeof ( Str255 ); LStr255 name; for ( int i = 0; i < number; i++ ) { name = *list; if ( name == value ) return noErr; list++; } if ( list ) DisposePtr( (Ptr)list ); return -1; } void LMUCHandler::InitDialog( LDialogBox* dialog ) { Rect wFrame; SDimension16 helpFrameSize; SPoint32 helpFrameLoc; LView::SetDefaultView( dialog ); UReanimator::ReadObjects( 'PPob', 135 ); mConfigHelp = (LView*)dialog->FindPaneByID( 'Hcfg' ); mConfigHelp->Enable(); mConfigHelp->FinishCreate(); mAutoConfigCheck = (LStdCheckBox*)dialog->FindPaneByID( 'Cnet' ); mAutoConfigCheck->AddListener( this ); mAdvancedButton = (LControl*)dialog->FindPaneByID( 'Abut' ); mAdvancedButton->AddListener( this ); mLocationPopup = (LPPPPopup*)dialog->FindPaneByID( 'Ploc' ); mLocationPopup->SetPPPFunction( GetLocationsList ); mLocationPopup->UpdateList(); mAccountName = (LCaption*)dialog->FindPaneByID( 'Anam' ); mModemName = (LCaption*)dialog->FindPaneByID( 'Mnam' ); mConfigHelp->GetFrameSize( helpFrameSize ); mConfigHelp->GetFrameLocation( helpFrameLoc ); dialog->CalcPortFrameRect( wFrame ); mSizeToGrow = helpFrameSize.height - ( wFrame.bottom - helpFrameLoc.v ); } void LMUCHandler::PrettyPrint( short resNum, const LStr255& string, LStr255& buffer ) { LStr255 tmp; ::GetIndString( tmp, kMUCStrings, resNum ); buffer += tmp; buffer += string; buffer += LStr255( "\r" ); } ExceptionCode LMUCHandler::ProfileSelectionChanged( const FSSpec* profileSpec ) { FreePPPInfo pppInfo; LStr255 accDesc; LStr255 modemDesc; if ( mAccountName && mModemName ) { if ( profileSpec && this->GetProfile( profileSpec, &pppInfo ) == noErr ) { PrettyPrint( kAccountString, pppInfo.mAccountName, accDesc ); PrettyPrint( kModemString, pppInfo.mModemName, modemDesc ); } mAccountName->SetDescriptor( accDesc ); mModemName->SetDescriptor( modemDesc ); } if ( mLocationPopup ) { if ( !profileSpec || !mLocationPopup->SetToNamedItem( pppInfo.mLocationName ) ) { // ¥Êswitch to the default Str255 tmp; GetCurrentLocationName( &tmp ); mLocationPopup->SetToNamedItem( (LStr255)tmp ); } } return noErr; } void LMUCHandler::ListenToMessage( MessageT inMessage, void* /*ioParam*/ ) { switch ( inMessage ) { case cmd_AdvancedSettings: { LWindow* window; Rect wFrame; // ¥Êmake the window bigger window = LWindow::FetchWindowObject( mAdvancedButton->GetMacPort() ); if ( !window ) return; window->CalcPortFrameRect( wFrame ); window->PortToGlobalPoint( topLeft( wFrame ) ); window->PortToGlobalPoint( botRight( wFrame ) ); wFrame.bottom += mShowingHelp ? -mSizeToGrow : mSizeToGrow; window->DoSetBounds( wFrame ); mShowingHelp = !mShowingHelp; } break; } } void LMUCHandler::GetDialConfigurationFile( const FSSpec& inPrefsFolder, FSSpec& configFile ) { CInfoPBRec pb; // ¥ this is the "Configuration" fileÉÊit sits inside the user's // directory with his "Mail", "News", and other folders configFile.vRefNum = inPrefsFolder.vRefNum; pb.hFileInfo.ioNamePtr = inPrefsFolder.name; pb.hFileInfo.ioVRefNum = inPrefsFolder.vRefNum; pb.hFileInfo.ioDirID = inPrefsFolder.parID; pb.hFileInfo.ioFDirIndex = 0; OSErr err = PBGetCatInfoSync( &pb ); if ( err == noErr ) configFile.parID = pb.dirInfo.ioDrDirID; else return; ::GetIndString( configFile.name, kMUCStrings, kConfigurationFileName ); } void LMUCHandler::RegisterClasses() { URegistrar::RegisterClass( LMUCDialog::class_ID, (ClassCreatorFunc)LMUCDialog::CreateMUCDialogStream ); URegistrar::RegisterClass( LSingleClickListBox::class_ID, (ClassCreatorFunc)LSingleClickListBox::CreateSingleClickListBox ); URegistrar::RegisterClass( LPPPListBox::class_ID, (ClassCreatorFunc)LPPPListBox::CreatePPPListBox ); URegistrar::RegisterClass( LMUCEditDialog::class_ID, (ClassCreatorFunc)LMUCEditDialog::CreateMUCEditDialogStream ); URegistrar::RegisterClass( LPPPPopup::class_ID, (ClassCreatorFunc)LPPPPopup::CreatePPPPopup ); }