⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chatwindow.tcl

📁 Linux下的MSN聊天程序源码
💻 TCL
📖 第 1 页 / 共 5 页
字号:
##########################################    Chat Window code abstraction       ##           By Alberto D�z            ##########################################package require framecpackage require scalable-bgnamespace eval ::ChatWindow {	#///////////////////////////////////////////////////////////////////////////////	# Namespace variables, relative to chat windows' data. In the code are accessible	# through '::namespace::variable' syntax (to avoid local instances of the variable	# and have the scope more clear).	# As ::ChatWindow::winid is the index used in the	# window widgets for chat windows, we only initialize	# it at the first time, to avoid problems with proc	# reload_files wich will cause some bugs related to	# winid being 0 after some windows have been created.	if { $initialize_amsn == 1  } {		variable chat_ids		variable first_message		variable msg_windows		variable new_message_on		variable recent_message		variable titles		variable windows [list]		variable winid 0		variable containers		variable containerwindows		variable tab2win		variable win2tab		variable containercurrent		variable containerid 0		variable scrolling	}	#///////////////////////////////////////////////////////////////////////////////	#///////////////////////////////////////////////////////////////////////////////	# ::ChatWindow::Change (chatid, newchatid)	# This proc is called from the protocol layer when a private chat changes into a	# conference, right after a JOI command comes from the SB. It means that the window	# assigned to $chatid should now be related to $newchatid. ::ChatWindow::Change 	# will return the new chatid if the change is OK (no other window for that name 	# exists), or the old chatid if the change is not right	# Arguments:	# - chatid => Is the name of the chat that was a single private before.	# - newchatid => Is the new id of the chat for the conference	proc Change { chatid newchatid } {		set win_name [::ChatWindow::For $chatid]		if { $win_name == 0 } {			# Old window window does not exists, so just accept the change, no worries			status_log "::ChatWindow::Change: Window doesn't exist (probably invited to a conference)\n"			return $newchatid		}		if { [::ChatWindow::For $newchatid] != 0} {			#Old window existed, probably a conference, but new one exists too, so we can't			#just allow that messages shown in old window now are shown in a different window,			#that wouldn't be nice, so don't allow change			status_log "conference wants to become private, but there's already a window\n"			return $chatid		}		#So, we had an old window for chatid, but no window for newchatid, so the window will		#change it's assigned chat		::ChatWindow::UnsetFor $chatid $win_name		::ChatWindow::SetFor $newchatid $win_name		status_log "::ChatWindow::Change: changing $chatid into $newchatid\n"		return $newchatid	}	#///////////////////////////////////////////////////////////////////////////////	#///////////////////////////////////////////////////////////////////////////////	# ::ChatWindow::GetTopFrame (window)	# Returns the path to the top frame (containing "To: ...") for a given window 	# Arguments:	#  - window => Is the chat window widget (.msg_n - Where n is an integer)	proc GetTopFrame { window } {		return $window.top	}	#///////////////////////////////////////////////////////////////////////////////	#///////////////////////////////////////////////////////////////////////////////	# ::ChatWindow::GetOutText (window)	# Returns the path to the output text widget in a given window 	# Arguments:	#  - window => Is the chat window widget (.msg_n - Where n is an integer)	proc GetOutText { window } {		return $window.f.out.scroll.text	}	#///////////////////////////////////////////////////////////////////////////////	#///////////////////////////////////////////////////////////////////////////////	# ::ChatWindow::GetInputText (window)	# Returns the path to the input text widget in a given window 	# Arguments:	#  - window => Is the chat window widget (.msg_n - Where n is an integer)	proc GetInputText { window } {		return [$window.f.bottom.left.in getinnerframe].text	}	#///////////////////////////////////////////////////////////////////////////////	#///////////////////////////////////////////////////////////////////////////////	# ::ChatWindow::GetStatusText (window)	# Returns the path to the statusbar text widget in a given window 	# Arguments:	#  - window => Is the chat window widget (.msg_n - Where n is an integer)	proc GetStatusText { window } {		return [$window.statusbar getinnerframe].status	}	#///////////////////////////////////////////////////////////////////////////////	#///////////////////////////////////////////////////////////////////////////////	# ::ChatWindow::GetStatusCharsTypedText (window)	# Returns the path to the statusbar text widget in a given window 	# Arguments:	#  - window => Is the chat window widget (.msg_n - Where n is an integer)	proc GetStatusCharsTypedText { window } {		return [$window.statusbar getinnerframe].charstyped	}	#///////////////////////////////////////////////////////////////////////////////	#///////////////////////////////////////////////////////////////////////////////	# ::ChatWindow::Clear (window)	# Deletes all the text in the chat window's input widget	# Arguments:	#  - window => Is the chat window widget (.msg_n - Where n is an integer)	proc Clear { window } {		set window [::ChatWindow::getCurrentTab $window]		[::ChatWindow::GetOutText $window] configure -state normal		[::ChatWindow::GetOutText $window] delete 0.0 end		[::ChatWindow::GetOutText $window] configure -state disabled	}	#///////////////////////////////////////////////////////////////////////////////	#///////////////////////////////////////////////////////////////////////////////	# ::ChatWindow::Close (window)	# Called when a window is about to be closed, for example when we press ESC.	# Arguments:	#  - window => Is the window widget destroyed (.msg_n - Where n is an integer)	proc Close { window } {		if { $::ChatWindow::recent_message($window) == 1  && [::config::getKey recentmsg] == 1} {			status_log "Recent message exists\n" white			set ::ChatWindow::recent_message($window) 0		} else {			set idx [lsearch $::ChatWindow::windows $window]			if { $idx != -1 } {				set ::ChatWindow::windows [lreplace $::ChatWindow::windows $idx $idx]			}			destroy $window		}			}	proc ContainerClose { window } {		variable win2tab				set current [GetCurrentWindow $window]		set currenttab [set win2tab($current)]		#If there is just one tab OR user choosed to always close one tab when clicking the close button		if { [::ChatWindow::CountTabs $window] == 1 || [::config::getKey ContainerCloseAction] == 2} {			::ChatWindow::CloseTab $currenttab			return		}		#If user choosed to always close all tabs when clicking the close button		if {[::config::getKey ContainerCloseAction] == 1} {			::ChatWindow::CloseAll $window; destroy $window			return		}						set nodot [string map { "." "_"} $window]		set w .close$nodot		if { [winfo exists $w] } {			raise $w			return		}		toplevel $w		wm title $w "[trans closeall]"				#Create the 2 frames		frame $w.top		frame $w.buttons				#Create the picture of warning (at left)		label $w.top.bitmap -image [::skin::loadPixmap warning]		pack $w.top.bitmap -side left -pady 5 -padx 10				label $w.top.question -text "[trans closeall]" -font bigfont		pack $w.top.question -pady 5 -padx 10					checkbutton $w.top.remember -text [trans remembersetting] -variable [::config::getVar remember]		pack $w.top.remember -pady 5 -padx 10 -side left				#Create the buttons		button $w.buttons.yes -text "[trans yes]" -command "::ChatWindow::ContainerCloseAction yes $window $w"		button $w.buttons.no -text "[trans no]" -command "::ChatWindow::ContainerCloseAction no $currenttab $w" -default active		button $w.buttons.cancel -text "[trans cancel]" -command "destroy $w"		pack $w.buttons.yes -pady 5 -padx 5 -side right		pack $w.buttons.cancel -pady 5 -padx 5 -side left		pack $w.buttons.no -pady 5 -padx 5 -side right				#Pack frames		pack $w.top -pady 5 -padx 5 -side top		pack $w.buttons -pady 5 -padx 5 -fill x		moveinscreen $w 30		bind $w <<Escape>> "destroy $w"					}		#Action to do when someone chooses yes/or inside ContainerClose	proc ContainerCloseAction {action window w} {				if {$action == "yes"} {			::ChatWindow::CloseAll $window; destroy $window; destroy $w			if {[::config::getKey remember]} {				::config::setKey ContainerCloseAction 1			}		} else {			::ChatWindow::CloseTab $window; destroy $w			if {[::config::getKey remember]} {				::config::setKey ContainerCloseAction 2			}		}			}	proc DetachAll { w } {		variable containerwindows		variable containers		variable containercurrent		if {![info exists containerwindows($w)] || [winfo toplevel $w] != $w} {			return		}		status_log "detaching containerwindows $w\n" red		foreach window [set containerwindows($w)] {			status_log "destroy $window\n" red			DetachTab [set ::ChatWindow::win2tab($window)]		}		status_log "unsetting containerwindow and containercurrent\n" red		unset containerwindows($w)		unset containercurrent($w)		status_log "unsetting containers array...\n" red		foreach { key value } [array get containers] {			if { $value == $w } {				status_log "found containers $key $value\n" red				unset containers($key)			}		}		destroy $w			}	proc CountTabs { w } {		return [llength [set ::ChatWindow::containerwindows($w)]]	}	proc CloseAll { w } {		variable containerwindows		variable containers		variable containercurrent		if {![info exists containerwindows($w)] || [winfo toplevel $w] != $w} {			return		}		status_log "destroying containerwindows $w\n" red		foreach window [set containerwindows($w)] {			status_log "destroy $window\n" red			destroy $window		}		status_log "unsetting containerwindow and containercurrent\n" red		unset containerwindows($w)		unset containercurrent($w)		status_log "unsetting containers array...\n" red		foreach { key value } [array get containers] {			if { $value == $w } {				status_log "found containers $key $value\n" red				unset containers($key)			}		}					}	#///////////////////////////////////////////////////////////////////////////////	#///////////////////////////////////////////////////////////////////////////////	# ::ChatWindow::Closed (window, path)	# Called when a window and its children are destroyed. When the main window is	# destroyed ($window == $path) then it tells the protocol layer to leave the	# chat related to $window, and unsets variables used for that window.	# Arguments:	#  - window => Is the window widget destroyed (.msg_n - Where n is an integer)	#  - path => Is the parent widget of the destroyed childrens (the window)	proc Closed { window path } {		#Only run when the parent window close event comes		if { "$window" != "$path" } {			return 0		}		set chatid [::ChatWindow::Name $window]		if { $chatid == 0 } {			status_log "VERY BAD ERROR in ::ChatWindow::Closed!!!\n" red			return 0		}		if {[::config::getKey keep_logs]} {			set user_list [::MSN::usersInChat $chatid]			foreach user_login $user_list {				::log::StopLog $user_login			}		}		::ChatWindow::UnsetFor $chatid $window		unset ::ChatWindow::titles(${window})		unset ::ChatWindow::first_message(${window})		unset ::ChatWindow::recent_message(${window})		#Delete images if not in use		catch {destroy $window.bottom.pic}		set user_list [::MSN::usersInChat $chatid]				#Could be cleaner, but this works, destroying unused vars, saving mem				catch {			global ${window}_show_picture ${window}.f.bottom.left.in.inner.text			unset ${window}_show_picture			unset ${window}.f.bottom.left.in.inner.text		}						::MSN::leaveChat $chatid	}	#///////////////////////////////////////////////////////////////////////////////	#///////////////////////////////////////////////////////////////////////////////	# ::ChatWindow::Configured (window)	# This proc is called when we resize the window, it stores the new size in config	# Arguments:	#  - window => Is the chat window widget (.msg_n - Where n is an integer)	proc Configured { window } {		#only run this if the window is the outer window		if { ![string equal $window [winfo toplevel $window]]} { return }		set chatid [::ChatWindow::Name $window]		if { $chatid != 0 } {			after cancel "::ChatWindow::TopUpdate $chatid"			after 200 "::ChatWindow::TopUpdate $chatid"		}		if { [::config::getKey savechatwinsize] } {			set geometry [wm geometry $window]			set pos_start [string first "+" $geometry]			::config::setKey winchatsize  [string range $geometry 0 [expr {$pos_start-1}]]		}	}	#///////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -