1998-03-28 02:44:41 +00:00
|
|
|
|
/* -*- 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 "profile.h"
|
|
|
|
|
#include "client.h"
|
|
|
|
|
#include "UStdDialogs.h"
|
|
|
|
|
#include "ufilemgr.h"
|
|
|
|
|
#include "uerrmgr.h"
|
|
|
|
|
#include "uapp.h"
|
|
|
|
|
#include "uprefd.h"
|
|
|
|
|
#include "prefwutil.h"
|
|
|
|
|
#include "macutil.h"
|
|
|
|
|
#include "prefapi.h"
|
1998-06-23 01:36:59 +00:00
|
|
|
|
#include "msgcom.h"
|
1998-03-28 02:44:41 +00:00
|
|
|
|
#include "resgui.h"
|
1998-06-23 01:36:59 +00:00
|
|
|
|
#include "UDeferredTask.h"
|
1998-03-28 02:44:41 +00:00
|
|
|
|
#include "xp_file_mac.h"
|
|
|
|
|
#include "DirectoryCopy.h"
|
1998-06-02 21:00:07 +00:00
|
|
|
|
#include <LGARadioButton.h>
|
|
|
|
|
#include <LGAPushButton.h>
|
|
|
|
|
#include <LGAEditField.h>
|
1998-03-28 02:44:41 +00:00
|
|
|
|
|
|
|
|
|
// for multi-user profile support in PE
|
|
|
|
|
#include "MUC.h"
|
|
|
|
|
#include <CodeFragments.h>
|
|
|
|
|
#include <LString.h>
|
|
|
|
|
|
|
|
|
|
#define updateWizardDialog 9800
|
|
|
|
|
|
|
|
|
|
#define profilePEPane 9801
|
|
|
|
|
#define profileIntroPane 9802
|
|
|
|
|
#define userNamePane 9803
|
|
|
|
|
#define profileNamePane 9804
|
|
|
|
|
#define profileFolderPane 9805
|
|
|
|
|
#define profileIconsPane 9806
|
|
|
|
|
#define profileDonePane 9807
|
|
|
|
|
|
|
|
|
|
#define profileSelectDialog 9900
|
|
|
|
|
#define profileManagerDialog 9901
|
|
|
|
|
|
|
|
|
|
// NOTE: Magic name must be kept in sync with ns/modules/libreg/src/reg.h
|
|
|
|
|
#define MAGIC_PROFILE_NAME "User1"
|
|
|
|
|
|
|
|
|
|
const char* kProfileNamePref = "profile.name";
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
|
* The resource format for storing profile metadata (i.e., username and
|
|
|
|
|
* email) in the profile database so it can be easily searched. In order
|
|
|
|
|
* to allow an arbitrary amount of metadata, the resource is divided into
|
|
|
|
|
* a header section, which counts the number of metadata items and the length
|
|
|
|
|
* to each, and a data section, which simply consists of the data in packed
|
|
|
|
|
* format. The offset to each set of data is the sum of the first offset
|
|
|
|
|
* plus all of the lengths. Strings are null terminated for convenience.
|
|
|
|
|
* All of this is stored in the profile database in a 'DATA' resource
|
|
|
|
|
* which corresponds to the id of the profile in use.
|
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
|
|
/* The version of the metadata for Nav 4.0 */
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
short int count;
|
|
|
|
|
short int firstOffset;
|
|
|
|
|
long int nameLength;
|
|
|
|
|
long int emailLength;
|
|
|
|
|
/* New data element lengths would go here, along with a corresponding
|
|
|
|
|
change in the count and firstOffset items */
|
|
|
|
|
/* Data follows here */
|
|
|
|
|
} ProfileDataHeader;
|
|
|
|
|
|
|
|
|
|
MODULE_PRIVATE int PR_CALLBACK ProfilePrefChangedFunc(const char *pref, void *data);
|
|
|
|
|
|
|
|
|
|
CFragConnectionID CUserProfile::mConfigPluginID;
|
|
|
|
|
|
|
|
|
|
class LWhiteListBox: public LListBox
|
|
|
|
|
{
|
1998-06-23 01:36:59 +00:00
|
|
|
|
private:
|
|
|
|
|
typedef LListBox Inherited;
|
|
|
|
|
|
1998-03-28 02:44:41 +00:00
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
enum { class_ID = 'Lwht' };
|
|
|
|
|
|
|
|
|
|
LWhiteListBox( LStream* inStream );
|
|
|
|
|
|
|
|
|
|
virtual Boolean FocusDraw(LPane* inSubPane = nil);
|
|
|
|
|
virtual void DrawSelf();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
LWhiteListBox::LWhiteListBox( LStream* inStream ): LListBox( inStream )
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Boolean LWhiteListBox::FocusDraw(LPane* /*inSubPane*/)
|
|
|
|
|
{
|
|
|
|
|
const RGBColor rgbWhite = { 0xFFFF, 0xFFFF, 0xFFFF };
|
|
|
|
|
|
1998-06-23 01:36:59 +00:00
|
|
|
|
if ( Inherited::FocusDraw() )
|
1998-03-28 02:44:41 +00:00
|
|
|
|
{
|
|
|
|
|
::RGBBackColor( &rgbWhite );
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void LWhiteListBox::DrawSelf()
|
|
|
|
|
{
|
|
|
|
|
Rect frame;
|
|
|
|
|
|
|
|
|
|
this->CalcLocalFrameRect( frame );
|
|
|
|
|
::EraseRect( &frame );
|
|
|
|
|
LListBox::DrawSelf();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MODULE_PRIVATE int PR_CALLBACK ProfilePrefChangedFunc(const char *pref, void * /* data */)
|
|
|
|
|
{
|
|
|
|
|
FSSpec profileSpec = CPrefs::GetFilePrototype(CPrefs::UsersFolder);
|
|
|
|
|
GetIndString(profileSpec.name, 300, userProfiles);
|
|
|
|
|
|
|
|
|
|
CUserProfileDB profile(profileSpec);
|
|
|
|
|
|
|
|
|
|
if ((!XP_STRCASECMP(pref,"mail.identity.username")) ||
|
|
|
|
|
(!XP_STRCASECMP(pref,"mail.identity.useremail")))
|
|
|
|
|
{
|
|
|
|
|
profile.SetProfileData( CUserProfile::sCurrentProfileID );
|
|
|
|
|
}
|
|
|
|
|
else if (!XP_STRCMP(pref, kProfileNamePref))
|
|
|
|
|
{
|
|
|
|
|
char profileName[255];
|
|
|
|
|
int len = 255;
|
|
|
|
|
if ( PREF_GetCharPref(kProfileNamePref, profileName, &len) == PREF_NOERROR )
|
|
|
|
|
{
|
|
|
|
|
profile.SetProfileName( CUserProfile::sCurrentProfileID, (CStr255) profileName );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class CProfilePaneMonitor : public LListener
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
CProfilePaneMonitor(CDialogWizardHandler*);
|
|
|
|
|
virtual void ListenToMessage(MessageT inMessage, void *ioParam);
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
CDialogWizardHandler* fWizard;
|
|
|
|
|
Boolean fCopiedName;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
|
* class CUserProfile
|
|
|
|
|
*
|
|
|
|
|
* Dialog handlers & wizards for multi-user profile support.
|
|
|
|
|
*
|
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
|
|
short CUserProfile::sCurrentProfileID = CUserProfile::kInvalidProfileID;
|
|
|
|
|
Boolean CUserProfile::mHasConfigPlugin = FALSE;
|
|
|
|
|
Boolean CUserProfile::mPluginLoaded = FALSE;
|
|
|
|
|
|
|
|
|
|
void CUserProfile::InitUserProfiles()
|
|
|
|
|
{
|
|
|
|
|
mHasConfigPlugin = ( LoadConfigPlugin() != NULL );
|
|
|
|
|
if ( mHasConfigPlugin )
|
|
|
|
|
CloseConfigPlugin();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Attempts to open "User Profiles" and put up a selection dialog.
|
|
|
|
|
// Returns the location of the user's selected Prefs folder.
|
|
|
|
|
ProfileErr
|
|
|
|
|
CUserProfile::GetUserProfile( const FSSpec& usersFolder, FSSpec& profileFolder,
|
|
|
|
|
Boolean showDialog, short fileType )
|
|
|
|
|
{
|
|
|
|
|
ProfileErr result = eOK;
|
|
|
|
|
Boolean done = true;
|
|
|
|
|
Boolean wantsProfileManager = showDialog;
|
|
|
|
|
FSSpec profileSpec;
|
|
|
|
|
short numProfiles = 1;
|
|
|
|
|
CStr31 profileName;
|
|
|
|
|
|
|
|
|
|
// <20><>profileSpec here is "User Profiles"
|
|
|
|
|
profileSpec.vRefNum = usersFolder.vRefNum;
|
|
|
|
|
profileSpec.parID = usersFolder.parID;
|
|
|
|
|
GetIndString( profileSpec.name, 300, userProfiles );
|
|
|
|
|
|
|
|
|
|
// <20><>I have no idea why this is so convoluted
|
|
|
|
|
|
|
|
|
|
if ( !CFileMgr::FileExists( profileSpec ) )
|
|
|
|
|
return eNeedUpgrade;
|
|
|
|
|
|
|
|
|
|
if ( DeleteMagicProfile( profileSpec ) )
|
|
|
|
|
return eNeedUpgrade;
|
|
|
|
|
|
|
|
|
|
CUserProfileDB profileDB( profileSpec );
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
Try_
|
|
|
|
|
{
|
|
|
|
|
short newUserID = 0;
|
|
|
|
|
short lastUserID = profileDB.GetLastProfileID();
|
|
|
|
|
|
|
|
|
|
// <20><>only put up dialog if there's more than one user
|
|
|
|
|
if ( showDialog || profileDB.CountProfiles() > 1 )
|
|
|
|
|
{
|
|
|
|
|
// HACK ALERT!!!!!
|
|
|
|
|
// If we're being asked to open a doc or get a URL just skip the dialog
|
|
|
|
|
// and use the last profile that was selected
|
|
|
|
|
if ( (fileType == FILE_TYPE_ODOC) || (fileType == FILE_TYPE_GETURL) )
|
|
|
|
|
{
|
|
|
|
|
newUserID = lastUserID;
|
|
|
|
|
if ( profileDB.GetProfileAlias( newUserID, profileFolder ) )
|
|
|
|
|
result = eOK;
|
|
|
|
|
else
|
|
|
|
|
result = eUnknownError;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
// END HACK ALERT!!!!!
|
|
|
|
|
result = HandleProfileDialog(
|
|
|
|
|
profileSpec,
|
|
|
|
|
profileDB,
|
|
|
|
|
profileFolder,
|
|
|
|
|
newUserID,
|
|
|
|
|
lastUserID,
|
|
|
|
|
wantsProfileManager );
|
|
|
|
|
|
|
|
|
|
if ( result >= 0 && lastUserID != newUserID )
|
|
|
|
|
profileDB.SetLastProfileID( newUserID );
|
|
|
|
|
|
|
|
|
|
if ( result >= eOK )
|
|
|
|
|
PREF_RegisterCallback("mail.identity",ProfilePrefChangedFunc, NULL);
|
|
|
|
|
done = true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
newUserID = lastUserID;
|
|
|
|
|
Try_
|
|
|
|
|
{
|
|
|
|
|
if ( profileDB.GetProfileAlias( lastUserID, profileFolder ) )
|
|
|
|
|
result = eOK;
|
|
|
|
|
else
|
|
|
|
|
result = eUnknownError;
|
|
|
|
|
}
|
|
|
|
|
Catch_ ( inErr )
|
|
|
|
|
{
|
|
|
|
|
CStr255 errStr;
|
|
|
|
|
GetIndString( errStr, kProfileStrings, kReadError );
|
|
|
|
|
ErrorManager::ErrorNotify( inErr, errStr );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( result < eOK )
|
|
|
|
|
{
|
|
|
|
|
// <20> if we failed to load the profile, loop back to the
|
|
|
|
|
// beginning and force Profile Manager to appear
|
|
|
|
|
done = false;
|
|
|
|
|
showDialog = wantsProfileManager = true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
long err;
|
|
|
|
|
err = SendMessageToPlugin( kAutoSelectDialConfig, &profileFolder );
|
|
|
|
|
if ( err == errProfileNotFound )
|
|
|
|
|
SendMessageToPlugin( kEditDialConfig, &profileFolder );
|
|
|
|
|
|
|
|
|
|
PREF_RegisterCallback( "mail.identity",ProfilePrefChangedFunc, NULL );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20> save the previous user ID back to profile db
|
|
|
|
|
if ( result >= eOK )
|
|
|
|
|
{
|
1998-06-23 01:36:59 +00:00
|
|
|
|
if ( sCurrentProfileID != kTemporaryProfileID )
|
|
|
|
|
sCurrentProfileID = newUserID;
|
1998-03-28 02:44:41 +00:00
|
|
|
|
numProfiles = profileDB.CountProfiles();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Catch_ ( inErr )
|
|
|
|
|
{
|
|
|
|
|
CStr255 errStr;
|
|
|
|
|
GetIndString( errStr, kProfileStrings, kReadError );
|
|
|
|
|
ErrorManager::ErrorNotify( inErr, errStr );
|
|
|
|
|
result = eUnknownError;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
while ( !done );
|
|
|
|
|
|
|
|
|
|
if (result != eUserCancelled) {
|
|
|
|
|
// <20><>reflect path & name into xp preferences
|
1998-06-23 01:36:59 +00:00
|
|
|
|
if ( (sCurrentProfileID != kInvalidProfileID)
|
|
|
|
|
&& sCurrentProfileID != kTemporaryProfileID )
|
|
|
|
|
{
|
1998-03-28 02:44:41 +00:00
|
|
|
|
profileDB.GetProfileName( sCurrentProfileID, profileName );
|
1998-06-23 01:36:59 +00:00
|
|
|
|
ReflectToPreferences(profileName, profileFolder, numProfiles);
|
|
|
|
|
}
|
1998-03-28 02:44:41 +00:00
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
1998-06-02 21:00:07 +00:00
|
|
|
|
static void PrefToEditField(const char * prefName, LGAEditField * field);
|
|
|
|
|
static void EditFieldToPref(LGAEditField * field, const char * prefName);
|
1998-03-28 02:44:41 +00:00
|
|
|
|
|
1998-06-02 21:00:07 +00:00
|
|
|
|
#define PREF_STRING_LEN 255
|
|
|
|
|
void PrefToEditField(const char * prefName, LGAEditField * field)
|
1998-03-28 02:44:41 +00:00
|
|
|
|
{
|
|
|
|
|
int prefStringLen;
|
|
|
|
|
char prefString[PREF_STRING_LEN];
|
|
|
|
|
prefStringLen = PREF_STRING_LEN;
|
|
|
|
|
if ( PREF_GetCharPref(prefName, prefString, &prefStringLen) == 0 )
|
|
|
|
|
{
|
|
|
|
|
c2pstr(prefString);
|
|
|
|
|
field->SetDescriptor((unsigned char *)prefString);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1998-06-02 21:00:07 +00:00
|
|
|
|
void EditFieldToPref(LGAEditField * field, const char * prefName)
|
1998-03-28 02:44:41 +00:00
|
|
|
|
{
|
|
|
|
|
Str255 s;
|
|
|
|
|
field->GetDescriptor(s);
|
|
|
|
|
p2cstr(s);
|
|
|
|
|
PREF_SetCharPref(prefName, (char*)s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Displays the additional data login dialog. Throws are taken care of by
|
|
|
|
|
// the caller
|
|
|
|
|
void
|
|
|
|
|
CUserProfile::DoNetExtendedProfileDialog(LCommander * super)
|
|
|
|
|
{
|
|
|
|
|
StDialogHandler theHandler(9911, super);
|
|
|
|
|
LWindow *theDialog = theHandler.GetDialog();
|
|
|
|
|
|
1998-06-02 21:00:07 +00:00
|
|
|
|
LGAEditField *ldapAddressField = (LGAEditField*)theDialog->FindPaneByID('addr');
|
|
|
|
|
LGAEditField *searchBaseField = (LGAEditField*)theDialog->FindPaneByID('sbas');
|
|
|
|
|
LGAEditField *httpAddressField = (LGAEditField*)theDialog->FindPaneByID('hurl');
|
|
|
|
|
LGARadioButton * ldapRadio = (LGARadioButton *)theDialog->FindPaneByID('ldap');
|
|
|
|
|
LGARadioButton * httpRadio = (LGARadioButton *)theDialog->FindPaneByID('http');
|
1998-03-28 02:44:41 +00:00
|
|
|
|
|
|
|
|
|
ThrowIfNil_(ldapAddressField);
|
|
|
|
|
ThrowIfNil_(searchBaseField);
|
|
|
|
|
ThrowIfNil_(httpAddressField);
|
|
|
|
|
ThrowIfNil_(ldapRadio);
|
|
|
|
|
ThrowIfNil_(httpRadio);
|
|
|
|
|
|
|
|
|
|
// Initialize the dialog from the preferences
|
1998-06-23 01:36:59 +00:00
|
|
|
|
PrefToEditField("li.server.ldap.url", ldapAddressField );
|
|
|
|
|
PrefToEditField("li.server.ldap.userbase", searchBaseField );
|
|
|
|
|
PrefToEditField("li.server.http.baseURL", httpAddressField);
|
|
|
|
|
#define PREF_LEN 10;
|
1998-03-28 02:44:41 +00:00
|
|
|
|
int prefStringLen;
|
|
|
|
|
char prefString[PREF_STRING_LEN];
|
|
|
|
|
prefStringLen = PREF_STRING_LEN;
|
|
|
|
|
if ( PREF_GetCharPref("li.protocol", prefString, &prefStringLen) == 0 )
|
|
|
|
|
if (XP_STRCMP(prefString, "http") == 0)
|
|
|
|
|
httpRadio->SetValue(1);
|
1998-06-23 01:36:59 +00:00
|
|
|
|
else
|
|
|
|
|
ldapRadio->SetValue(1);
|
1998-03-28 02:44:41 +00:00
|
|
|
|
// Do the dialog
|
|
|
|
|
httpAddressField->SelectAll();
|
|
|
|
|
theDialog->SetLatentSub(httpAddressField);
|
|
|
|
|
theDialog->Show();
|
|
|
|
|
|
|
|
|
|
while (true)
|
|
|
|
|
{
|
|
|
|
|
MessageT hitMessage = theHandler.DoDialog();
|
|
|
|
|
if ( hitMessage == msg_Cancel )
|
|
|
|
|
break;
|
|
|
|
|
else if ( hitMessage == msg_OK )
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
LStr255 httpAddress;
|
|
|
|
|
httpAddressField->GetDescriptor(httpAddress);
|
|
|
|
|
if ( httpAddress.Length() > 2 )
|
|
|
|
|
{
|
|
|
|
|
if (!httpAddress.BeginsWith(LStr255("http://")))
|
|
|
|
|
httpAddress.Insert(LStr255("http://"), 0);
|
|
|
|
|
}
|
1998-06-23 01:36:59 +00:00
|
|
|
|
EditFieldToPref(ldapAddressField, "li.server.ldap.url");
|
|
|
|
|
EditFieldToPref(searchBaseField, "li.server.ldap.userbase");
|
1998-03-28 02:44:41 +00:00
|
|
|
|
EditFieldToPref(httpAddressField, "li.server.http.baseURL");
|
|
|
|
|
|
|
|
|
|
if ( ldapRadio->GetValue() > 0 )
|
|
|
|
|
PREF_SetCharPref("li.protocol", "ldap");
|
|
|
|
|
else
|
|
|
|
|
PREF_SetCharPref("li.protocol", "http");
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Displays the modal login dialog
|
|
|
|
|
ProfileErr
|
|
|
|
|
CUserProfile::DoNetProfileDialog()
|
|
|
|
|
{
|
|
|
|
|
ProfileErr perr = eOK;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
StDialogHandler theHandler(9910, CFrontApp::GetApplication());
|
|
|
|
|
LWindow *theDialog = theHandler.GetDialog();
|
|
|
|
|
|
1998-06-02 21:00:07 +00:00
|
|
|
|
LGAEditField *usernameField = (LGAEditField*)theDialog->FindPaneByID('user');
|
|
|
|
|
LGAEditField *passwordField = (LGAEditField*)theDialog->FindPaneByID('pass');
|
1998-03-28 02:44:41 +00:00
|
|
|
|
|
|
|
|
|
ThrowIfNil_(usernameField);
|
|
|
|
|
ThrowIfNil_(passwordField);
|
|
|
|
|
|
1998-06-23 01:36:59 +00:00
|
|
|
|
PrefToEditField( "li.login.name", usernameField);
|
|
|
|
|
PrefToEditField( "li.login.password", passwordField);
|
|
|
|
|
|
1998-03-28 02:44:41 +00:00
|
|
|
|
usernameField->SelectAll();
|
|
|
|
|
theDialog->SetLatentSub(usernameField);
|
|
|
|
|
theDialog->Show();
|
|
|
|
|
|
|
|
|
|
while (true)
|
|
|
|
|
{
|
|
|
|
|
MessageT hitMessage = theHandler.DoDialog();
|
|
|
|
|
|
|
|
|
|
if (hitMessage == msg_Cancel)
|
|
|
|
|
{
|
|
|
|
|
perr = eUserCancelled;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else if (hitMessage == msg_OK)
|
|
|
|
|
{
|
|
|
|
|
EditFieldToPref( usernameField, "li.login.name");
|
|
|
|
|
EditFieldToPref( passwordField, "li.login.password");
|
|
|
|
|
|
|
|
|
|
PREF_SetBoolPref("li.enabled", true);
|
|
|
|
|
perr = eOK;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else if (hitMessage == 'adva') // Advanced button
|
|
|
|
|
{
|
|
|
|
|
DoNetExtendedProfileDialog(theDialog);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (ExceptionCode err)
|
|
|
|
|
{
|
|
|
|
|
XP_ASSERT(false);
|
|
|
|
|
perr = eUnknownError;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return perr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Creates a network profile folder
|
|
|
|
|
// The folder is located inside the users folder
|
|
|
|
|
ProfileErr
|
|
|
|
|
CUserProfile::CreateNetProfile( FSSpec usersFolder, FSSpec& profileFolderSpec )
|
|
|
|
|
{
|
|
|
|
|
ProfileErr perr;
|
|
|
|
|
perr = DoNetProfileDialog();
|
|
|
|
|
|
|
|
|
|
if (perr == eOK)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
CStr255 profileFolderName("Temporary Profile");
|
|
|
|
|
OSErr err;
|
|
|
|
|
|
|
|
|
|
// Create the folder spec of the profile directory
|
|
|
|
|
profileFolderSpec = usersFolder;
|
|
|
|
|
LString::CopyPStr(profileFolderName, profileFolderSpec.name, sizeof(profileFolderSpec.name));
|
|
|
|
|
|
|
|
|
|
// If the folder already exists, delete it
|
|
|
|
|
err = CFileMgr::DeleteFolder( profileFolderSpec );
|
|
|
|
|
XP_ASSERT((err == noErr) || (err == fnfErr));
|
|
|
|
|
|
|
|
|
|
// Create the folder
|
|
|
|
|
short dummy;
|
|
|
|
|
long dummy2;
|
|
|
|
|
err = CFileMgr::CreateFolderInFolder(usersFolder.vRefNum, usersFolder.parID, profileFolderName,
|
|
|
|
|
&dummy, &dummy2);
|
|
|
|
|
ThrowIfOSErr_(err);
|
|
|
|
|
ReflectToPreferences( CStr255("Network Profile"), profileFolderSpec);
|
|
|
|
|
}
|
|
|
|
|
catch (ExceptionCode err)
|
|
|
|
|
{
|
|
|
|
|
XP_ASSERT(false);
|
|
|
|
|
return eUnknownError;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return perr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><>launches upgrade wizard for users who have not run 4.0 before
|
|
|
|
|
// creates an initial profile folder and User Profiles file.
|
|
|
|
|
// if oldNetscapeF is non-null, it points to the user's 3.0
|
|
|
|
|
// Netscape <20> folder and the profile "folder" is an alias to it
|
|
|
|
|
ProfileErr
|
|
|
|
|
CUserProfile::HandleUpgrade( FSSpec& profileFolder, const FSSpec* oldNetscapeF )
|
|
|
|
|
{
|
|
|
|
|
ProfileErr result = eOK;
|
|
|
|
|
CStr31 profileName;
|
|
|
|
|
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
Try_
|
|
|
|
|
{
|
|
|
|
|
FSSpec profileSpec = CPrefs::GetFilePrototype( CPrefs::UsersFolder );
|
|
|
|
|
|
|
|
|
|
if ( mHasConfigPlugin && !oldNetscapeF )
|
|
|
|
|
{
|
|
|
|
|
profileFolder.vRefNum = profileSpec.vRefNum;
|
|
|
|
|
profileFolder.parID = profileSpec.parID;
|
|
|
|
|
profileName = MAGIC_PROFILE_NAME;
|
|
|
|
|
LString::CopyPStr( profileName, profileFolder.name, 32 );
|
|
|
|
|
|
|
|
|
|
CreateDefaultProfileFolder( profileFolder );
|
|
|
|
|
result = eRunAccountSetup;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
UpgradeEnum upgrading = (oldNetscapeF == nil) ? eNewInstall : eExistingPrefs;
|
|
|
|
|
result = NewUserProfile( profileSpec, profileFolder, profileName,
|
|
|
|
|
upgrading, oldNetscapeF );
|
|
|
|
|
}
|
|
|
|
|
if ( result == eUserCancelled )
|
|
|
|
|
return eUserCancelled;
|
|
|
|
|
|
|
|
|
|
if ( profileName.Length() == 0 )
|
|
|
|
|
GetIndString( profileName, kProfileStrings, kDefaultName );
|
|
|
|
|
|
|
|
|
|
// <20><>create Profiles file and add the alias
|
|
|
|
|
GetIndString( profileSpec.name, 300, userProfiles );
|
|
|
|
|
CUserProfileDB profileDB( profileSpec, true );
|
|
|
|
|
|
|
|
|
|
profileDB.AddNewProfile( 0, profileName, profileFolder );
|
|
|
|
|
sCurrentProfileID = 0;
|
|
|
|
|
}
|
|
|
|
|
Catch_( inErr )
|
|
|
|
|
{
|
|
|
|
|
CStr255 errStr;
|
|
|
|
|
GetIndString( errStr, kProfileStrings, kCreateError );
|
|
|
|
|
ErrorManager::ErrorNotify( inErr, errStr );
|
|
|
|
|
result = eUnknownError;
|
|
|
|
|
// <20><>loop through wizard again if error
|
|
|
|
|
// don't loop 5/14/97 tgm
|
|
|
|
|
//done = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
while ( 0 /*!done*/);
|
|
|
|
|
|
|
|
|
|
ReflectToPreferences(profileName, profileFolder);
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20> puts up user-selection dialog and returns selected user ID
|
|
|
|
|
ProfileErr CUserProfile::HandleProfileDialog(
|
|
|
|
|
FSSpec& profileSpec,
|
|
|
|
|
CUserProfileDB& profileDB,
|
|
|
|
|
FSSpec& profileFolder,
|
|
|
|
|
short& newUserID,
|
|
|
|
|
short lastUserID,
|
|
|
|
|
Boolean wantsProfileManager )
|
|
|
|
|
{
|
|
|
|
|
int dialogID = wantsProfileManager ?
|
|
|
|
|
profileManagerDialog : profileSelectDialog;
|
|
|
|
|
Boolean success = false;
|
|
|
|
|
LListBox* listBox;
|
1998-06-02 21:00:07 +00:00
|
|
|
|
LGAPushButton* okButton;
|
1998-03-28 02:44:41 +00:00
|
|
|
|
LPane* newButton;
|
|
|
|
|
LPane* deleteButton;
|
|
|
|
|
LPane* renameButton;
|
|
|
|
|
LPane* optionsButton;
|
1998-06-23 01:36:59 +00:00
|
|
|
|
LPane* remoteButton;
|
1998-03-28 02:44:41 +00:00
|
|
|
|
|
|
|
|
|
ProfileErr result = eOK;
|
|
|
|
|
|
|
|
|
|
RegisterClass_( LWhiteListBox);
|
|
|
|
|
|
|
|
|
|
StBlockingDialogHandler dialog( dialogID, CFrontApp::GetApplication() );
|
|
|
|
|
|
|
|
|
|
listBox = (LListBox*)dialog.GetDialog()->FindPaneByID( 'user' );
|
|
|
|
|
ThrowIfNil_( listBox );
|
|
|
|
|
ListHandle listHand = listBox->GetMacListH();
|
|
|
|
|
(**listHand).selFlags = lOnlyOne + lNoNilHilite; // only one selection
|
|
|
|
|
|
|
|
|
|
LAddColumn( 1, 0, listHand );
|
|
|
|
|
PopulateListBox( listHand, profileDB, lastUserID );
|
1998-06-23 01:36:59 +00:00
|
|
|
|
Cell cell;
|
|
|
|
|
if( listBox->GetLastSelectedCell( cell ) )
|
|
|
|
|
listBox->MakeCellVisible(cell);
|
1998-03-28 02:44:41 +00:00
|
|
|
|
listBox->AddListener( &dialog );
|
|
|
|
|
listBox->SwitchTarget( listBox );
|
|
|
|
|
|
1998-06-02 21:00:07 +00:00
|
|
|
|
okButton = (LGAPushButton*)dialog.GetDialog()->FindPaneByID( 'ok ' );
|
1998-03-28 02:44:41 +00:00
|
|
|
|
deleteButton = dialog.GetDialog()->FindPaneByID( 2 );
|
|
|
|
|
renameButton = dialog.GetDialog()->FindPaneByID( 3 );
|
|
|
|
|
newButton = dialog.GetDialog()->FindPaneByID( 1 );
|
|
|
|
|
optionsButton = dialog.GetDialog()->FindPaneByID( 'Ebut' );
|
1998-06-23 01:36:59 +00:00
|
|
|
|
remoteButton = dialog.GetDialog()->FindPaneByID( 'remo' );
|
|
|
|
|
|
|
|
|
|
if ( remoteButton )
|
|
|
|
|
{
|
|
|
|
|
XP_Bool daBool = FALSE;;
|
|
|
|
|
PREF_GetBoolPref("li.ui.enabled", &daBool);
|
|
|
|
|
if (!daBool)
|
|
|
|
|
{
|
|
|
|
|
remoteButton->Hide();
|
|
|
|
|
listBox->ResizeFrameBy(0, 24, true);
|
|
|
|
|
}
|
|
|
|
|
}
|
1998-03-28 02:44:41 +00:00
|
|
|
|
if ( wantsProfileManager )
|
|
|
|
|
ThrowIfNil_( okButton && deleteButton && renameButton && newButton );
|
|
|
|
|
else
|
|
|
|
|
ThrowIfNil_( okButton );
|
|
|
|
|
|
|
|
|
|
if ( !mHasConfigPlugin )
|
|
|
|
|
{
|
|
|
|
|
if ( optionsButton )
|
|
|
|
|
optionsButton->Hide();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if ( !wantsProfileManager )
|
|
|
|
|
SendMessageToPlugin( kInitListener, (LDialogBox*)dialog.GetDialog() );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
short tempUserID = -1;
|
|
|
|
|
|
|
|
|
|
/* keep track of the amount of time we've been idly showing this dialog */
|
|
|
|
|
long startTime = TickCount();
|
|
|
|
|
long elapsedTime = 0;
|
1998-06-23 01:36:59 +00:00
|
|
|
|
long secsLeft = 30; //we actually get this from a resource in the User Profiles file if it exists.
|
|
|
|
|
Boolean keepCounting = (!wantsProfileManager); /* only countdown in simple profile picker. not manager*/
|
1998-03-28 02:44:41 +00:00
|
|
|
|
const ResIDT autoStartResID = 9999;
|
|
|
|
|
|
1998-06-23 01:36:59 +00:00
|
|
|
|
// Check to see if our secret keep coounting resource exists
|
1998-03-28 02:44:41 +00:00
|
|
|
|
StUseResFile resFile( profileDB.GetFile()->GetResourceForkRefNum() );
|
|
|
|
|
StringHandle numSecsStringH = (StringHandle) ::Get1Resource('TEXT', autoStartResID);
|
|
|
|
|
if (keepCounting && numSecsStringH)
|
|
|
|
|
{
|
|
|
|
|
char buffer[4];
|
|
|
|
|
buffer[sizeof(buffer)-1] = 0;
|
|
|
|
|
|
|
|
|
|
memcpy( (unsigned char *)buffer, (unsigned char *)*numSecsStringH, min(GetHandleSize((Handle)numSecsStringH),(long)sizeof(buffer)-1));
|
|
|
|
|
secsLeft = atoi(buffer);
|
1998-06-23 01:36:59 +00:00
|
|
|
|
if (secsLeft <= 0 || secsLeft > 300)
|
1998-03-28 02:44:41 +00:00
|
|
|
|
keepCounting = false;
|
|
|
|
|
}
|
1998-06-23 01:36:59 +00:00
|
|
|
|
else
|
|
|
|
|
keepCounting = false;
|
1998-03-28 02:44:41 +00:00
|
|
|
|
|
1998-06-23 01:36:59 +00:00
|
|
|
|
(dialog.GetDialog())->Show();
|
1998-03-28 02:44:41 +00:00
|
|
|
|
|
|
|
|
|
while ( !success )
|
|
|
|
|
{
|
|
|
|
|
//ʥ catch any errors inside dialog loop
|
|
|
|
|
Try_
|
|
|
|
|
{
|
|
|
|
|
Cell cell;
|
|
|
|
|
|
|
|
|
|
MessageT hit = dialog.DoDialog();
|
|
|
|
|
|
|
|
|
|
// default to selecting the last selected profile if enough time has elapsed
|
|
|
|
|
if (keepCounting && (secsLeft <= 0))
|
|
|
|
|
{
|
|
|
|
|
okButton->SimulateHotSpotClick(1);
|
|
|
|
|
hit = cmd_SelectProfile;
|
|
|
|
|
}
|
|
|
|
|
else if (keepCounting)
|
|
|
|
|
{
|
|
|
|
|
// update secsLeft
|
|
|
|
|
elapsedTime = TickCount() - startTime;
|
|
|
|
|
if (elapsedTime >= 60)
|
|
|
|
|
{
|
|
|
|
|
secsLeft--;
|
|
|
|
|
startTime = TickCount();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (secsLeft >= 0)
|
|
|
|
|
secsLeft = -1;
|
|
|
|
|
|
|
|
|
|
if (listBox->GetLastSelectedCell( cell ) )
|
|
|
|
|
{
|
|
|
|
|
newUserID = cell.v;
|
|
|
|
|
okButton->Enable();
|
|
|
|
|
if (wantsProfileManager) {
|
|
|
|
|
renameButton->Enable();
|
|
|
|
|
if ( profileDB.CountProfiles() > 1 )
|
|
|
|
|
// <20><>don't allow deleting last profile
|
|
|
|
|
deleteButton->Enable();
|
|
|
|
|
else
|
|
|
|
|
deleteButton->Disable();
|
|
|
|
|
}
|
|
|
|
|
if ( optionsButton )
|
|
|
|
|
optionsButton->Enable();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
newUserID = -1;
|
|
|
|
|
okButton->Disable();
|
|
|
|
|
if (wantsProfileManager) {
|
|
|
|
|
renameButton->Disable();
|
|
|
|
|
deleteButton->Disable();
|
|
|
|
|
}
|
|
|
|
|
if ( optionsButton )
|
|
|
|
|
optionsButton->Disable();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( newUserID != tempUserID )
|
|
|
|
|
{
|
|
|
|
|
if (tempUserID > -1)
|
|
|
|
|
keepCounting = false;
|
|
|
|
|
if ( newUserID != -1 && mHasConfigPlugin )
|
|
|
|
|
{
|
|
|
|
|
if ( profileDB.GetProfileAlias( newUserID, profileFolder, false ) )
|
|
|
|
|
SendMessageToPlugin( kNewProfileSelect, &profileFolder );
|
|
|
|
|
else
|
|
|
|
|
SendMessageToPlugin( kClearProfileSelect, NULL );
|
|
|
|
|
}
|
|
|
|
|
tempUserID = newUserID;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch ( hit )
|
|
|
|
|
{
|
|
|
|
|
case cmd_SelectProfile:
|
|
|
|
|
success = profileDB.GetProfileAlias( newUserID, profileFolder );
|
|
|
|
|
if ( success )
|
|
|
|
|
{
|
|
|
|
|
long err;
|
|
|
|
|
err = SendMessageToPlugin( kSelectDialConfig, &profileFolder );
|
|
|
|
|
if ( err == errProfileNotFound )
|
|
|
|
|
SendMessageToPlugin( kEditDialConfig, &profileFolder );
|
|
|
|
|
}
|
|
|
|
|
keepCounting = false;
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case cmd_NewProfile:
|
|
|
|
|
CStr31 profileName;
|
|
|
|
|
result = NewUserProfile( profileSpec, profileFolder, profileName );
|
|
|
|
|
|
|
|
|
|
if ( result == eUserCancelled )
|
|
|
|
|
{
|
|
|
|
|
result = eOK;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
newUserID = profileDB.CountProfiles();
|
|
|
|
|
profileDB.AddNewProfile( newUserID, profileName, profileFolder );
|
|
|
|
|
|
|
|
|
|
// redraw the profile list box
|
|
|
|
|
LDelRow(0, 0, listHand);
|
|
|
|
|
PopulateListBox(listHand, profileDB, newUserID);
|
|
|
|
|
listBox->Refresh();
|
|
|
|
|
success = true;
|
|
|
|
|
|
|
|
|
|
// <20><>we ran the Profile Wizard and now we should
|
|
|
|
|
// open the Edit Settings dialog for the associated
|
|
|
|
|
// dial configuration
|
|
|
|
|
if ( result == eRunMUC )
|
|
|
|
|
{
|
|
|
|
|
SendMessageToPlugin( kEditDialConfig, &profileFolder );
|
|
|
|
|
result = eOK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20> we ran the Profile Wizard, but we don't want to
|
|
|
|
|
// associate a dialing configuration, so write out
|
|
|
|
|
// an empty "Configuration" file by calling
|
|
|
|
|
// the plugin
|
|
|
|
|
else if ( result == eSkipMUC )
|
|
|
|
|
{
|
|
|
|
|
SendMessageToPlugin( kAutoSelectDialConfig, &profileFolder );
|
|
|
|
|
result = eOK;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
keepCounting = false;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case cmd_RenameProfile:
|
|
|
|
|
RenameProfile( newUserID, profileDB, cell, listHand );
|
|
|
|
|
keepCounting = false;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case cmd_DeleteProfile:
|
|
|
|
|
DeleteProfile( newUserID, profileDB, listHand );
|
|
|
|
|
listBox->Refresh();
|
|
|
|
|
keepCounting = false;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case cmd_QuitProfile:
|
|
|
|
|
keepCounting = false;
|
|
|
|
|
return eUserCancelled;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case cmd_EditDialSettings:
|
|
|
|
|
if ( profileDB.GetProfileAlias( newUserID, profileFolder ) )
|
|
|
|
|
{
|
|
|
|
|
SendMessageToPlugin( kEditDialConfig, &profileFolder );
|
|
|
|
|
tempUserID = -1;
|
|
|
|
|
}
|
|
|
|
|
keepCounting = false;
|
|
|
|
|
break;
|
1998-06-23 01:36:59 +00:00
|
|
|
|
case cmd_RemoteProfile:
|
|
|
|
|
{
|
|
|
|
|
result = DoNetProfileDialog();
|
|
|
|
|
if ( result == eOK )
|
|
|
|
|
result = CreateNetProfile( profileSpec, profileFolder);
|
|
|
|
|
|
|
|
|
|
if ( result != eUserCancelled )
|
|
|
|
|
{
|
|
|
|
|
newUserID = lastUserID;
|
|
|
|
|
success = true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
result = eOK;
|
|
|
|
|
}
|
|
|
|
|
break;
|
1998-03-28 02:44:41 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Catch_ ( inErr )
|
|
|
|
|
{
|
|
|
|
|
CStr255 errStr;
|
|
|
|
|
GetIndString( errStr, kProfileStrings, kReadError );
|
|
|
|
|
ErrorManager::ErrorNotify( inErr, errStr );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Boolean CUserProfile::DeleteMagicProfile( FSSpec& inSpec )
|
|
|
|
|
{
|
|
|
|
|
short nextID = 0;
|
|
|
|
|
CStr31 profileName;
|
|
|
|
|
FSSpec profileSpec;
|
|
|
|
|
char* fullURL;
|
|
|
|
|
Boolean found = FALSE;
|
|
|
|
|
|
|
|
|
|
profileSpec.vRefNum = inSpec.vRefNum;
|
|
|
|
|
profileSpec.parID = inSpec.parID;
|
|
|
|
|
profileName = MAGIC_PROFILE_NAME;
|
|
|
|
|
LString::CopyPStr( profileName, profileSpec.name, 32 );
|
|
|
|
|
|
|
|
|
|
CUserProfileDB db( inSpec );
|
|
|
|
|
|
|
|
|
|
while ( db.GetProfileName( nextID++, profileName ) )
|
|
|
|
|
{
|
|
|
|
|
if ( profileName == MAGIC_PROFILE_NAME )
|
|
|
|
|
{
|
|
|
|
|
db.DeleteProfile( --nextID );
|
|
|
|
|
if ( db.GetLastProfileID() == nextID )
|
|
|
|
|
db.SetLastProfileID( 0 );
|
|
|
|
|
found = TRUE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fullURL = CFileMgr::EncodedPathNameFromFSSpec( profileSpec, TRUE );
|
|
|
|
|
if ( fullURL && found )
|
|
|
|
|
{
|
|
|
|
|
XP_RemoveDirectoryRecursive( fullURL, xpURL );
|
|
|
|
|
XP_FREE( fullURL );
|
|
|
|
|
}
|
|
|
|
|
if ( found )
|
|
|
|
|
return TRUE;
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CUserProfile::PopulateListBox(ListHandle& listHand, CUserProfileDB& profileDB, short defaultID)
|
|
|
|
|
{
|
|
|
|
|
LSetDrawingMode(false, listHand);
|
|
|
|
|
|
|
|
|
|
short nextID = 0;
|
|
|
|
|
Cell cell;
|
|
|
|
|
CStr31 str;
|
|
|
|
|
Boolean gotOne = profileDB.GetProfileName(nextID, str);
|
|
|
|
|
while (gotOne) {
|
|
|
|
|
LAddRow(1, nextID, listHand);
|
|
|
|
|
SetPt(&cell, 0, nextID);
|
|
|
|
|
LSetCell(&str.fStr[1], str.fStr[0], cell, listHand);
|
|
|
|
|
gotOne = profileDB.GetProfileName(++nextID, str);
|
|
|
|
|
}
|
|
|
|
|
// <20><>select last user or first cell & scroll to it
|
|
|
|
|
SetPt(&cell, 0, defaultID);
|
|
|
|
|
LSetSelect(true, cell, listHand);
|
|
|
|
|
LAutoScroll(listHand);
|
|
|
|
|
LSetDrawingMode(true, listHand);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ensure the requested new profile folder does not exist;
|
|
|
|
|
// if it does, append a number to make a unique name.
|
|
|
|
|
void CUserProfile::GetUniqueFolderName(FSSpec& folder)
|
|
|
|
|
{
|
|
|
|
|
if (CFileMgr::FileExists(folder)) {
|
|
|
|
|
int nextIndex = 2;
|
|
|
|
|
CStr31 requestedName = folder.name;
|
|
|
|
|
if (requestedName.Length() > 28)
|
|
|
|
|
requestedName.Length() = 28;
|
|
|
|
|
CStr31 uniqueName;
|
|
|
|
|
do {
|
|
|
|
|
uniqueName = requestedName;
|
|
|
|
|
char suffix[3];
|
|
|
|
|
sprintf(suffix, "-%d", nextIndex++);
|
|
|
|
|
uniqueName += suffix;
|
|
|
|
|
LString::CopyPStr(uniqueName, folder.name, 32);
|
|
|
|
|
}
|
|
|
|
|
while (CFileMgr::FileExists(folder));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Make one desktop icon
|
|
|
|
|
static const kIconNameStringsListID = 9800;
|
|
|
|
|
|
|
|
|
|
static OSErr MakeOneDesktopIcon(const CStr31 &profileName, short templateNameIndex, short iconNameIndex)
|
|
|
|
|
{
|
|
|
|
|
OSErr err = noErr;
|
|
|
|
|
FSSpec shortcutSpec = CPrefs::GetFilePrototype(CPrefs::RequiredGutsFolder);
|
|
|
|
|
FSSpec desktopFolderSpec;
|
|
|
|
|
FSSpec desktopIconSpec;
|
|
|
|
|
short vRefNum;
|
|
|
|
|
long folderID;
|
|
|
|
|
|
|
|
|
|
GetIndString(shortcutSpec.name, kIconNameStringsListID, templateNameIndex);
|
|
|
|
|
|
|
|
|
|
//find the source file
|
|
|
|
|
if (!CFileMgr::FileExists(shortcutSpec) || CFileMgr::IsFolder(shortcutSpec))
|
|
|
|
|
ThrowIfOSErr_(fnfErr);
|
|
|
|
|
|
|
|
|
|
//check the destination
|
|
|
|
|
err = ::FindFolder(kOnSystemDisk, kDesktopFolderType, true,
|
|
|
|
|
&vRefNum, &folderID);
|
|
|
|
|
ThrowIfOSErr_(err);
|
|
|
|
|
|
|
|
|
|
err = CFileMgr::FolderSpecFromFolderID(vRefNum, folderID, desktopFolderSpec);
|
|
|
|
|
ThrowIfOSErr_(err);
|
|
|
|
|
|
|
|
|
|
desktopIconSpec.parID = folderID;
|
|
|
|
|
desktopIconSpec.vRefNum = vRefNum;
|
|
|
|
|
GetIndString(desktopIconSpec.name, kIconNameStringsListID, iconNameIndex);
|
|
|
|
|
|
|
|
|
|
//Append the profile name. We know that it does not contain colons
|
|
|
|
|
CStr63 iconName(desktopIconSpec.name);
|
|
|
|
|
|
|
|
|
|
iconName += profileName;
|
|
|
|
|
|
|
|
|
|
//Truncate the iconName if necessary to 31 chars
|
|
|
|
|
if (iconName.Length() > 30) {
|
|
|
|
|
iconName[0] = 30;
|
|
|
|
|
iconName[30] = '<EFBFBD>';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LString::CopyPStr(iconName, desktopIconSpec.name, 31);
|
|
|
|
|
|
|
|
|
|
//If there is already an icon with the same name, append the profile name
|
|
|
|
|
long nextIndex = 1;
|
|
|
|
|
|
|
|
|
|
while (CFileMgr::FileExists(desktopIconSpec))
|
|
|
|
|
{
|
|
|
|
|
CStr63 uniqueName(iconName);
|
|
|
|
|
char suffix[5];
|
|
|
|
|
short len;
|
|
|
|
|
|
|
|
|
|
sprintf(suffix, "-%d", nextIndex++);
|
|
|
|
|
|
|
|
|
|
len = 30 - strlen(suffix);
|
|
|
|
|
//Truncate the uniqueName if necessary
|
|
|
|
|
if (uniqueName.Length() > len) {
|
|
|
|
|
uniqueName[0] = len;
|
|
|
|
|
uniqueName[len] = '<EFBFBD>';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uniqueName += suffix;
|
|
|
|
|
|
|
|
|
|
LString::CopyPStr(uniqueName, desktopIconSpec.name, 31);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//phew. now we have a unique name to copy to
|
|
|
|
|
err = CFileMgr::CopyFile(shortcutSpec, desktopFolderSpec, desktopIconSpec.name);
|
|
|
|
|
ThrowIfOSErr_(err);
|
|
|
|
|
|
|
|
|
|
//make sure the custom icon bit is set
|
|
|
|
|
err = CFileMgr::SetFileFinderFlag(desktopIconSpec, kHasCustomIcon, TRUE);
|
|
|
|
|
ThrowIfOSErr_(err);
|
|
|
|
|
|
|
|
|
|
//And now copy the profile name into the data fork
|
|
|
|
|
if (! CFileMgr::FileExists(desktopIconSpec)) //if it does not, we're in trouble
|
|
|
|
|
ThrowIfOSErr_(fnfErr);
|
|
|
|
|
|
|
|
|
|
LFile scriptFile(desktopIconSpec);
|
|
|
|
|
|
|
|
|
|
scriptFile.OpenDataFork(fsRdWrPerm);
|
|
|
|
|
scriptFile.WriteDataFork((const char*)profileName, profileName.Length());
|
|
|
|
|
scriptFile.CloseDataFork();
|
|
|
|
|
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Make the desktop icons for the selected profile.
|
|
|
|
|
// They are acually applescripts copied from the essential files
|
|
|
|
|
// folder, with a property modified for this profile.
|
|
|
|
|
|
|
|
|
|
OSErr CUserProfile::MakeDesktopIcons(
|
|
|
|
|
const CStr31 &profileName,
|
|
|
|
|
const Boolean wantsNavigator,
|
|
|
|
|
const Boolean wantsInbox )
|
|
|
|
|
{
|
|
|
|
|
OSErr err = noErr;
|
|
|
|
|
|
|
|
|
|
enum { kNavShortcutName = 1, kInboxShortcutName,
|
|
|
|
|
kNavDesktopName, kInboxDesktopName}; //in profile.cnst
|
|
|
|
|
|
|
|
|
|
if (wantsNavigator)
|
|
|
|
|
err = MakeOneDesktopIcon(profileName, kNavShortcutName, kNavDesktopName);
|
|
|
|
|
|
|
|
|
|
if (wantsInbox)
|
|
|
|
|
err = MakeOneDesktopIcon(profileName, kInboxShortcutName, kInboxDesktopName);
|
|
|
|
|
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// <20> prompts for a new user profile
|
|
|
|
|
ProfileErr CUserProfile::NewUserProfile(
|
|
|
|
|
const FSSpec& profileSpec,
|
|
|
|
|
FSSpec& profileFolder,
|
|
|
|
|
CStr31& profileName,
|
|
|
|
|
UpgradeEnum upgrading,
|
|
|
|
|
const FSSpec* oldNetscapeF )
|
|
|
|
|
{
|
|
|
|
|
Boolean userChoseFolder = false;
|
|
|
|
|
ProfileErr result = eOK;
|
|
|
|
|
|
|
|
|
|
profileFolder.vRefNum = profileSpec.vRefNum;
|
|
|
|
|
profileFolder.parID = profileSpec.parID;
|
|
|
|
|
|
|
|
|
|
result = NewProfileWizard( upgrading, profileName, profileSpec,
|
|
|
|
|
profileFolder, userChoseFolder );
|
|
|
|
|
|
|
|
|
|
if ( result == eUserCancelled )
|
|
|
|
|
return eUserCancelled;
|
|
|
|
|
|
|
|
|
|
// <20> If the user chose a folder, see if it contains an existing
|
|
|
|
|
// Preferences file. If so, this folder becomes the new profile
|
|
|
|
|
// folder; otherwise, create a new folder inside it.
|
|
|
|
|
if ( userChoseFolder ) {
|
|
|
|
|
long parentID;
|
|
|
|
|
ThrowIfOSErr_( CFileMgr::GetFolderID(profileFolder, parentID) );
|
|
|
|
|
|
|
|
|
|
FSSpec prefFile;
|
|
|
|
|
prefFile.vRefNum = profileFolder.vRefNum;
|
|
|
|
|
prefFile.parID = parentID;
|
|
|
|
|
::GetIndString( prefFile.name, 300, prefFileName );
|
|
|
|
|
if (! CFileMgr::FileExists(prefFile)) {
|
|
|
|
|
// want to create a new folder inside the selected one
|
|
|
|
|
userChoseFolder = false;
|
|
|
|
|
profileFolder.parID = parentID;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><>create a folder and return it
|
|
|
|
|
if ( !userChoseFolder )
|
|
|
|
|
{
|
|
|
|
|
LString::CopyPStr( profileName, profileFolder.name, 32 );
|
|
|
|
|
GetUniqueFolderName(profileFolder);
|
|
|
|
|
|
|
|
|
|
if ( oldNetscapeF )
|
|
|
|
|
{
|
|
|
|
|
// <20><>special case: point profile to existing 3.0 Netscape <20>
|
|
|
|
|
CFileMgr::MakeAliasFile( profileFolder, *oldNetscapeF );
|
|
|
|
|
|
|
|
|
|
profileFolder = *oldNetscapeF;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
CreateDefaultProfileFolder(profileFolder);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1998-06-23 01:36:59 +00:00
|
|
|
|
if (CFrontApp::GetApplication()->HasImportModule())
|
|
|
|
|
{
|
|
|
|
|
CDeferredCommand* task = new CDeferredCommand(
|
|
|
|
|
CFrontApp::GetApplication(),
|
|
|
|
|
cmd_LaunchImportModule, nil);
|
|
|
|
|
CDeferredTaskManager::Post(task, nil);
|
|
|
|
|
}
|
1998-03-28 02:44:41 +00:00
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ProfileErr CUserProfile::NewProfileWizard(
|
|
|
|
|
UpgradeEnum upgrading,
|
|
|
|
|
CStr31 &profileName,
|
|
|
|
|
const FSSpec &profileFolder,
|
|
|
|
|
FSSpec &newProfileFolder,
|
|
|
|
|
Boolean &userChoseFolder )
|
|
|
|
|
{
|
|
|
|
|
// <20> if we're upgrading 3.0 prefs, we don't allow the user to change
|
|
|
|
|
// the profile folder; just display & disable the default folder.
|
|
|
|
|
// Otherwise, the callback fills in the user name as the profile
|
|
|
|
|
// folder and lets the user edit it. (--this needs work)
|
|
|
|
|
LArray paneList( sizeof( PaneIDT ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef CAN_MAKE_DESKTOP_ICONS_FOR_PROFILE
|
|
|
|
|
PaneIDT normalPaneList[] = { profileIntroPane, userNamePane, profileNamePane,
|
|
|
|
|
profileFolderPane, profileIconsPane, profileDonePane, 0 };
|
|
|
|
|
PaneIDT mucPaneList[] = { profileIntroPane, profilePEPane, userNamePane, profileNamePane,
|
|
|
|
|
profileFolderPane, profileIconsPane, profileDonePane, 0 };
|
|
|
|
|
#else
|
|
|
|
|
PaneIDT normalPaneList[] = { profileIntroPane, userNamePane, profileNamePane,
|
|
|
|
|
profileFolderPane, profileDonePane, 0 };
|
|
|
|
|
PaneIDT mucPaneList[] = { profileIntroPane, profilePEPane, userNamePane, profileNamePane,
|
|
|
|
|
profileFolderPane, profileDonePane, 0 };
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
PaneIDT* tmpP;
|
|
|
|
|
|
|
|
|
|
if ( !mHasConfigPlugin )
|
|
|
|
|
tmpP = normalPaneList;
|
|
|
|
|
else
|
|
|
|
|
tmpP = mucPaneList;
|
|
|
|
|
|
|
|
|
|
while ( *tmpP != 0 )
|
|
|
|
|
paneList.InsertItemsAt( 1, LArray::index_Last, tmpP++ );
|
|
|
|
|
|
|
|
|
|
CDialogWizardHandler wizard( updateWizardDialog, paneList );
|
|
|
|
|
|
|
|
|
|
LListener* listener = new CProfilePaneMonitor( &wizard );
|
|
|
|
|
wizard.AddListener( listener );
|
|
|
|
|
|
|
|
|
|
LWindow* window = wizard.GetDialog();
|
|
|
|
|
if ( upgrading == eExistingPrefs )
|
|
|
|
|
{
|
|
|
|
|
wizard.SetEditText( 'name', CPrefs::GetString( CPrefs::UserName ) );
|
|
|
|
|
wizard.SetEditText( 'mail', CPrefs::GetString( CPrefs::UserEmail ) );
|
|
|
|
|
}
|
|
|
|
|
if ( upgrading != eNoUpgrade )
|
|
|
|
|
{
|
|
|
|
|
LStdControl* cancel = (LStdControl*)window->FindPaneByID( 'cncl' );
|
|
|
|
|
if (cancel)
|
|
|
|
|
{
|
|
|
|
|
CStr31 label;
|
|
|
|
|
GetIndString( label, kProfileStrings, kQuitLabel );
|
|
|
|
|
cancel->SetDescriptor( label );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20> hide "detected previous Navigator version" text if appropriate
|
|
|
|
|
if ( upgrading != eExistingPrefs || CPrefs::sPrefFileVersion != 3 )
|
|
|
|
|
{
|
|
|
|
|
LPane* upgradeText = window->FindPaneByID( 40 );
|
|
|
|
|
if ( upgradeText )
|
|
|
|
|
upgradeText->Hide();
|
|
|
|
|
upgradeText = window->FindPaneByID( 41 );
|
|
|
|
|
if ( upgradeText )
|
|
|
|
|
upgradeText->Hide();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FSSpec tempFolder;
|
|
|
|
|
tempFolder.vRefNum = profileFolder.vRefNum;
|
|
|
|
|
tempFolder.parID = profileFolder.parID;
|
|
|
|
|
LString::CopyPStr( "\p", tempFolder.name, 32 );
|
|
|
|
|
|
|
|
|
|
CFilePicker* picker = (CFilePicker*)window->FindPaneByID( 'fold' );
|
|
|
|
|
ThrowIfNil_( picker );
|
|
|
|
|
picker->SetPickType( CFilePicker::Folders );
|
|
|
|
|
picker->SetFSSpec( tempFolder, false );
|
|
|
|
|
// <20> don't allow different folder when upgrading
|
|
|
|
|
if ( upgrading == eExistingPrefs ) {
|
|
|
|
|
LPane* chooseBtn = picker->FindPaneByID(2);
|
|
|
|
|
LPane* chooseText = window->FindPaneByID(31);
|
|
|
|
|
if (chooseBtn && chooseText) {
|
|
|
|
|
chooseBtn->Hide();
|
|
|
|
|
chooseText->Hide();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// show the profile wizard
|
|
|
|
|
if ( wizard.DoWizard() == false )
|
|
|
|
|
{
|
|
|
|
|
// <20><>user cancelled
|
|
|
|
|
delete listener;
|
|
|
|
|
return eUserCancelled;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// copy user name & email to prefs; return profile name
|
|
|
|
|
CStr255 userName;
|
|
|
|
|
wizard.GetEditText( 'name', userName );
|
|
|
|
|
CPrefs::SetString( userName, CPrefs::UserName );
|
|
|
|
|
CStr255 emailAddr;
|
|
|
|
|
wizard.GetEditText( 'mail', emailAddr );
|
|
|
|
|
CPrefs::SetString( emailAddr, CPrefs::UserEmail );
|
|
|
|
|
|
|
|
|
|
wizard.GetEditText( 'pnam', profileName );
|
|
|
|
|
StripColons(profileName);
|
|
|
|
|
|
|
|
|
|
#ifdef CAN_MAKE_DESKTOP_ICONS_FOR_PROFILE
|
|
|
|
|
// make the desktop icons
|
|
|
|
|
OSErr err = MakeDesktopIcons(profileName, wizard.GetCheckboxValue('navb'), wizard.GetCheckboxValue('inbb'));
|
|
|
|
|
ThrowIfOSErr_(err); //should we do this?
|
|
|
|
|
#endif // CAN_MAKE_DESKTOP_ICONS_FOR_PROFILE
|
|
|
|
|
|
|
|
|
|
if ( picker->WasSet() )
|
|
|
|
|
{
|
|
|
|
|
userChoseFolder = true;
|
|
|
|
|
CFileMgr::CopyFSSpec( picker->GetFSSpec(), newProfileFolder );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
delete listener;
|
|
|
|
|
|
|
|
|
|
if ( mHasConfigPlugin )
|
|
|
|
|
{
|
|
|
|
|
LControl* radioNew = (LControl*)window->FindPaneByID( 'Rnew' );
|
|
|
|
|
LControl* radioExs = (LControl*)window->FindPaneByID( 'Rexs' );
|
|
|
|
|
|
|
|
|
|
if ( ( radioNew && radioNew->GetValue() ) || upgrading != eNoUpgrade )
|
|
|
|
|
return eRunAccountSetup;
|
|
|
|
|
else if ( radioExs && radioExs->GetValue() /* ( upgrading != eNoUpgrade ) */)
|
|
|
|
|
return eRunMUC;
|
|
|
|
|
return eSkipMUC;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return eOK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CUserProfile::RenameProfile(short selectedID, CUserProfileDB& profileDB,
|
|
|
|
|
Cell& cell, ListHandle& listHand)
|
|
|
|
|
{
|
|
|
|
|
CStr31 newName;
|
|
|
|
|
if (profileDB.GetProfileName(selectedID, newName) == false)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
CStr255 prompt;
|
|
|
|
|
GetIndString(prompt, kProfileStrings, kRenamePrompt);
|
|
|
|
|
|
|
|
|
|
Boolean ok = UStdDialogs::AskStandardTextPrompt(nil, prompt, newName,
|
|
|
|
|
NULL, NULL, kStr31Len);
|
|
|
|
|
|
|
|
|
|
if (ok && newName.Length() > 0) {
|
|
|
|
|
LSetCell(&newName.fStr[1], newName.Length(), cell, listHand);
|
|
|
|
|
|
|
|
|
|
profileDB.SetProfileName(selectedID, newName);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CUserProfile::DeleteProfile(short selectedID, CUserProfileDB& profileDB, ListHandle& listHand)
|
|
|
|
|
{
|
|
|
|
|
CStr255 prompt;
|
|
|
|
|
GetIndString(prompt, kProfileStrings, kDeletePrompt);
|
|
|
|
|
if (ErrorManager::PlainConfirm(prompt))
|
|
|
|
|
{
|
|
|
|
|
profileDB.DeleteProfile(selectedID);
|
|
|
|
|
|
|
|
|
|
if (--selectedID < 0)
|
|
|
|
|
selectedID = 0;
|
|
|
|
|
|
|
|
|
|
// redraw the profile list box
|
|
|
|
|
LDelRow(0, 0, listHand);
|
|
|
|
|
|
|
|
|
|
PopulateListBox(listHand, profileDB, selectedID);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20> Reflects profile name & path into xp preferences for querying by PE;
|
|
|
|
|
// also registers a callback so changing the name renames the profile.
|
|
|
|
|
// if we don't know how many profiles we have, pass -1 and the numprofiles
|
|
|
|
|
// pref will not be set (nasty hack: see CPrefs::InitPrefsFolder())
|
|
|
|
|
void
|
|
|
|
|
CUserProfile::ReflectToPreferences(const CStr31& profileName,
|
|
|
|
|
const FSSpec& profileFolder, short numProfiles)
|
|
|
|
|
{
|
|
|
|
|
char* folderPath = CFileMgr::EncodedPathNameFromFSSpec( profileFolder, true );
|
|
|
|
|
if ( folderPath )
|
|
|
|
|
{
|
|
|
|
|
PREF_SetDefaultCharPref( "profile.directory", folderPath );
|
|
|
|
|
free( folderPath );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PREF_SetDefaultCharPref( "profile.name", profileName );
|
|
|
|
|
|
1998-06-23 01:36:59 +00:00
|
|
|
|
#ifdef MOZ_MAIL_NEWS
|
|
|
|
|
MSG_WriteNewProfileAge();
|
|
|
|
|
#endif // MOZ_MAIL_NEWS
|
|
|
|
|
|
1998-03-28 02:44:41 +00:00
|
|
|
|
if (numProfiles > -1)
|
|
|
|
|
PREF_SetDefaultIntPref( "profile.numprofiles", numProfiles );
|
|
|
|
|
|
|
|
|
|
PREF_RegisterCallback( "profile.name", ProfilePrefChangedFunc, NULL );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20> If a Defaults folder exists in Essential Files, copy it into
|
|
|
|
|
// Netscape Users and rename it to the selected profile name.
|
|
|
|
|
// Otherwise, or in case of a copying error, create a new folder.
|
|
|
|
|
void CUserProfile::CreateDefaultProfileFolder(const FSSpec& profileFolder)
|
|
|
|
|
{
|
|
|
|
|
OSErr err = noErr;
|
|
|
|
|
Boolean needToCreate = true;
|
|
|
|
|
|
|
|
|
|
FSSpec usersFolder;
|
|
|
|
|
CFileMgr::FolderSpecFromFolderID(profileFolder.vRefNum,
|
|
|
|
|
profileFolder.parID, usersFolder);
|
|
|
|
|
|
|
|
|
|
FSSpec templateFolder = CPrefs::GetFilePrototype(CPrefs::RequiredGutsFolder);
|
|
|
|
|
GetIndString( templateFolder.name, 300, profileTemplateDir );
|
|
|
|
|
|
|
|
|
|
if (CFileMgr::FileExists(templateFolder))
|
|
|
|
|
{
|
|
|
|
|
err = FSpDirectoryCopy( &templateFolder, &usersFolder,
|
|
|
|
|
nil, 0, true, nil );
|
|
|
|
|
|
|
|
|
|
if (err == noErr) {
|
|
|
|
|
needToCreate = false;
|
|
|
|
|
|
|
|
|
|
err = HRename(profileFolder.vRefNum, profileFolder.parID,
|
|
|
|
|
templateFolder.name, profileFolder.name);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (needToCreate) {
|
|
|
|
|
short newRefNum;
|
|
|
|
|
long newParID;
|
|
|
|
|
err = CFileMgr::CreateFolderInFolder(
|
|
|
|
|
profileFolder.vRefNum, profileFolder.parID,
|
|
|
|
|
profileFolder.name, &newRefNum, &newParID );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ThrowIfOSErr_( err );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><>find the network configuration plugin and return a function ptr.
|
|
|
|
|
// to it's only entry point if possible
|
|
|
|
|
void* CUserProfile::LoadConfigPlugin()
|
|
|
|
|
{
|
|
|
|
|
// BULLSHIT ALERT: Get out if I can't call GetSharedLibrary.
|
|
|
|
|
// Future: do the right thing for 68K. See bug#56245
|
|
|
|
|
long sSysArchitecture = 0;
|
|
|
|
|
if ( (Gestalt(gestaltSysArchitecture, &sSysArchitecture) != noErr)
|
|
|
|
|
|| (sSysArchitecture != gestaltPowerPC) )
|
|
|
|
|
{
|
|
|
|
|
// Can't determine what we _do_ have, or we determined that it's _not_ PPC...
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ptr main;
|
|
|
|
|
Str255 errName;
|
|
|
|
|
PE_PluginFuncType pluginFunc;
|
|
|
|
|
|
|
|
|
|
OSErr err = ::GetSharedLibrary( "\pMUP", kPowerPCCFragArch, kFindCFrag, &mConfigPluginID,
|
|
|
|
|
&main, errName );
|
|
|
|
|
if ( err != noErr )
|
|
|
|
|
{
|
|
|
|
|
err = ::GetSharedLibrary( "\pMUP", kPowerPCCFragArch, kLoadCFrag, &mConfigPluginID,
|
|
|
|
|
&main, errName );
|
|
|
|
|
}
|
|
|
|
|
if ( err == noErr )
|
|
|
|
|
{
|
|
|
|
|
CFragSymbolClass dontCare;
|
|
|
|
|
mPluginLoaded = TRUE;
|
|
|
|
|
err = ::FindSymbol( mConfigPluginID, "\pPE_PluginFunc", (Ptr*)&pluginFunc, &dontCare );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( err == noErr )
|
|
|
|
|
return pluginFunc;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><>close the connection to the configuration plugin
|
|
|
|
|
OSErr CUserProfile::CloseConfigPlugin()
|
|
|
|
|
{
|
|
|
|
|
// if ( mPluginLoaded )
|
|
|
|
|
// return CloseConnection( &mConfigPluginID );
|
|
|
|
|
return noErr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
long CUserProfile::SendMessageToPlugin( long selector, void* pb )
|
|
|
|
|
{
|
|
|
|
|
OSErr err;
|
|
|
|
|
PE_PluginFuncType pluginFunc;
|
|
|
|
|
|
|
|
|
|
if ( !mHasConfigPlugin )
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
pluginFunc = (PE_PluginFuncType)LoadConfigPlugin();
|
|
|
|
|
if ( pluginFunc )
|
|
|
|
|
{
|
|
|
|
|
union {
|
|
|
|
|
char buffer[ 1024 ];
|
|
|
|
|
MUCInfo mucInfo;
|
|
|
|
|
} tmp;
|
|
|
|
|
|
|
|
|
|
// <20><>call the stub to have it switch all the local machine
|
|
|
|
|
// stuff to use this user's configuration
|
|
|
|
|
err = (*pluginFunc)( selector, pb, tmp.buffer );
|
|
|
|
|
CloseConfigPlugin();
|
|
|
|
|
|
|
|
|
|
// if ( err == noErr && selector == kGetDialConfig )
|
|
|
|
|
// {
|
|
|
|
|
// cstring descString;
|
|
|
|
|
// PrettyPrintConfiguration( mucInfo, descString );
|
|
|
|
|
// inCaption->SetDescriptor( (CStr255)(char*)descString );
|
|
|
|
|
// }
|
|
|
|
|
return noErr;
|
|
|
|
|
}
|
|
|
|
|
return noErr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
|
*/
|
|
|
|
|
CUserProfileDB::CUserProfileDB( FSSpec& spec, Boolean createIt ): fFile( spec )
|
|
|
|
|
{
|
|
|
|
|
if ( createIt )
|
|
|
|
|
{
|
|
|
|
|
Try_
|
|
|
|
|
{
|
|
|
|
|
fFile.CreateNewFile( emSignature, 'PRFL' ); // ?? file type?
|
|
|
|
|
}
|
|
|
|
|
Catch_( inErr )
|
|
|
|
|
{
|
|
|
|
|
if ( inErr == dupFNErr )
|
|
|
|
|
;
|
|
|
|
|
else
|
|
|
|
|
Throw_( inErr );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
fFile.OpenResourceFork( fsRdWrPerm );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
short CUserProfileDB::CountProfiles()
|
|
|
|
|
{
|
|
|
|
|
return ::Count1Resources('STR ');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
short CUserProfileDB::GetNextProfileID()
|
|
|
|
|
{
|
|
|
|
|
short nextUserID = CountProfiles();
|
|
|
|
|
|
|
|
|
|
return nextUserID;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
short CUserProfileDB::GetProfileIDByUsername(const CString& username)
|
|
|
|
|
{
|
|
|
|
|
int id = kFirstProfileID, returnID = -1;
|
|
|
|
|
Handle hProfileData = GetDBResource('DATA', id);
|
|
|
|
|
ProfileDataHeader *pHeader;
|
|
|
|
|
char *profileUser;
|
|
|
|
|
|
|
|
|
|
while (hProfileData && (returnID == -1)) {
|
|
|
|
|
HLock(hProfileData);
|
|
|
|
|
pHeader = (ProfileDataHeader *) *hProfileData;
|
|
|
|
|
|
|
|
|
|
profileUser = ((char *) pHeader) + pHeader->firstOffset;
|
|
|
|
|
|
|
|
|
|
if (username == profileUser) {
|
|
|
|
|
returnID = id - kFirstProfileID;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HUnlock(hProfileData);
|
|
|
|
|
|
|
|
|
|
hProfileData = GetDBResource('DATA', ++id);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return returnID;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
short CUserProfileDB::GetProfileIDByEmail(const CString& emailAddr)
|
|
|
|
|
{
|
|
|
|
|
int id = kFirstProfileID, returnID = -1;
|
|
|
|
|
Handle hProfileData = GetDBResource('DATA', id);
|
|
|
|
|
ProfileDataHeader *pHeader;
|
|
|
|
|
char *profileEmail;
|
|
|
|
|
|
|
|
|
|
while (hProfileData && (returnID == -1)) {
|
|
|
|
|
HLock(hProfileData);
|
|
|
|
|
pHeader = (ProfileDataHeader *) *hProfileData;
|
|
|
|
|
|
|
|
|
|
profileEmail = ((char *) pHeader) + pHeader->firstOffset
|
|
|
|
|
+ pHeader->nameLength;
|
|
|
|
|
|
|
|
|
|
if (emailAddr == profileEmail) {
|
|
|
|
|
returnID = id - kFirstProfileID;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HUnlock(hProfileData);
|
|
|
|
|
|
|
|
|
|
hProfileData = GetDBResource('DATA', ++id);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return returnID;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
short CUserProfileDB::GetLastProfileID()
|
|
|
|
|
{
|
|
|
|
|
short lastUserID = kFirstProfileID;
|
|
|
|
|
short nextUserID = kFirstProfileID + GetNextProfileID();
|
|
|
|
|
|
|
|
|
|
// ID of the previous user is stored as a resource
|
|
|
|
|
Handle lastUser = GetDBResource('user', kFirstProfileID);
|
|
|
|
|
if (lastUser) {
|
|
|
|
|
lastUserID = **(short **) lastUser;
|
|
|
|
|
if (lastUserID >= nextUserID)
|
|
|
|
|
lastUserID = kFirstProfileID;
|
|
|
|
|
::ReleaseResource(lastUser);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return lastUserID - kFirstProfileID;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CUserProfileDB::SetLastProfileID(short newUserID)
|
|
|
|
|
{
|
|
|
|
|
newUserID += kFirstProfileID;
|
|
|
|
|
Handle lastUser = GetDBResource('user', kFirstProfileID);
|
|
|
|
|
if (!lastUser) {
|
|
|
|
|
PtrToHand(&newUserID, &lastUser, sizeof(short));
|
|
|
|
|
::AddResource(lastUser, 'user', kFirstProfileID, nil);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
BlockMove(&newUserID, *lastUser, sizeof(short));
|
|
|
|
|
::ChangedResource(lastUser);
|
|
|
|
|
::ReleaseResource(lastUser);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CUserProfileDB::AddNewProfile(short id, const CStr31& profileName, const FSSpec& profileFolder)
|
|
|
|
|
{
|
|
|
|
|
id += kFirstProfileID;
|
|
|
|
|
// create new STR, alis, and DATA resources
|
|
|
|
|
StringHandle nameHand;
|
|
|
|
|
PtrToHand(profileName, &(Handle) nameHand, profileName.Length() + 1);
|
|
|
|
|
AddResource((Handle) nameHand, 'STR ', id, nil);
|
|
|
|
|
|
|
|
|
|
AliasHandle alias;
|
|
|
|
|
OSErr err = NewAlias( nil, &profileFolder, &alias );
|
|
|
|
|
if (err == noErr) {
|
|
|
|
|
AddResource((Handle) alias, 'alis', id, profileFolder.name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SetProfileData(id - kFirstProfileID);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Boolean CUserProfileDB::GetProfileName(short id, CStr31& name)
|
|
|
|
|
{
|
|
|
|
|
// -- use Get1Resource instead of GetString to avoid grabbing
|
|
|
|
|
// spurious strings from other programs (e.g. Kaleidoscope)
|
|
|
|
|
StringHandle strHand = (StringHandle) GetDBResource('STR ', id + kFirstProfileID);
|
|
|
|
|
if (strHand == nil)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
HLock((Handle) strHand);
|
|
|
|
|
int len = *strHand[0] + 1;
|
|
|
|
|
if (len > 32) len = 32;
|
|
|
|
|
BlockMove(*strHand, name.fStr, len);
|
|
|
|
|
name.Length() = len - 1;
|
|
|
|
|
HUnlock((Handle) strHand);
|
|
|
|
|
|
|
|
|
|
ReleaseResource((Handle) strHand);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CUserProfileDB::SetProfileName(short id, const CStr31& name)
|
|
|
|
|
{
|
|
|
|
|
StringHandle strHand = (StringHandle) GetDBResource('STR ', id + kFirstProfileID);
|
|
|
|
|
if (strHand) {
|
|
|
|
|
SetString(strHand, name);
|
|
|
|
|
ChangedResource((Handle) strHand);
|
|
|
|
|
ReleaseResource((Handle) strHand);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CUserProfileDB::SetProfileData(short id)
|
|
|
|
|
{
|
|
|
|
|
Handle hProfileData;
|
|
|
|
|
ProfileDataHeader profileHeader;
|
|
|
|
|
short int dataLength;
|
|
|
|
|
long int dataOffset;
|
|
|
|
|
CStr255 userName;
|
|
|
|
|
CStr255 emailName;
|
|
|
|
|
XP_Bool addResource = false;
|
|
|
|
|
|
|
|
|
|
id += kFirstProfileID; // In order to allow this method to be called from
|
|
|
|
|
// outside the class, we have to allow the value in to
|
|
|
|
|
// be a "raw" profile number (i.e., as returned by
|
|
|
|
|
// GetLastProfile);
|
|
|
|
|
|
|
|
|
|
emailName = CPrefs::GetString(CPrefs::UserEmail);
|
|
|
|
|
userName = CPrefs::GetString(CPrefs::UserName);
|
|
|
|
|
|
|
|
|
|
profileHeader.count = 2;
|
|
|
|
|
profileHeader.firstOffset = sizeof(ProfileDataHeader);
|
|
|
|
|
|
|
|
|
|
/* (the +1 is for the null terminator for each string) */
|
|
|
|
|
profileHeader.nameLength = userName.Length() + 1;
|
|
|
|
|
profileHeader.emailLength = emailName.Length() + 1;
|
|
|
|
|
|
|
|
|
|
/* First, compute the length of the resource */
|
|
|
|
|
dataLength = sizeof(ProfileDataHeader) + profileHeader.nameLength + profileHeader.emailLength;
|
|
|
|
|
|
|
|
|
|
/* See if we're replacing or adding */
|
|
|
|
|
hProfileData = GetDBResource('DATA', id);
|
|
|
|
|
|
|
|
|
|
if (hProfileData) {
|
|
|
|
|
SetHandleSize(hProfileData, dataLength);
|
|
|
|
|
if (MemError() == noErr) {
|
|
|
|
|
XP_MEMSET(*hProfileData, '\0', dataLength);
|
|
|
|
|
} else {
|
|
|
|
|
ReleaseResource(hProfileData);
|
|
|
|
|
hProfileData = nil;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
hProfileData = NewHandleClear(dataLength);
|
|
|
|
|
addResource = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (hProfileData) {
|
|
|
|
|
dataOffset = 0;
|
|
|
|
|
|
|
|
|
|
HLock((Handle) hProfileData);
|
|
|
|
|
|
|
|
|
|
BlockMove(&profileHeader, *hProfileData, sizeof(ProfileDataHeader));
|
|
|
|
|
|
|
|
|
|
dataOffset = sizeof(ProfileDataHeader);
|
|
|
|
|
BlockMove(&(userName.fStr[1]), ((unsigned char *) *hProfileData) + dataOffset,
|
|
|
|
|
profileHeader.nameLength-1);
|
|
|
|
|
|
|
|
|
|
dataOffset += profileHeader.nameLength;
|
|
|
|
|
BlockMove(&(emailName.fStr[1]), ((unsigned char *) *hProfileData) + dataOffset,
|
|
|
|
|
profileHeader.emailLength-1);
|
|
|
|
|
|
|
|
|
|
HUnlock((Handle) hProfileData);
|
|
|
|
|
|
|
|
|
|
if (addResource) {
|
|
|
|
|
::AddResource(hProfileData, 'DATA', id, nil);
|
|
|
|
|
} else {
|
|
|
|
|
::ChangedResource(hProfileData);
|
|
|
|
|
::ReleaseResource(hProfileData);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Boolean CUserProfileDB::GetProfileAlias(short id, FSSpec& profileFolder, Boolean allowUserInteraction )
|
|
|
|
|
{
|
|
|
|
|
Boolean success = true;
|
|
|
|
|
AliasHandle a;
|
|
|
|
|
a = (AliasHandle) GetDBResource('alis', id + kFirstProfileID);
|
|
|
|
|
ThrowIfNil_(a);
|
|
|
|
|
|
|
|
|
|
Boolean changed;
|
|
|
|
|
OSErr err;
|
|
|
|
|
|
|
|
|
|
if ( allowUserInteraction )
|
|
|
|
|
{
|
|
|
|
|
err = ResolveAlias( NULL, a, &profileFolder, &changed );
|
|
|
|
|
|
|
|
|
|
// If the alias couldn't be resolved, give the user
|
|
|
|
|
// a chance to locate the profile folder
|
|
|
|
|
if (err < 0) {
|
|
|
|
|
success = false;
|
|
|
|
|
CStr255 errStr;
|
|
|
|
|
CStr31 profileName;
|
|
|
|
|
GetIndString(errStr, CUserProfile::kProfileStrings, CUserProfile::kBadAliasError);
|
|
|
|
|
GetProfileName(id, profileName);
|
|
|
|
|
StringParamText(errStr, profileName);
|
|
|
|
|
|
|
|
|
|
if (ErrorManager::PlainConfirm(errStr))
|
|
|
|
|
{
|
|
|
|
|
StandardFileReply reply;
|
|
|
|
|
reply.sfFile = CPrefs::GetFilePrototype(CPrefs::UsersFolder);
|
|
|
|
|
if ( CFilePicker::DoCustomGetFile(reply, CFilePicker::Folders, true) )
|
|
|
|
|
{
|
|
|
|
|
CFileMgr::CopyFSSpec(reply.sfFile, profileFolder);
|
|
|
|
|
Boolean changed;
|
|
|
|
|
err = UpdateAlias(nil, &reply.sfFile, a, &changed);
|
|
|
|
|
ThrowIfOSErr_(err);
|
|
|
|
|
ChangedResource((Handle) a);
|
|
|
|
|
success = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
short aliasCount = 1;
|
|
|
|
|
|
|
|
|
|
err = MatchAlias( NULL, kARMMountVol | kARMNoUI | kARMMultVols | kARMSearch | kARMSearchMore,
|
|
|
|
|
a, &aliasCount, &profileFolder, &changed, NULL, NULL );
|
|
|
|
|
if ( err < 0 )
|
|
|
|
|
success = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ReleaseResource((Handle) a);
|
|
|
|
|
|
|
|
|
|
return success;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// This will change the value of selectedID if it becomes out of bounds
|
|
|
|
|
void CUserProfileDB::DeleteProfile(short selectedID)
|
|
|
|
|
{
|
|
|
|
|
selectedID += kFirstProfileID;
|
|
|
|
|
// delete profile resources and move the subsequent
|
|
|
|
|
// resources down to fill the space
|
|
|
|
|
Handle toDelete = GetDBResource('STR ', selectedID);
|
|
|
|
|
if (toDelete)
|
|
|
|
|
RemoveResource(toDelete);
|
|
|
|
|
toDelete = GetDBResource('alis', selectedID);
|
|
|
|
|
if (toDelete)
|
|
|
|
|
RemoveResource(toDelete);
|
|
|
|
|
|
|
|
|
|
toDelete = GetDBResource('DATA', selectedID);
|
|
|
|
|
if (toDelete)
|
|
|
|
|
RemoveResource(toDelete);
|
|
|
|
|
|
|
|
|
|
int id = selectedID + 1;
|
|
|
|
|
Handle next = GetDBResource('STR ', id);
|
|
|
|
|
while (next) {
|
|
|
|
|
::SetResInfo(next, id - 1, nil);
|
|
|
|
|
|
|
|
|
|
next = GetDBResource('DATA', id);
|
|
|
|
|
if (next) {
|
|
|
|
|
::SetResInfo(next, id - 1, nil);
|
|
|
|
|
ReleaseResource(next);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
next = GetDBResource('alis', id);
|
|
|
|
|
if (next) {
|
|
|
|
|
::SetResInfo(next, id - 1, nil);
|
|
|
|
|
ReleaseResource(next);
|
|
|
|
|
}
|
|
|
|
|
// don't need to release strings because Populate uses them
|
|
|
|
|
next = GetDBResource('STR ', ++id);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Handle CUserProfileDB::GetDBResource(ResType theType, short theID)
|
|
|
|
|
{
|
|
|
|
|
StUseResFile resFile( fFile.GetResourceForkRefNum() );
|
|
|
|
|
|
|
|
|
|
return ::Get1Resource(theType, theID);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
|
*/
|
|
|
|
|
const int cmd_NextPane = 8000;
|
|
|
|
|
const int cmd_PrevPane = 8001;
|
|
|
|
|
|
|
|
|
|
CProfilePaneMonitor::CProfilePaneMonitor( CDialogWizardHandler* wizard )
|
|
|
|
|
{
|
|
|
|
|
fWizard = wizard;
|
|
|
|
|
fCopiedName = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// !! This needs some work.
|
|
|
|
|
void CProfilePaneMonitor::ListenToMessage( MessageT inMessage, void* /* ioParam */)
|
|
|
|
|
{
|
|
|
|
|
PaneIDT nameField;
|
|
|
|
|
Boolean onNameField = false;
|
|
|
|
|
LView* window;
|
|
|
|
|
|
|
|
|
|
window = fWizard->GetDialog();
|
|
|
|
|
|
|
|
|
|
LStdControl* next = (LStdControl*)window->FindPaneByID( 'ok ' );
|
|
|
|
|
LStdControl* back = (LStdControl*)window->FindPaneByID( 'back' );
|
|
|
|
|
CStr255 buttonTitle;
|
|
|
|
|
|
|
|
|
|
if (fWizard->CurrentPane() == userNamePane) {
|
|
|
|
|
nameField = 'name';
|
|
|
|
|
onNameField = true;
|
|
|
|
|
}
|
|
|
|
|
else if (fWizard->CurrentPane() == profileNamePane) {
|
|
|
|
|
nameField = 'pnam';
|
|
|
|
|
onNameField = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( next && ( inMessage == cmd_NextPane || inMessage == cmd_PrevPane ) )
|
|
|
|
|
{
|
|
|
|
|
if ( fWizard->CurrentPaneNumber() == fWizard->TotalPanes() )
|
|
|
|
|
{
|
|
|
|
|
LControl* radioNew = (LControl*)window->FindPaneByID( 'Rnew' );
|
|
|
|
|
LControl* radioExs = (LControl*)window->FindPaneByID( 'Rexs' );
|
|
|
|
|
LPane* vnorm = (LView*)window->FindPaneByID('Vnor');
|
|
|
|
|
LPane* vexs = (LView*)window->FindPaneByID('Vexs');
|
|
|
|
|
LPane* vnew = (LView*)window->FindPaneByID('Vnew');
|
|
|
|
|
|
|
|
|
|
vnorm->Hide();
|
|
|
|
|
vexs->Hide();
|
|
|
|
|
vnew->Hide();
|
|
|
|
|
if ( radioExs && radioExs->GetValue() )
|
|
|
|
|
{
|
|
|
|
|
GetIndString( buttonTitle, CUserProfile::kProfileStrings, CUserProfile::kCreateProfileLabel );
|
|
|
|
|
vexs->Show();
|
|
|
|
|
}
|
|
|
|
|
else if ( radioNew && radioNew->GetValue() )
|
|
|
|
|
{
|
|
|
|
|
//GetIndString( buttonTitle, CUserProfile::kProfileStrings, CUserProfile::kDoneLabel );
|
|
|
|
|
GetIndString( buttonTitle, CUserProfile::kProfileStrings, CUserProfile::kRunASLabel );
|
|
|
|
|
vnew->Show();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
GetIndString( buttonTitle, CUserProfile::kProfileStrings, CUserProfile::kDoneLabel );
|
|
|
|
|
vnorm->Show();
|
|
|
|
|
}
|
|
|
|
|
next->SetDescriptor( buttonTitle );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
GetIndString( buttonTitle, CUserProfile::kProfileStrings, CUserProfile::kNextLabel );
|
|
|
|
|
next->SetDescriptor( buttonTitle );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( back && ( inMessage == cmd_NextPane || inMessage == cmd_PrevPane ) )
|
|
|
|
|
{
|
|
|
|
|
if ( fWizard->CurrentPaneNumber() == LArray::index_First )
|
|
|
|
|
back->Disable();
|
|
|
|
|
else
|
|
|
|
|
back->Enable();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// copy profile name to folder name, unless the user has changed
|
|
|
|
|
// the path or we're creating the default profile
|
|
|
|
|
if ( inMessage == cmd_NextPane && fWizard->CurrentPane() == profileFolderPane )
|
|
|
|
|
{
|
|
|
|
|
CStr31 profileName;
|
|
|
|
|
fWizard->GetEditText('pnam', profileName);
|
|
|
|
|
StripColons(profileName);
|
|
|
|
|
CFilePicker* picker = (CFilePicker*) fWizard->GetDialog()->FindPaneByID('fold');
|
|
|
|
|
if (picker && !picker->WasSet()) {
|
|
|
|
|
FSSpec folder = picker->GetFSSpec();
|
|
|
|
|
LString::CopyPStr(profileName, folder.name, 32);
|
|
|
|
|
|
|
|
|
|
CUserProfile::GetUniqueFolderName(folder);
|
|
|
|
|
picker->SetFSSpec(folder, false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// copy user name to profile name (only do this once)
|
|
|
|
|
else if ( inMessage == cmd_NextPane && fWizard->CurrentPane() == profileNamePane
|
|
|
|
|
&& !fCopiedName)
|
|
|
|
|
{
|
|
|
|
|
CStr31 profileName;
|
|
|
|
|
fWizard->GetEditText('name', profileName);
|
|
|
|
|
StripColons(profileName);
|
|
|
|
|
if (profileName.Length() > kStr31Len)
|
|
|
|
|
profileName.Length() = kStr31Len;
|
|
|
|
|
fWizard->SetEditText('pnam', profileName);
|
|
|
|
|
fCopiedName = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// select Name field
|
|
|
|
|
if (onNameField && (inMessage == cmd_NextPane || inMessage == cmd_PrevPane)) {
|
|
|
|
|
LEditField* field = (LEditField*) fWizard->GetDialog()->FindPaneByID(nameField);
|
|
|
|
|
if (field) {
|
|
|
|
|
field->SwitchTarget(field);
|
|
|
|
|
field->SelectAll();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// disable Next button if user hasn't entered name
|
|
|
|
|
if (onNameField)
|
|
|
|
|
{
|
|
|
|
|
CStr255 text;
|
|
|
|
|
fWizard->GetEditText( nameField, text );
|
|
|
|
|
if ( text.Length() == 0 )
|
|
|
|
|
fWizard->DisableNextButton();
|
|
|
|
|
else
|
|
|
|
|
fWizard->EnableNextButton();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
fWizard->EnableNextButton();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
CDialogWizardHandler::CDialogWizardHandler( ResIDT dlogID, LArray& paneList ):
|
|
|
|
|
fDialog( dlogID, CFrontApp::GetApplication() ), fPaneList( paneList )
|
|
|
|
|
{
|
|
|
|
|
ArrayIndexT index;
|
|
|
|
|
PaneIDT paneID;
|
|
|
|
|
LView* pane;
|
|
|
|
|
|
|
|
|
|
index = LArray::index_First;
|
|
|
|
|
|
|
|
|
|
fCurrentPane = LArray::index_First;
|
|
|
|
|
fListener = nil;
|
|
|
|
|
|
|
|
|
|
LWindow* window = fDialog.GetDialog();
|
|
|
|
|
ThrowIfNil_( window );
|
|
|
|
|
|
|
|
|
|
for ( index = LArray::index_First; index <= fPaneList.GetCount(); index++ )
|
|
|
|
|
{
|
|
|
|
|
fPaneList.FetchItemAt( index, &paneID );
|
|
|
|
|
LView::SetDefaultView( window );
|
|
|
|
|
if ( GetResource( 'PPob', paneID ) == nil )
|
|
|
|
|
break;
|
|
|
|
|
pane = (LView*)UReanimator::ReadObjects( 'PPob', paneID );
|
|
|
|
|
if ( pane )
|
|
|
|
|
{
|
|
|
|
|
if ( index != LArray::index_First )
|
|
|
|
|
pane->Hide();
|
|
|
|
|
pane->Enable();
|
|
|
|
|
pane->FinishCreate();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PaneIDT CDialogWizardHandler::CurrentPane()
|
|
|
|
|
{
|
|
|
|
|
PaneIDT paneID;
|
|
|
|
|
fPaneList.FetchItemAt( fCurrentPane, &paneID );
|
|
|
|
|
return paneID;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ArrayIndexT CDialogWizardHandler::CurrentPaneNumber()
|
|
|
|
|
{
|
|
|
|
|
return fCurrentPane;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ArrayIndexT CDialogWizardHandler::TotalPanes()
|
|
|
|
|
{
|
|
|
|
|
return fPaneList.GetCount();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDialogWizardHandler::AddListener(LListener* st)
|
|
|
|
|
{
|
|
|
|
|
fListener = st;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Boolean CDialogWizardHandler::DoWizard()
|
|
|
|
|
{
|
|
|
|
|
Boolean cancelled = false;
|
|
|
|
|
LWindow* window = fDialog.GetDialog();
|
|
|
|
|
ShowPane( fCurrentPane, window );
|
|
|
|
|
|
|
|
|
|
Boolean done = false;
|
|
|
|
|
while ( !done )
|
|
|
|
|
{
|
|
|
|
|
MessageT hit = fDialog.DoDialog();
|
|
|
|
|
|
|
|
|
|
switch ( hit )
|
|
|
|
|
{
|
|
|
|
|
case cmd_NextPane:
|
|
|
|
|
done = ShowPane( fCurrentPane + 1, window );
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case cmd_PrevPane:
|
|
|
|
|
done = ShowPane( fCurrentPane - 1, window );
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case msg_Cancel:
|
|
|
|
|
cancelled = done = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if ( !done && fListener )
|
|
|
|
|
fListener->ListenToMessage( hit, nil );
|
|
|
|
|
}
|
|
|
|
|
return !cancelled;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Boolean CDialogWizardHandler::ShowPane( ArrayIndexT paneNum, LWindow* window )
|
|
|
|
|
{
|
|
|
|
|
PaneIDT paneID;
|
|
|
|
|
|
|
|
|
|
if ( paneNum < LArray::index_First )
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if ( paneNum != fCurrentPane )
|
|
|
|
|
{
|
|
|
|
|
fPaneList.FetchItemAt( fCurrentPane, &paneID );
|
|
|
|
|
LPane* pane = window->FindPaneByID( paneID );
|
|
|
|
|
if ( pane )
|
|
|
|
|
pane->Hide();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fCurrentPane = paneNum;
|
|
|
|
|
if ( paneNum > fPaneList.GetCount() )
|
|
|
|
|
return true;
|
|
|
|
|
fPaneList.FetchItemAt( paneNum, &paneID );
|
|
|
|
|
LPane* pane = window->FindPaneByID( paneID );
|
|
|
|
|
if ( pane )
|
|
|
|
|
pane->Show();
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDialogWizardHandler::EnableNextButton()
|
|
|
|
|
{
|
|
|
|
|
LWindow* window = fDialog.GetDialog();
|
|
|
|
|
if ( window )
|
|
|
|
|
{
|
|
|
|
|
LStdControl* next = (LStdControl*)window->FindPaneByID( 'ok ' );
|
|
|
|
|
if ( next )
|
|
|
|
|
next->Enable();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDialogWizardHandler::DisableNextButton()
|
|
|
|
|
{
|
|
|
|
|
LWindow* window = fDialog.GetDialog();
|
|
|
|
|
if ( window )
|
|
|
|
|
{
|
|
|
|
|
LStdControl* next = (LStdControl*)window->FindPaneByID( 'ok ' );
|
|
|
|
|
if ( next )
|
|
|
|
|
next->Disable();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LWindow* CDialogWizardHandler::GetDialog()
|
|
|
|
|
{
|
|
|
|
|
return fDialog.GetDialog();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDialogWizardHandler::SetEditText(PaneIDT paneID, const CString& text)
|
|
|
|
|
{
|
|
|
|
|
LWindow* window = fDialog.GetDialog();
|
|
|
|
|
if (window) {
|
|
|
|
|
LEditField* field = (LEditField*) window->FindPaneByID(paneID);
|
|
|
|
|
if (field) {
|
|
|
|
|
field->SetDescriptor(text);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDialogWizardHandler::GetEditText(PaneIDT paneID, CString& text)
|
|
|
|
|
{
|
|
|
|
|
LWindow* window = fDialog.GetDialog();
|
|
|
|
|
if (window) {
|
|
|
|
|
LEditField* field = (LEditField*) window->FindPaneByID(paneID);
|
|
|
|
|
if (field) {
|
|
|
|
|
field->GetDescriptor(text);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDialogWizardHandler::SetCheckboxValue(PaneIDT paneID, const Boolean value)
|
|
|
|
|
{
|
|
|
|
|
LWindow* window = fDialog.GetDialog();
|
|
|
|
|
if (window) {
|
|
|
|
|
LControl* checkbox = (LControl*) window->FindPaneByID(paneID);
|
|
|
|
|
if (checkbox) {
|
|
|
|
|
checkbox->SetValue((Int32)value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Boolean CDialogWizardHandler::GetCheckboxValue(PaneIDT paneID)
|
|
|
|
|
{
|
|
|
|
|
LWindow* window = fDialog.GetDialog();
|
|
|
|
|
if (window) {
|
|
|
|
|
LControl* checkbox = (LControl*) window->FindPaneByID(paneID);
|
|
|
|
|
if (checkbox) {
|
|
|
|
|
return (Boolean)checkbox->GetValue();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|