1# $Id$ 2# 3# Bookmarks (XEP-0048) support (conference bookmarks in roster) 4# 5# In addition to XEP-0048, Tkabber stores roster groups using 6# proprietory namespace tkabber:bookmarks:groups inside 7# jabber:iq:private storage (XEP-0049) 8# 9# tkabber:bookmarks:groups description: 10# 11# setting: 12# <iq type='set' id='setgroups'> 13# <query xmlns='jabber:iq:private'> 14# <storage xmlns='tkabber:bookmarks:groups'> 15# <conference jid='talks@conference.jabber.ru'> 16# <group>Conferences</group> 17# <group>jabber.ru</group> 18# </conference> 19# </storage> 20# </query> 21# </iq> 22# 23# getting: 24# <iq type='get' id='getgroups'> 25# <query xmlns='jabber:iq:private'> 26# <storage xmlns='tkabber:bookmarks:groups'/> 27# </query> 28# </iq> 29# 30 31package require xmpp::roster::bookmarks 32 33namespace eval conferences { 34 # variable to store roster conference bookmarks 35 array set bookmarks {} 36 37 set ::NS(tkabber:groups) "tkabber:bookmarks:groups" 38 39 custom::defvar options(ignore_autojoin) 0 \ 40 [::msgcat::mc "Ignore autojoin option and do not automatically join\ 41 conference rooms on login."] \ 42 -type boolean -group Chat 43 44 custom::defvar options(roster_group) [::msgcat::mc "Conferences"] \ 45 [::msgcat::mc "Default group for conferences in roster."] \ 46 -type string -group Hidden 47} 48 49############################################################################### 50# 51# Free bookmarks on disconnect 52# 53 54proc conferences::free_bookmarks {xlib} { 55 variable bookmarks 56 57 array unset bookmarks $xlib,* 58} 59 60hook::add disconnected_hook [namespace current]::conferences::free_bookmarks 61 62############################################################################### 63# 64# Retrieve bookmarks on connect 65# 66 67proc conferences::request_bookmarks {xlib} { 68 variable bookmarks 69 variable responds 70 71 set responds($xlib) 0 72 array unset bookmarks $xlib,* 73 set bookmarks($xlib) {} 74 75 ::xmpp::roster::bookmarks::retrieve $xlib \ 76 -command [list [namespace current]::process_bookmarks $xlib] 77 78 ::xmpp::private::retrieve $xlib [list [::xmpp::xml::create storage \ 79 -xmlns $::NS(tkabber:groups)]] \ 80 -command [list [namespace current]::process_groups $xlib] 81} 82 83hook::add connected_hook [namespace current]::conferences::request_bookmarks 20 84 85proc conferences::process_bookmarks {xlib status bmlist} { 86 variable bookmarks 87 variable responds 88 global NS 89 90 if {$status != "ok"} return 91 92 incr responds($xlib) 93 94 foreach bookmark $bmlist { 95 create_muc_bookmark $xlib $bookmark 96 } 97 98 if {$responds($xlib) < 2} return 99 100 push_bookmarks_to_roster $xlib 101 after idle [list [namespace current]::autojoin_groups $xlib] 102} 103 104proc conferences::process_groups {xlib status xmlList} { 105 variable bookmarks 106 variable responds 107 global NS 108 109 if {$status != "ok"} return 110 111 incr responds($xlib) 112 113 foreach xml $xmlList { 114 ::xmpp::xml::split $xml tag xmlns attrs cdata subels 115 116 if {$xmlns == $NS(tkabber:groups)} { 117 foreach bookmark $subels { 118 create_muc_bmgroup $xlib $bookmark 119 } 120 } 121 } 122 123 if {$responds($xlib) < 2} return 124 125 push_bookmarks_to_roster $xlib 126 after idle [list [namespace current]::autojoin_groups $xlib] 127} 128 129proc conferences::create_muc_bookmark {xlib bookmark args} { 130 variable bookmarks 131 132 set merge 0 133 foreach {opt val} $args { 134 switch -- $opt { 135 -merge { set merge $val } 136 default { 137 return -code error "Bad option \"$opt\": must be -merge" 138 } 139 } 140 } 141 142 array set n $bookmark 143 144 set jid [::xmpp::jid::normalize $n(jid)] 145 146 if {$merge && [info exists bookmarks($xlib,jid,$jid)]} { 147 return 0 148 } else { 149 if {[lsearch -exact $bookmarks($xlib) $jid] < 0} { 150 lappend bookmarks($xlib) $jid 151 } 152 set bookmarks($xlib,jid,$jid) $jid 153 154 set bookmarks($xlib,name,$jid) "" 155 set bookmarks($xlib,nick,$jid) "" 156 set bookmarks($xlib,password,$jid) "" 157 set bookmarks($xlib,autojoin,$jid) 0 158 159 if {[info exists n(name)]} { 160 set bookmarks($xlib,name,$jid) $n(name) 161 } 162 if {[info exists n(nick)]} { 163 set bookmarks($xlib,nick,$jid) $n(nick) 164 } 165 if {[info exists n(password)]} { 166 set bookmarks($xlib,password,$jid) $n(password) 167 } 168 if {[info exists n(autojoin)]} { 169 set bookmarks($xlib,autojoin,$jid) $n(autojoin) 170 } 171 172 if {![info exists bookmarks($xlib,groups,$jid)]} { 173 set bookmarks($xlib,groups,$jid) {} 174 set bookmarks($xlib,hasgroups,$jid) 0 175 } else { 176 set bookmarks($xlib,hasgroups,$jid) 1 177 } 178 179 return 1 180 } 181} 182 183proc conferences::create_muc_bmgroup {xlib xmldata args} { 184 variable bookmarks 185 186 set merge 0 187 foreach {opt val} $args { 188 switch -- $opt { 189 -merge { set merge $val } 190 default { 191 return -code error "Bad option \"$opt\":\ 192 must be -merge" 193 } 194 } 195 } 196 197 ::xmpp::xml::split $xmldata tag xmlns attrs cdata subels 198 199 if {![string equal $tag conference]} return 200 201 set jid [::xmpp::jid::normalize [::xmpp::xml::getAttr $attrs jid]] 202 203 set groups [list] 204 foreach subel $subels { 205 ::xmpp::xml::split $subel stag sxmlns sattrs scdata ssubels 206 if {[string equal $stag group]} { 207 lappend groups $scdata 208 } 209 } 210 211 if {$merge && [info exists bookmarks($xlib,jid,$jid)] 212 && $bookmarks($xlib,hasgroups,$jid)} { 213 return 0 214 } else { 215 set bookmarks($xlib,groups,$jid) $groups 216 set bookmarks($xlib,hasgroups,$jid) 1 217 return 1 218 } 219} 220 221proc conferences::push_bookmarks_to_roster {xlib} { 222 variable bookmarks 223 224 foreach idx [array names bookmarks $xlib,jid,*] { 225 set jid $bookmarks($idx) 226 client:roster_push $xlib $jid \ 227 -name $bookmarks($xlib,name,$jid) \ 228 -groups $bookmarks($xlib,groups,$jid) \ 229 -subscription bookmark 230 roster::override_category_and_subtype $xlib $jid conference "" 231 } 232} 233 234############################################################################### 235# 236# Store bookmarks 237# 238 239proc conferences::serialize_bookmarks {xlib} { 240 variable bookmarks 241 242 set bookmarklist {} 243 set grouplist {} 244 foreach jid $bookmarks($xlib) { 245 set name $bookmarks($xlib,name,$jid) 246 set autojoin $bookmarks($xlib,autojoin,$jid) 247 248 set vars [list jid $jid name $name autojoin $autojoin] 249 250 if {$bookmarks($xlib,nick,$jid) != ""} { 251 lappend vars nick $bookmarks($xlib,nick,$jid) 252 } 253 if {$bookmarks($xlib,password,$jid) != ""} { 254 lappend vars password $bookmarks($xlib,password,$jid) 255 } 256 lappend bookmarklist $vars 257 258 set vars [list jid $jid] 259 set groups {} 260 foreach group $bookmarks($xlib,groups,$jid) { 261 lappend groups [::xmpp::xml::create group \ 262 -cdata $group] 263 } 264 lappend grouplist [::xmpp::xml::create conference \ 265 -attrs $vars \ 266 -subelements $groups] 267 } 268 269 return [list $bookmarklist \ 270 [::xmpp::xml::create storage \ 271 -xmlns $::NS(tkabber:groups) \ 272 -subelements $grouplist]] 273} 274 275proc conferences::store_bookmarks {xlib args} { 276 set command [list [namespace current]::store_bookmarks_result $xlib] 277 foreach {opt val} $args { 278 switch -- $opt { 279 -command { set command $val } 280 default { 281 return -code error "Bad option \"$opt\":\ 282 must be -command" 283 } 284 } 285 } 286 287 lassign [serialize_bookmarks $xlib] bookmarks groups 288 289 ::xmpp::roster::bookmarks::store $xlib $bookmarks -command $command 290 ::xmpp::private::store $xlib [list $groups] -command $command 291} 292 293proc conferences::store_bookmarks_result {xlib res child} { 294 295 if {$res == "ok"} return 296 297 if {[winfo exists .store_bookmarks_error]} { 298 return 299 } 300 301 MessageDlg .store_bookmarks_error -aspect 50000 -icon error \ 302 -message [::msgcat::mc "Storing conferences failed: %s" \ 303 [error_to_string $child]] \ 304 -type user -buttons ok -default 0 -cancel 0 305} 306 307############################################################################### 308# 309# Menu item for conference window 310# 311 312proc conferences::add_conference_menu_item {m xlib jid} { 313 set chatid [chat::chatid $xlib $jid] 314 315 if {[info exists ::muc::muc_password($chatid)]} { 316 set password $::muc::muc_password($chatid) 317 } else { 318 set password "" 319 } 320 321 $m add command -label [::msgcat::mc "Add conference to roster..."] \ 322 -command [list [namespace current]::add_conference_dialog $xlib \ 323 -group [::xmpp::jid::node $jid] \ 324 -server [::xmpp::jid::server $jid] \ 325 -password $password] 326} 327 328hook::add chat_create_conference_menu_hook \ 329 [namespace current]::conferences::add_conference_menu_item 35 330 331############################################################################### 332# 333# Add conference to roster dialog 334# 335 336proc conferences::add_conference_dialog {xlib args} { 337 variable options 338 variable gra_group 339 variable gra_server 340 variable gra_nick 341 variable gra_password 342 variable gra_autojoin 343 variable gra_xlib 344 345 if {[lempty [connections]]} return 346 347 set gw .addgroup 348 catch { destroy $gw } 349 350 if {$xlib == ""} { 351 set xlib [lindex [connections] 0] 352 } 353 set gra_server conference.[connection_server $xlib] 354 set gra_group "" 355 set gra_password "" 356 set gra_autojoin 0 357 catch { unset gra_nick } 358 359 foreach {key val} $args { 360 switch -- $key { 361 -group { set gra_group $val } 362 -server { set gra_server $val } 363 -nick { set gra_nick $val } 364 -password { set gra_password $val } 365 -autojoin { set gra_autojoin $val } 366 } 367 } 368 369 if {![info exists gra_nick]} { 370 set gra_nick [get_group_nick $xlib [::xmpp::jid::jid $gra_group $gra_server]] 371 } 372 set gra_xlib [connection_jid $xlib] 373 374 Dialog $gw -title [::msgcat::mc "Add Conference to Roster"] -separator 1 -anchor e \ 375 -default 0 -cancel 1 -modal none 376 377 set gf [$gw getframe] 378 grid columnconfigure $gf 0 -weight 0 379 grid columnconfigure $gf 1 -weight 1 380 381 label $gf.lgroup -text [::msgcat::mc "Conference:"] 382 entry $gf.group -textvariable [namespace current]::gra_group 383 label $gf.lserver -text [::msgcat::mc "Server:"] 384 entry $gf.server -textvariable [namespace current]::gra_server 385 label $gf.lnick -text [::msgcat::mc "Nick:"] 386 entry $gf.nick -textvariable [namespace current]::gra_nick 387 label $gf.lpassword -text [::msgcat::mc "Password:"] 388 entry $gf.password -show * -textvariable [namespace current]::gra_password 389 checkbutton $gf.autojoin -text [::msgcat::mc "Automatically join conference upon connect"] \ 390 -variable [namespace current]::gra_autojoin 391 label $gf.lrostergroup -text [::msgcat::mc "Roster group:"] 392 ComboBox $gf.rostergroup -textvariable [namespace current]::options(roster_group) \ 393 -values [get_groups $xlib] 394 395 grid $gf.lgroup -row 0 -column 0 -sticky e 396 grid $gf.group -row 0 -column 1 -sticky ew 397 grid $gf.lserver -row 1 -column 0 -sticky e 398 grid $gf.server -row 1 -column 1 -sticky ew 399 grid $gf.lnick -row 2 -column 0 -sticky e 400 grid $gf.nick -row 2 -column 1 -sticky ew 401 grid $gf.lpassword -row 3 -column 0 -sticky e 402 grid $gf.password -row 3 -column 1 -sticky ew 403 grid $gf.autojoin -row 4 -column 0 -sticky w -columnspan 2 404 grid $gf.lrostergroup -row 5 -column 0 -sticky e 405 grid $gf.rostergroup -row 5 -column 1 -sticky ew 406 407 if {[llength [connections]] > 1} { 408 foreach c [connections] { 409 lappend connections [connection_jid $c] 410 } 411 label $gf.lconnection -text [::msgcat::mc "Connection:"] 412 ComboBox $gf.connection -textvariable [namespace current]::gra_xlib \ 413 -values $connections -editable 0 \ 414 -modifycmd [list [namespace current]::change_groups \ 415 $gf.rostergroup] 416 417 grid $gf.lconnection -row 6 -column 0 -sticky e 418 grid $gf.connection -row 6 -column 1 -sticky ew 419 } 420 421 422 $gw add -text [::msgcat::mc "Add"] -command [list [namespace current]::add_conference $gw] 423 $gw add -text [::msgcat::mc "Cancel"] -command [list destroy $gw] 424 425 $gw draw $gf.group 426} 427 428proc conferences::change_groups {combo args} { 429 variable gra_xlib 430 431 foreach xlib [connections] { 432 if {[connection_jid $xlib] == $gra_xlib} { 433 $combo configure -values [get_groups $xlib] 434 return 435 } 436 } 437} 438 439proc conferences::get_groups {xlib} { 440 return [roster::get_groups $xlib \ 441 -nested $::ifacetk::roster::options(nested) \ 442 -delimiter $::ifacetk::roster::options(nested_delimiter) \ 443 -undefined 0] 444} 445 446proc conferences::add_conference {gw} { 447 variable options 448 variable bookmarks 449 variable gra_group 450 variable gra_server 451 variable gra_nick 452 variable gra_password 453 variable gra_autojoin 454 variable gra_xlib 455 456 destroy $gw 457 458 set jid [::xmpp::jid::normalize ${gra_group}@$gra_server] 459 if {$options(roster_group) == ""} { 460 set groups {} 461 } else { 462 set groups [list $options(roster_group)] 463 } 464 465 foreach c [connections] { 466 if {[connection_jid $c] == $gra_xlib} { 467 set xlib $c 468 } 469 } 470 if {![info exists xlib]} { 471 # Disconnect while dialog is opened 472 return 473 } 474 475 if {[info exists bookmarks($xlib,jid,$jid)]} { 476 update_bookmark $xlib $jid -name $gra_group -nick $gra_nick \ 477 -password $gra_password -autojoin $gra_autojoin \ 478 -groups $groups 479 } else { 480 add_bookmark $xlib $jid -name $gra_group -nick $gra_nick \ 481 -password $gra_password -autojoin $gra_autojoin \ 482 -groups $groups 483 } 484} 485 486############################################################################### 487# 488# Add bookmark to roster 489# 490 491proc conferences::add_bookmark {xlib jid args} { 492 variable bookmarks 493 494 if {[info exists bookmarks($xlib,jid,$jid)]} return 495 496 foreach {key val} $args { 497 switch -- $key { 498 -name { set name $val } 499 -nick { set nick $val } 500 -password { set password $val } 501 -autojoin { set autojoin $val } 502 -groups { set groups $val } 503 } 504 } 505 506 if {![info exists name]} { 507 set name [::xmpp::jid::node $jid] 508 } 509 if {![info exists nick]} { 510 set nick [get_group_nick $xlib $jid] 511 } 512 if {![info exists password]} { 513 set password "" 514 } 515 if {![info exists autojoin]} { 516 set autojoin 0 517 } 518 if {![info exists groups]} { 519 set groups {} 520 } 521 522 if {[lsearch -exact $bookmarks($xlib) $jid] < 0} { 523 lappend bookmarks($xlib) $jid 524 } 525 set bookmarks($xlib,jid,$jid) $jid 526 set bookmarks($xlib,name,$jid) $name 527 set bookmarks($xlib,nick,$jid) $nick 528 set bookmarks($xlib,password,$jid) $password 529 set bookmarks($xlib,autojoin,$jid) $autojoin 530 set bookmarks($xlib,groups,$jid) $groups 531 set bookmarks($xlib,hasgroups,$jid) 1 532 533 # TODO should we remove $jid from the roster if it is here? 534 client:roster_push $xlib $jid \ 535 -name $name \ 536 -groups $groups \ 537 -subscription bookmark 538 roster::override_category_and_subtype $xlib $jid conference "" 539 store_bookmarks $xlib 540} 541 542############################################################################### 543# 544# Update bookmark in roster 545# 546 547proc conferences::update_bookmark {xlib jid args} { 548 variable bookmarks 549 550 set store 0 551 552 foreach {key val} $args { 553 switch -- $key { 554 -name { set name $val } 555 -nick { set nick $val } 556 -password { set password $val } 557 -autojoin { set autojoin $val } 558 -groups { set groups $val } 559 } 560 } 561 562 if {[info exists name] && $name != $bookmarks($xlib,name,$jid)} { 563 set bookmarks($xlib,name,$jid) $name 564 set store 1 565 } 566 if {[info exists nick] && $nick != $bookmarks($xlib,nick,$jid)} { 567 set bookmarks($xlib,nick,$jid) $nick 568 set store 1 569 } 570 if {[info exists password] && $password != $bookmarks($xlib,password,$jid)} { 571 set bookmarks($xlib,password,$jid) $password 572 set store 1 573 } 574 if {[info exists autojoin] && $autojoin != $bookmarks($xlib,autojoin,$jid)} { 575 set bookmarks($xlib,autojoin,$jid) $autojoin 576 set store 1 577 } 578 if {[info exists groups] && [lsort $groups] != [lsort $bookmarks($xlib,groups,$jid)]} { 579 set bookmarks($xlib,groups,$jid) $groups 580 set store 1 581 } 582 if {$store} { 583 client:roster_push $xlib $jid \ 584 -name $bookmarks($xlib,name,$jid) \ 585 -groups $bookmarks($xlib,groups,$jid) \ 586 -subscription bookmark 587 roster::override_category_and_subtype $xlib $jid conference "" 588 store_bookmarks $xlib 589 } 590} 591 592############################################################################### 593# 594# Add or update item in roster 595# 596 597proc conferences::send_bookmark {xlib jid} { 598 599 if {[roster::itemconfig $xlib $jid -subsc] != "bookmark"} return 600 601 set groups [roster::itemconfig $xlib $jid -group] 602 603 add_bookmark $xlib $jid -groups $groups 604 update_bookmark $xlib $jid -groups $groups 605 606 return stop 607} 608 609hook::add roster_send_item_hook [namespace current]::conferences::send_bookmark 610 611############################################################################### 612# 613# Remove bookmark from roster 614# 615 616proc conferences::remove_bookmark {xlib jid} { 617 variable bookmarks 618 619 if {[roster::itemconfig $xlib $jid -subsc] != "bookmark"} return 620 621 if {![info exists bookmarks($xlib,jid,$jid)]} return 622 623 client:roster_push $xlib $jid \ 624 -name $bookmarks($xlib,name,$jid) \ 625 -groups $bookmarks($xlib,groups,$jid) \ 626 -subscription remove 627 628 if {[set idx [lsearch -exact $bookmarks($xlib) $jid]] >= 0} { 629 set bookmarks($xlib) [lreplace $bookmarks($xlib) $idx $idx] 630 } 631 catch { unset bookmarks($xlib,jid,$jid) } 632 catch { unset bookmarks($xlib,name,$jid) } 633 catch { unset bookmarks($xlib,nick,$jid) } 634 catch { unset bookmarks($xlib,password,$jid) } 635 catch { unset bookmarks($xlib,autojoin,$jid) } 636 catch { unset bookmarks($xlib,groups,$jid) } 637 catch { unset bookmarks($xlib,hasgroups,$jid) } 638 639 store_bookmarks $xlib 640 641 return stop 642} 643 644hook::add roster_remove_item_hook \ 645 [namespace current]::conferences::remove_bookmark 646 647############################################################################### 648# 649# Rename group in roster bookmarks 650# 651 652proc conferences::rename_group {xlib name new_name} { 653 variable bookmarks 654 655 set store 0 656 foreach idx [array names bookmarks $xlib,jid,*] { 657 set jid $bookmarks($idx) 658 659 set groups $bookmarks($xlib,groups,$jid) 660 if {[lcontain $groups $name] || \ 661 ($name == $roster::undef_group_name && $groups == {})} { 662 set idx [lsearch -exact $groups $name] 663 if {$new_name != ""} { 664 set groups [lreplace $groups $idx $idx $new_name] 665 } else { 666 set groups [lreplace $groups $idx $idx] 667 } 668 set groups [lrmdups $groups] 669 client:roster_push $xlib $jid \ 670 -name $bookmarks($xlib,name,$jid) \ 671 -groups $groups \ 672 -subscription bookmark 673 roster::override_category_and_subtype $xlib $jid conference "" 674 set bookmarks($xlib,groups,$jid) $groups 675 set store 1 676 } 677 } 678 if {$store} { 679 store_bookmarks $xlib 680 } 681} 682 683hook::add roster_rename_group_hook \ 684 [namespace current]::conferences::rename_group 685 686############################################################################### 687# 688# Remove group name from roster bookmarks 689# 690 691proc conferences::remove_bookmarks_group {xlib name} { 692 variable bookmarks 693 694 set store 0 695 foreach idx [array names bookmarks $xlib,jid,*] { 696 set jid $bookmarks($idx) 697 698 set groups $bookmarks($xlib,groups,$jid) 699 if {[lcontain $groups $name] || \ 700 (($name == $roster::undef_group_name) && ($groups == {}))} { 701 702 client:roster_push $xlib $jid \ 703 -name $bookmarks($xlib,name,$jid) \ 704 -groups $groups \ 705 -subscription remove 706 707 if {[set idx [lsearch -exact $bookmarks($xlib) $jid]] >= 0} { 708 set bookmarks($xlib) [lreplace $bookmarks($xlib) $idx $idx] 709 } 710 catch { unset bookmarks($xlib,jid,$jid) } 711 catch { unset bookmarks($xlib,name,$jid) } 712 catch { unset bookmarks($xlib,nick,$jid) } 713 catch { unset bookmarks($xlib,password,$jid) } 714 catch { unset bookmarks($xlib,autojoin,$jid) } 715 catch { unset bookmarks($xlib,groups,$jid) } 716 catch { unset bookmarks($xlib,hasgroups,$jid) } 717 718 set store 1 719 } 720 } 721 if {$store} { 722 store_bookmarks $xlib 723 } 724} 725 726hook::add roster_remove_users_group_hook \ 727 [namespace current]::conferences::remove_bookmarks_group 728 729############################################################################### 730# 731# Join group on roster item doubleclick 732# 733 734proc conferences::join_group {xlib jid} { 735 variable bookmarks 736 737 set args {} 738 if {$bookmarks($xlib,nick,$jid) != ""} { 739 set nick $bookmarks($xlib,nick,$jid) 740 } else { 741 set nick [get_group_nick $xlib $jid] 742 } 743 if {$bookmarks($xlib,password,$jid) != ""} { 744 set password $bookmarks($xlib,password,$jid) 745 } else { 746 set password "" 747 } 748 muc::join_group_raise $xlib $jid $nick $password 749} 750 751############################################################################### 752# 753# Join group during autojoin 754# 755 756proc conferences::autojoin_group {xlib jid} { 757 variable bookmarks 758 759 if {$bookmarks($xlib,nick,$jid) != ""} { 760 set nick $bookmarks($xlib,nick,$jid) 761 } else { 762 set nick [get_group_nick $xlib $jid] 763 } 764 if {$bookmarks($xlib,password,$jid) != ""} { 765 set password $bookmarks($xlib,password,$jid) 766 } else { 767 set password "" 768 } 769 after idle [list muc::join_group $xlib $jid $nick $password] 770} 771 772############################################################################### 773# 774# Autojoin groups 775# 776 777proc conferences::autojoin_groups {xlib} { 778 variable options 779 variable bookmarks 780 781 if {$options(ignore_autojoin)} return 782 783 foreach idx [array names bookmarks $xlib,jid,*] { 784 set jid $bookmarks($idx) 785 set chatid [chat::chatid $xlib $jid] 786 if {$bookmarks($xlib,autojoin,$jid) && ![chat::is_opened $chatid]} { 787 autojoin_group $xlib $jid 788 } 789 } 790} 791 792############################################################################### 793# 794# "Join" item in roster conference popup menu 795# 796 797proc conferences::popup_menu {m xlib jid} { 798 variable bookmarks 799 800 set args {} 801 if {[roster::itemconfig $xlib $jid -subsc] == "bookmark"} { 802 if {$bookmarks($xlib,nick,$jid) != ""} { 803 lappend args -nick $bookmarks($xlib,nick,$jid) 804 } 805 if {$bookmarks($xlib,password,$jid) != ""} { 806 lappend args -password $bookmarks($xlib,password,$jid) 807 } 808 } 809 810 $m add command -label [::msgcat::mc "Join..."] \ 811 -command [list eval [list join_group_dialog $xlib \ 812 -server [::xmpp::jid::server $jid] \ 813 -group [::xmpp::jid::node $jid]] \ 814 $args] 815 816 # TODO: Check for real MUC? Move to muc.tcl? 817 ::add_muc_menu_items $m $xlib $jid 818} 819 820hook::add roster_conference_popup_menu_hook \ 821 [namespace current]::conferences::popup_menu 20 822 823############################################################################### 824# 825# Roster doubleclick 826# 827 828proc conferences::roster_doubleclick {xlib jid category subtype} { 829 switch -- $category { 830 conference { 831 if {[roster::itemconfig $xlib $jid -subsc] == "bookmark"} { 832 join_group $xlib $jid 833 } else { 834 muc::join_group_raise $xlib $jid [get_group_nick $xlib $jid] 835 } 836 return stop 837 } 838 } 839} 840 841hook::add roster_jid_doubleclick \ 842 [namespace current]::conferences::roster_doubleclick 843 844############################################################################### 845# 846# Main menu setup 847# 848 849proc conferences::main_menu {} { 850 set m [.mainframe getmenu services] 851 $m insert 2 command -label [::msgcat::mc "Add conference to roster..."] \ 852 -command [list [namespace current]::add_conference_dialog ""] 853} 854 855hook::add finload_hook [namespace current]::conferences::main_menu 856 857############################################################################### 858# 859# Edit roster item 860# 861 862proc conferences::edit_item_setup {f xlib jid} { 863 variable egra_name 864 variable egra_nick 865 variable egra_password 866 variable egra_autojoin 867 variable bookmarks 868 869 if {[roster::itemconfig $xlib $jid -subsc] != "bookmark"} return 870 871 set tf [TitleFrame $f.prop \ 872 -text [::msgcat::mc "Edit properties for %s" $jid]] 873 set slaves [pack slaves $f] 874 if {$slaves == ""} { 875 pack $tf -side top -expand yes -fill both 876 } else { 877 pack $tf -side top -expand yes -fill both -before [lindex $slaves 0] 878 } 879 set g [$tf getframe] 880 881 set egra_name $bookmarks($xlib,name,$jid) 882 set egra_autojoin [string is true -strict $bookmarks($xlib,autojoin,$jid)] 883 if {[info exists bookmarks($xlib,nick,$jid)]} { 884 set egra_nick $bookmarks($xlib,nick,$jid) 885 } else { 886 set egra_nick "" 887 } 888 if {[info exists bookmarks($xlib,password,$jid)]} { 889 set egra_password $bookmarks($xlib,password,$jid) 890 } else { 891 set egra_password "" 892 } 893 894 label $g.lname -text [string trim [::msgcat::mc "Name: "]] 895 entry $g.name -textvariable [namespace current]::egra_name 896 label $g.lnick -text [::msgcat::mc "Nick:"] 897 entry $g.nick -textvariable [namespace current]::egra_nick 898 label $g.lpassword -text [::msgcat::mc "Password:"] 899 entry $g.password -show * -textvariable [namespace current]::egra_password 900 checkbutton $g.autojoin \ 901 -text [::msgcat::mc "Automatically join conference upon connect"] \ 902 -variable [namespace current]::egra_autojoin 903 grid columnconfigure $g 0 -weight 0 904 grid columnconfigure $g 1 -weight 1 905 906 grid $g.lname -row 0 -column 0 -sticky e 907 grid $g.name -row 0 -column 1 -sticky ew 908 grid $g.lnick -row 1 -column 0 -sticky e 909 grid $g.nick -row 1 -column 1 -sticky ew 910 grid $g.lpassword -row 2 -column 0 -sticky e 911 grid $g.password -row 2 -column 1 -sticky ew 912 grid $g.autojoin -row 3 -column 0 -sticky w -columnspan 2 913 914 return stop 915} 916 917hook::add roster_itemedit_setup_hook \ 918 [namespace current]::conferences::edit_item_setup 919 920proc conferences::commit_bookmark_changes {xlib jid groups} { 921 variable egra_name 922 variable egra_nick 923 variable egra_password 924 variable egra_autojoin 925 926 if {[roster::itemconfig $xlib $jid -subsc] != "bookmark"} return 927 928 plugins::conferences::update_bookmark $xlib $jid \ 929 -name $egra_name -nick $egra_nick -password $egra_password \ 930 -autojoin $egra_autojoin -groups $groups 931 932 return stop 933} 934 935hook::add roster_itemedit_commit_hook \ 936 [namespace current]::conferences::commit_bookmark_changes 937 938############################################################################### 939 940proc conferences::disco_node_menu_setup {m bw tnode data parentdata} { 941 lassign $data type xlib jid node 942 lassign $parentdata ptype pxlib pjid pnode 943 switch -- $type { 944 item - 945 item2 { 946 set identities [::disco::browser::get_identities $bw $tnode] 947 948 if {[lempty $identities]} { 949 set identities [::disco::browser::get_parent_identities $bw $tnode] 950 } 951 952 # JID with resource is not a room JID 953 if {[::xmpp::jid::resource $jid] != ""} return 954 955 foreach id $identities { 956 if {[::xmpp::xml::getAttr $id category] == "conference"} { 957 $m add command -label [::msgcat::mc "Add conference to roster..."] \ 958 -command [list [namespace current]::add_conference_dialog $xlib \ 959 -group [::xmpp::jid::node $jid] \ 960 -server [::xmpp::jid::server $jid]] 961 break 962 } 963 } 964 } 965 } 966} 967 968hook::add disco_node_menu_hook \ 969 [namespace current]::conferences::disco_node_menu_setup 50 970 971# vim:ts=8:sw=4:sts=4:noet 972