testconns/statapi/device/source/statapi/src/stat_window.cpp
changeset 4 b8d1455fddc0
equal deleted inserted replaced
2:73b88125830c 4:b8d1455fddc0
       
     1 /*
       
     2 * Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20  /*************************************************************************
       
    21  *
       
    22  * Switches
       
    23  *
       
    24  ************************************************************************/
       
    25 //#define ENABLE_INFO
       
    26 
       
    27  /*************************************************************************
       
    28  *
       
    29  * System Includes
       
    30  *
       
    31  ************************************************************************/
       
    32 #include <eikcmbut.h>
       
    33 #include <bautils.h>
       
    34 #include <iniparser.h>
       
    35 #include <s32file.h>
       
    36 
       
    37 /*************************************************************************
       
    38  *
       
    39  * Local Includes
       
    40  *
       
    41  ************************************************************************/
       
    42 
       
    43 #include "stat_window.h"
       
    44 #include "assert.h"
       
    45 #include "filedump.h"
       
    46 #include "stat.h"
       
    47 
       
    48 /*************************************************************************
       
    49  *
       
    50  * Local Includes
       
    51  *
       
    52  ************************************************************************/
       
    53 
       
    54 /*************************************************************************
       
    55  *
       
    56  * Definitions - COMMON
       
    57  *
       
    58  ************************************************************************/
       
    59 
       
    60 // Control sections
       
    61 #define KControlPanel			100
       
    62 #define KVersionPanel			101
       
    63 #define KConnectPanel			102
       
    64 
       
    65 // Position Constants
       
    66 #define KButtonBorderOffset		4
       
    67 #define KConnectLabelWidth		100
       
    68 
       
    69 // Background Colours
       
    70 #define KBackgroundColour		KMistyGray
       
    71 #define KButtonColour			KLightGray
       
    72 #define KLightGray				TRgb(0xC0C0C0)
       
    73 #define KMistyGray				TRgb(0xFFC0C0)
       
    74 
       
    75 // Addresses Contants
       
    76 #define KDefaultAddressSerial		0
       
    77 #define KDefaultAddressInfraRed		0
       
    78 #define KSerialPortCount			6
       
    79 #define KInfraRedPortCount			4
       
    80 
       
    81 // Maximum address field length
       
    82 #define KAddressTextLimit 16
       
    83 #define MAXMESSAGESIZE 128
       
    84 
       
    85 // Hardcoded comms parameters
       
    86 //#define KSerialBaudRate			_L("38400")
       
    87 //#define KIRBaudRate				_L("38400")
       
    88 #define KSerialBaudRate			_L("115200")
       
    89 #define KIRBaudRate				_L("115200")
       
    90 
       
    91 //version info
       
    92 #define KVersionNotKnown		_L("Version not known.")
       
    93 #define KBuildInfoFilePath		_L("Z:\\system\\data\\BuildInfo.txt")
       
    94 #define KBuildNumberFlag		_L8("ManufacturerSoftwareBuild")
       
    95 const TInt KOffsetToBuildNumber = 27; // Length of ManufacturerSoftwareBuild + 2 spaces 
       
    96 
       
    97 // Stored comms data
       
    98 // This is a hard coded choice of drive depending uopn the
       
    99 // target platform.  See CStatApiCommandDecoder::ScreenCapture
       
   100 // for code whch determines if a drive is available.
       
   101 #if defined __WINSCW__
       
   102 	_LIT( KIniFile, "C:\\statui.ini" );
       
   103 #else // defined __WINSCW__
       
   104 	_LIT( KIniFile, "D:\\statui.ini" );
       
   105 #endif // defined __WINSCW__
       
   106 
       
   107 // Coms fields in ini file
       
   108 _LIT( KIniFormat, "%S= %d\r\n" );
       
   109 _LIT( KIniConnectType, "ConnectType" );
       
   110 _LIT( KIniAddress, "Address" );
       
   111 _LIT( KIniRunning, "Running" );
       
   112 _LIT( KIniConnectAutomatically, "ConnectAutomatically" );
       
   113 
       
   114 LOCAL_D MNotifyLogMessage *iMsg = NULL;
       
   115 LOCAL_D	RFs iFsSession;
       
   116 
       
   117 #define UndefinedData				(-1)
       
   118 #define DefaultConnect				ESerial
       
   119 #define DefaultAddress				1
       
   120 #define DefaultRunning				0
       
   121 #define DefaultConnectAutomatically	1
       
   122 
       
   123 /*************************************************************************
       
   124  *
       
   125  * Definitions - SERIES 60
       
   126  *
       
   127  ************************************************************************/
       
   128 #ifdef SYMBIAN_DIST_SERIES60
       
   129 
       
   130 #define KButtonHeight				18
       
   131 #define KButtonWidth				82
       
   132 #define KStatusLabelWidth			(KButtonBorderOffset)
       
   133 
       
   134 #define KConnectPanelTop			(3*KButtonBorderOffset + 2*KButtonHeight)
       
   135 #define KEditControlFudgeTop		1
       
   136 #define KConnectPanelFudge			6
       
   137 
       
   138 #define KEditControlFlags			(CEikEdwin::ELineCursor | CEikEdwin::EAvkonEditor | CEikEdwin::EAvkonDisableCursor)
       
   139 
       
   140 #define KConnectingStatusStr		_L("STAT is connecting.")
       
   141 #define KWaitingForDataStatusStr	_L("STAT is waiting for data.")
       
   142 
       
   143 #define KButtonsVisible				EFalse
       
   144 #endif
       
   145 
       
   146 /*************************************************************************
       
   147  *
       
   148  * Definitions - TECHVIEW
       
   149  *
       
   150  ************************************************************************/
       
   151 #ifdef SYMBIAN_DIST_TECHVIEW
       
   152 
       
   153 #define KButtonHeight				24
       
   154 #define KButtonWidth				82
       
   155 #define KStatusLabelWidth			(2*KButtonBorderOffset + KButtonWidth)
       
   156 
       
   157 #define KConnectPanelTop			(4*KButtonBorderOffset + 3*KButtonHeight)
       
   158 #define KEditControlFudgeTop		0
       
   159 #define KConnectPanelFudge			0
       
   160 
       
   161 #define KEditControlFlags			(CEikEdwin::ELineCursor)
       
   162 
       
   163 #define KConnectingStatusStr		_L("STAT is waiting for a connection.")
       
   164 #define KWaitingForDataStatusStr	_L("STAT is waiting to receive data.")
       
   165 
       
   166 #define KButtonsVisible				ETrue
       
   167 #endif
       
   168 
       
   169 /*************************************************************************
       
   170  *
       
   171  * Definitions - UIQ
       
   172  *
       
   173  ************************************************************************/
       
   174 #ifdef SYMBIAN_DIST_UIQ
       
   175 
       
   176 #define KButtonHeight				20
       
   177 #define KButtonWidth				60
       
   178 
       
   179 #define KStatusLabelWidth			(2*KButtonBorderOffset + KButtonWidth)
       
   180 
       
   181 #define KConnectPanelTop			(4*KButtonBorderOffset + 3*KButtonHeight)
       
   182 #define KEditControlFudgeTop		0
       
   183 #define KConnectPanelFudge			0
       
   184 
       
   185 #define KEditControlFlags			(CEikEdwin::ELineCursor)
       
   186 
       
   187 #define KConnectingStatusStr		_L("STAT is waiting for a connection.")
       
   188 #define KWaitingForDataStatusStr	_L("STAT is waiting to receive data.")
       
   189 
       
   190 #define KButtonsVisible				ETrue
       
   191 #endif
       
   192 
       
   193 /*************************************************************************
       
   194  *
       
   195  * CStatWindow - Construction
       
   196  *
       
   197  ************************************************************************/
       
   198 CStatWindow *CStatWindow::NewL( const TRect& rect, MStatController *aStatController )
       
   199 {
       
   200 	CStatWindow* self = new(ELeave) CStatWindow();
       
   201 	CleanupStack::PushL( self );
       
   202 	self->ConstructL( rect, aStatController );
       
   203 	CleanupStack::Pop();
       
   204 	return self;
       
   205 }
       
   206 
       
   207 CStatWindow::CStatWindow()
       
   208 {
       
   209 	iStatusLabel = NULL;
       
   210 	iErrorLabel = NULL;
       
   211 	iVersionLabel = NULL;
       
   212 	iTransportLabel = NULL;
       
   213 	iAddressLabel = NULL;
       
   214 	iTransportEdit = NULL;
       
   215 	iAddressEdit = NULL;
       
   216 	iActionButton = NULL;
       
   217 	iExitButton = NULL;
       
   218 	iInfoLabel = NULL;
       
   219 	iLogButton = NULL;
       
   220 	iClearLabelsOnly = 0;
       
   221 	bIsForeground = EFalse;
       
   222 	iIniData = NULL;
       
   223 	iAOConnection = NULL;
       
   224 }
       
   225 
       
   226 CStatWindow::~CStatWindow()
       
   227 {
       
   228 	delete iIniData;
       
   229 	delete iStatusLabel;
       
   230 	delete iErrorLabel;
       
   231 	delete iVersionLabel;
       
   232 	delete iTransportLabel;
       
   233 	delete iAddressLabel;
       
   234 	delete iTransportEdit;
       
   235 	delete iAddressEdit;
       
   236 	delete iActionButton;
       
   237 	delete iExitButton;
       
   238 	delete iInfoLabel;
       
   239 	delete iLogButton;
       
   240 
       
   241 	if( iMsg->IsInitialised() )
       
   242 		{
       
   243 		iMsg->CloseFile();
       
   244 		}
       
   245 
       
   246 	iFsSession.Close();
       
   247 
       
   248 	delete iMsg;
       
   249 	iMsg =	NULL;
       
   250 
       
   251 	asserte(NULL==iAOConnection);
       
   252 }
       
   253 
       
   254 void CStatWindow::ConstructL( const TRect& rect, MStatController *aStatController )
       
   255 {
       
   256 	TBuf<16> choiceItem;
       
   257 
       
   258 	User::LeaveIfError( iFsSession.Connect() );
       
   259 	iMsg = new FileDump();
       
   260 	
       
   261 	
       
   262 	RFs fileServer;
       
   263 	TVersionName version(fileServer.Version().Name());
       
   264 	
       
   265 	TBuf<KMaxFileName> statLogFile;
       
   266 	
       
   267 	TDriveNumber defaultSysDrive(EDriveC);
       
   268 	RLibrary pluginLibrary;
       
   269 	TInt pluginErr = pluginLibrary.Load(KFileSrvDll);
       
   270 	
       
   271 	if (pluginErr == KErrNone)
       
   272 		{
       
   273 		typedef TDriveNumber(*fun1)();
       
   274 		fun1 sysdrive;
       
   275 	
       
   276 	#ifdef __EABI__
       
   277 		sysdrive = (fun1)pluginLibrary.Lookup(336);
       
   278 	#else
       
   279 		sysdrive = (fun1)pluginLibrary.Lookup(304);
       
   280 	#endif
       
   281 		
       
   282 		if(sysdrive!=NULL)
       
   283 			{
       
   284 			defaultSysDrive = sysdrive();
       
   285 			}
       
   286 		}
       
   287 	pluginLibrary.Close();
       
   288 	
       
   289 	statLogFile.Append(TDriveUnit(defaultSysDrive).Name());
       
   290 	statLogFile.Append(KFileSeparator);
       
   291 	statLogFile.Append(KStatLogFile);
       
   292 	
       
   293 	iMsg->Init( iFsSession, statLogFile, NULL );
       
   294 
       
   295 	// Store the pointer to the STAT controller
       
   296 	iStatController = aStatController;
       
   297 
       
   298 	// create a window and set the size to the full screen
       
   299 	CreateWindowL();
       
   300 	SetRect(rect);
       
   301 
       
   302 	// create all sub components -- note that I should push stuff onto the cleanup stack
       
   303 	iStatusLabel = new(ELeave) CEikLabel();
       
   304 	iStatusLabel->SetContainerWindowL(*this);
       
   305 	iStatusLabel->SetRect( GetControlPosition(KStatusLabel) );
       
   306 	iStatusLabel->SetAlignment( EHLeftVCenter );
       
   307 	iStatusLabel->SetFont( iEikonEnv->AnnotationFont() );
       
   308 	iStatusLabel->SetBufferReserveLengthL( 200 );
       
   309 	iStatusLabel->SetTextL( _L("STAT is not running") );
       
   310 	iStatusLabel->ActivateL( );
       
   311 
       
   312 	iErrorLabel = new(ELeave) CEikLabel();
       
   313 	iErrorLabel->SetContainerWindowL(*this);
       
   314 	iErrorLabel->SetRect( GetControlPosition(KErrorLabel) );
       
   315 	iErrorLabel->SetAlignment( EHLeftVCenter );
       
   316 	iErrorLabel->SetFont( iEikonEnv->AnnotationFont() );
       
   317 	iErrorLabel->SetBufferReserveLengthL( 200 );
       
   318 	iErrorLabel->SetTextL( _L("No errors") );
       
   319 	iErrorLabel->ActivateL( );
       
   320 
       
   321 	// The info-label is only for debugging. It prints strings sent up to the
       
   322 	// UI from the transport and engine. It's too much code to take the control 
       
   323 	// out completely so I'm just disabling it (making it invisible).
       
   324 	iInfoLabel = new(ELeave) CEikLabel();
       
   325 	iInfoLabel->SetContainerWindowL(*this);
       
   326 	iInfoLabel->SetRect( GetControlPosition(KInfoLabel) );
       
   327 	iInfoLabel->SetAlignment( EHLeftVCenter );
       
   328 	iInfoLabel->SetFont( iEikonEnv->AnnotationFont() );
       
   329 	iInfoLabel->SetBufferReserveLengthL( 200 );
       
   330 	iInfoLabel->SetTextL( _L("") );
       
   331 	iInfoLabel->ActivateL( );
       
   332 	// iInfoLabel->MakeVisible( EFalse );
       
   333 	iInfoLabel->MakeVisible( ETrue );
       
   334 
       
   335 	iActionButton = new(ELeave) CEikCommandButton();
       
   336 	iActionButton->SetContainerWindowL(*this);
       
   337 	iActionButton->SetDisplayContent( CEikCommandButton::ETextOnly );
       
   338 	iActionButton->SetTextL( _L("Start") );
       
   339 	iActionButton->SetRect( GetControlPosition(KActionButton) );
       
   340 	iActionButton->SetObserver( this );
       
   341 	iActionButton->SetButtonLayout( (CEikCommandButton::TLayout)CEikCommandButton::EDenseFont );
       
   342 	iActionButton->MakeVisible( KButtonsVisible );
       
   343 	iActionButton->OverrideColorL( EColorButtonFaceClear, KButtonColour );
       
   344 	iActionButton->OverrideColorL( EColorButtonFaceSet, KButtonColour );
       
   345 	iActionButton->OverrideColorL( EColorButtonFaceSetPressed, KButtonColour );
       
   346 	iActionButton->OverrideColorL( EColorButtonFaceClearPressed, KButtonColour );
       
   347 	iActionButton->ActivateL();
       
   348 	
       
   349 	iExitButton = new(ELeave) CEikCommandButton();
       
   350 	iExitButton->SetContainerWindowL(*this);
       
   351 	iExitButton->SetDisplayContent( CEikCommandButton::ETextOnly );
       
   352 	iExitButton->SetTextL( _L("Exit") );
       
   353 	iExitButton->SetRect( GetControlPosition(KExitButton) );
       
   354 	iExitButton->SetObserver( this );
       
   355 	iExitButton->SetButtonLayout( (CEikCommandButton::TLayout)0 );
       
   356 	iExitButton->MakeVisible( KButtonsVisible );
       
   357 	iExitButton->OverrideColorL( EColorButtonFaceClear, KButtonColour );
       
   358 	iExitButton->OverrideColorL( EColorButtonFaceSet, KButtonColour );
       
   359 	iExitButton->OverrideColorL( EColorButtonFaceSetPressed, KButtonColour );
       
   360 	iExitButton->OverrideColorL( EColorButtonFaceClearPressed, KButtonColour );
       
   361 	iExitButton->ActivateL();
       
   362 
       
   363 	iLogButton = new(ELeave) CEikCommandButton();
       
   364 	iLogButton->SetContainerWindowL(*this);
       
   365 	iLogButton->SetDisplayContent( CEikCommandButton::ETextOnly );
       
   366 	iLogButton->SetTextL( _L("Logging") );
       
   367 	iLogButton->SetRect( GetControlPosition(KLogButton) );
       
   368 	iLogButton->SetObserver( this );
       
   369 	iLogButton->SetButtonLayout( (CEikCommandButton::TLayout)0 );
       
   370 	iLogButton->SetBehavior( EEikButtonLatches );
       
   371 	iLogButton->MakeVisible( KButtonsVisible );
       
   372 	iLogButton->OverrideColorL( EColorButtonFaceClear, KButtonColour );
       
   373 	iLogButton->OverrideColorL( EColorButtonFaceSet, KButtonColour );
       
   374 	iLogButton->OverrideColorL( EColorButtonFaceSetPressed, KButtonColour );
       
   375 	iLogButton->OverrideColorL( EColorButtonFaceClearPressed, KButtonColour );
       
   376 	iLogButton->ActivateL();
       
   377 	iLoggingEnabled = EFalse;
       
   378 
       
   379 	iVersionLabel = new(ELeave) CEikLabel();
       
   380 	iVersionLabel->SetContainerWindowL(*this);
       
   381 	iVersionLabel->SetRect( GetControlPosition(KVersionLabel) );
       
   382 	iVersionLabel->SetAlignment( EHLeftVCenter );
       
   383 	iVersionLabel->SetFont( iEikonEnv->AnnotationFont() );
       
   384 	iVersionLabel->SetBufferReserveLengthL( 200 );
       
   385 	SetVersionLabelL();;
       
   386 	iVersionLabel->ActivateL( );
       
   387 
       
   388 	iTransportLabel = new(ELeave) CEikLabel();
       
   389 	iTransportLabel->SetContainerWindowL(*this);
       
   390 	iTransportLabel->SetRect( GetControlPosition(KTransportLabel) );
       
   391 	iTransportLabel->SetAlignment( EHLeftVCenter );
       
   392 	iTransportLabel->SetFont( iEikonEnv->AnnotationFont() );
       
   393 	iTransportLabel->SetBufferReserveLengthL( 200 );
       
   394 	iTransportLabel->SetTextL( _L("Connect Type") );
       
   395 	iTransportLabel->ActivateL( );
       
   396 
       
   397 	iAddressLabel = new(ELeave) CEikLabel();
       
   398 	iAddressLabel->SetContainerWindowL(*this);
       
   399 	iAddressLabel->SetRect( GetControlPosition(KAddressLabel) );
       
   400 	iAddressLabel->SetAlignment( EHLeftVCenter );
       
   401 	iAddressLabel->SetFont( iEikonEnv->AnnotationFont() );
       
   402 	iAddressLabel->SetBufferReserveLengthL( 200 );
       
   403 	iAddressLabel->SetTextL( _L("Address") );
       
   404 	iAddressLabel->ActivateL( );
       
   405 
       
   406 	iTransportEdit = new(ELeave) CStatChoice();
       
   407 	iTransportEdit->SetContainerWindowL(*this);
       
   408 	iTransportEdit->ConstructL( KEditControlFlags ); 
       
   409 	iTransportEdit->SetRect( GetControlPosition(KTransportEdit) );
       
   410 	iTransportEdit->SetDimmed( EFalse );
       
   411 	iTransportEdit->SetReadOnly( ETrue );
       
   412 	iTransportEdit->SetFocus( ETrue );
       
   413 
       
   414 	choiceItem.Copy( _L("TCPIP") );
       
   415 	iTransportEdit->AddItemL( choiceItem );
       
   416 	choiceItem.Copy( _L("Serial") );
       
   417 	iTransportEdit->AddItemL( choiceItem );
       
   418 	choiceItem.Copy( _L("InfraRed") );
       
   419 	iTransportEdit->AddItemL( choiceItem );
       
   420 	choiceItem.Copy( _L("Bluetooth") );
       
   421 	iTransportEdit->AddItemL( choiceItem );
       
   422 
       
   423 	iTransportEdit->SetCurrentItem( ESerial );
       
   424 	iTransportEdit->OverrideColorL( EColorControlDimmedBackground, KButtonColour );	
       
   425 	iTransportEdit->ActivateL();
       
   426 	iTransportEdit->ClearSelectionL();
       
   427 	iTransportEdit->SetCursorPosL( 0, EFalse );
       
   428 	iTransportEdit->SetCurrentItem( 1 );
       
   429 
       
   430 	iAddressEdit = new(ELeave) CStatChoice();
       
   431 	iAddressEdit->SetContainerWindowL(*this);
       
   432 	iAddressEdit->ConstructL( KEditControlFlags ); 
       
   433 	iAddressEdit->SetRect( GetControlPosition(KAddressEdit) );
       
   434 	iAddressEdit->SetDimmed( EFalse );
       
   435 	iAddressEdit->SetReadOnly( ETrue );
       
   436 	iAddressEdit->SetFocus( ETrue );
       
   437 	iAddressEdit->OverrideColorL( EColorControlDimmedBackground, KButtonColour );	
       
   438 	iAddressEdit->ActivateL();
       
   439 	iAddressEdit->ClearSelectionL();
       
   440 	iAddressEdit->SetCursorPosL( 0, EFalse );
       
   441 
       
   442 	// Get the ini data from the user preference file.
       
   443 	iIniData = new(ELeave) CStatIniData;
       
   444 	iIniData->ReadIniData( KIniFile );
       
   445 	// Set the user's preferred transpor connection
       
   446 	// if one was specified in the ini file data.
       
   447 	if( iIniData->iConnectType != UndefinedData )
       
   448 	{
       
   449 		iTransportEdit->SetCurrentItem( iIniData->iConnectType );
       
   450 	}
       
   451 
       
   452 	// call ontransportchange so that iAddressEdit is set up properly
       
   453 	OnTransportChange();
       
   454 
       
   455 	// Set the user's preferred transport address
       
   456 	// if one was specified in the ini file data.
       
   457 	if( iIniData->iAddress != UndefinedData )
       
   458 	{
       
   459 		iAddressEdit->SetCurrentItem( iIniData->iAddress );
       
   460 	}
       
   461 
       
   462 	// Check if the the applicatoin was running when it
       
   463 	// was shut down last time (this can happen if the application
       
   464 	// was not shut down gracefully through an 'exit', maybe
       
   465 	// it was rebooted) and the user has specified that we
       
   466 	// connect automatically.
       
   467 	TBool connectAutomatically = FALSE;
       
   468 
       
   469 	if( (iIniData->iIsRunning != UndefinedData) &&
       
   470 		(iIniData->iConnectAutomatically != UndefinedData))
       
   471 	{
       
   472 		connectAutomatically = ((iIniData->iIsRunning) && 
       
   473 					(iIniData->iConnectAutomatically));
       
   474 	}
       
   475 	// End of reading ini data.
       
   476 
       
   477 	// activate the window (which in turn activates all sub components
       
   478 	ActivateL();
       
   479 	iTransportEdit->ClearSelectionL();
       
   480 	iAddressEdit->ClearSelectionL();
       
   481 	DrawNow();
       
   482 
       
   483 	// Check if we need to connect now.
       
   484 	if(connectAutomatically)
       
   485 	{
       
   486 		HandleActionL();
       
   487 	}
       
   488 }
       
   489 
       
   490 /*************************************************************************
       
   491  *
       
   492  * CStatWindow - From CCoeControl
       
   493  *
       
   494  ************************************************************************/
       
   495 void CStatWindow::SetForeground( TBool aIsForeground )
       
   496 {
       
   497 	bIsForeground = aIsForeground;
       
   498 }
       
   499 
       
   500 /*************************************************************************
       
   501  *
       
   502  * CStatWindow - From CCoeControl
       
   503  *
       
   504  ************************************************************************/
       
   505 TInt CStatWindow::CountComponentControls() const
       
   506 {
       
   507 	return KControlCount;
       
   508 }
       
   509 
       
   510 CCoeControl* CStatWindow::ComponentControl(TInt aIndex) const
       
   511 {
       
   512 	switch( aIndex ) {
       
   513 	case KStatusLabel:
       
   514 		return iStatusLabel;
       
   515 	case KErrorLabel:
       
   516 		return iErrorLabel;
       
   517 	case KVersionLabel:
       
   518 		return iVersionLabel;
       
   519 	case KTransportLabel:
       
   520 		return iTransportLabel;
       
   521 	case KAddressLabel:
       
   522 		return iAddressLabel;
       
   523 	case KTransportEdit:
       
   524 		return iTransportEdit;
       
   525 	case KAddressEdit:
       
   526 		return iAddressEdit;
       
   527 	case KActionButton:
       
   528 		return iActionButton;
       
   529 	case KExitButton:
       
   530 		return iExitButton;
       
   531 	case KInfoLabel:
       
   532 		return iInfoLabel;
       
   533 	case KLogButton:
       
   534 		return iLogButton;
       
   535 	}
       
   536 	return NULL;
       
   537 }
       
   538 
       
   539 void CStatWindow::Draw( const TRect& /*aRect*/ ) const
       
   540 {
       
   541 	TRect r;
       
   542 
       
   543 	// all draw operations must be done via the graphics context
       
   544 	CWindowGc &gc = SystemGc();
       
   545 
       
   546 	// draw the control panel
       
   547 	ClearControlPanel();
       
   548 
       
   549 	// if we signalled to only draw the label panel then stop here
       
   550 	if( iClearLabelsOnly ) {
       
   551 		iClearLabelsOnly = 0;	// Ensure this is mutable and so can
       
   552 								// be updated from within the 'const'
       
   553 								// declared 'Draw' mehod.
       
   554 		return;
       
   555 	}
       
   556 
       
   557 	// draw the connect panel
       
   558 	gc.SetBrushColor( KRgbWhite );
       
   559 	gc.SetBrushStyle( CGraphicsContext::ESolidBrush );
       
   560 	gc.SetPenColor( KRgbBlack );
       
   561 	gc.SetPenStyle( CGraphicsContext::ESolidPen );
       
   562 	r = GetControlPosition( KConnectPanel );
       
   563 	gc.DrawRect( r );
       
   564 
       
   565 	// draw the version panel
       
   566 	gc.SetBrushColor( KBackgroundColour );
       
   567 	gc.SetBrushStyle( CGraphicsContext::ESolidBrush );
       
   568 	gc.SetPenColor( KRgbBlack );
       
   569 	gc.SetPenStyle( CGraphicsContext::ESolidPen );
       
   570 	r = GetControlPosition( KVersionPanel );
       
   571 	gc.DrawRect( r );
       
   572 
       
   573 	// draw a border on the text box with focus on series 60
       
   574 	DrawEditBorders();
       
   575 }
       
   576 
       
   577 void CStatWindow::DrawEditBorders( ) const
       
   578 {
       
   579 
       
   580 	// Only draw a border for the focussed textbox
       
   581 #ifdef SYMBIAN_DIST_SERIES60
       
   582 	TRect r;
       
   583 	CWindowGc &gc = SystemGc();
       
   584 
       
   585 	if( iTransportEdit->IsFocused() ) {
       
   586 		gc.SetBrushStyle( CGraphicsContext::ENullBrush );
       
   587 		gc.SetPenColor( KLightGray );
       
   588 		gc.SetPenStyle( CGraphicsContext::ESolidPen );
       
   589 		r = GetControlPosition( KTransportEdit );
       
   590 		r.iTl.iY -= 2;
       
   591 		r.iTl.iX -= 1;
       
   592 		gc.DrawRect( r );
       
   593 	}
       
   594 
       
   595 	if( iAddressEdit->IsFocused() ) {
       
   596 		gc.SetBrushStyle( CGraphicsContext::ENullBrush );
       
   597 		gc.SetPenColor( KLightGray );
       
   598 		gc.SetPenStyle( CGraphicsContext::ESolidPen );
       
   599 		r = GetControlPosition( KAddressEdit );
       
   600 		r.iTl.iY -= 2;
       
   601 		r.iTl.iX -= 1;
       
   602 		gc.DrawRect( r );
       
   603 	}
       
   604 #endif
       
   605 }
       
   606  
       
   607 void CStatWindow::HandleControlEventL( CCoeControl* aControl, TCoeEvent /*aEventType*/ )
       
   608 {
       
   609 	TInt control;
       
   610 
       
   611 	// Set the control to the aControl ptr. For Series-60 this will really be the 
       
   612 	// control ID (passed from CStatAppUi::HandleControlEventL). On other platforms
       
   613 	// this will really be a ptr -- which we convert below.
       
   614 	control = (TInt)aControl;
       
   615 
       
   616 	// Convert aControl into control identifier on non-series 60 platforms. This reduces
       
   617 	// the amount of DFRD specific code.
       
   618 #ifndef SYMBIAN_DIST_SERIES60
       
   619 	if( aControl == iActionButton ) {
       
   620 		control = KActionButton; 
       
   621 	} else if( aControl == iExitButton ) {
       
   622 		control = KExitButton;
       
   623 	} else if( aControl == iLogButton ) {
       
   624 		control = KLogButton;
       
   625 	} else {
       
   626 		return;
       
   627 	}
       
   628 #endif
       
   629 	
       
   630 	// Now handle the button events
       
   631 	switch( control ) {
       
   632 
       
   633 	// If we are idle then start the engine, if we are anything else then stop the engine
       
   634 	case KActionButton:
       
   635 		HandleActionL();
       
   636 		break;
       
   637 			
       
   638 	// Send shutdown event to the appui, will end up in CStatAppUi::HandleControlEventL
       
   639 	case KExitButton:
       
   640 		if( iStatStatus == EIdle ) {
       
   641 			ReportEventL( EEventRequestExit );
       
   642 		}
       
   643 		break;
       
   644 	
       
   645 	// For the logging button we want to toggle the current setting
       
   646 	case KLogButton:
       
   647 		iLoggingEnabled = ((iLoggingEnabled == EFalse) ? ETrue : EFalse);
       
   648 		break;
       
   649 	}
       
   650 }
       
   651 
       
   652 void CStatWindow::HandleActionL( void )
       
   653 {
       
   654 	TInt expInfo = KErrNone;
       
   655 	TInt expLabel = KErrNone;
       
   656 	TStatConnectType selectedTransport;
       
   657 	TBuf<KAddressTextLimit> tbAddress;
       
   658 
       
   659 	// if we are not in the idle state then stop the current session
       
   660 	if( iStatStatus != EIdle ) {
       
   661 		iStatController->StopSession( 1 );
       
   662 
       
   663 		if(iAOConnection)
       
   664 		{
       
   665 			iAOConnection->CloseSocket();
       
   666 			delete iAOConnection;
       
   667 			iAOConnection = NULL;
       
   668 		}
       
   669 
       
   670 		// Store the fact that we have stopped in the
       
   671 		// user preference ini data.
       
   672 		iIniData->iIsRunning = FALSE;
       
   673 		iIniData->WriteIniData( KIniFile );
       
   674 		// End of writing ini data.
       
   675 
       
   676 		return;
       
   677 	}
       
   678 
       
   679 	// otherwise -- first update the GUI
       
   680 	TRAP( expInfo, (iInfoLabel->SetTextL(_L(""))) );
       
   681 	TRAP( expLabel, (iErrorLabel->SetTextL(_L(""))) );
       
   682 	if( (expInfo == KErrNone) && (expLabel == KErrNone) ) {
       
   683 		iClearLabelsOnly = 1;
       
   684 		DrawNow();
       
   685 	}
       
   686 
       
   687 	// get the transport and the basic address info
       
   688 	selectedTransport = (enum TStatConnectType)iTransportEdit->CurrentItem();
       
   689 	iAddressEdit->GetText( tbAddress );
       
   690 
       
   691 	// get a simple pointer to the address so we can munge it
       
   692 	char* p = (char*)tbAddress.Ptr();
       
   693 
       
   694 	// now do any transport specific munging 
       
   695 	switch( selectedTransport ) {
       
   696 
       
   697 	// for serial - subtract one from the port count and add the baud rate
       
   698 	case ESerial:
       
   699 		(*p) -= 1;
       
   700 		tbAddress.Append( _L("|") );
       
   701 		tbAddress.Append( KSerialBaudRate );
       
   702 		break;
       
   703 
       
   704 	// for IR - subtract one from the port count and add the baud rate
       
   705 	case EInfrared:
       
   706 		(*p) -= 1;
       
   707 		tbAddress.Append( _L("|") );
       
   708 		tbAddress.Append( KIRBaudRate );
       
   709 		break;
       
   710 	case ETCPIP:
       
   711 		//active object used to start ppp connection, only started if using tcpip 
       
   712 		asserte(NULL==iAOConnection);
       
   713 		iAOConnection=CActiveConnection::NewL(_L("81.89.143.203"),80);
       
   714 		//if we are using tcpip
       
   715 		iAOConnection->Start();
       
   716 		break;
       
   717 	case EBluetooth:
       
   718 		break;
       
   719 	// Add a case handler for the 'number of enumerations' to prevent
       
   720 	// a compile warning.
       
   721 	case ENumConnectTypes:
       
   722 		;
       
   723 		break;
       
   724 	}
       
   725 
       
   726 	// Store the session options in the user preference file
       
   727 	// so we can prepare the interface next time.
       
   728 	iIniData->iConnectType = selectedTransport;
       
   729 	iIniData->iAddress = iAddressEdit->CurrentItem();
       
   730 	iIniData->iIsRunning = TRUE;
       
   731 	iIniData->WriteIniData( KIniFile );
       
   732 	// End of writing ini data.
       
   733 
       
   734 	// start the session
       
   735 	iStatController->StartSession( selectedTransport, &tbAddress, this, &iFsSession, iMsg );
       
   736 	return;
       
   737 }
       
   738 
       
   739 /*************************************************************************
       
   740  *
       
   741  * CStatWindow - Handle User Input
       
   742  *
       
   743  ************************************************************************/
       
   744 TKeyResponse CStatWindow::OfferKeyEventL( const TKeyEvent& aKeyEvent, TEventCode aType )
       
   745 {
       
   746 	TKeyResponse ret = EKeyWasNotConsumed;
       
   747 
       
   748 	// we process up and down at this level to allow moving the focus, all other
       
   749 	// keys are passed to the edit box with the focus
       
   750 	if( aKeyEvent.iScanCode == EStdKeyUpArrow ) 
       
   751 	{
       
   752 		iTransportEdit->SetFocus( ETrue );
       
   753 		iAddressEdit->SetFocus( EFalse );
       
   754 		DrawNow();
       
   755 		return EKeyWasConsumed;
       
   756 	} 
       
   757 	else if( aKeyEvent.iScanCode == EStdKeyDownArrow ) 
       
   758 	{
       
   759 		iTransportEdit->SetFocus( EFalse );
       
   760 		iAddressEdit->SetFocus( ETrue );
       
   761 		DrawNow();
       
   762 		return EKeyWasConsumed;
       
   763 	}
       
   764 	
       
   765 	// pass the key to the control with the focus -- only if we are Idle
       
   766 	if( iStatStatus == EIdle ) 
       
   767 	{
       
   768 		if( iAddressEdit->IsFocused() ) 
       
   769 		{
       
   770 			ret = iAddressEdit->OfferKeyEventL( aKeyEvent, aType );
       
   771 		} 
       
   772 		else if( iTransportEdit->IsFocused() ) 
       
   773 		{
       
   774 			ret = iTransportEdit->OfferKeyEventL( aKeyEvent, aType );
       
   775 			OnTransportChange();
       
   776 		}
       
   777 	}
       
   778 	return ret;
       
   779 }
       
   780 
       
   781 void CStatWindow::HandlePointerEventL(const TPointerEvent& aPointerEvent)
       
   782 {
       
   783 	TInt control;
       
   784 
       
   785 	// Find out where this event occured so we can send it to the right control
       
   786 	control = GetControlFromPoint( aPointerEvent.iPosition );
       
   787 	switch( control ) {
       
   788 
       
   789 	case KActionButton:
       
   790 		iTransportEdit->SetFocus( EFalse );
       
   791 		iAddressEdit->SetFocus( EFalse );
       
   792 		iActionButton->HandlePointerEventL( aPointerEvent );
       
   793 		break;
       
   794 
       
   795 	case KExitButton:
       
   796 		iTransportEdit->SetFocus( EFalse );
       
   797 		iAddressEdit->SetFocus( EFalse );
       
   798 		iExitButton->HandlePointerEventL( aPointerEvent );
       
   799 		break;
       
   800 
       
   801 	case KLogButton:
       
   802 		iLogButton->HandlePointerEventL( aPointerEvent );
       
   803 		break;
       
   804 
       
   805 	case KTransportEdit:
       
   806 		if( !iTransportEdit->IsDimmed() ) {
       
   807 			iTransportEdit->SetFocus( ETrue );
       
   808 			iAddressEdit->SetFocus( EFalse );
       
   809 			iTransportEdit->HandlePointerEventL( aPointerEvent );
       
   810 			OnTransportChange();
       
   811 		}
       
   812 		break;
       
   813 
       
   814 	case KAddressEdit:
       
   815 		if( !iAddressEdit->IsDimmed() ) {
       
   816 			iTransportEdit->SetFocus( EFalse );
       
   817 			iAddressEdit->SetFocus( ETrue );
       
   818 			iAddressEdit->HandlePointerEventL( aPointerEvent );
       
   819 		}
       
   820 		break;
       
   821 
       
   822 	default:
       
   823 		if( aPointerEvent.iType != TPointerEvent::EButton1Down ) 
       
   824 			break;
       
   825 		iTransportEdit->SetFocus( EFalse );
       
   826 		iAddressEdit->SetFocus( EFalse );
       
   827 		DrawNow();
       
   828 		break;
       
   829 	}
       
   830 }
       
   831 
       
   832 /*************************************************************************
       
   833  *
       
   834  * CStatWindow - MNotifyUI
       
   835  *
       
   836  ************************************************************************/
       
   837 void CStatWindow::HandleStatusChange( TInt /*aSessionId*/, TCommStatus aNewStatus )
       
   838 {
       
   839 	TInt exp = KErrNone;
       
   840 
       
   841 	TPtrC status[] = {
       
   842 		_L( "STAT is not running." ),
       
   843 		_L( "STAT is initialising." ),
       
   844 		_L( "STAT is initialised." ),
       
   845 		KConnectingStatusStr,
       
   846 		_L( "STAT is connected." ),
       
   847 		_L( "STAT is disconnecting." ),
       
   848 		_L( "STAT is disconnected." ),
       
   849 		_L( "STAT is releasing." ),
       
   850 		_L( "STAT is sending data."),
       
   851 		KWaitingForDataStatusStr,
       
   852 		_L( "<error>" )
       
   853 	};
       
   854 
       
   855 	// save the new status
       
   856 	iStatStatus = aNewStatus;
       
   857 
       
   858 	// set the status label
       
   859 	assert( (aNewStatus >= EIdle) && (aNewStatus < ELast) );
       
   860 	TRAP( exp, (iStatusLabel->SetTextL(status[aNewStatus])) );
       
   861 
       
   862 	// enable / disable the appropriate buttons
       
   863 	switch( iStatStatus ) {
       
   864 
       
   865 	case EIdle:
       
   866 		TRAP( exp, (iActionButton->SetTextL(_L("Start"))) );
       
   867 		iActionButton->SetDimmed( EFalse );
       
   868 		iExitButton->SetDimmed( EFalse );
       
   869 		iActionButton->DrawNow();
       
   870 		iExitButton->DrawNow();
       
   871 		iTransportEdit->SetDimmed( EFalse );
       
   872 		iAddressEdit->SetDimmed( EFalse );
       
   873 		iLogButton->SetDimmed( EFalse );
       
   874 		// Remove the call to OnTransport change because the
       
   875 		// transport has not changed and we have just set
       
   876 		// the state of the interface components here.
       
   877 		// OnTransportChange();
       
   878 		break;
       
   879 
       
   880 	case EDisconnecting: 
       
   881 	case EDisconnected: 
       
   882 	case EReleasing: 
       
   883 		TRAP( exp, (iActionButton->SetTextL(_L("Stop"))) );
       
   884 		iActionButton->SetDimmed( ETrue );
       
   885 		iExitButton->SetDimmed( ETrue );
       
   886 		iActionButton->DrawNow();
       
   887 		iExitButton->DrawNow();
       
   888 		iTransportEdit->SetDimmed( ETrue );
       
   889 		iAddressEdit->SetDimmed( ETrue );
       
   890 		iLogButton->SetDimmed( ETrue );
       
   891 		break;
       
   892 
       
   893 	case EConnected:
       
   894 		DrawNow();
       
   895 		/* fall through */
       
   896 
       
   897 	case ESendPending:
       
   898 	case EReceivePending:
       
   899 	case EInitialising: 
       
   900 	case EInitialised: 
       
   901 	case EConnecting: 
       
   902 		TRAP( exp, (iActionButton->SetTextL(_L("Stop"))) );
       
   903 		iActionButton->SetDimmed( EFalse );
       
   904 		iExitButton->SetDimmed( ETrue );
       
   905 		iActionButton->DrawNow();
       
   906 		iExitButton->DrawNow();
       
   907 		iTransportEdit->SetDimmed( ETrue );
       
   908 		iAddressEdit->SetDimmed( ETrue );
       
   909 		iLogButton->SetDimmed( ETrue );
       
   910 		break;
       
   911 
       
   912 	case ELast:
       
   913 		assert( !"Illegal case" );
       
   914 		break;
       
   915 	}
       
   916 
       
   917 	// If we are in the foreground then redraw the screen
       
   918 	iClearLabelsOnly = 1;
       
   919 	DrawNow();
       
   920 }
       
   921 
       
   922 void CStatWindow::HandleError( TInt aError, void* aErrorData )
       
   923 {
       
   924 	TInt exp;
       
   925 	TBuf<MAXMESSAGESIZE> msg; 
       
   926 
       
   927 	// If aError is < 0 then it is an EPOC error code, if it is > 0 then
       
   928 	// it is one of my error codes. aErrorData is defined for each code
       
   929 	switch( aError ) 
       
   930 	{
       
   931 		case KSTErrReadFailure:
       
   932 			msg.SetLength( 0 );
       
   933 			msg.Append( _L("Read failed (") );
       
   934 			msg.AppendNum( (int)aErrorData );
       
   935 			msg.Append( _L(").") );
       
   936 			TRAP( exp, (iErrorLabel->SetTextL(msg)) );
       
   937 			break;
       
   938 
       
   939 		//This means that a disconnect has come across from the PC.  Because we are not sure
       
   940 		//of why this occured (i.e. could be end of script or an error) we will not display
       
   941 		//a message to ensure that the user can at least see what the error was (if there was one)
       
   942 		case KErrDisconnected:
       
   943 			break;
       
   944 
       
   945 		case KErrAccessDenied:
       
   946 			TRAP( exp, (iErrorLabel->SetTextL(_L("Comm port access denied."))) );
       
   947 			break;
       
   948 	
       
   949 		case KErrNotSupported:
       
   950 			TRAP( exp, (iErrorLabel->SetTextL(_L("Unsupported comm port."))) );
       
   951 			break;
       
   952 
       
   953 		case KErrCancel:
       
   954 			TRAP( exp, (iErrorLabel->SetTextL(_L("Operation cancelled."))) );
       
   955 			break;
       
   956 
       
   957 		default:
       
   958 			TRAP( exp, (iErrorLabel->SetTextL(_L("Unknown error occured."))) );
       
   959 			break;
       
   960 	}
       
   961 }
       
   962 
       
   963 void CStatWindow::HandleInfo( const TDesC *aInfo )
       
   964 {
       
   965 	TInt exp;
       
   966 	TRAP( exp, (iInfoLabel->SetTextL(*aInfo)) );
       
   967 	iClearLabelsOnly = 1;
       
   968 	DrawNow();
       
   969 }
       
   970 
       
   971 /*************************************************************************
       
   972  *
       
   973  * CStatWindow - Helper Functions
       
   974  *
       
   975  ************************************************************************/
       
   976 TCommStatus CStatWindow::GetCommStatus()
       
   977 {
       
   978 	return iStatStatus;
       
   979 }
       
   980 
       
   981 void CStatWindow::ClearControlPanel() const
       
   982 {
       
   983 	TRect r;
       
   984 
       
   985 	// all draw operations must be done via the graphics context
       
   986 	CWindowGc &gc = SystemGc();
       
   987 
       
   988 	// draw the control panel
       
   989 	gc.SetBrushColor( KBackgroundColour );
       
   990 	gc.SetBrushStyle( CGraphicsContext::ESolidBrush );
       
   991 	gc.SetPenColor( KRgbBlack );
       
   992 	gc.SetPenStyle( CGraphicsContext::ESolidPen );
       
   993 	r = GetControlPosition( KControlPanel );
       
   994 	gc.DrawRect( r );
       
   995 }
       
   996 
       
   997 void CStatWindow::OnTransportChange()
       
   998 {
       
   999 	TInt i;
       
  1000 	TInt exp;
       
  1001 	TBuf<1> null( _L("") );
       
  1002 	TBuf<9> portname( _L("1") );
       
  1003 	TInt currentItem = iTransportEdit->CurrentItem();
       
  1004 
       
  1005 	// Clear the Address field and set text to NULL
       
  1006 	iAddressEdit->ClearAllItems();
       
  1007 	TRAP( exp, (iAddressEdit->SetTextL(&null)) );
       
  1008 	TRAP( exp, (iAddressEdit->ClearSelectionL()) );
       
  1009 	
       
  1010 	// Now set the items
       
  1011 	switch( currentItem ) {
       
  1012 
       
  1013 	case EBluetooth:
       
  1014 	case ETCPIP:
       
  1015 		iAddressEdit->SetFocus( EFalse );
       
  1016 		iAddressEdit->SetDimmed( ETrue );
       
  1017 		break;
       
  1018 
       
  1019 	case ESerial:
       
  1020 		for( i = 0; i < KSerialPortCount; i++ ) {
       
  1021 			TRAP( exp, (iAddressEdit->AddItemL(portname)) );
       
  1022 			((short*)portname.PtrZ())[0]++;
       
  1023 		}
       
  1024 		iAddressEdit->SetCurrentItem( KDefaultAddressSerial );
       
  1025 		iAddressEdit->SetDimmed( EFalse );
       
  1026 		break;
       
  1027 
       
  1028 	case EInfrared:
       
  1029 		for( i = 0; i < KInfraRedPortCount; i++ ) {
       
  1030 			TRAP( exp, (iAddressEdit->AddItemL(portname)) );
       
  1031 			((short*)portname.PtrZ())[0]++;
       
  1032 		}
       
  1033 		iAddressEdit->SetCurrentItem( KDefaultAddressInfraRed );
       
  1034 		iAddressEdit->SetDimmed( EFalse );
       
  1035 	}
       
  1036 
       
  1037 	// Redraw so the changes take effect
       
  1038 	iAddressEdit->DrawNow();
       
  1039 
       
  1040 }
       
  1041 
       
  1042 TInt CStatWindow::PositionInRange( TPoint aPosition, TRect aArea ) const
       
  1043 {
       
  1044 	if( (aPosition.iX <= aArea.iBr.iX) && (aPosition.iX >= aArea.iTl.iX) && (aPosition.iY <= aArea.iBr.iY) && (aPosition.iY >= aArea.iTl.iY) )
       
  1045 		return 1;
       
  1046 	return 0;
       
  1047 }
       
  1048 
       
  1049 TInt CStatWindow::GetControlFromPoint( TPoint aPosition ) const
       
  1050 {
       
  1051 	TRect rActionButton, rExitButton, rLogButton;
       
  1052 	TRect rAddressEdit, rTransportEdit;
       
  1053 
       
  1054 	// Get the positions of the controls that can handle pointer events
       
  1055 	rActionButton = GetControlPosition( KActionButton );
       
  1056 	rExitButton = GetControlPosition( KExitButton );
       
  1057 	rLogButton = GetControlPosition( KLogButton );
       
  1058 	rTransportEdit = GetControlPosition( KTransportEdit );
       
  1059 	rAddressEdit = GetControlPosition( KAddressEdit );
       
  1060 
       
  1061 	// See if any match 
       
  1062 	if( PositionInRange(aPosition,rTransportEdit) )
       
  1063 		return KTransportEdit;
       
  1064 	else if( PositionInRange(aPosition,rAddressEdit) )
       
  1065 		return KAddressEdit;
       
  1066 	else if( PositionInRange(aPosition,rLogButton) )
       
  1067 		return KLogButton;
       
  1068 	else if( PositionInRange(aPosition,rActionButton) )
       
  1069 		return KActionButton;
       
  1070 	else if( PositionInRange(aPosition,rExitButton) )
       
  1071 		return KExitButton;
       
  1072 
       
  1073 	return KControlCount;
       
  1074 }
       
  1075 
       
  1076 TRect CStatWindow::GetControlPosition( TInt aControlId ) const
       
  1077 {
       
  1078 	TRect controlRect;
       
  1079 
       
  1080 	switch( aControlId ) {
       
  1081 
       
  1082 	case KActionButton:
       
  1083 		controlRect = Rect();
       
  1084 		controlRect.iBr.iX -= KButtonBorderOffset;
       
  1085 		controlRect.iTl.iX = controlRect.iBr.iX - KButtonWidth;
       
  1086 		controlRect.iTl.iY += KButtonBorderOffset;
       
  1087 		controlRect.iBr.iY = controlRect.iTl.iY + KButtonHeight;
       
  1088 		break;
       
  1089 
       
  1090 	case KExitButton:
       
  1091 		controlRect = Rect();
       
  1092 		controlRect.iBr.iX -= KButtonBorderOffset;
       
  1093 		controlRect.iTl.iX = controlRect.iBr.iX - KButtonWidth;
       
  1094 		controlRect.iTl.iY += 2*KButtonBorderOffset + KButtonHeight;
       
  1095 		controlRect.iBr.iY = controlRect.iTl.iY + KButtonHeight;
       
  1096 		break;
       
  1097 
       
  1098 	case KLogButton:
       
  1099 		controlRect = Rect();
       
  1100 		controlRect.iBr.iX -= KButtonBorderOffset;
       
  1101 		controlRect.iTl.iX = controlRect.iBr.iX - KButtonWidth;
       
  1102 		controlRect.iTl.iY += 3*KButtonBorderOffset + 2*KButtonHeight;
       
  1103 		controlRect.iBr.iY = controlRect.iTl.iY + KButtonHeight;
       
  1104 		break;
       
  1105 
       
  1106 	case KStatusLabel:
       
  1107 		controlRect = Rect();
       
  1108 		controlRect.iTl.iX += 2*KButtonBorderOffset;
       
  1109 		controlRect.iTl.iY += KButtonBorderOffset;
       
  1110 		controlRect.iBr.iX -= KStatusLabelWidth;
       
  1111 		controlRect.iBr.iY = controlRect.iTl.iY + KButtonHeight;
       
  1112 		break;
       
  1113 
       
  1114 	case KErrorLabel:
       
  1115 		controlRect = Rect();
       
  1116 		controlRect.iTl.iX += 2*KButtonBorderOffset;
       
  1117 		controlRect.iTl.iY += 2*KButtonBorderOffset + KButtonHeight;
       
  1118 		controlRect.iBr.iX -= KStatusLabelWidth;
       
  1119 		controlRect.iBr.iY = controlRect.iTl.iY + KButtonHeight;
       
  1120 		break;
       
  1121 
       
  1122 	case KInfoLabel:
       
  1123 		controlRect = Rect();
       
  1124 		controlRect.iTl.iX += 2*KButtonBorderOffset;
       
  1125 		controlRect.iTl.iY += 3*KButtonBorderOffset + 2*KButtonHeight;
       
  1126 		controlRect.iBr.iX -= KStatusLabelWidth;
       
  1127 		controlRect.iBr.iY = controlRect.iTl.iY + KButtonHeight;
       
  1128 		break;
       
  1129 
       
  1130 	case KVersionLabel:
       
  1131 		controlRect = Rect();
       
  1132 		controlRect.iTl.iX += 2*KButtonBorderOffset;
       
  1133 		controlRect.iTl.iY = controlRect.iBr.iY - 2*KButtonHeight;
       
  1134 		controlRect.iBr.iX -= KButtonBorderOffset;
       
  1135 		break;
       
  1136 
       
  1137 	case KTransportLabel:
       
  1138 		controlRect = Rect();
       
  1139 		controlRect.iTl.iX += 2*KButtonBorderOffset;
       
  1140 		controlRect.iTl.iY = KConnectPanelTop + KButtonBorderOffset + KConnectPanelFudge;
       
  1141 		controlRect.iBr.iX += 2*KButtonBorderOffset + KConnectLabelWidth;
       
  1142 		controlRect.iBr.iY = controlRect.iTl.iY + KButtonHeight;
       
  1143 		break;
       
  1144 
       
  1145 	case KAddressLabel:
       
  1146 		controlRect = Rect();
       
  1147 		controlRect.iTl.iX += 2*KButtonBorderOffset;
       
  1148 		controlRect.iTl.iY = KConnectPanelTop + 2*KButtonBorderOffset + KButtonHeight + KConnectPanelFudge;
       
  1149 		controlRect.iBr.iX += 2*KButtonBorderOffset + KConnectLabelWidth;
       
  1150 		controlRect.iBr.iY = controlRect.iTl.iY + KButtonHeight;
       
  1151 		break;
       
  1152 
       
  1153 	case KTransportEdit:
       
  1154 		controlRect = Rect();
       
  1155 		controlRect.iTl.iX += 2*KButtonBorderOffset + KConnectLabelWidth;
       
  1156 		controlRect.iTl.iY = KConnectPanelTop + KButtonBorderOffset + KEditControlFudgeTop + KConnectPanelFudge;
       
  1157 		controlRect.iBr.iX -= KButtonBorderOffset;
       
  1158 		controlRect.iBr.iY = controlRect.iTl.iY + KButtonHeight;
       
  1159 		break;
       
  1160 
       
  1161 	case KAddressEdit:
       
  1162 		controlRect = Rect();
       
  1163 		controlRect.iTl.iX += 2*KButtonBorderOffset + KConnectLabelWidth;
       
  1164 		controlRect.iTl.iY = KConnectPanelTop + 2*KButtonBorderOffset + KButtonHeight + KEditControlFudgeTop + KConnectPanelFudge;
       
  1165 		controlRect.iBr.iX -= KButtonBorderOffset;
       
  1166 		controlRect.iBr.iY = controlRect.iTl.iY + KButtonHeight;
       
  1167 		break;
       
  1168 
       
  1169 	case KControlPanel:
       
  1170 		controlRect = Rect();
       
  1171 		controlRect.iBr.iY = KConnectPanelTop;
       
  1172 		break;
       
  1173 
       
  1174 	case KConnectPanel:
       
  1175 		controlRect = Rect();
       
  1176 		controlRect.iTl.iY = KConnectPanelTop;
       
  1177 		controlRect.iBr.iY -= 2*KButtonHeight;
       
  1178 		break;
       
  1179 
       
  1180 	case KVersionPanel:
       
  1181 		controlRect = Rect();
       
  1182 		controlRect.iTl.iY = controlRect.iBr.iY - 2*KButtonHeight;
       
  1183 		break;
       
  1184 
       
  1185 	default:
       
  1186 		assert( !"Unknown Control" );
       
  1187 		break;
       
  1188 	}
       
  1189 
       
  1190 	return controlRect;
       
  1191 }
       
  1192 void	CStatWindow::SetVersionLabelL()
       
  1193 {
       
  1194 	TBuf<32> versionstring;
       
  1195 
       
  1196 	RFs& fs=CCoeEnv::Static()->FsSession();
       
  1197 	TBool fileopen=EFalse;
       
  1198 	if(BaflUtils::FileExists(fs,KBuildInfoFilePath))
       
  1199 		{
       
  1200 		if (!(fs.IsFileOpen(KBuildInfoFilePath,fileopen)))
       
  1201 			{													
       
  1202 			RFile file;			
       
  1203 			User::LeaveIfError(file.Open(fs, KBuildInfoFilePath, EFileShareAny));					
       
  1204 			TBuf8<256> buf;
       
  1205 			User::LeaveIfError(file.Read(buf));
       
  1206 			TInt startOfData =0;
       
  1207 			startOfData = buf.Find(KBuildNumberFlag);
       
  1208 			if(!(startOfData==KErrNotFound))  // if build number flag present
       
  1209 				{
       
  1210 				startOfData += KOffsetToBuildNumber;
       
  1211 				if(buf.Length()>startOfData)  // if build number present
       
  1212 					{
       
  1213 					TPtrC8 buildNumPtr = buf.Mid(startOfData, buf.Length()-startOfData);
       
  1214 					versionstring.Copy(buildNumPtr);
       
  1215 					}
       
  1216 				}
       
  1217 			file.Close();
       
  1218 			}
       
  1219 		}
       
  1220 		else
       
  1221 			versionstring.Copy(KVersionNotKnown);	
       
  1222 	iVersionLabel->SetTextL(versionstring);
       
  1223 
       
  1224 }
       
  1225 /*************************************************************************
       
  1226  *
       
  1227  * CStatChoice - Complete
       
  1228  *
       
  1229  ************************************************************************/
       
  1230 CStatChoice::~CStatChoice( )
       
  1231 {
       
  1232 	ClearAllItems();
       
  1233 }
       
  1234 
       
  1235 void CStatChoice::ClearAllItems()
       
  1236 {
       
  1237 	int i;
       
  1238 
       
  1239 	// delete all the existing items
       
  1240 	for( i = 0; i < iItemCount; i++ )
       
  1241 		delete iChoiceItems[i];
       
  1242 
       
  1243 	// set the count to zero
       
  1244 	iItemCount = 0;
       
  1245 	iCurrentItem = 0;
       
  1246 }
       
  1247 
       
  1248 TInt CStatChoice::AddItemL( TDesC &aItemStr )
       
  1249 {
       
  1250 	// make sure that there is room left at the inn
       
  1251 	assert( iItemCount < KMaxChoiceItems );
       
  1252 
       
  1253 	// create the new item
       
  1254 	iChoiceItems[iItemCount] = new(ELeave) TBuf<KMaxChoiceItemSize>(aItemStr);
       
  1255 	iItemCount++;
       
  1256 
       
  1257 	// done
       
  1258 	return KErrNone;
       
  1259 }
       
  1260 
       
  1261 TDesC *CStatChoice::CurrentItemStr()
       
  1262 {
       
  1263 	// make sure there is something to return
       
  1264 	if( iItemCount == 0 )
       
  1265 		return NULL;
       
  1266 
       
  1267 	// sanity check the index
       
  1268 	assert( (iCurrentItem >= 0) && (iCurrentItem < iItemCount) );
       
  1269 
       
  1270 	// return a pointer to the descriptor
       
  1271 	return iChoiceItems[iCurrentItem];
       
  1272 }
       
  1273 
       
  1274 void CStatChoice::SetCurrentItem( TInt aIndex )
       
  1275 {
       
  1276 	TInt exp;
       
  1277 
       
  1278 	// check the passed index
       
  1279 	if( (aIndex < 0) || (aIndex >= iItemCount) ) 
       
  1280 		return;
       
  1281 	iCurrentItem = aIndex;
       
  1282 
       
  1283 	// set the text
       
  1284 	TRAP( exp, (SetTextL(iChoiceItems[iCurrentItem])) );
       
  1285 	TRAP( exp, (SetCursorPosL(0,EFalse)) );
       
  1286 	TRAP( exp, ClearSelectionL() );
       
  1287 	DrawNow();
       
  1288 }
       
  1289 
       
  1290 TInt CStatChoice::CurrentItem()
       
  1291 {
       
  1292 	return iCurrentItem;
       
  1293 }
       
  1294 
       
  1295 void CStatChoice::SetNextItem()
       
  1296 {
       
  1297 	TInt item;
       
  1298 	item = (iCurrentItem + 1) % iItemCount;
       
  1299 	SetCurrentItem( item );
       
  1300 }
       
  1301 
       
  1302 void CStatChoice::SetPrevItem()
       
  1303 {
       
  1304 	TInt item;
       
  1305 	item = iCurrentItem - 1;
       
  1306 	if( item == -1 )
       
  1307 		item = iItemCount - 1;
       
  1308 	SetCurrentItem( item );
       
  1309 }
       
  1310 
       
  1311 TKeyResponse CStatChoice::OfferKeyEventL( const TKeyEvent& aKeyEvent, TEventCode aType )
       
  1312 {
       
  1313 	if( !IsDimmed() ) {
       
  1314 		if( (aType == EEventKeyDown) && (aKeyEvent.iScanCode == EStdKeyLeftArrow) ) {
       
  1315 			SetPrevItem();
       
  1316 		} else if( (aType == EEventKeyDown) && (aKeyEvent.iScanCode == EStdKeyRightArrow) ) {
       
  1317 			SetNextItem();
       
  1318 		}
       
  1319 	}
       
  1320 	return EKeyWasConsumed;
       
  1321 }
       
  1322 
       
  1323 void CStatChoice::HandlePointerEventL( const TPointerEvent& aPointerEvent )
       
  1324 {
       
  1325 	if( !IsDimmed() ) {
       
  1326 		if( aPointerEvent.iType == TPointerEvent::EButton1Up )
       
  1327 			SetNextItem();
       
  1328 	}
       
  1329 }
       
  1330 
       
  1331 /*************************************************************************
       
  1332  *
       
  1333  * Class CStatWindow::CStatIniData
       
  1334  *
       
  1335  ************************************************************************/
       
  1336 
       
  1337 /*************************************************************************
       
  1338  *
       
  1339  * Class CStatWindow::CStatIniData - Construction
       
  1340  *
       
  1341  ************************************************************************/
       
  1342 
       
  1343 CStatWindow::CStatIniData::CStatIniData(void) :
       
  1344 	iConnectType(static_cast<TStatConnectType>(UndefinedData)),
       
  1345 	iAddress(UndefinedData),
       
  1346 	iIsRunning(UndefinedData),
       
  1347 	iConnectAutomatically(UndefinedData)
       
  1348 {
       
  1349 }
       
  1350 
       
  1351 CStatWindow::CStatIniData::~CStatIniData()
       
  1352 {
       
  1353 }
       
  1354 
       
  1355 TBool CStatWindow::CStatIniData::WriteIniData(const TDesC& aName) const
       
  1356 {
       
  1357 	// Write data to an ini file in the same format such that
       
  1358 	// the CIniData class can read it.
       
  1359 	// Wouldn't it be nice if CIniData wrote data as well as reading
       
  1360 	// it?
       
  1361 
       
  1362 	TBool result = TRUE;
       
  1363 	TInt errNum = KErrNone;
       
  1364 
       
  1365 	RFs fSession;
       
  1366 
       
  1367 	if( result == TRUE )
       
  1368 	{
       
  1369 		errNum = fSession.Connect();
       
  1370 
       
  1371 		result = ( errNum == KErrNone );
       
  1372 
       
  1373 		if( result == TRUE )
       
  1374 		{
       
  1375 			RFile	file;
       
  1376 
       
  1377 			errNum = file.Replace( fSession, aName, EFileWrite );
       
  1378 
       
  1379 			result = ( errNum == KErrNone );
       
  1380 
       
  1381 			if( result == TRUE )
       
  1382 			{
       
  1383 				const int iniLineBufferLength = 256;
       
  1384 				TBuf<iniLineBufferLength> iniFileBuffer;
       
  1385 				TBuf8<iniLineBufferLength> writeBuffer;
       
  1386 
       
  1387 				// Write the connect type.
       
  1388 				iniFileBuffer.Format( KIniFormat, &KIniConnectType,
       
  1389 					iConnectType );
       
  1390 				writeBuffer.Copy( iniFileBuffer );
       
  1391 				file.Write( writeBuffer );
       
  1392 
       
  1393 				// Write the address.
       
  1394 				iniFileBuffer.Format( KIniFormat, &KIniAddress,
       
  1395 					iAddress );
       
  1396 				writeBuffer.Copy( iniFileBuffer );
       
  1397 				file.Write( writeBuffer );
       
  1398 
       
  1399 				// Write the running status.
       
  1400 				iniFileBuffer.Format( KIniFormat, &KIniRunning,
       
  1401 					iIsRunning );
       
  1402 				writeBuffer.Copy( iniFileBuffer );
       
  1403 				file.Write( writeBuffer );
       
  1404 
       
  1405 				// Write the connect-automatically preference.
       
  1406 				iniFileBuffer.Format( KIniFormat, &KIniConnectAutomatically,
       
  1407 					iConnectAutomatically );
       
  1408 				writeBuffer.Copy( iniFileBuffer );
       
  1409 				file.Write( writeBuffer );
       
  1410 
       
  1411 				file.Close();
       
  1412 			}
       
  1413 
       
  1414 			fSession.Close();
       
  1415 		}
       
  1416 	}
       
  1417 
       
  1418 	return (result);
       
  1419 }
       
  1420 
       
  1421 #if defined __CINIDATA_H__
       
  1422 TBool CStatWindow::CStatIniData::ReadIniData(const TDesC& aName )
       
  1423 {
       
  1424 	// Read configuration data from ini file if we are using
       
  1425 	// CIniData and its supporting DLL.
       
  1426 
       
  1427 	TBool result = TRUE;
       
  1428 	TPtrC iniText;
       
  1429 	TLex lexResult;
       
  1430 	TInt lexValue;
       
  1431 
       
  1432 	CIniData* lIniFile = NULL;
       
  1433 
       
  1434 	// If the file can not be opened then we store
       
  1435 	// the error and do not process any further.
       
  1436 	if( result == TRUE )
       
  1437 	{
       
  1438 		// Open ini data file object.
       
  1439 		TRAPD( r, lIniFile = CIniData::NewL( aName ) );
       
  1440 		result = ( r == KErrNone );
       
  1441 	}
       
  1442 
       
  1443 	// If any ini file data value is not found then we ignore
       
  1444 	// the error and carry on and try to read the next.
       
  1445 	// The caller will know what was read by the values in the
       
  1446 	// ini data.
       
  1447 
       
  1448 	// Read the connect type.
       
  1449 	if( result == TRUE )
       
  1450 	{
       
  1451 		if( lIniFile->FindVar( KIniConnectType, iniText ) )
       
  1452 		{
       
  1453 			lexResult = iniText;
       
  1454 			if( KErrNone == lexResult.Val( lexValue ) )
       
  1455 			{
       
  1456 				iConnectType = static_cast<TStatConnectType>(lexValue);
       
  1457 			}
       
  1458 		}
       
  1459 	}	
       
  1460 
       
  1461 	// Read the address.
       
  1462 	if( result == TRUE )
       
  1463 	{
       
  1464 		if( lIniFile->FindVar( KIniAddress, iniText ) )
       
  1465 		{
       
  1466 			lexResult = iniText;
       
  1467 			if( KErrNone == lexResult.Val( lexValue ) )
       
  1468 			{
       
  1469 				iAddress = lexValue;
       
  1470 			}
       
  1471 		}
       
  1472 	}	
       
  1473 
       
  1474 	// Read the running status.
       
  1475 	if( result == TRUE )
       
  1476 	{
       
  1477 		if( lIniFile->FindVar( KIniRunning, iniText ) )
       
  1478 		{
       
  1479 			lexResult = iniText;
       
  1480 			if( KErrNone == lexResult.Val( lexValue ) )
       
  1481 			{
       
  1482 				iIsRunning = lexValue;
       
  1483 			}
       
  1484 		}
       
  1485 	}	
       
  1486 
       
  1487 	// Read the connect-automatically preference.
       
  1488 	if( result == TRUE )
       
  1489 	{
       
  1490 		if( lIniFile->FindVar( KIniConnectAutomatically, iniText ) )
       
  1491 		{
       
  1492 			lexResult = iniText;
       
  1493 			if( KErrNone == lexResult.Val( lexValue ) )
       
  1494 			{
       
  1495 				iConnectAutomatically = lexValue;
       
  1496 			}
       
  1497 		}
       
  1498 	}	
       
  1499 
       
  1500 	delete lIniFile;
       
  1501 	lIniFile = NULL;
       
  1502 
       
  1503 	return (result);
       
  1504 }
       
  1505 #else // defined __CINIDATA_H__
       
  1506 TBool CStatWindow::CStatIniData::ReadIniData(const TDesC& aName )
       
  1507 {
       
  1508 	const TInt KOffsetToData = 2; // The length of '= '.
       
  1509 
       
  1510 	// Read configuration data from ini file if we are using
       
  1511 	// our own code.  There is no advantage in this and
       
  1512 	// the downside is maintenance and code size
       
  1513 	// but support for CIniData is uncertain and it
       
  1514 	// does not have a write facility anyway.
       
  1515 
       
  1516 	TBool result = TRUE;
       
  1517 	HBufC *data = NULL;
       
  1518 
       
  1519 	if( result == TRUE )
       
  1520 	{
       
  1521 		data = GetFileContents( aName );
       
  1522 
       
  1523 		result = ( NULL != data );
       
  1524 	}
       
  1525 
       
  1526 	if( result == TRUE )
       
  1527 	{
       
  1528 		asserte( data != NULL );
       
  1529 
       
  1530 		TInt fieldIndex = 0;
       
  1531 		TInt val = -1;
       
  1532 		TLex value;
       
  1533 
       
  1534 		// Get the connect type.
       
  1535 		fieldIndex = data->Find( KIniConnectType );
       
  1536 
       
  1537 		if( KErrNotFound != fieldIndex )
       
  1538 		{
       
  1539 			fieldIndex += ( KIniConnectType.iTypeLength + KOffsetToData );
       
  1540 			value = data->Ptr() + fieldIndex;
       
  1541 			val = -1;
       
  1542 			value.Val(val);
       
  1543 			iConnectType = static_cast<TStatConnectType>(val);
       
  1544 		}
       
  1545 
       
  1546 		// Get the address.
       
  1547 		fieldIndex = data->Find( KIniAddress );
       
  1548 
       
  1549 		if( KErrNotFound != fieldIndex )
       
  1550 		{
       
  1551 			fieldIndex += ( KIniAddress.iTypeLength + KOffsetToData );
       
  1552 			value = data->Ptr() + fieldIndex;
       
  1553 			val = -1;
       
  1554 			value.Val(val);
       
  1555 			iAddress = val;
       
  1556 		}
       
  1557 
       
  1558 		// Get the running status.
       
  1559 		fieldIndex = data->Find( KIniRunning );
       
  1560 
       
  1561 		if( KErrNotFound != fieldIndex )
       
  1562 		{
       
  1563 			fieldIndex += ( KIniRunning.iTypeLength + KOffsetToData );
       
  1564 			value = data->Ptr() + fieldIndex;
       
  1565 			val = -1;
       
  1566 			value.Val(val);
       
  1567 			iIsRunning = val;
       
  1568 		}
       
  1569 
       
  1570 		// Get the connect-automatically preference.
       
  1571 		fieldIndex = data->Find( KIniConnectAutomatically );
       
  1572 
       
  1573 		if( KErrNotFound != fieldIndex )
       
  1574 		{
       
  1575 			fieldIndex += ( KIniConnectAutomatically.iTypeLength + KOffsetToData );
       
  1576 			value = data->Ptr() + fieldIndex;
       
  1577 			val = -1;
       
  1578 			value.Val(val);
       
  1579 			iConnectAutomatically = val;
       
  1580 		}
       
  1581 	}
       
  1582 
       
  1583 	delete data;
       
  1584 	data = NULL;
       
  1585 
       
  1586 	return (result);
       
  1587 }
       
  1588 
       
  1589 HBufC* CStatWindow::CStatIniData::GetFileContents(const TDesC& aName) const
       
  1590 {
       
  1591 	TBool result = TRUE;
       
  1592 	TInt errNum = KErrNone;
       
  1593 	HBufC8 *local = NULL;
       
  1594 	HBufC *retVal = NULL;
       
  1595 	TInt size = 0;
       
  1596 
       
  1597 	RFs fSession;
       
  1598 
       
  1599 	if( result == TRUE )
       
  1600 	{
       
  1601 		errNum = fSession.Connect();
       
  1602 
       
  1603 		result = ( errNum == KErrNone );
       
  1604 
       
  1605 		if( result == TRUE )
       
  1606 		{
       
  1607 			RFile file;
       
  1608 
       
  1609 			errNum = file.Open( fSession, aName, EFileRead | EFileStream | EFileShareAny );
       
  1610 
       
  1611 			result = ( errNum == KErrNone );
       
  1612 
       
  1613 			if( result == TRUE )
       
  1614 			{
       
  1615 				errNum = file.Size( size );
       
  1616 
       
  1617 				result = ( errNum == KErrNone );
       
  1618 
       
  1619 				if( result == TRUE )
       
  1620 				{
       
  1621 					TRAP(errNum, local = HBufC8::NewL(size));
       
  1622 
       
  1623 					result = ( errNum == KErrNone );
       
  1624 				}
       
  1625 
       
  1626 				if( result == TRUE )
       
  1627 				{
       
  1628 					TPtr8 pBuffer( local->Des() );
       
  1629 
       
  1630 					errNum = file.Read( pBuffer );
       
  1631 
       
  1632 					result = ( errNum == KErrNone );
       
  1633 				}
       
  1634 
       
  1635 				file.Close();
       
  1636 			}
       
  1637 
       
  1638 			fSession.Close();
       
  1639 		}
       
  1640 	}
       
  1641 
       
  1642 	if( TRUE == result )
       
  1643 	{
       
  1644 		// Need to copy the 8 bit read buffer to a 16 bit buffer.
       
  1645 		TRAP(errNum, retVal = HBufC::NewL(size));
       
  1646 
       
  1647 		result = ( errNum == KErrNone );
       
  1648 
       
  1649 		if( result == TRUE )
       
  1650 		{
       
  1651 			retVal->Des().Copy( local->Des() );
       
  1652 		}
       
  1653 	}
       
  1654 
       
  1655 	delete local;
       
  1656 	local = NULL;
       
  1657 
       
  1658 	return ( retVal );
       
  1659 }
       
  1660 #endif // defined __CINIDATA_H__