Code Search for Developers
 
 
  

login_screen.tcl from aMSN at Krugle


Show login_screen.tcl syntax highlighted


::Version::setSubversionId {$Id: login_screen.tcl 8879 2007-06-28 06:26:38Z baaazen $}

package require contentmanager
package require scalable-bg

snit::widgetadaptor loginscreen {

	option	-font	-default splainf

	variable after_id
	variable accept_userSelected 1

	variable background_tag

	variable lang_button_icon
	variable lang_button_text

	component dp_label
	variable dp_label_tag

	component user_label
	component user_field
	variable user_field_tag

	component pass_label
	component pass_field
	variable pass_field_tag

	component status_label
	component status_field
	variable status_field_tag

	component rem_me_field
	variable forget_me_label
	component rem_pass_field
	component auto_login_field

	component login_button
	component login_button_background
	variable login_button_tag

	component forgot_pass_link
	component service_status_link
	component new_account_link

	component check_ver_icon
	component check_ver_text

	variable more_label

	variable remember_me 0

	delegate method * to hull except {SortElements PopulateStateList LoginButtonPressed CanvasTextToLink LinkClicked LoggingIn ShowMore}
	delegate option * to hull except -font


	typeconstructor {
		::Event::registerEvent loggedOut all [list ::loginscreen LoggingOut]
		::Event::registerEvent show_login_screen all [list ::loginscreen LoggingOut]
	}

	constructor { args } {
		# Set up after_id array entries
		array set after_id {checkUser {} PosBg {} Sort {}}

		# Create canvas
		installhull using canvas -background [::skin::getKey loginbg] -highlightthickness 0 -xscrollcommand "$self CanvasScrolled" -yscrollcommand "$self CanvasScrolled"

		# Parse and apply creation-time options
		$self configurelist $args

		# Create background image
		set background_tag [$self create image 0 0 -anchor se -image [::skin::loadPixmap back]]

		# Create framework for elements
		contentmanager add group login_screen				-orient vertical	-widget $self
		contentmanager add group login_screen lang			-orient horizontal	-widget $self	-ipadx 4	-ipady 4
		contentmanager add group login_screen main			-orient vertical	-widget $self	-align center 	-pady 16
		contentmanager add group login_screen main dp			-orient horizontal	-widget $self	-align center
		contentmanager add group login_screen main fields 		-orient vertical	-widget $self	-pady 4		-align center
		contentmanager add group login_screen main fields user		-orient vertical	-widget $self	-pady 4		-align center
		contentmanager add group login_screen main fields pass		-orient vertical	-widget $self	-pady 4		-align center
		contentmanager add group login_screen main fields status	-orient vertical	-widget $self	-pady 4		-align center
		contentmanager add group login_screen main checkboxes 		-orient vertical	-widget $self
		contentmanager add group login_screen main checkboxes rem_me	-orient horizontal	-widget $self	-pady 2
		contentmanager add group login_screen main checkboxes forget_me	-orient horizontal	-widget $self	-pady 2		-padx 32
		contentmanager add group login_screen main checkboxes rem_pass	-orient horizontal	-widget $self	-pady 2
		contentmanager add group login_screen main checkboxes auto_login -orient horizontal	-widget $self	-pady 2
		contentmanager add group login_screen main login		-orient horizontal	-widget $self	-align center	-pady 8
		contentmanager add group login_screen main links		-orient vertical	-pady 32	-widget $self	-align left
		contentmanager add group login_screen main check_ver		-orient horizontal	-pady 8		-widget $self	-align center
		contentmanager add group login_screen main more			-orient horizontal	-pady 8		-widget $self	-align right

		# Create widgets
		# Language button
		set lang_button_icon [$self create image 0 0 -anchor nw -image [::skin::loadPixmap globe]]
		set lang_button_text [$self create text 0 0 -anchor nw -text [trans language] -fill [::skin::getKey loginurlfg]]
		# Display picture
		set dp_label [label $self.dp -image [::skin::getDisplayPicture ""] -borderwidth 1 -highlightthickness 0 -relief solid]
		set dp_label_tag [$self create window 0 0 -anchor nw -window $dp_label]
		# Username
		set user_label_tag [$self create text 0 0 -anchor nw -text "[trans user]:" -fill [::skin::getKey loginfg]]
		set user_field [combobox::combobox $self.user -editable true -relief solid -width 25 -command "$self UserSelected" -background [::skin::getKey loginwidgetbg]]
		set user_field_tag [$self create window 0 0 -anchor nw -window $user_field]
		# Password
		set pass_label_tag [$self create text 0 0 -anchor nw -text "[trans pass]:" -fill [::skin::getKey loginfg]]
		set pass_field [entry $self.pass -show "*" -relief solid -width 25 -vcmd {expr {[string length %P] <= 16} } -validate key -background [::skin::getKey loginwidgetbg]]
		set pass_field_tag [$self create window 0 0 -anchor nw -window $pass_field]
		# Status
		set status_label_tag [$self create text 0 0 -anchor nw -text "[trans signinstatus]:" -fill [::skin::getKey loginfg]]
		set status_field [combobox::combobox $self.status -editable true -relief solid -width 25 -command remember_state_list -background [::skin::getKey loginwidgetbg]]
		set status_field_tag [$self create window 0 0 -anchor nw -window $status_field]
		# Options
		# Remember me
		set rem_me_label_tag [$self create text 0 0 -anchor nw -text [trans rememberaccount] -fill [::skin::getKey loginfg]]
		set rem_me_field [checkbutton $self.rem_me -variable [myvar remember_me] -background [::skin::getKey loginbg]]
		set rem_me_field_tag [$self create window 0 0 -anchor nw -window $rem_me_field]
		# Forget me
		set forget_me_label [$self create text 0 0 -anchor nw -text [trans forget_me] -fill [::skin::getKey loginfg]]
		# Remember password
		set rem_pass_label_tag [$self create text 0 0 -anchor nw -text [trans rememberpass] -fill [::skin::getKey loginfg]]
		set rem_pass_field [checkbutton $self.rem_pass -variable [::config::getVar save_password] -background [::skin::getKey loginbg] -command [list $self ValidateCheckbuttonsSP]]
		set rem_pass_field_tag [$self create window 0 0 -anchor nw -window $rem_pass_field]
		# Log in automatically
		set auto_login_label_tag [$self create text 0 0 -anchor nw -text [trans autoconnect] -fill [::skin::getKey loginfg]]
		set auto_login_field [checkbutton $self.auto_login -variable [::config::getVar autoconnect] -background [::skin::getKey loginbg] -command [list $self ValidateCheckbuttonsAC]]
		set auto_login_field_tag [$self create window 0 0 -anchor nw -window $auto_login_field]

		set login_button_background [scalable-bg ::$self.login.bg -source [::skin::loadPixmap loginbutton] \
			-n [::skin::getKey loginbuttony 1] -e [::skin::getKey loginbuttonx 1] \
			-s [::skin::getKey loginbuttony 1] -w [::skin::getKey loginbuttonx 1] \
			-resizemethod [::skin::getKey loginbuttonresize "tile"]]

		# Login button
		set login_button [button $self.login \
				-text [trans login] \
				-image [::skin::loadPixmap nullimage] \
				-background [::skin::getKey loginbuttonbg] \
				-activebackground [::skin::getKey loginbuttonbg] \
				-foreground [::skin::getKey loginbuttonfg] \
				-activeforeground [::skin::getKey loginbuttonfghover] \
				-command [list $self LoginFormSubmitted] -cursor hand2 \
				-bd 0 -relief flat -font sboldf -highlightthickness 0 \
				-pady 0 -padx 0 -overrelief flat -compound center]

		bind $login_button <Configure> [list $self ResizeLoginButton %w %h]
		bind $login_button <Destroy> [list $login_button_background destroy]
		bind $login_button <Enter> \
			[list $login_button_background configure -source [::skin::loadPixmap loginbutton_hover]]
		bind $login_button <Leave> \
			[list $login_button_background configure -source [::skin::loadPixmap loginbutton]]

		set login_button_tag [$self create window 0 0 -anchor nw -window $login_button]
		# Useful links
		# Forgot password
		set forgot_pass_link [$self create text 0 0 -anchor nw -text [trans forgot_pass]]
		# Service status
		set service_status_link [$self create text 0 0 -anchor nw -text [trans msnstatus]]
		# New account
		set new_account_link [$self create text 0 0 -anchor nw -text [trans new_account]]
		# Check for newer amsn version
		set check_version_icon [$self create image 0 0 -anchor nw -image [::skin::loadPixmap download]]
		set check_version_text [$self create text 0 0 -anchor nw -text [trans checkver] -fill [::skin::getKey loginurlfg]]

		set more_label [$self create text 0 0 -anchor nw -text [trans more]]

		# Place widgets in framework
		# Language button
		contentmanager add element login_screen lang icon -widget $self -tag $lang_button_icon -valign middle -padx 8
		contentmanager add element login_screen lang text -widget $self -tag $lang_button_text -valign middle
		# Display picture
		contentmanager add element login_screen main dp label -widget $self -tag $dp_label_tag
		# Username
		contentmanager add element login_screen main fields user label -widget $self -tag $user_label_tag
		contentmanager add element login_screen main fields user field -widget $self -tag $user_field_tag
		# Password
		contentmanager add element login_screen main fields pass label -widget $self -tag $pass_label_tag
		contentmanager add element login_screen main fields pass field -widget $self -tag $pass_field_tag
		# Status
		contentmanager add element login_screen main fields status label -widget $self -tag $status_label_tag
		contentmanager add element login_screen main fields status field -widget $self -tag $status_field_tag
		# Options
		contentmanager add element login_screen main checkboxes rem_me field -widget $self -tag $rem_me_field_tag -padx 2 -valign middle
		contentmanager add element login_screen main checkboxes rem_me label -widget $self -tag $rem_me_label_tag -padx 4 -valign middle
		contentmanager add element login_screen main checkboxes forget_me	label	-widget $self	-tag $forget_me_label
		contentmanager add element login_screen main checkboxes rem_pass field -widget $self -tag $rem_pass_field_tag -padx 2 -valign middle
		contentmanager add element login_screen main checkboxes rem_pass label -widget $self -tag $rem_pass_label_tag -padx 2 -valign middle
		contentmanager add element login_screen main checkboxes auto_login field -widget $self -tag $auto_login_field_tag -padx 2 -valign middle
		contentmanager add element login_screen main checkboxes auto_login label -widget $self -tag $auto_login_label_tag -padx 2 -valign middle
		# Login button
		contentmanager add element login_screen main login login_button -widget $self -tag $login_button_tag
		# Links
		contentmanager add element login_screen main links forgot_pass -widget $self -tag $forgot_pass_link -pady 2
		contentmanager add element login_screen main links service_status -widget $self -tag $service_status_link -pady 2
		contentmanager add element login_screen main links new_account -widget $self -tag $new_account_link -pady 2
		contentmanager add element login_screen main check_ver icon -widget $self -tag $check_version_icon -padx 4 -valign middle
		contentmanager add element login_screen main check_ver text -widget $self -tag $check_version_text -padx 4 -valign middle
		contentmanager add element login_screen main more label	-widget $self	-tag $more_label

		# Set font for canvas all text items
		set all_tags [$self find all]
		foreach tag $all_tags {
			if { [$self type $tag] == "text" } {
				$self itemconfigure $tag -font splainf
			}
		}

		# Make checkbuttons look nice
		foreach checkbutton [list $rem_me_field $rem_pass_field $auto_login_field] {
			if {[OnMac]} {
				# Checkbuttons already look nice for us.
				$checkbutton configure -relief flat -highlightthickness 0 -bd 0 -bg [::skin::getKey loginbg] -selectcolor [::skin::getKey logincheckfg]
			} else {
				$checkbutton configure -relief flat -highlightthickness 0 -bd 0 \
					-bg [::skin::getKey loginbg] -selectcolor [::skin::getKey logincheckfg] \
					-image [::skin::loadPixmap checkbox] -selectimage [::skin::loadPixmap checkbox_on] -indicatoron 0
			}
		}

		# Bindings
		# Geometry events
		bind $self <Map> "$self WidgetResized"
		bind $self <Configure> "$self WidgetResized"
		# Bind language button
		contentmanager bind login_screen lang <ButtonRelease-1> "::lang::show_languagechoose"
		contentmanager bind login_screen lang <Enter> "$self configure -cursor hand2"
		contentmanager bind login_screen lang <Leave> "$self configure -cursor left_ptr"
		# Catch hand-editing of username field
		bind $user_field <KeyRelease> "$self UsernameEdited"
		# Bind <Return> on password field to submit login form
		bind $pass_field <Return> "$self LoginFormSubmitted"
		# Make checkbutton labels clickable
		contentmanager bind login_screen main checkboxes rem_me label <ButtonPress-1> "$rem_me_field invoke"
		contentmanager bind login_screen main checkboxes rem_pass label <ButtonPress-1> "$rem_pass_field invoke"
		contentmanager bind login_screen main checkboxes auto_login label <ButtonPress-1> "$auto_login_field invoke"
		# Make text items into links
		$self CanvasTextToLink login_screen main checkboxes forget_me label "$self ForgetMe"
		$self CanvasTextToLink login_screen main more label "$self ShowMore"
		$self CanvasTextToLink login_screen main links forgot_pass [list launch_browser "https://accountservices.passport.net/uiresetpw.srf?lc=1033"]
		$self CanvasTextToLink login_screen main links service_status [list launch_browser "http://messenger.msn.com/Status.aspx"]
		$self CanvasTextToLink login_screen main links new_account [list launch_browser "https://accountservices.passport.net/reg.srf?sl=1&lc=1033"]
		$self CanvasTextToLink login_screen main check_ver text "::autoupdate::check_version"

		$self FillLoginFields

		# Register for events
		::Event::registerEvent loggingIn all [list $self LoggingIn]
		::Event::registerEvent reconnecting all [list $self LoggingIn]
		::Event::registerEvent profileCreated all [list $self profileCreated]
		::Event::registerEvent profileDeleted all [list $self profileDeleted]

		if { [$user_field get] == "" } {
			catch {focus -force $user_field}
		} else {
			catch {focus -force $pass_field}
			
		}
	}

	destructor {
		catch { contentmanager delete login_screen }
		foreach {name id} [array get after_id] {
			after cancel $id
		}
		# Unregister for events
		::Event::unregisterEvent loggingIn all [list $self LoggingIn]
		::Event::unregisterEvent reconnecting all [list $self LoggingIn]
		::Event::unregisterEvent profileCreated all [list $self profileCreated]
		::Event::unregisterEvent profileDeleted all [list $self profileDeleted]
	}

	method ResizeLoginButton {width height} {
		#Don't put {} here for expr as we need to substitute in the current context
		$login_button_background configure -width [expr $width+2*[::skin::getKey loginbuttonx 1]] \
			-height [expr $height+2*[::skin::getKey loginbuttony 1]]
		bind $login_button <Configure> ""
		$login_button configure -image [$login_button_background name]
	}

	# ------------------------------------------------------------------------------------------------------------
	# WidgetResized
	# Called when canvas is resized. Calls methods to do things dependent on size of window
	# Called by: Binding
	method WidgetResized {} {
		# Keep background in bottom right corner
		after cancel $after_id(PosBg)
		set after_id(PosBg) [after 10 [list $self AutoPositionBackground]]
		# Resize input fields
		$self AutoResizeInputFields
		# Arrange items on the canvas
		after cancel $after_id(Sort)
		set after_id(Sort) [after 10 [list $self SortElements]]
	}

	# ------------------------------------------------------------------------------------------------------------
	# 
	method CanvasScrolled { args } {
		# Keep background in bottom right corner
		#$self AutoPositionBackground
	}

	# ------------------------------------------------------------------------------------------------------------
	# AutoPositionBackground
	# Places the background in its correct place on the canvas
	# Called by: WidgetResized
	method AutoPositionBackground {} {
		set bg_x [expr {round([expr {[winfo width $self] - 5}])}]
		set bg_y [expr {round([expr {[winfo height $self] - 5}])}]
		$self coords $background_tag $bg_x $bg_y
	}

	# ------------------------------------------------------------------------------------------------------------
	# AutoResizeInputFields
	# Resizes input fields (username, password and status) based on the canvas's size
	# Called by: WidgetResized
	method AutoResizeInputFields {} {
		# Get window's width
		set win_width [winfo width $self]
		# Set field width to 3/4 of window's width
		set field_width [expr {round($win_width * 0.75)}]
		# Get the maximum width we want the fields (approx. 35 characters wide)
		set max_field_width [expr {[font measure $options(-font) -displayof $user_field "_"] * 35}]
		# Enforce maximum width
		if { $field_width > $max_field_width } {
			set field_width $max_field_width
		}
		# Resize fields
		foreach tag [list $user_field_tag $pass_field_tag $status_field_tag] {
			$self itemconfigure $tag -width $field_width
		}
	}

	# ------------------------------------------------------------------------------------------------------------
	# FillLoginFields
	# Fills in login fields
	# Called by: constructor, profileDeleted
	method FillLoginFields { } {
		# Fill in usernames and states
		$user_field list delete 0 end
		$self PopulateUserList
		$user_field delete 0 end
		$user_field insert end [::config::getKey login]
		$self UsernameEdited
		$self PopulateStateList
	}

	# ------------------------------------------------------------------------------------------------------------
	# PopulateUserList
	# Add profiles to user combobox
	# Called by: FillLoginFields
	method PopulateUserList { } {
		# Populate user list
		LoadLoginList 1
		set tmp_list ""
		$user_field list delete 0 end
		set idx 0
		while { [LoginList get $idx] != 0 } {
			lappend tmp_list [LoginList get $idx]
			incr idx
		}
		eval $user_field list insert end $tmp_list
	}

	# ------------------------------------------------------------------------------------------------------------
	# PopulateStateList
	# Add normal and custom states to list of available sign-in states
	# Called by: constructor, UserSelected
	method PopulateStateList {} {
		# Make the list editable
		$status_field configure -editable true
		# Standard states
		$status_field list delete 0 end
		set i 0
		while { $i < 8 } {
			set statecode "[::MSN::numberToState $i]"
			set description "[trans [::MSN::stateToDescription $statecode]]"
			$status_field list insert end $description
			incr i
		}
		# Custom states
		AddStatesToList $status_field
		# Make it non-editable
		$status_field configure -editable false
		# Select remembered state
		$status_field select [get_state_list_idx [::config::getKey connectas]]
	}

	# ------------------------------------------------------------------------------------------------------------
	# CanvasTextToLink
	# Makes a canvas text into a blue link with a command binding
	# Called by: constructor
	method CanvasTextToLink { args } {
		# Get path for contentmanager item
		set tree [lrange $args 0 end-1]
		# Get "link"'s command
		set cmd [list [lindex $args end]]
		# Get the canvas tag
		set canvas_tag [eval contentmanager cget $tree -tag]
		# Bind the tag
		eval contentmanager bind $tree <Enter> [list "$self configure -cursor hand2"]
		eval contentmanager bind $tree <Leave> [list "$self configure -cursor left_ptr"]
		eval contentmanager bind $tree <ButtonRelease-1> [list "$self LinkClicked $canvas_tag %x %y $cmd"]
		# Make it blue :)
		$self itemconfigure $canvas_tag -fill [::skin::getKey loginurlfg]
	}
	
	method ValidateCheckbuttonsAC { } {
		if { [::config::getKey autoconnect] == 1} {
			::config::setKey save_password 1
		} 
		if { [::config::getKey save_password] != 1} {
			::config::setKey autoconnect 0
		}
	}
	method ValidateCheckbuttonsSP { } {
		if { [::config::getKey save_password] != 1} {
			::config::setKey autoconnect 0
		}
		if { [::config::getKey autoconnect] == 1} {
			::config::setKey save_password 1
		} 
	}

	# ------------------------------------------------------------------------------------------------------------
	# LinkClicked
	# Checks that the ButtonRelease event happened inside the bounding box of the link and execute's its command if it does.
	# Called by: Various bindings
	method LinkClicked { tag x y cmd } {
		# Convert x and y to actual canvas coords, in case we've scrolled.
		set x [$self canvasx $x]
		set y [$self canvasy $y]
		# Get item's coords
		set item_coords [$self bbox $tag]
		# Check the ButtonRelease was within the link's bbox. If it was, execute the link's command
		if { $x > [lindex $item_coords 0] && $x < [lindex $item_coords 2] && $y > [lindex $item_coords 1] && $y < [lindex $item_coords 3] } {
			eval $cmd
		}
	}

	# ------------------------------------------------------------------------------------------------------------
	# SortElements
	# Arrange elements on the canvas
	# Called by: Binding
	method SortElements {} {

		# We need to show everything so that it calculates their sizes when it sorts them
 		contentmanager show login_screen lang
 		contentmanager show login_screen main
 		contentmanager show login_screen main dp
 		contentmanager show login_screen main fields
 		contentmanager show login_screen main checkboxes
 		contentmanager show login_screen main login
 		contentmanager show login_screen main links
 		contentmanager show login_screen main check_ver
 		contentmanager show login_screen main more

		# We sort to get the sizes of each element..
		contentmanager sort login_screen  -level r


		# Then we hide everything apart from the fields and the 'show' button
 		contentmanager hide login_screen lang
 		contentmanager show login_screen main
 		contentmanager hide login_screen main dp
 		contentmanager show login_screen main fields
 		contentmanager hide login_screen main checkboxes
 		contentmanager hide login_screen main login
 		contentmanager hide login_screen main links
 		contentmanager hide login_screen main check_ver
 		contentmanager show login_screen main more

 		set max [winfo height $self]


 		set current 0

		incr current [contentmanager height login_screen main fields]
		incr current [contentmanager cget login_screen main fields -pady]
		incr current [contentmanager cget login_screen main fields -pady]
		incr current [contentmanager height login_screen main login]
		incr current [contentmanager cget login_screen main login -pady]
		incr current [contentmanager cget login_screen main login -pady]
		incr current [contentmanager height login_screen main more]
		incr current [contentmanager cget login_screen main more -pady]
		incr current [contentmanager cget login_screen main more -pady]


		if { $current < $max } {
			contentmanager show login_screen main login
			incr current [contentmanager height login_screen main checkboxes]
			incr current [contentmanager cget login_screen main checkboxes -pady]
			incr current [contentmanager cget login_screen main checkboxes -pady]
			
			if { $current < $max } {
				contentmanager show login_screen main checkboxes
				
				incr current [contentmanager height login_screen main dp]
				incr current [contentmanager cget login_screen main dp -pady]
				incr current [contentmanager cget login_screen main dp -pady]
			
				if { $current < $max } {
					contentmanager show login_screen main dp
					
					incr current [contentmanager height login_screen lang]
					incr current [contentmanager cget login_screen lang -pady]
					incr current [contentmanager cget login_screen lang -pady]
			
					if { $current < $max } {
						contentmanager show login_screen lang

						incr current [contentmanager height login_screen main check_ver]
						incr current [contentmanager cget login_screen main check_ver -pady]
						incr current [contentmanager cget login_screen main check_ver -pady]
						
						if { $current < $max } {
							contentmanager show login_screen main check_ver

							if { [::config::getKey show_login_screen_links 1] } {
								incr current [contentmanager height login_screen main links]
								incr current [contentmanager cget login_screen main links -pady]
								incr current [contentmanager cget login_screen main links -pady]

								if { $current < $max } {
									contentmanager show login_screen main links
									contentmanager hide login_screen main more
								}
							} else {
								contentmanager hide login_screen main links
								contentmanager hide login_screen main more
							}
						}
					}
				}
			}
		} 

		set padx [expr {[winfo width $self] - [contentmanager width login_screen main]}]
		if { $padx < 0 } {
			set padx 0
		}
		contentmanager configure login_screen main -padx $padx
		contentmanager sort login_screen  -level r

		# TODO : this should be done by simply specifying a -padx or -ipadx to login_screen main.. I can't get it to work, I don't understand the damn contentmanager!
		#set main_x [expr {([winfo width $self] / 2) - ([contentmanager width login_screen main] / 2)}]
		#set main_y [expr {[contentmanager height login_screen lang] + 16}]
	 	#contentmanager coords login_screen main $main_x $main_y
		
	}

	# ------------------------------------------------------------------------------------------------------------
	# ShowMore
	# Show all elements on login screen and enlarge login window accordingly
	# Called by: Binding
	method ShowMore { } {
		# We need to show everything so that it calculates their sizes when it sorts them
 		contentmanager show login_screen lang
 		contentmanager show login_screen main
 		contentmanager show login_screen main dp
 		contentmanager show login_screen main fields
 		contentmanager show login_screen main checkboxes
 		contentmanager show login_screen main login
 		contentmanager show login_screen main links
 		contentmanager show login_screen main check_ver
 		contentmanager show login_screen main more

		# We sort to get the sizes of each element..
		contentmanager sort login_screen  -level r

		set h [contentmanager height login_screen]
		set w [contentmanager width login_screen]
		incr h [contentmanager cget login_screen -pady]
		incr h [contentmanager cget login_screen -pady]
		incr w [contentmanager cget login_screen -padx]
		incr w [contentmanager cget login_screen -padx]
	      
		set current_w [winfo width $self]
		set current_h [winfo height $self]

		set adjustment_w [expr {$w - $current_w}]
		set adjustment_h [expr {$h - $current_h}]
		
		set geometry [winfo geometry [winfo toplevel $self]]

		regexp {=?(\d+)x(\d+)[+\-](-?\d+)[+\-](-?\d+)} $geometry -> width height x y
		
		incr width $adjustment_w
		incr height $adjustment_h

		wm geometry [winfo toplevel $self] ${width}x${height}
	
	}

	# ------------------------------------------------------------------------------------------------------------
	# UsernameEdited
	# Called when the username field is edited
	# Called by: Binding
	method UsernameEdited {} {
		# Get username
		set username [$user_field get]
		# Don't let it check numbers, it'll try and load that number profile (e.g. 0 would load the first profile, 1 the second etc)
		if { [string is integer $username] } { set username "" }
		after cancel $after_id(checkUser)
		set after_id(checkUser) [after 100 [list $self CheckUsername "$username"]]
	}

	# ------------------------------------------------------------------------------------------------------------
	# CheckUsername
	# Check whether $username exists as an amsn profile. If so, switch to it and set up DP etc
	# Called by: UsernameEdited
	method CheckUsername { {username ""} } {
		# Check if the username has a profile.
		# If it does, switch to it, select the remember me box and set the DP.
		# If it doesn't, deselect the remember me box and set the DP to generic 'nopic' DP
		if { [LoginList exists 0 $username] } {
			$self UserSelected $user_field $username
		} else {
			# De-select 'remember me' field
			$rem_me_field deselect
			# Disable 'forget me' button
			$self itemconfigure $forget_me_label -fill [::skin::getKey disabledfg] -state disabled
			if { [::config::getGlobalKey disableprofiles] != 1 } {
				$rem_me_field configure -state normal
			}
			# If we've got a profile loaded, switch to default generic one
			if { [::config::getKey login] != "" } {
				# Switching to default profile, remove lock on previous profiles if needed
				SwitchToDefaultProfile
				# -------------------------------------------------------
				# Change DP
				$dp_label configure -image [::skin::getNoDisplayPicture]
			}
			# Blank password field
			$pass_field delete 0 end
		}
	}

	# ------------------------------------------------------------------------------------------------------------
	# UserSelected
	# Various changes to login screen after changing user, e.g display picture, password (if stored) etc
	# Called by: CheckUsername, loggedOut
	method UserSelected { combo user } {
		# This is needed here to make sure we change user only once per 100 ms, the reason behind it is that the combobox calls the -command (which is UserSelected)
		# on <FocusOut> so if we enter a profile in use by typing the address, then we'll get a 'profile in use' popup which generates a <FocusOut> which causes a second
		# popup to appear at the same time..
		if { $accept_userSelected == 0 } {
			return
		} else {
			set accept_userSelected 0
			after 100 "if \[info exists [myvar accept_userSelected]\] [list [list set [myvar accept_userSelected] 1]]"
		}

		# Don't let us use integers as username (see UsernameEdited)
		if { [string is integer $user] } { set user "" }
		# We have to check whether this profile exists because sometimes userSelected gets called when it shouldn't,
		# e.g when tab is pressed in the username combobox
		if { [LoginList exists 0 $user] } {
			# Select and disable 'remember me' checkbutton
			$rem_me_field select
			$rem_me_field configure -state disabled
			# Enable 'forget me' buttton
			$self itemconfigure $forget_me_label -fill [::skin::getKey loginurlfg] -state normal
			# Switch to this profile
			ConfigChange $combo $user
			# Get states
			$self PopulateStateList
			# Change DP
			$dp_label configure -image displaypicture_std_self
			# If we've remembered the password, insert it, if not, clear the password field
			if { [set [$rem_pass_field cget -variable]] } {
				global password
				$pass_field delete 0 end
				$pass_field insert end $password
			} else {
				$pass_field delete 0 end
			}
		} else {
			$pass_field delete 0 end
		}

		# Re-sort stuff on canvas (in case, for example, we now have a larger/smaller DP)
		# The 'after 100' is because the status combobox doesn't seem to regain it's height immediately for some
		# reason, so if we sort straight away, the checkbox below the status combo overlaps it.
		after cancel $after_id(Sort)
		set after_id(Sort) [after 100 [list $self SortElements]]
	}

	# ------------------------------------------------------------------------------------------------------------
	# ForgetMe
	# Dialog confirming user wants to delete current profile. Provides link to relevant section of preferences window.
	# Called by: Binding
	method ForgetMe {} {
		# Create dialog
		set w [toplevel .forgetme_dialog -width 400]
		wm title $w [trans delprofile]
		
		# Icon
		set icon [label $w.icon -image [::skin::loadPixmap info]]

		# Message
		set message [label $w.msg -text [trans howto_remove_profile [::config::getKey login]] -justify left]

		# Link to prefs "Others" page
		set link [label $w.link		-text			[trans goto_prefs_removeprofile] \
						-fg			blue \
						-font			splainf \
						-cursor			hand2 ]

		# Bind the clickable label 
		bind $w.link <Enter> "$w.link configure -font sunderf"
		bind $w.link <Leave> "$w.link configure -font splainf"
		bind $w.link <ButtonRelease> [list $self ForgetMeLinkClicked $w]

		# OK button
		set ok_button [button $w.ok -text [trans Ok] -command "destroy $w"]


		# Set widgets out using grid
		grid $icon	-row 0	-column	0	-sticky nw	-columnspan 1	-padx 4	-pady 4
		grid $message	-row 0	-column 1	-sticky new	-columnspan 1	-padx 4	-pady 4
		grid $link	-row 1	-column 1	-sticky new	-columnspan 2	-padx 4	-pady 4
		grid $ok_button	-row 2	-column 0	-sticky s	-columnspan 2	-padx 4	-pady 4 -ipadx 20

		grid columnconfigure	$w	1	-weight 1
		grid rowconfigure	$w	2	-weight 1

		# Make dialog transient
		wm transient $w $self

		# Make the dialog non-resizable
		wm resizable .forgetme_dialog 0 0

		# Raise dialog and put local grab on it
		raise $w
		grab set $w
	}

	# ------------------------------------------------------------------------------------------------------------
	# ForgetMeLinkClicked
	# Switches to default profile, clears login screen and opens preferences window at "Others" page so user can delete profile. Closes forget me dialog too.
	# Called by: Binding
	method ForgetMeLinkClicked { w } {
		# Switch to default profile so user can delete the current one
		SwitchToDefaultProfile
		# Open preferences window at "Others" page
		Preferences others

		# Remove grab on dialog and destroy it
		grab release $w
		destroy $w
	}

	# ------------------------------------------------------------------------------------------------------------
	# LoginFormSubmitted
	# Validates login data and logs in if all is fine. Creates profile if 'remember me' is selected and the profile doesn't already exist.
	# Called by: Various bindings
	method LoginFormSubmitted { } {
		# Get user and pass
		set user [$user_field get]
		set pass [$pass_field get]

		# remove spaces from username
		set user [string trim $user]

		# Check we actually have a username and password entered!
		if { $user == "" || $pass == "" } { return }

		# Check if username has a valid form
		if { ![regexp {^[[:alnum:]\._\-]+@[[:alnum:]]+[[:alnum:]\.\-]*\.[[:alnum:]]{2,4}$} $user] } { 
			msg_box "[trans invalidusername]"
			return 
		}
		
		# If remember me checkbutton is selected and a profile doesn't already exists for this user, create a profile for them.
		if { $remember_me && ![LoginList exists 0 $user] } {
			CreateProfile $user
		}

		# Login with them
		$self login $user $pass
	}

	# ------------------------------------------------------------------------------------------------------------
	# profileDeleted
	# Receives event when a profile is deleted and removes that profile from user list
	method profileDeleted { event email } {
		# Remove profile from user list
		for { set i 0 } { $i < [$user_field list size] } { incr i 1 } {
			if { [$user_field list get $i] == $email } {
				$user_field list delete $i
			}
		}

		# Fill login fields
		$self FillLoginFields
	}

	# ------------------------------------------------------------------------------------------------------------
	# Receives event when a profile is created and adds that profile to user list
	method profileCreated { event email } {
		# Add profile to user list
		$user_field list insert end $email
	}

	# ------------------------------------------------------------------------------------------------------------
	# login
	# Logs in with the current details
	# Called by: LoginFormSubmitted
	method login { user pass } {
		global password

		# Set username and password key and global respectively
		set password $pass
		if { !$remember_me || ![LoginList exists 0 $user] } {
			::config::setKey login [string tolower $user]
		}

		# Connect
		::MSN::connect $password
	}

	# ------------------------------------------------------------------------------------------------------------
	# logginIn
	# Receives the event fired by protocol. Unpacks this widget and packs the sign-in progress widget.
	method LoggingIn { event } {
		status_log "logging in, destroying loginscreen : $event "
		pack forget $self
		pack .main.f -expand true -fill both
		destroy $self
	}

	# ------------------------------------------------------------------------------------------------------------
	# loggedOut
	typemethod LoggingOut { event } {
		status_log "logging out, creating loginscreen : $event "
		# TODO : this is very ugly code... damn!
		if {! [winfo exists .main.loginscreen] } {
			loginscreen .main.loginscreen						
		}
		pack forget .main.f
		pack .main.loginscreen -e 1 -f both
	}

	# ------------------------------------------------------------------------------------------------------------
	# clear
	# Clears/deselects all fields on the login screen
	# Called by: 
	method clear { } {
		$user_field delete 0 end

		$self UsernameEdited
	}
}





See more files for this project here

aMSN

A very nice MSN compatible messenger application, aMSN Messenger is a multiplatform MSN messenger clone. Works pretty much like its Windows based counterpart. Perfect for keeping in touch with those friends who have not yet seen the light. Works on linux

Project homepage: http://sourceforge.net/projects/amsn
Programming language(s): C,C++,PHP,Tcl,XML
License: other

  autopackage/
    @tcl.sourceforge.net/
      tcl/
        skeleton.1
      tk/
        skeleton.1
    default.apspec
  debian/
    changelog.in
    compat
    control
    copyright
    dirs
    package.postinst
    package.postrm
    rules
  desktop-icons/
    128x128/
    16x16/
    22x22/
    32x32/
    48x48/
    64x64/
    72x72/
    96x96/
  docs/
    DOCS-HOWTO
    FAQbs
    FAQca
    FAQca_VC
    FAQde
    FAQdu
    FAQee
    FAQel
    FAQes
    FAQfr
    FAQfr.html
    FAQfr_CA
    FAQfur
    FAQhu
    FAQit
    FAQmn
    FAQnl
    FAQno
    FAQpt
    FAQpt_BR
    FAQsl
    FAQsv
    FAQtr
    HELPca
    HELPca_VC
    HELPcs
    HELPda
    HELPde
    HELPee
    HELPel
    HELPes
    HELPfr
    HELPfr_CA
    HELPfur
    HELPhu
    HELPit
    HELPmn
    HELPnl
    HELPno
    HELPpt
    HELPpt_BR
    HELPro
    HELPru
    HELPtr
    HELPzh_TW
    READMEca
    READMEca_VC
    READMEcs
    READMEda
    READMEde
    READMEes
    READMEfr
    READMEfr_CA
    READMEfur
    READMEhu
    READMEit
    READMEmn
    READMEnl
    READMEpt
    READMEpt_BR
    READMEro
    READMEru
    READMEsv
    READMEtr
    READMEzh_TW
  lang/
    LANG-HOWTO
    addkey.tcl
    complete.pl
    convert.tcl
    genlangfiles.c
    genpage.c
    lang1.tmpl
    lang2.tmpl
    lang3.tmpl
    langal
    langast
    langca
    langca_VC
    langchk.sh
    langcs
    langcy
    langda
    langde
    langee
    langel
    langen
    langes
    langeu
    langfi
    langfr
    langfr_CA
    langfri
    langglg
    langgr2
    langhu
    langid
    langis
    langit
    langko
    langlt
    langmk
    langnl
    langno
    langoc
    langpl
    langpt
    langpt_BR
    langro
    langru
    langsk
    langsl
    langsr
    langsv
    langtr
    langzh-CN
    langzh-TW
    missing.py
    sortlang
  plugins/
    Nudge/
    PowerTool/
    WebcamShooter/
    inkdraw/
    remind/
    winks/
  skins/
    default/
  utils/
    TkCximage/
    base64/
    bwidget1.8.0/
    combobox/
    contentmanager/
    dpbrowser/
    drawboard/
    framec/
    http2.4/
    linux/
    log/
    macosx/
    pixmapbutton/
    pixmapmenu/
    pixmapoption/
    pixmapprogbar/
    pixmapscroll/
    scalable-bg/
    sexytile/
    sha1/
  AGREEMENT
  AppMain.tcl
  BWidget_mods.tcl
  CREDITS
  Compile.mk
  FAQ
  GNUGPL
  HELP
  INSTALL
  Makefile.in
  README
  README.macosx
  TODO
  abook.tcl
  alarm.tcl
  amsn
  amsn-remote
  amsn-remote-CLI
  amsn.debianmenu
  amsn.desktop
  amsn.spec
  amsn_des.tcl
  amsncore.tcl
  assistant.tcl
  audio.tcl
  automsg.tcl
  autoupdate.tcl
  balloon.tcl
  bugs.tcl
  chatwindow.tcl
  clgui.tcl
  config.tcl
  configure
  configure.ac
  console.tcl
  contactlist.tcl
  ctthemes.tcl
  debug.tcl
  dock.tcl
  groups.tcl
  gui.tcl
  guicontactlist.tcl
  hotmail.tcl
  hotmlog.htm
  lang.tcl
  langlist
  login_screen.tcl
  loging.tcl
  migmd5.tcl
  msncam.tcl
  msnp2p.tcl
  mutex.tcl
  notes.tcl
  picture.tcl
  plugins.tcl
  pluginslog.tcl
  preferences.tcl
  progressbar.tcl
  protocol.tcl
  proxy.tcl
  remote.help
  remote.tcl
  searchdialog.tcl
  skins.tcl
  smileys.tcl
  soap.tcl
  socks.tcl
  spaces.tcl
  sxml.tcl
  trayicon.tcl