# $Id$
#
# Bookmarks (XEP-0048) support (conference bookmarks in roster)
#
# In addition to XEP-0048, Tkabber stores roster groups using
# proprietory namespace tkabber:bookmarks:groups inside
# jabber:iq:private storage (XEP-0049)
#
# tkabber:bookmarks:groups description:
#
# setting:
# <iq type='set' id='setgroups'>
# <query xmlns='jabber:iq:private'>
# <storage xmlns='tkabber:bookmarks:groups'>
# <conference jid='talks@conference.jabber.ru'>
# <group>Conferences</group>
# <group>jabber.ru</group>
# </conference>
# </storage>
# </query>
# </iq>
#
# getting:
# <iq type='get' id='getgroups'>
# <query xmlns='jabber:iq:private'>
# <storage xmlns='tkabber:bookmarks:groups'/>
# </query>
# </iq>
#
namespace eval conferences {
# variable to store roster conference bookmarks
array set bookmarks {}
set ::NS(bookmarks) "storage:bookmarks"
set ::NS(tkabber:groups) "tkabber:bookmarks:groups"
}
###############################################################################
#
# Free bookmarks on disconnect
#
proc conferences::free_bookmarks {connid} {
variable bookmarks
array unset bookmarks $connid,*
}
hook::add disconnected_hook [namespace current]::conferences::free_bookmarks
###############################################################################
#
# Retrieve bookmarks on connect
#
proc conferences::request_bookmarks {connid} {
variable bookmarks
variable responds
set responds($connid) 0
array unset bookmarks $connid,*
private::retrieve [list [jlib::wrapper:createtag storage \
-vars [list xmlns $::NS(bookmarks)]]] \
-command [list [namespace current]::process_bookmarks $connid] \
-connection $connid
private::retrieve [list [jlib::wrapper:createtag storage \
-vars [list xmlns $::NS(tkabber:groups)]]] \
-command [list [namespace current]::process_bookmarks $connid] \
-connection $connid
}
hook::add connected_hook [namespace current]::conferences::request_bookmarks 20
proc conferences::process_bookmarks {connid res child} {
variable bookmarks
variable responds
global NS
if {$res != "OK"} return
incr responds($connid)
foreach ch $child {
jlib::wrapper:splitxml $ch tag1 vars1 isempty1 cdata1 children1
switch -- [jlib::wrapper:getattr $vars1 xmlns] \
$NS(bookmarks) {
foreach bookmark $children1 {
create_muc_bookmark $connid $bookmark
}
} \
$NS(tkabber:groups) {
foreach bookmark $children1 {
create_muc_bmgroup $connid $bookmark
}
}
}
if {$responds($connid) < 2} return
push_bookmarks_to_roster $connid
after idle [list [namespace current]::autojoin_groups $connid]
}
proc conferences::create_muc_bookmark {connid xmldata args} {
variable bookmarks
set merge 0
foreach {opt val} $args {
switch -- $opt {
-merge { set merge $val }
default {
return -code error "Bad option \"$opt\":\
must be -merge"
}
}
}
jlib::wrapper:splitxml $xmldata btag bvars bisempty bcdata bchildren
if {![string equal $btag conference]} { return 0 }
set jid [string tolower [jlib::wrapper:getattr $bvars jid]]
if {$merge && [info exists bookmarks($connid,jid,$jid)]} {
return 0
} else {
set bookmarks($connid,jid,$jid) $jid
set bookmarks($connid,name,$jid) [jlib::wrapper:getattr $bvars name]
set bookmarks($connid,nick,$jid) ""
set bookmarks($connid,password,$jid) ""
if {![info exists bookmarks($connid,groups,$jid)]} {
set bookmarks($connid,groups,$jid) {}
set bookmarks($connid,hasgroups,$jid) 0
} else {
set bookmarks($connid,hasgroups,$jid) 1
}
set autojoin [jlib::wrapper:getattr $bvars autojoin]
switch -- $autojoin {
1 -
true { set bookmarks($connid,autojoin,$jid) 1 }
default { set bookmarks($connid,autojoin,$jid) 0 }
}
foreach bch $bchildren {
jlib::wrapper:splitxml \
$bch tag2 vars2 isempty2 cdata2 children2
switch -- $tag2 {
nick { set bookmarks($connid,nick,$jid) $cdata2 }
password { set bookmarks($connid,password,$jid) $cdata2 }
}
}
return 1
}
}
proc conferences::create_muc_bmgroup {connid xmldata args} {
variable bookmarks
set merge 0
foreach {opt val} $args {
switch -- $opt {
-merge { set merge $val }
default {
return -code error "Bad option \"$opt\":\
must be -merge"
}
}
}
jlib::wrapper:splitxml $xmldata btag bvars bisempty bcdata bchildren
if {![string equal $btag conference]} return
set jid [string tolower [jlib::wrapper:getattr $bvars jid]]
set groups [list]
foreach bch $bchildren {
jlib::wrapper:splitxml $bch tag2 vars2 isempty2 cdata2 children2
if {[string equal $tag2 group]} {
lappend groups $cdata2
}
}
if {$merge && [info exists bookmarks($connid,jid,$jid)]
&& $bookmarks($connid,hasgroups,$jid)} {
return 0
} else {
set bookmarks($connid,groups,$jid) $groups
set bookmarks($connid,hasgroups,$jid) 1
return 1
}
}
proc conferences::push_bookmarks_to_roster {connid} {
variable bookmarks
foreach idx [array names bookmarks $connid,jid,*] {
set jid $bookmarks($idx)
client:roster_push $connid $jid $bookmarks($connid,name,$jid) \
$bookmarks($connid,groups,$jid) \
bookmark ""
roster::override_category_and_subtype $connid $jid conference ""
}
}
###############################################################################
#
# Store bookmarks
#
proc conferences::serialize_bookmarks {connid} {
variable bookmarks
set bookmarklist {}
set grouplist {}
foreach idx [array names bookmarks $connid,jid,*] {
set jid $bookmarks($idx)
set name $bookmarks($connid,name,$jid)
set autojoin $bookmarks($connid,autojoin,$jid)
set vars [list jid $jid name $name autojoin $autojoin]
set subtags {}
if {$bookmarks($connid,nick,$jid) != ""} {
lappend subtags [jlib::wrapper:createtag nick \
-chdata $bookmarks($connid,nick,$jid)]
}
if {$bookmarks($connid,password,$jid) != ""} {
lappend subtags [jlib::wrapper:createtag password \
-chdata $bookmarks($connid,password,$jid)]
}
lappend bookmarklist [jlib::wrapper:createtag conference \
-vars $vars \
-subtags $subtags]
set vars [list jid $jid]
set groups {}
foreach group $bookmarks($connid,groups,$jid) {
lappend groups [jlib::wrapper:createtag group \
-chdata $group]
}
lappend grouplist [jlib::wrapper:createtag conference \
-vars $vars \
-subtags $groups]
}
list [jlib::wrapper:createtag storage \
-vars [list xmlns $::NS(bookmarks)] \
-subtags $bookmarklist] \
[jlib::wrapper:createtag storage \
-vars [list xmlns $::NS(tkabber:groups)] \
-subtags $grouplist]
}
proc conferences::store_bookmarks {connid} {
foreach item [serialize_bookmarks $connid] {
private::store [list $item] \
-command [list [namespace current]::store_bookmarks_result $connid] \
-connection $connid
}
}
proc conferences::store_bookmarks_result {connid res child} {
if {$res == "OK"} return
if {[winfo exists .store_bookmarks_error]} {
return
}
MessageDlg .store_bookmarks_error -aspect 50000 -icon error \
-message [format [::msgcat::mc "Storing conferences failed: %s"] \
[error_to_string $child]] \
-type user -buttons ok -default 0 -cancel 0
}
###############################################################################
#
# Menu item for conference window
#
proc conferences::add_conference_menu_item {m connid jid} {
set chatid [chat::chatid $connid $jid]
if {[info exists ::muc::muc_password($chatid)]} {
set password $::muc::muc_password($chatid)
} else {
set password ""
}
$m add command -label [::msgcat::mc "Add conference to roster..."] \
-command [list [namespace current]::add_conference_dialog \
-group [node_from_jid $jid] \
-server [server_from_jid $jid] \
-password $password \
-connection $connid]
}
hook::add chat_create_conference_menu_hook \
[namespace current]::conferences::add_conference_menu_item 35
###############################################################################
#
# Add conference to roster dialog
#
proc conferences::add_conference_dialog {args} {
variable gra_group
variable gra_server
variable gra_nick
variable gra_password
variable gra_autojoin
variable gra_connid
variable gra_rostergroup
if {[lempty [jlib::connections]]} return
set gw .addgroup
catch { destroy $gw }
set connid [lindex [jlib::connections] 0]
set gra_server conference.[jlib::connection_server $connid]
set gra_group ""
set gra_password ""
set gra_autojoin 0
set gra_rostergroup [::msgcat::mc "Conferences"]
catch { unset gra_nick }
foreach {key val} $args {
switch -- $key {
-group { set gra_group $val }
-server { set gra_server $val }
-nick { set gra_nick $val }
-password { set gra_password $val }
-autojoin { set gra_autojoin $val }
-connection { set connid $val }
}
}
if {![info exists gra_nick]} {
set gra_nick [get_group_nick ${gra_group}@$gra_server ""]
}
set gra_connid [jlib::connection_jid $connid]
Dialog $gw -title [::msgcat::mc "Add Conference to Roster"] -separator 1 -anchor e \
-default 0 -cancel 1 -parent . -modal none
set gf [$gw getframe]
grid columnconfigure $gf 0 -weight 0
grid columnconfigure $gf 1 -weight 1
label $gf.lgroup -text [::msgcat::mc "Conference:"]
entry $gf.group -textvariable [namespace current]::gra_group
label $gf.lserver -text [::msgcat::mc "Server:"]
entry $gf.server -textvariable [namespace current]::gra_server
label $gf.lnick -text [::msgcat::mc "Nick:"]
entry $gf.nick -textvariable [namespace current]::gra_nick
label $gf.lpassword -text [::msgcat::mc "Password:"]
entry $gf.password -show * -textvariable [namespace current]::gra_password
checkbutton $gf.autojoin -text [::msgcat::mc "Automatically join conference upon connect"] \
-variable [namespace current]::gra_autojoin
label $gf.lrostergroup -text [::msgcat::mc "Roster group:"]
ComboBox $gf.rostergroup -textvariable [namespace current]::gra_rostergroup \
-values [get_groups $connid]
grid $gf.lgroup -row 0 -column 0 -sticky e
grid $gf.group -row 0 -column 1 -sticky ew
grid $gf.lserver -row 1 -column 0 -sticky e
grid $gf.server -row 1 -column 1 -sticky ew
grid $gf.lnick -row 2 -column 0 -sticky e
grid $gf.nick -row 2 -column 1 -sticky ew
grid $gf.lpassword -row 3 -column 0 -sticky e
grid $gf.password -row 3 -column 1 -sticky ew
grid $gf.autojoin -row 4 -column 0 -sticky w -columnspan 2
grid $gf.lrostergroup -row 5 -column 0 -sticky e
grid $gf.rostergroup -row 5 -column 1 -sticky ew
if {[llength [jlib::connections]] > 1} {
foreach c [jlib::connections] {
lappend connections [jlib::connection_jid $c]
}
label $gf.lconnection -text [::msgcat::mc "Connection:"]
ComboBox $gf.connection -textvariable [namespace current]::gra_connid \
-values $connections -editable 0 \
-modifycmd [list [namespace current]::change_groups \
$gf.rostergroup]
grid $gf.lconnection -row 6 -column 0 -sticky e
grid $gf.connection -row 6 -column 1 -sticky ew
}
$gw add -text [::msgcat::mc "Add"] -command [list [namespace current]::add_conference $gw]
$gw add -text [::msgcat::mc "Cancel"] -command [list destroy $gw]
$gw draw $gf.group
}
proc conferences::change_groups {combo args} {
variable gra_connid
foreach connid [jlib::connections] {
if {[jlib::connection_jid $connid] == $gra_connid} {
$combo configure -values [get_groups $connid]
return
}
}
}
proc conferences::get_groups {connid} {
return [roster::get_groups $connid \
-nested $::ifacetk::roster::options(nested) \
-delimiter $::ifacetk::roster::options(nested_delimiter) \
-undefined 0]
}
proc conferences::add_conference {gw} {
variable bookmarks
variable gra_group
variable gra_server
variable gra_nick
variable gra_password
variable gra_autojoin
variable gra_connid
variable gra_rostergroup
destroy $gw
set jid [string tolower ${gra_group}@$gra_server]
if {$gra_rostergroup == ""} {
set groups {}
} else {
set groups [list $gra_rostergroup]
}
foreach c [jlib::connections] {
if {[jlib::connection_jid $c] == $gra_connid} {
set connid $c
}
}
if {![info exists connid]} {
# Disconnect while dialog is opened
return
}
if {[info exists bookmarks($connid,jid,$jid)]} {
update_bookmark $connid $jid -name $gra_group -nick $gra_nick \
-password $gra_password -autojoin $gra_autojoin \
-groups $groups
} else {
add_bookmark $connid $jid -name $gra_group -nick $gra_nick \
-password $gra_password -autojoin $gra_autojoin \
-groups $groups
}
}
###############################################################################
#
# Add bookmark to roster
#
proc conferences::add_bookmark {connid jid args} {
variable bookmarks
if {[info exists bookmarks($connid,jid,$jid)]} return
foreach {key val} $args {
switch -- $key {
-name { set name $val }
-nick { set nick $val }
-password { set password $val }
-autojoin { set autojoin $val }
-groups { set groups $val }
}
}
if {![info exists name]} {
set name [node_from_jid $jid]
}
if {![info exists nick]} {
set nick [get_group_nick $jid ""]
}
if {![info exists password]} {
set password ""
}
if {![info exists autojoin]} {
set autojoin 0
}
if {![info exists groups]} {
set groups {}
}
set bookmarks($connid,jid,$jid) $jid
set bookmarks($connid,name,$jid) $name
set bookmarks($connid,nick,$jid) $nick
set bookmarks($connid,password,$jid) $password
set bookmarks($connid,autojoin,$jid) $autojoin
set bookmarks($connid,groups,$jid) $groups
set bookmarks($connid,hasgroups,$jid) 1
# TODO should we remove $jid from the roster if it is here?
client:roster_push $connid $jid $name $groups bookmark ""
roster::override_category_and_subtype $connid $jid conference ""
store_bookmarks $connid
}
###############################################################################
#
# Update bookmark in roster
#
proc conferences::update_bookmark {connid jid args} {
variable bookmarks
set store 0
foreach {key val} $args {
switch -- $key {
-name { set name $val }
-nick { set nick $val }
-password { set password $val }
-autojoin { set autojoin $val }
-groups { set groups $val }
}
}
if {[info exists name] && $name != $bookmarks($connid,name,$jid)} {
set bookmarks($connid,name,$jid) $name
set store 1
}
if {[info exists nick] && $nick != $bookmarks($connid,nick,$jid)} {
set bookmarks($connid,nick,$jid) $nick
set store 1
}
if {[info exists password] && $password != $bookmarks($connid,password,$jid)} {
set bookmarks($connid,password,$jid) $password
set store 1
}
if {[info exists autojoin] && $autojoin != $bookmarks($connid,autojoin,$jid)} {
set bookmarks($connid,autojoin,$jid) $autojoin
set store 1
}
if {[info exists groups] && [lsort $groups] != [lsort $bookmarks($connid,groups,$jid)]} {
set bookmarks($connid,groups,$jid) $groups
set store 1
}
if {$store} {
client:roster_push $connid $jid $bookmarks($connid,name,$jid) \
$bookmarks($connid,groups,$jid) bookmark ""
roster::override_category_and_subtype $connid $jid conference ""
store_bookmarks $connid
}
}
###############################################################################
#
# Add or update item in roster
#
proc conferences::send_bookmark {connid jid} {
if {[roster::itemconfig $connid $jid -subsc] != "bookmark"} return
set groups [roster::itemconfig $connid $jid -group]
add_bookmark $connid $jid -groups $groups
update_bookmark $connid $jid -groups $groups
return stop
}
hook::add roster_send_item_hook [namespace current]::conferences::send_bookmark
###############################################################################
#
# Remove bookmark from roster
#
proc conferences::remove_bookmark {connid jid} {
variable bookmarks
if {[roster::itemconfig $connid $jid -subsc] != "bookmark"} return
if {![info exists bookmarks($connid,jid,$jid)]} return
client:roster_push $connid $jid $bookmarks($connid,name,$jid) \
$bookmarks($connid,groups,$jid) \
remove ""
catch { unset bookmarks($connid,jid,$jid) }
catch { unset bookmarks($connid,name,$jid) }
catch { unset bookmarks($connid,nick,$jid) }
catch { unset bookmarks($connid,password,$jid) }
catch { unset bookmarks($connid,autojoin,$jid) }
catch { unset bookmarks($connid,groups,$jid) }
catch { unset bookmarks($connid,hasgroups,$jid) }
store_bookmarks $connid
return stop
}
hook::add roster_remove_item_hook \
[namespace current]::conferences::remove_bookmark
###############################################################################
#
# Rename group in roster bookmarks
#
proc conferences::rename_group {connid name new_name} {
variable bookmarks
set store 0
foreach idx [array names bookmarks $connid,jid,*] {
set jid $bookmarks($idx)
set groups $bookmarks($connid,groups,$jid)
if {[lcontain $groups $name] || \
($name == $roster::undef_group_name && $groups == {})} {
set idx [lsearch -exact $groups $name]
if {$new_name != ""} {
set groups [lreplace $groups $idx $idx $new_name]
} else {
set groups [lreplace $groups $idx $idx]
}
set groups [lrmdups $groups]
client:roster_push $connid $jid $bookmarks($connid,name,$jid) \
$groups bookmark ""
roster::override_category_and_subtype $connid $jid conference ""
set bookmarks($connid,groups,$jid) $groups
set store 1
}
}
if {$store} {
store_bookmarks $connid
}
}
hook::add roster_rename_group_hook \
[namespace current]::conferences::rename_group
###############################################################################
#
# Remove group name from roster bookmarks
#
proc conferences::remove_bookmarks_group {connid name} {
variable bookmarks
set store 0
foreach idx [array names bookmarks $connid,jid,*] {
set jid $bookmarks($idx)
set groups $bookmarks($connid,groups,$jid)
if {(([llength $groups] == 1) && [lcontain $groups $name]) || \
(($name == $roster::undef_group_name) && ($groups == {}))} {
client:roster_push $connid $jid $bookmarks($connid,name,$jid) \
$groups remove ""
catch { unset bookmarks($connid,jid,$jid) }
catch { unset bookmarks($connid,name,$jid) }
catch { unset bookmarks($connid,nick,$jid) }
catch { unset bookmarks($connid,password,$jid) }
catch { unset bookmarks($connid,autojoin,$jid) }
catch { unset bookmarks($connid,groups,$jid) }
set store 1
} elseif {[lcontain $groups $name]} {
set idx [lsearch -exact $groups $name]
set groups [lreplace $groups $idx $idx]
client:roster_push $connid $jid $bookmarks($connid,name,$jid) \
$groups bookmark ""
roster::override_category_and_subtype $connid $jid conference ""
set bookmarks($connid,groups,$jid) $groups
set store 1
}
}
if {$store} {
store_bookmarks $connid
}
}
hook::add roster_remove_users_group_hook \
[namespace current]::conferences::remove_bookmarks_group
###############################################################################
#
# Join group on roster item doubleclick
#
proc conferences::join_group {connid jid} {
variable bookmarks
set args {}
if {$bookmarks($connid,nick,$jid) != ""} {
lappend args -nick $bookmarks($connid,nick,$jid)
}
if {$bookmarks($connid,password,$jid) != ""} {
lappend args -password $bookmarks($connid,password,$jid)
}
eval [list ::join_group $jid -connection $connid] $args
}
###############################################################################
#
# Join group during autojoin
#
proc conferences::autojoin_group {connid jid} {
variable bookmarks
global gr_nick
if {$bookmarks($connid,nick,$jid) != ""} {
set nick $bookmarks($connid,nick,$jid)
} else {
set nick [get_group_nick $jid $gr_nick]
}
if {$bookmarks($connid,password,$jid) != ""} {
set password $bookmarks($connid,password,$jid)
} else {
set password ""
}
after idle [list muc::join_group $connid $jid $nick $password]
}
###############################################################################
#
# Autojoin groups
#
proc conferences::autojoin_groups {connid} {
variable bookmarks
foreach idx [array names bookmarks $connid,jid,*] {
set jid $bookmarks($idx)
set chatid [chat::chatid $connid $jid]
if {$bookmarks($connid,autojoin,$jid) && ![chat::is_opened $chatid]} {
autojoin_group $connid $jid
}
}
}
###############################################################################
#
# "Join" item in roster conference popup menu
#
proc conferences::popup_menu {m connid jid} {
variable bookmarks
set args {}
if {[roster::itemconfig $connid $jid -subsc] == "bookmark"} {
if {$bookmarks($connid,nick,$jid) != ""} {
lappend args -nick $bookmarks($connid,nick,$jid)
}
if {$bookmarks($connid,password,$jid) != ""} {
lappend args -password $bookmarks($connid,password,$jid)
}
}
$m add command -label [::msgcat::mc "Join..."] \
-command [list eval [list join_group_dialog \
-server [server_from_jid $jid] \
-group [node_from_jid $jid] \
-connection $connid] \
$args]
}
hook::add roster_conference_popup_menu_hook \
[namespace current]::conferences::popup_menu 20
###############################################################################
#
# Roster doubleclick
#
proc conferences::roster_doubleclick {connid jid category subtype} {
switch -- $category {
conference {
if {[roster::itemconfig $connid $jid -subsc] == "bookmark"} {
join_group $connid $jid
} else {
global gr_nick
::join_group $jid \
-nick [get_group_nick $jid $gr_nick] \
-connection $connid
}
return stop
}
}
}
hook::add roster_jid_doubleclick \
[namespace current]::conferences::roster_doubleclick
###############################################################################
#
# Main menu setup
#
proc conferences::main_menu {} {
set m [.mainframe getmenu services]
$m insert 2 command -label [::msgcat::mc "Add conference to roster..."] \
-command [list [namespace current]::add_conference_dialog]
}
hook::add finload_hook [namespace current]::conferences::main_menu
###############################################################################
#
# Edit roster item
#
proc conferences::edit_item_setup {f connid jid} {
variable egra_name
variable egra_nick
variable egra_password
variable egra_autojoin
variable bookmarks
if {[roster::itemconfig $connid $jid -subsc] != "bookmark"} return
set tf [TitleFrame $f.prop \
-text [::msgcat::mc "Edit properties for %s" $jid]]
set slaves [pack slaves $f]
if {$slaves == ""} {
pack $tf -side top -expand yes -fill both
} else {
pack $tf -side top -expand yes -fill both -before [lindex $slaves 0]
}
set g [$tf getframe]
set egra_name $bookmarks($connid,name,$jid)
set egra_autojoin $bookmarks($connid,autojoin,$jid)
if {[info exists bookmarks($connid,nick,$jid)]} {
set egra_nick $bookmarks($connid,nick,$jid)
} else {
set egra_nick ""
}
if {[info exists bookmarks($connid,password,$jid)]} {
set egra_password $bookmarks($connid,password,$jid)
} else {
set egra_password ""
}
label $g.lname -text [string trim [::msgcat::mc "Name: "]]
entry $g.name -textvariable [namespace current]::egra_name
label $g.lnick -text [::msgcat::mc "Nick:"]
entry $g.nick -textvariable [namespace current]::egra_nick
label $g.lpassword -text [::msgcat::mc "Password:"]
entry $g.password -show * -textvariable [namespace current]::egra_password
checkbutton $g.autojoin \
-text [::msgcat::mc "Automatically join conference upon connect"] \
-variable [namespace current]::egra_autojoin
grid columnconfigure $g 0 -weight 0
grid columnconfigure $g 1 -weight 1
grid $g.lname -row 0 -column 0 -sticky e
grid $g.name -row 0 -column 1 -sticky ew
grid $g.lnick -row 1 -column 0 -sticky e
grid $g.nick -row 1 -column 1 -sticky ew
grid $g.lpassword -row 2 -column 0 -sticky e
grid $g.password -row 2 -column 1 -sticky ew
grid $g.autojoin -row 3 -column 0 -sticky w -columnspan 2
return stop
}
hook::add roster_itemedit_setup_hook \
[namespace current]::conferences::edit_item_setup
proc conferences::commit_bookmark_changes {connid jid groups} {
variable egra_name
variable egra_nick
variable egra_password
variable egra_autojoin
if {[roster::itemconfig $connid $jid -subsc] != "bookmark"} return
plugins::conferences::update_bookmark $connid $jid \
-name $egra_name -nick $egra_nick -password $egra_password \
-autojoin $egra_autojoin -groups $groups
return stop
}
hook::add roster_itemedit_commit_hook \
[namespace current]::conferences::commit_bookmark_changes
###############################################################################
proc conferences::disco_node_menu_setup {m bw tnode data parentdata} {
lassign $data type connid jid node
lassign $parentdata ptype pconnid pjid pnode
switch -- $type {
item {
set identities [disco::get_jid_identities $connid $jid $node]
set pidentities [disco::get_jid_identities $pconnid $pjid $pnode]
# JID with resource is not a room JID
if {[node_and_server_from_jid $jid] != $jid} return
if {[lempty $identities]} {
set identities $pidentities
}
foreach id $identities {
if {[jlib::wrapper:getattr $id category] == "conference"} {
$m add command -label [::msgcat::mc "Add conference to roster..."] \
-command [list [namespace current]::add_conference_dialog \
-group [node_from_jid $jid] \
-server [server_from_jid $jid] \
-connection $connid]
break
}
}
}
}
}
hook::add disco_node_menu_hook \
[namespace current]::conferences::disco_node_menu_setup 50
# vim:ts=8:sw=4:sts=4:noet