tkabber-0.11.1/0000755000175000017500000000000011076120366012524 5ustar sergeisergeitkabber-0.11.1/balloon.tcl0000644000175000017500000001204410701766224014662 0ustar sergeisergei# $Id: balloon.tcl 1251 2007-10-06 20:14:12Z sergei $ option add *Balloon*background LightYellow widgetDefault option add *Balloon*foreground Black widgetDefault option add *Balloon.style delay widgetDefault option add *Balloon.text.padX 1 widgetDefault option add *Balloon.text.padY 1 widgetDefault toplevel .balloon -bd 0 -class Balloon bind .balloon \ [list balloon::default_balloon .balloon leave %X %Y] pack [message .balloon.text -text "" \ -aspect 5000 \ -width 0 \ -relief solid \ -bd 1] if {$::tcl_platform(platform) == "macintosh"} { catch { unsupported1 style .balloon floating sideTitlebar } } elseif {$::aquaP} { ::tk::unsupported::MacWindowStyle style .balloon help none } else { wm transient .balloon . wm overrideredirect .balloon 1 } wm withdraw .balloon namespace eval balloon { variable _id "" variable _delay 600 variable _cur "" variable balloon_showed 0 variable balloon_remove 0 set style [option get .balloon style Balloon] } proc balloon::set_text {text args} { set width 0 set aspect 5000 foreach {opt val} $args { switch -- $opt { -width { set width $val } -aspect { set aspect $val } } } after idle [list .balloon.text configure -text $text \ -aspect $aspect \ -width $width] } proc balloon::show {mx my} { variable balloon_showed variable balloon_remove variable max_bx if {[.balloon.text cget -text] == ""} { balloon::destroy return } set balloon_showed 1 set balloon_remove 0 set b_w [winfo reqwidth .balloon] set b_h [winfo reqheight .balloon] if {$::tcl_platform(platform) == "windows" && \ ($mx >= [winfo screenwidth .] || $my >= [winfo screenheight .] || $mx < 0 || $my < 0)} { set b_x [expr {$mx + 1}] set b_y [expr {$my + 1}] } else { set max_bx [expr {[winfo screenwidth .] - $b_w}] set max_by [expr {[winfo screenheight .] - $b_h}] set b_x [expr {$mx + 12}] set b_y [expr {$my + 15}] set b_x [max [min $b_x $max_bx] 0] set b_y [max [min $b_y $max_by] 0] if {($mx >= $b_x) && ($mx <= $b_x+$b_w)} { if {($my >= $b_y) && ($my <= $b_y+$b_h)} { set b_y1 [expr {$my - 5 - $b_h}] if {$b_y1 >= 0} { set b_y $b_y1 } } } } wm geometry .balloon +$b_x+$b_y wm deiconify .balloon # need the raise in case we're ballooning over a detached menu (emoticons) raise .balloon } proc balloon::set_delay {w mx my} { variable balloon_showed variable balloon_remove variable _id variable _delay variable _cur if {$_cur != $w} { if {$_id != ""} { after cancel $_id } set _id [after $_delay "balloon::show $mx $my"] set _cur $w wm withdraw .balloon set balloon_showed 0 set balloon_remove 0 } else { set balloon_remove 0 if {$balloon_showed == 0} { if {$_id != ""} { after cancel $_id } set _id [after $_delay "balloon::show $mx $my"] } } } proc balloon::on_mouse_move {w mx my} { variable style switch -- $style { delay {set_delay $w $mx $my} follow {show $mx $my} } } proc balloon::destroy {} { variable balloon_showed variable balloon_remove variable _id if {$_id != ""} { after cancel $_id set _id "" } set balloon_remove 1 after 100 { if {$balloon::balloon_remove} { wm withdraw .balloon set balloon::balloon_showed 0 set balloon::balloon_remove 0 } } } proc balloon::default_balloon {w action X Y args} { set sw $w set text "" set command "" set newargs $args # $args may contain odd number of members, so a bit unusual parsing set idx 0 foreach {opt val} $args { switch -- $opt { -text { set text $val set newargs [lreplace $newargs $idx [expr {$idx + 1}]] } -command { set command $val set newargs [lreplace $newargs $idx [expr {$idx + 1}]] } default { incr idx 2 } } } if {$command != ""} { set newargs [lassign [eval $command $newargs] sw text] } switch -- $action { enter { eval [list balloon::set_text $text] $newargs } motion { balloon::on_mouse_move $sw $X $Y } leave { balloon::destroy } } } proc balloon::setup {w args} { # Try to bind in Tree widget if {![catch { $w bindText \ [list eval [list [namespace current]::default_balloon $w enter %X %Y] \ [double% $args]] }]} { $w bindText \ [list eval [list [namespace current]::default_balloon $w motion %X %Y] \ [double% $args]] $w bindText \ [list balloon::default_balloon $w leave %X %Y] } else { bind $w \ [list eval [list [namespace current]::default_balloon $w enter %X %Y] \ [double% $args]] bind $w \ [list eval [list [namespace current]::default_balloon $w motion %X %Y] \ [double% $args]] bind $w \ [list balloon::default_balloon $w leave %X %Y] } } tkabber-0.11.1/README0000644000175000017500000026067511076045704013426 0ustar sergeisergei A. Shchepin Process-One M. Rose Dover Beach Consulting, Inc. S. Golovan New Economic School M. Litvak Colocall Ltd. K. Khomoutov Service 007 June 2008 Tkabber 0.11.1 Abstract _Tkabber_ is an open source Jabber client, written in _Tcl/Tk_. This memo describes the installation, configuration, and extension of _Tkabber_. Shchepin, et al. [Page 1] Tkabber 0.11.1 June 2008 Table of Contents 1. Features . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 2. Requirements . . . . . . . . . . . . . . . . . . . . . . . . . 7 3. Download, install and run . . . . . . . . . . . . . . . . . . 10 4. Upgrading from version 0.10.0 . . . . . . . . . . . . . . . . 12 4.1. Configuration options . . . . . . . . . . . . . . . . . . 12 4.1.1. Proxy servers . . . . . . . . . . . . . . . . . . . . 12 4.1.2. Resources to control fonts . . . . . . . . . . . . . . 13 4.1.3. Keep-alives and dead link detection . . . . . . . . . 13 4.1.4. Resources to control appearance of balloon windows . . 14 4.1.5. Support for external XML parser . . . . . . . . . . . 14 4.2. User interface . . . . . . . . . . . . . . . . . . . . . . 14 4.2.1. System tray icon mouse gestures . . . . . . . . . . . 15 4.2.2. New tab management widget . . . . . . . . . . . . . . 15 4.2.3. Window splitters . . . . . . . . . . . . . . . . . . . 15 5. Upgrading from version 0.9.9 . . . . . . . . . . . . . . . . . 16 6. Configuration . . . . . . . . . . . . . . . . . . . . . . . . 17 6.1. Pre-load . . . . . . . . . . . . . . . . . . . . . . . . . 19 6.1.1. Tabbed Interface . . . . . . . . . . . . . . . . . . . 20 6.1.2. Fonts and colors . . . . . . . . . . . . . . . . . . . 20 6.1.3. Cryptography by default . . . . . . . . . . . . . . . 22 6.1.4. Using of external XML parser from tDOM . . . . . . . . 22 6.1.5. Debugging Output . . . . . . . . . . . . . . . . . . . 22 6.1.6. Splash window . . . . . . . . . . . . . . . . . . . . 23 6.1.7. I18n/L10n . . . . . . . . . . . . . . . . . . . . . . 23 6.1.8. Searching . . . . . . . . . . . . . . . . . . . . . . 23 6.2. Post-load . . . . . . . . . . . . . . . . . . . . . . . . 24 6.2.1. Look-and-Feel . . . . . . . . . . . . . . . . . . . . 27 6.2.2. The Autoaway Module . . . . . . . . . . . . . . . . . 28 6.2.3. The Avatar Module . . . . . . . . . . . . . . . . . . 29 6.2.4. The Chat Module . . . . . . . . . . . . . . . . . . . 29 6.2.5. The Clientinfo Module . . . . . . . . . . . . . . . . 29 6.2.6. The Conferenceinfo Module . . . . . . . . . . . . . . 29 6.2.7. The Cryptographic Module . . . . . . . . . . . . . . . 30 6.2.8. The Emoticons Module . . . . . . . . . . . . . . . . . 30 6.2.9. The File Transfer Module . . . . . . . . . . . . . . . 30 6.2.10. The Groupchat Module . . . . . . . . . . . . . . . . . 31 6.2.11. The Ispell Module . . . . . . . . . . . . . . . . . . 31 6.2.12. The Stream Initiation Module . . . . . . . . . . . . . 32 6.2.13. The Logger Module . . . . . . . . . . . . . . . . . . 32 6.2.14. The Login Module . . . . . . . . . . . . . . . . . . . 32 6.2.15. The Message Module . . . . . . . . . . . . . . . . . . 34 6.2.16. The Raw XML Input Module . . . . . . . . . . . . . . . 34 6.2.17. The Roster Module . . . . . . . . . . . . . . . . . . 34 6.2.18. The Sound Module . . . . . . . . . . . . . . . . . . . 34 6.3. Menu-load . . . . . . . . . . . . . . . . . . . . . . . . 36 6.3.1. The Avatar Module . . . . . . . . . . . . . . . . . . 37 Shchepin, et al. [Page 2] Tkabber 0.11.1 June 2008 6.3.2. The Browser Module . . . . . . . . . . . . . . . . . . 37 6.3.3. The Groupchat Module . . . . . . . . . . . . . . . . . 37 6.3.4. The Login Module . . . . . . . . . . . . . . . . . . . 37 6.3.5. The Message Module . . . . . . . . . . . . . . . . . . 37 6.3.6. The Presence Module . . . . . . . . . . . . . . . . . 37 6.3.7. Miscellany . . . . . . . . . . . . . . . . . . . . . . 38 6.4. Final-Load . . . . . . . . . . . . . . . . . . . . . . . . 38 7. Extensibility . . . . . . . . . . . . . . . . . . . . . . . . 40 7.1. Chat Hooks . . . . . . . . . . . . . . . . . . . . . . . . 41 7.2. Login Hooks . . . . . . . . . . . . . . . . . . . . . . . 43 7.3. Presence Hooks . . . . . . . . . . . . . . . . . . . . . . 43 7.4. Roster Hooks . . . . . . . . . . . . . . . . . . . . . . . 44 7.5. Miscellaneous Hooks . . . . . . . . . . . . . . . . . . . 45 8. User Interface basics . . . . . . . . . . . . . . . . . . . . 46 8.1. Searching . . . . . . . . . . . . . . . . . . . . . . . . 46 Appendix A. Releases History . . . . . . . . . . . . . . . . . . 48 A.1. Main changes in 0.11.1 . . . . . . . . . . . . . . . . . . 48 A.2. Main changes in 0.11.0 . . . . . . . . . . . . . . . . . . 48 A.3. Main changes in 0.10.0 . . . . . . . . . . . . . . . . . . 49 A.4. Main changes in 0.9.9 . . . . . . . . . . . . . . . . . . 50 A.5. Main changes in 0.9.8 . . . . . . . . . . . . . . . . . . 50 A.6. Main changes in 0.9.7beta . . . . . . . . . . . . . . . . 50 A.7. Main changes in 0.9.6beta . . . . . . . . . . . . . . . . 51 A.8. Main changes in 0.9.5beta . . . . . . . . . . . . . . . . 51 Appendix B. Tk option database resources . . . . . . . . . . . . 52 Appendix C. Documentation TODO . . . . . . . . . . . . . . . . . 56 Appendix D. Acknowledgements . . . . . . . . . . . . . . . . . . 57 Appendix E. Copyrights . . . . . . . . . . . . . . . . . . . . . 58 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 59 Shchepin, et al. [Page 3] Tkabber 0.11.1 June 2008 1. Features Tkabber [1] provides a _Tcl/Tk_ interface to the Jabber/XMPP [2] instant messaging and presence service. _Tcl/Tk_ is a graphical scripting language that runs on the Unix, Windows, and Macintosh platforms. The choice of _Tcl/Tk_ for a Jabber client is three-fold: o it is portable: once you install a _Tcl/Tk_ interpreter on your system, the _Tkabber_ script "just runs" -- without having to compile anything; o it is customizable: _Tkabber_ reads a configuration file when it starts that tells it the settings of various parameters; and, o it is extensible: the configuration file is actually a _Tcl_ script, so you can replace or augment entire portions of _Tkabber_ (if you're so inclined). _Tkabber_ is fully-featured: sessions: * TCP and HTTP-polling session transports * XMPP SRV and TXT DNS-records handling * hashed passwords * SASL authentication * encrypted sessions (if you install an optional extension) * compressed sessions (if you install an optional extension) * login via SOCKS4a, SOCKS5 or HTTPS proxy * user-defined hooks for connection establishment and release * XMPP/Jabber MIME type messages: * privacy rules * signed/encrypted messages (if you install an optional extension) Shchepin, et al. [Page 4] Tkabber 0.11.1 June 2008 * file transfers (HTTP, SOCKS bytestream, DTCP and IBB transports) * groupchat (GroupChat-1.0 and Multi-User Chat conferencing protocols) * headline messages * message events * completions of nick and commands * hyperlinks * emoticons * user-defined hooks for chat window events presence: * signed presence (if you install an optional extension) * avatars * browsing * groupchat and roster invitations * conference room bookmarks * annotations about roster items * vCards * user-defined hooks for presence changes windowing: * configurable look-and-feel via a resources database * unicode * tabbed/non-tabbed interface * sound notifications * nested roster groups Shchepin, et al. [Page 5] Tkabber 0.11.1 June 2008 * for Unix: auto-away, spell checking, KDE or freedesktop docking, and WMaker icons * for Windows: auto-away, and taskbar icons Shchepin, et al. [Page 6] Tkabber 0.11.1 June 2008 2. Requirements You should already have installed: o Tcl/Tk version 8.3.3 [3] (or later, Tcl/Tk 8.4.9 or later is recommended) o tcllib version 1.2 [4] (or later, tcllib 1.8 or later is required for SRV and TXT DNS-records support). o BWidget 1.3 [4] (or later) Most systems already come with these packages pre-installed. If not, various Unix systems have them available as ready-made packages. Otherwise, go to the URLs above and click on the appropriate download link for your system. Both _tcllib_ and _BWidget_ are script libraries -- no compiling is necessary. In the case of _Tcl/Tk_, there are many ready-made binary packages available on the download site. The ActiveTcl [5] distribution contains all three packages (along with the _Img_ package mentioned next); so, you may want to use that instead of three separate downloads. At your discretion, there are several optional packages that you may also install. _Tkabber_ will run just fine without them, but if they're available _Tkabber_ will make additional features available to you. So, here's the list: o _Tcl/Tk_ supports only a small number of image formats (i.e., bitmaps, GIFs and portable pixmaps). If presence information contains avatars, these may be in other formats (e.g., PNGs or JPGs). Accordingly, you may want to install Img version 1.2 [6] (or later). This package works on both Unix and Windows. o By default, Tkabber uses pure-Tcl XML parser. If its performance is insufficient, you may want to install tDOM version 0.8.0 [7] (or later) and use expat based XML parser. o By default, communications between the server and client take place over a plaintext connection. While this may not be a problem in some local, wired environments, if your server is distant or your client is wireless, then you may want to encrypt all the client/server traffic. Accordingly, you may to install tls version 1.4.1 [8] (or later). This package works on both Unix and Windows. Note that if you're Shchepin, et al. [Page 7] Tkabber 0.11.1 June 2008 using Unix, then you'll also need to have _OpenSSL_ installed. Fortunately, this comes preinstalled on many Unix systems. If it's not on your system, check OpenSSL source page [9]. (The Windows distribution of _tls_ comes with all the necessary DLLs.) o Another option in Unix is to compress connection between client and server (it currently disables encryption). If you want to compress traffic you should install ZTcl version 1.0b4 [10] (or later) and Tclmore version 0.7b1 [10] (or later). (At the time of 0.11.0 release _ZTcl_ and _Tclmore_ home page were unavailable, so you may grab them from a mirror [11].) o By default, end-to-end communications between two or more Jabber clients is plaintext. Depending on your environment, this may not be a problem for you. Alternatively, you may want to digitally- sign all of your outgoing messages, and allow others to encrypt their messages to you. Accordingly, you may want to install the _gpgme_ package, which, at present, works only on Unix. Depending on what's already installed on your system, you may have to download upto three files: * Tcl GPGME version 1.0 [12] (or later); * GPGME version 0.3.11 [13] (or later but only 0.3.x); and, * GPG version 1.0.7 [14] (or later). o If you're running Unix or Windows, then you may want _Tkabber_ to automatically mark you as away after a priod of inactivity. Accordingly (if you're using _Tcl/Tk_ 8.3 or 8.4), on Unix, you may want to install Tk Xwin version 1.0 [15] (or later), whilst on WIndows, you may want to install Tcl Winidle version 0.1 [16] (or later). o Users of _Tcl/Tk_ 8.5 don't have to use external packages to measure their idle time. o If you're running Unix, then you may want _Tkabber_ to use the docking tray. Accordingly, you may want to install Tk Theme version 1.20 [17] (or later) for _KDE_ icon, or tktray version 1.1 [18] (or later) for freedesktop icon (supported by modern _KDE_ and _GNOME_). Shchepin, et al. [Page 8] Tkabber 0.11.1 June 2008 o If you're running Windows, then you may want _Tkabber_ to use the system tray. Accordingly, you may want to install Winico version 0.6 [19] (or later). o If you're a Tcl/Tk guru, then you may want to access the Tk console to debug things. Accordingly, you may want to install tkcon version 2.3 [20] (or later). Please keep in mind that these are all "optional extras" -- if they're not right for you or your environment, don't bother with them! Shchepin, et al. [Page 9] Tkabber 0.11.1 June 2008 3. Download, install and run Latest stable version is 0.11.1 and available at http://tkabber.jabber.ru/download. Older versions can be found at http://files.jabber.ru/tkabber/. You can always find the latest development version via SVN. Execute the following command: svn co https://svn.xmpp.ru/repos/tkabber/trunk/tkabber And if you want to test some plugins, then do svn co https://svn.xmpp.ru/repos/tkabber/trunk/tkabber-plugins If you use the Debian GNU/Linux distribution, you may want to get all required packages by using _apt_. Just execute apt-get install tk tcllib bwidget or apt-get install tkabber to get the version included into Debian repository. No real installation is required, simply copy the "tkabber/" directory to a commonly-available area, and then either: o put this directory in your search-path; or, o make a calling script/shortcut to the file "tkabber.tcl" in that directory. Although _Tkabber_ comes with a Makefile, there's really not much to do -- most folks prefer to simply copy the distribution directory to somewhere in their home directory. From the shell, you can invoke _Tkabber_ as: % tkabber.tcl whilst on a windowing system, simply double-click on that file or a short-cut to it. Shchepin, et al. [Page 10] Tkabber 0.11.1 June 2008 If you're a Tcl/Tk guru and have installed _tkcon_, then you may want to invoke _Tkabber_ as: % tkcon.tcl -exec "" -root .tkconn -main "source tkabber.tcl" _Tkabber_ will automatically know that it's running under _tkcon_ and will start by hiding the _Tk_ console window. Look under the "Help" menu to find the checkbutton to show the console. Also you can setup _Tkabber_ as handler for XMPP/Jabber MIME Type [21]. For this you need to set hanler for "application/xmpp+xml" MIME type in your browser to something like this: tkabber -mime %s Shchepin, et al. [Page 11] Tkabber 0.11.1 June 2008 4. Upgrading from version 0.10.0 When upgrading _Tkabber_ from version 0.10.0 or earlier note that several configuration options and user interface elements have been changed. 4.1. Configuration options There are notable changes in handling connection through proxy servers, managing fonts and balloon colors, and detecting breaks in underlying TCP connection to a server. 4.1.1. Proxy servers Since SOCKS4 and SOCKS5 proxy types were implemented in addition to HTTP proxy type, the whole set of connection options regarding proxy servers has been changed. This means that after upgrade the old values stored using the Customize mechanism will be lost and the same values in "loginconf" arrays will not be recognized any longer. If you do not use HTTP proxy, you can skip this section because these changes will not affect you. If your options are set using the _Customize_ interface, write down values for options relevant to proxy server from the "Login" group of _Customize_ settings, then after upgrade visit this group of settings, select "HTTPS" for the option "::loginconf(proxy)" and then fill in the rest of relevant settings with recorded values. As usual, save each setting after you change them. Do not be surprised with the word "HTTPS" (which stands for "HTTP over SSL"). It just means that _Tkabber_ will use CONNECT method to tunnel TCP connection through a proxy. If you maintain "loginconf" arrays in config.tcl, you have to modify each array using this scheme: o Rename variable "useproxy", if present, to just "proxy" and change its value to either "https" if "useproxy" was set to true or to "none" (yes, the word "none", do not leave it empty) if it was set to false. o Modify existing variables in these arrays using this map: * Rename "httpproxy" to "proxyhost". * Rename "httpport" to "proxyport". Shchepin, et al. [Page 12] Tkabber 0.11.1 June 2008 * Rename "httplogin" to "proxyusername". * Rename "httppassword" to "proxypassword". 4.1.2. Resources to control fonts Fonts handling has been partially reworked: the global variable "font" that controls chat and roster fonts has been removed and now _Tkabber_ relies on _Tk_ option database to manage these settings. You can override roster and chat fonts independently of each other. To do that on systems not based on X Window use _Customize_ options described below. The main consequence of this change is that now the fonts are taken from _Tk_ option database and if it contains sane values you don't need to touch anything (until the update you had to tweak the "font" variable because it was set to font "fixed" by default). The variable "font" does not have any special meaning starting from 0.11.0 release. The second consequence is that you are now able to set fonts for chat and roster windows separately from each other using this list as a reference: o "*font" _Tk_ option database resource sets default font for all widgets used in _Tkabber_. o "*Chat*Text.font" _Tk_ option database resource can be used to override font used for chat windows. This resource can be overridden by the "::ifacetk::options(font)" option from the "Main Interface" group of _Customize_ settings. o "*Roster*font" _Tk_ option database resource can be used to override font used for roster windows. This resource can be overridden by the "::ifacetk::options(roster_font)" option from the "Main Interface" group of _Customize_ settings. 4.1.3. Keep-alives and dead link detection Keep-alive mechanism that was used to keep NATP devices from disconnecting idle XMPP sessions was accompanied in 0.10.0 with "XMPP ping" mechanism which also implemented dead link detection with support for disconnecting upon detection of network outage. In version 0.11.0, the old keep-alive mechanism has been dropped, so the following two global options have no effect now: Shchepin, et al. [Page 13] Tkabber 0.11.1 June 2008 o "keep_alive" o "keep_alive_interval" In order to get the same functionality, enable XMPP ping using these options in the "IQ" group of Customize settings: o Enabling "::plugins::ping::options(ping)" will make _Tkabber_ periodically send xmpp:ping IQ request to the server. o Set "::plugins::ping::options(timeout)" option to a number of seconds _Tkabber_ should wait for either a xmpp:ping reply or an error to arrive from the server; if there is no answer from the server during this timeout, the socket for this connection will be forcibly disconnected. 4.1.4. Resources to control appearance of balloon windows Resources controlling the appearance of balloon windows have been made more generic. If you use custom _Tk_ option database settings for balloon windows, change the relevant resources using this map: o Change references to "*Balloon.background" and "*Balloon.foreground" resources to "*Balloon*background" and "*Balloon*foreground", respectively. o Change references to "*Balloon*padX" and "*Balloon*padY" resources to "*Balloon.text.padX" and "*Balloon.text.padY", respectively. 4.1.5. Support for external XML parser Support for _TclXML_ as an external XML parser has been removed (since _TclXML_ has anyway been unable to support partial XML processing) along with the global variable "use_external_tclxml" which controlled the loading of _TclXML_. Now expat-based _Tcl_ package _tDOM_ is supported as an external XML parser. It can be enabled by loading it manually in config.tcl using the Tcl package command, for example: package require tdom 4.2. User interface There are notable changes in systray mouse gestures, appearance of a main tabbed window, and in behavior of paned window splitters. Shchepin, et al. [Page 14] Tkabber 0.11.1 June 2008 4.2.1. System tray icon mouse gestures Mouse gestures bound to system tray (system notification area) icon have been reworked: o Single click on it with the left mouse button now unconditionally brings the main _Tkabber_ window to front, possibly deiconifying it first. o Single click with the middle mouse button now unconditionally iconifies the main _Tkabber_ window. This differs from the previois behaviour where single click with the left mouse button on _Tkabber_'s system tray icon toggled the iconified/visible state of the main _Tkabber_ window. 4.2.2. New tab management widget The _notebook_ widget which was used to render tabs in tabbed interface mode has been replaced with a new custom widget providing the ability for multi-row placement of tabs and docking them to the left or right sides of the chat window (in addition to top or bottom docking available in 0.10.0 version and earlier). If you adjusted any specific _Tk_ option database resources pertaining to that _notebook_ widget, you have to change them keeping in mind that the new widget is just a bunch of _Tk_ buttons (class "Button") placed in a frame (called ".nb" as before). The class name for the new widget is "ButtonBar". So if you explicitly set, say "*Notebook*font" option, you have to change it to "*ButtonBar*font" and so on. 4.2.3. Window splitters Window splitters (thin vertical and horizontal windows used to change relative sizes of windows between which a splitter is placed) have been changed to "Windows" style. This differs from previous "Motif" style which implemented explicit "grip box" on each splitter which was the only "active point" of a splitter. Shchepin, et al. [Page 15] Tkabber 0.11.1 June 2008 5. Upgrading from version 0.9.9 When upgrading _Tkabber_ from version 0.9.9 or earlier note the following: o On Macintosh or Microsoft Windows _Tkabber_ will copy it's configuration directory to a new location (see the next section (Section 6) for details). If the transfer of the config directory goes smoothly you may delete old ""~/.tkabber"" directory and replace its name in your config file by "$::configdir". o Also, _Tkabber_ will convert chatlogs directory to a new format. o Also, _Tkabber_ changed the way it works with emoticons. Instead of loading them in config file you may put you faivorite emoticons directory into "$::configdir/plugins" directory, restart Tkabber and then choose emoticons set using Customize GUI. Shchepin, et al. [Page 16] Tkabber 0.11.1 June 2008 6. Configuration _Tkabber_ maintains its configuration using a set of files placed in a special configuration directory which location depends on the operating system _Tkabber_ runs on. These locations are: o Unix systems: ""~/.tkabber""; o Macintosh: ""~/Library/Application Support/Tkabber""; o Under Microsoft Windows this location is governed by the policy of the particular flavor of this OS, but the general rule is that the _Tkabber_ configuration directory is named ""Tkabber"" and is located in the special system folder for storing application- specific data. For example, under Windows XP this will be something like ""C:\Documents and Settings\USERNAME\Application Data\Tkabber"", where ""USERNAME"" is the login name of a particular operating system's user. _Tkabber_ also honors the value of the ""TKABBER_HOME"" environment variable -- if it exists the whole OS-based guessing of the configuration directory location is cancelled and the value of this environment variable is used instead. Once the pathname of the _Tkabber_ configuration directory is known, its value is assigned to the ""configdir"" global Tcl variable which can be accessed from within the main _Tkabber_ configuration file (see below). One of the first things that _Tkabber_ does when it's starting up is reading a file located in its configuration directory under the name ""config.tcl"". This is a _Tcl_ source file, so obviously, it's a lot easier to maintain this file if you know the Tcl programming language. If you're not familiar with it, that's okay -- most things you'll need to do are pretty simple! (In fact, if you don't have your own configuration file, you'll get the vanilla _Tkabber_, which hopefully you'll find quite usable.) Note that almost all _Tkabber_ options can be cofigured using graphical interface (menu Tkabber->Customize), so editing configuration file is not strictly necessary. _Tkabber_ is configured in four stages: o in the pre-load stage, configuration options which guide the loading process are set; Shchepin, et al. [Page 17] Tkabber 0.11.1 June 2008 o in the post-load stage, configuration options for each module are set; o in the menu-load stage, the user is given an option to re-arrange _Tkabber's_ menu bar; and, o the final-load stage allows any last changes to be made before the "login" dialog window is displayed to the user. Let's look at each, in turn. Shchepin, et al. [Page 18] Tkabber 0.11.1 June 2008 6.1. Pre-load There are a few things that you may let _Tkabber_ know immediately. These are: # tabbed interface set ifacetk::options(use_tabbar) 1 # primary look-and-feel set load_default_xrdb 1 option add *font \ "-monotype-arial-medium-r-normal-*-13-*-*-*-*-*-iso10646-1" \ userDefault # cryptography by default set ssj::options(sign-traffic) 0 set ssj::options(encrypt-traffic) 0 # using of external XML parser package require tdom 0.8 # debugging output set debug_lvls {jlib warning} # splash window set show_splash_window 0 # force english labels instead of native language ::msgcat::mclocale en Shchepin, et al. [Page 19] Tkabber 0.11.1 June 2008 6.1.1. Tabbed Interface The first of these options, "ifacetk::options(use_tabbar)", tells _Tkabber_ whether you want a tabbed interface or not. If not, here's what to put in your configuration file: set ifacetk::options(use_tabbar) 0 Although _Tkabber_ immediately applies most of its configuration changes, in order to apply changed option "ifacetk::options(use_tabbar)" you have to restart _Tkabber_. So, basically you have two options: set "ifacetk::options(use_tabbar)" at the beginning of your configuration file, or using graphical interface save the option and restart _Tkabber_. 6.1.2. Fonts and colors Many aspects of the _Tkabber_'s visual appearance such as fonts, colors and geometry of windows can be configured using the Tk option database. [22] The corresponding _Tk_'s option [23] command can be used in the _Tkabber_'s configuration file in any acceptable way: from small tweaks to reading files containing elaborate sets of configuration commands; ready-to-use examples of such files are included in the distribution and are located under the "examples/xrdb" directory. The _Tk_ toolkit is able to initialize its option database from the _XRDB_ (X Resource Database) if its availability is detected at run time. This means that any settings described here can be tuned via the standard XRDB mechanism (see "man xrdb"). Beware though that the _Tk_'s semantics of matching option specifications against the option database differ in some subtle details from that of the _Xt_ toolkit. The most notable one is the priority of options: _Tk_ prefers the latest option it sees, while _Xt_ prefers "the most specific" one. When specifying _Tkabber_-specific options in your _XRDB_ file use the "Tkabber" class as the root element of the options. See Appendix B for a list of all the resources that you can set to control _Tkabber's_ look-and-feel. Shchepin, et al. [Page 20] Tkabber 0.11.1 June 2008 Probably the most commonly used way to configure _Tkabber_'s visual appearance (especially on Windows platforms which lack _XRDB_ mechanism) is to put all the necessary settings in some file and then ask _Tk_ to update its option database from it, like this: set load_default_xrdb 0 option readfile $::configdir/newlook.xrdb userDefault The first line tells _Tkabber_ not to load its default "xrdb" file, whilst the second line tells _Tkabber_ which file to load instead. Look at the provided example "xrdb" files to get the idea about how they are organised. Of course, you can use any of that files as a template. And of course, you can simply specify any of the example files instead of your own to the "option readfile" command to get the provided "theme". Alternatively, if you're a Tcl "old timer", you can always do: set load_default_xrdb 0 tk_bisque to set the palette to a pleasing color scheme. Read more about this in "man palette". You can also customize the fonts _Tkabber_ uses to render its user interface: option add *font \ "-monotype-arial-medium-r-normal-*-13-*-*-*-*-*-iso10646-1" \ userDefault The above setting (operating on the Tk option database) selects the font used for all UI elements like buttons and labels and roster and conversation windows. Obviously, you should choose fonts that suit your taste. If you want to specify another font for roster labels use the following option: option add *Roster*font \ "-misc-fixed-medium-r-normal-*-12-*-*-*-*-*-iso10646-1" \ userDefault When picking fonts, observe these rules: o Under X, encoding (charset) of fonts must match that of your locale. Shchepin, et al. [Page 21] Tkabber 0.11.1 June 2008 o Ensure that the specified font exists, since if it's not, _Tk_ will try hard to pick the most suitable one which often yields not what you want. (The best bet is to first pick the font using some tool like "xfontsel".) Note that when specifying settings using the _Tkabber_'s configuration files (i.e. not using _XRDB_ directly) you are not forced to use "X-style" (XLFD) font descriptions and may instead specify fonts using sometimes more convenient _Tk_ features described in Tk font manual page. 6.1.3. Cryptography by default Next, you may want to _Tkabber_ to use cryptography by default. There are two options: o whether the traffic you send should be digitally-signed; and, o if you have cryptographic information for someone, should the default action be to encipher your traffic for them. (By defining these options early on, _Tkabber_ will complain immediately if it isn't able to load its cryptographic module; otherwise, the default behavior is to proceed without any cryptographic buttons, menus, and so on.) 6.1.4. Using of external XML parser from tDOM By default for parsing XML _Tkabber_ uses (modified) _TclXML_ library that comes with it distribution. This parser is pure-Tcl, and it performance can be not suitable. Then you can install _tDOM_ with built-in _expat_ support and require it in the config file: package require tdom 0.8 6.1.5. Debugging Output _Tkabber_ has a lot of debugging output. By default, it gets printed to the standard output by a Tcl procedure called "debugmsg". However, only information about those modules listed in a variable called "debug_lvls" will be printed. Shchepin, et al. [Page 22] Tkabber 0.11.1 June 2008 If you know how to program Tcl, then this will seem rather obvious: set debug_lvls [list message presence ssj warning] # if you want a different behavior, # define your own... proc debugmsg {module msg} { # ... } Most users won't care about "debugmsg" because they're running _Tkabber_ under an application launcher so the standard output is never seen. However, if this isn't the case for you, and you just don't want to see any of this stuff, put this one line in your configuration file: set debug_lvls {} 6.1.6. Splash window By default, when _Tkabber_ startup, it show loading process in splash window. To disable this feature, put this in your configuration file: set show_splash_window 0 6.1.7. I18n/L10n _Tkabber_ can show all messages in user's native language. This is done by using Tcl's built-in _msgcat_ package which looks for a directory called "msgs/" wherever you installed _Tkabber_, and then uses the "LC_MESSAGES" environment variable (or "LANG" if "LC_MESSAGES" not set) to select the appropriate file. If you wish, you can force use of a particular language by putting a line like this in your configuration file: ::msgcat::mclocale en 6.1.8. Searching _Tkabber_ allows the user to perform textual searching in certain classes of its windows. This searching is controlled by several settings which can be specified in this section. These settings are described in detail in Section 8.1. Shchepin, et al. [Page 23] Tkabber 0.11.1 June 2008 6.2. Post-load After _Tkabber_ reads your configuration file, it loads all of its own modules, it then invokes a procedure called "postload". This procedure is supposed to perform module-specific configuration. The default version of this procedure doesn't do anything. If you want to configure one more module modules, then you need to define the procedure in your configuration file, e.g., proc postload {} { # look-and-feel set pixmaps::options(pixmaps_theme) Default global alert colors alert_lvls set alert_lvls(error) 1 set alert_lvls(server) 1 set alert_lvls(message) 2 set alert_lvls(mesg_to_user) 3 set alert_colors {Black DarkBlue Blue Red} set ifacetk::options(raise_new_tab) 1 # the autoaway module set plugins::autoaway::options(awaytime) 5 set plugins::autoaway::options(xatime) 15 set plugins::autoaway::options(status) "Automatically away due to idle" set plugins::autoaway::options(drop_priority) 1 # the avatar module set avatar::options(announce) 0 set avatar::options(share) 0 # the chat module set chat::options(default_message_type) chat set chat::options(stop_scroll) 0 set plugins::options(timestamp_format) {[%R]} # the clientinfo module Shchepin, et al. [Page 24] Tkabber 0.11.1 June 2008 set plugins::clientinfo::options(autoask) 0 # the conferenceinfo module set plugins::conferenceinfo::options(autoask) 0 set plugins::conferenceinfo::options(interval) 1 set plugins::conferenceinfo::options(err_interval) 60 # the cryptographic module set ssj::options(encrypt,fred@example.com) 1 # the emoticon module set plugins::emoticons::options(theme) \ $::configdir/emoticons/rythmbox # the file transfer module set ft::options(download_dir) "/tmp" # the groupchat module global gra_group gra_server global gr_nick gr_group gr_server global defaultnick set defaultnick(adhoc@conference.example.com) publius set defaultnick(*@conference.example.com) cicerone # the ispell module set plugins::ispell::options(enable) 1 set plugins::ispell::options(executable) /usr/bin/ispell set plugins::ispell::options(command_line) -C -d russian set plugins::ispell::options(dictionary_encoding) koi8-r set plugins::ispell::options(check_every_symbol) 1 # the stream initiation module set si::transport(allowed,http://jabber.org/protocol/bytestreams) 0 set si::transport(allowed,http://jabber.org/protocol/ibb) 1 Shchepin, et al. [Page 25] Tkabber 0.11.1 June 2008 # the logger module set logger::options(logdir) [file join $::configdir logs] set logger::options(log_chat) 1 set logger::options(log_groupchat) 1 # the login module global loginconf loginconf1 loginconf2 autologin set loginconf(user) "" set loginconf(password) "" set loginconf(server) example.com set loginconf(resource) tkabber set loginconf(priority) 16 set loginconf(usealtserver) 0 set loginconf(altserver) "" set loginconf(altport) 5422 set loginconf(stream_options) plaintext set loginconf(proxy) https set loginconf(usesasl) 1 set loginconf(allowauthplain) 0 set loginconf(proxyhost) localhost set loginconf(proxyport) 3128 set loginconf(proxyusername) "" set loginconf(proxypassword) "" # The following variables are useful when your jabber-server # (example.com) does not have SRV or A-record in DNS set loginconf(usealtserver) 1 set loginconf(altserver) "jabber.example.com" set loginconf1(profile) "Default Account" set loginconf1(user) mrose set loginconf2(profile) "Test Account" set loginconf2(user) test array set loginconf [array get loginconf1] set autologin 0 # the message module set message::options(headlines,cache) 1 set message::options(headlines,multiple) 1 Shchepin, et al. [Page 26] Tkabber 0.11.1 June 2008 # the raw xml input module set plugins::rawxml::set options(pretty_print) 0 set plugins::rawxml::set options(indent) 2 # the roster module set roster::show_only_online 1 set roster::roster(collapsed,RSS) 1 set roster::roster(collapsed,Undefined) 1 set roster::aliases(friend@some.host) \ {friend@other.host friend@another.host} set roster::use_aliases 1 # the sound module set sound::options(mute) 0 set sound::options(mute_if_focus) 0 set sound::options(notify_online) 0 set sound::options(mute_groupchat_delayed) 1 set sound::options(mute_chat_delayed) 0 set sound::options(external_play_program) /usr/bin/aplay set sound::options(external_play_program_options) -q set sound::options(delay) set sound::options(connected_sound) "" set sound::options(presence_available_sound) "" set sound::options(presence_unavailable_sound) "" set sound::options(groupchat_server_message_sound) "" set sound::options(groupchat_their_message_to_me_sound) "" } This isn't nearly as complicated as it seems. Let's break it down by individual module 6.2.1. Look-and-Feel _Tkabber_ is shameless in borrowing icons from other Jabber clients. By setting "pixmaps::options(pixmaps_theme)", you can select a family of related icons. Besides ""Default"", you can choose one of ""Gabber"", ""JAJC"", ""Jarl"", ""Psi"", ""ICQ"", or a few other themes. If you want, you can have _Tkabber_ use a different theme by putting custom theme subdirectory to "$::configdir/pixmaps/" directory (tilde Shchepin, et al. [Page 27] Tkabber 0.11.1 June 2008 means home directory). _Tkabber_ knows that it is a theme directory by looking for "icondef.xml" file in the directory. To find out the structure of icon definition file, look through _XEP-0038_ and go to where you installed _Tkabber_ and take a look at the directory called ""pixmaps/default/"". If you're using the tabbed window interface, _Tkabber_ needs a way of telling you that something has changed in a window that's not on top. This is where the an array called _alert_lvls_ and a list called _alert_colors_ come in. The array maps an incoming message to a priority number from zero to three. The list, which is indexed starting at _zero_, indicates what color the tab should use to let you know that something's changed. So, the way to read the example is that receiving: o an error or server message will cause the tab of a lowered window to go dark blue; o a groupchat or headline message will cause the tab to go blue; and, o a chat message addressed directly to you will cause the tab to go red. By default, whenever a new tab is created, it is automatically raised. If you don't like this behavior, add this line: set ifacetk::options(raise_new_tab) 0 6.2.2. The Autoaway Module This module is presently available only if either: o on UNIX, if you have the _Tk Xwin_ extension installed; or, o On Windows, if you have the _Tcl Winidle_ extension installed. There are two variables that control when _Tkabber_ automatically marks you as away: "plugins::autoaway::options(awaytime)" and "plugins::autoaway::options(xatime)". Both define the idle threshold in minutes (the number does not have to be integer). If variable "plugins::autoaway::options(drop_priority)" is set in 1 then _Tkabber_ will set priority to 0 when moving in extended away state. Variable "plugins::autoaway::options(status)" allows to specify text status, which is set when _Tkabber_ is moving in away state. Shchepin, et al. [Page 28] Tkabber 0.11.1 June 2008 6.2.3. The Avatar Module There are two variables that you can set to control whether _Tkabber_ will allow others to see your avatar: o "avatar::options(announce)" determines whether your presence information indicates that you have an avatar; and, o "avatar::options(share)" determines whether requests for your avatar will be honored. 6.2.4. The Chat Module Most instant messaging users prefer to see all the back-and-forth communication in a single window. If you prefer to see each line sent back-and-forth in a separate window, here's what to put in your "postload": set chat::options(default_message_type) normal The variable named "chat::options(stop_scroll)" determines whether a chat window should automatically scroll down to the bottom whenever something new comes in. You can also set format of time stamp that displayed in beginning of each chat message. Refer to _Tcl_ documentation for description of format. E.g., to display it in ""dd:mm:ss"" format, add this line: set plugins::options(timestamp_format) {[%T]} 6.2.5. The Clientinfo Module This module shows in popup balloons information of used by this user client name, version, and OS. You can allow or deny automatic asking of this info from users by setting this variable to 1 or 0: set plugins::clientinfo::options(autoask) 1 6.2.6. The Conferenceinfo Module After you join a conference that's listed in your roster, then whenever you mouse over that roster entry, you'll see a popup listing the conference's participants. If you want to see this popup, regardless of whether you are currently joined with the conference, add this line to your post-load: set plugins::conferenceinfo::options(autoask) 1 Shchepin, et al. [Page 29] Tkabber 0.11.1 June 2008 You can also set interval between these requests with these two variables: set plugins::conferenceinfo::options(interval) 1 set plugins::conferenceinfo::options(err_interval) 60 The second variable defines how many minutes to wait after receiving an error reply before trying again. (Usually an error reply indicates that the server hosting the conference doesn't support browsing, so it makes sense not to try that often. 6.2.7. The Cryptographic Module Earlier (Section 6.1) we saw an example where the "ssj::options" array from the cryptographic module was set during the preload. In addition to "signed-traffic" and "encrypt-traffic", you can also tell _Tkabber_ whether to encrypt for a particular JID, e.g., set ssj::options(encrypt,fred@example.com) 1 6.2.8. The Emoticons Module The procedure called _plugins::emoticons::load_dir_ is used to load emoticon definitions from a directory. The directory contains a file called ""icondef.xml"", which defines the mapping between each image and its textual emoticon (To find out what this file looks like, go to where you installed _Tkabber_ and take a look at the file called ""emoticons/default/icondef.xml"" or read XEP-0038 [24].) If you have just a few icons, and you don't want to create a directory and a textual mapping, you can use the procedure called "plugins::emoticons::add", e.g., plugins::emoticons::add ":beer:" \ [image create photo -file $::configdir/emoticons/beer.gif] If you want to disable all emoticons, you can simply load empty directory. Put in postload function plugins::emoticons::load_dir "" 6.2.9. The File Transfer Module You can set directory in which files will be saved by default: set ft::options(download_dir) "/tmp" Shchepin, et al. [Page 30] Tkabber 0.11.1 June 2008 6.2.10. The Groupchat Module There are several variables that set the dialog window defaults for adding a groupchat to your roster, or joining a groupchat: add to roster dialog window: "gra_group" and "gra_server" specify the default room and conference server, repectively; and, join dialog window: "gr_nick", "gr_group" and "gr_server" specify the default nickname, room, and conference server, respectively. Note that variables "gra_server", "gr_nick" and "gr_server" overriden in login procedure, so better place for changing them is in "connected_hook" (see below). You may want to have different nicknames for different groupchats. Accordingly, the array called _defaultnick_ is used to set the default nickname for when you enter a conference. The array is indexed by the JID of the room, e.g., set defaultnick(adhoc@conference.example.com) publius Another possibility is to put pattern in parentheses. The following example shows how to specify default nickname for all conferences at _conference.example.com_: set defaultnick(*@conference.example.com) ciceroni Exact JID's take the higher precedence than patterns. 6.2.11. The Ispell Module On Unix, _Tkabber_ can check spelling of what you entered by calling an external program _ispell_. To enable this feature, add following lines to postload function: set plugins::ispell::options(enable) 1 If you enabled this module, then you can also define: o the path to the _ispell_ executable by setting "plugins::ispell::options(executable)" o the _ispell_ command line options by setting "plugins::ispell::options(command_line)"; and, o the encoding of the output by setting "plugins::ispell::options(dictionary_encoding)". Shchepin, et al. [Page 31] Tkabber 0.11.1 June 2008 If you don't care about putting a large load on your process, then you can also set "plugins::ispell::options(check_every_symbol)" to 1 to check correctness of current word after every entered symbol. (Usually you don't need to set this option.) 6.2.12. The Stream Initiation Module Stream initiation profile is defined in _XEP-0095_ with two transports (_XEP-0047_ - IBB, _XEP-0065_ - SOCKS5 bytestreams). With it you can specify what transports you can use, and via negotiation choose more appropriate one. _Tkabber_ comes with two transport implementations: bytestreams: that allows you to connect to any node that supports "bytestreams" transport (mediated connection is not supported yet); ibb: that uses your "Jabber" connection to transmit the data (which may slowdown other traffic to you). If your machine is behind a NAT, then you can't use the "bytestreams" transport, so you should disable it: set si::transport(allowed,http://jabber.org/protocol/bytestreams) 0 6.2.13. The Logger Module You can set directory to store logs: set logger::options(logdir) [file join $::configdir logs] Also you can allow or disallow storing of private and group chats logs: set logger::options(log_chat) 1 set logger::options(log_groupchat) 1 6.2.14. The Login Module The first task is to initialize the configuration defaults for the _login_ module. As you can see above, the global array "loginconf" has a whole bunch of elements, e.g., "user", "password", and so on. Elements "loginconf(user)" and "loginconf(password)"specify username and password to authenticate at your _Jabber_ server. Element "loginconf(server)" must be set to _Jabber_ server name (the part of you _JID_ after "@". Shchepin, et al. [Page 32] Tkabber 0.11.1 June 2008 Element "loginconf(stream_options)" is set to one of the following values: o plaintext -- use plaintext connection; o encrypted -- use encrypted (via STARTTLS mechanism) connection (this option requires tls extension to be installed); o ssl -- use encrypted (via legacy SSL mechanism) connection (this option requires tls extension to be installed); o compressed -- use compressed connection (this option requires Ztcl extension to be installed). _Tkabber_ tries to resolve _Jabber_ server name using _SRV_ first and usual _A_ records in _DNS_. If the resolution fails (for example if you are in LAN environment without _DNS_) you can force _Tkabber_ to connect to the server using "loginconf(altserver)" and "loginconf(altport)" options (do not forget to set "loginconf(usealtserver)" to "1"). Another option is to use _HTTP_-polling connect method (if your server supports it) and tunnel _XMPP_ traffic through _HTTP_. To enable _HTTP_-polling set "loginconf(usehttppoll)" to "1". _Tkabber_ then tries to find connect _URL_ using _TXT_ record in _DNS_ (see XEP-0156). You can specify _URL_ manually by setting "loginconf(pollurl)". This collection of elements, which is termed a login profile, is what populates the dialog window you'll see when _Tkabber_ wants to connect to the server. It turns out that _Tkabber_ lets you have as many different login profiles as you want. If you want more than just one, they're named "loginconf1", "loginconf2", and so on. What the example above shows is the default values for all profiles being set in "loginconf", and then two profiles, one called ""Default Account"" and the other called ""Test Account"" being created. If you want to automatically login to server, then you can set the "autologin" variable to "1". If you set the "autologin" variable to "-1", then _Tkabber_ will not automatically login and will not show login dialog. Default value for "autologin" is "0". In this case _Tkabber_ shows login dialog. Shchepin, et al. [Page 33] Tkabber 0.11.1 June 2008 6.2.15. The Message Module By default, when you restart _Tkabber_ it won't remember the headlines you received. If you want _Tkabber_ to remember headlines whenever you run it, set "message::options(headlines,cache)" to "1". By default, _Tkabber_ will put all headline messages into a single window. If you want _Tkabber_ to use a seperate window for each headline source, set "message::options(headlines,multiple)" to "1". 6.2.16. The Raw XML Input Module With this module you can monitor incoming/outgoing traffic from connection to server and send custom XML stanzas. Also you can switch on "pretty print" option to see incoming and outgoing XML stanzas pretty printed. Note, that with this option they may be drawed incorrectly, e.g. for XHTML tags. Also you can set indentation level via "indent" option. 6.2.17. The Roster Module By default, your entire roster is shown, even those items that aren't online. The variable called "roster::show_only_online" controls this. Similarly by default, each item in every category is shown in the roster. If you want to hide the items in a given category, the array called "roster::roster" lets you do this. In the example, we see that two groups (""RSS"" and ""Undefined"") start with their items hidden. Some peoples use several JIDs. _Tkabber_ lets you specify an alias for people like these, so it will show only one entry in the roster. In the example, we see that user "friend@some.host" have aliases "friend@other.host" and "friend@another.host". You can also disable all aliases by setting "roster::use_aliases" to "0". 6.2.18. The Sound Module _Tkabber_ can play sounds on some events. It can use for this _snack_ library or external program that can play _WAV_ files. Sound notifications is enabled when _Tkabber_ starts. If you want to start _Tkabber_ with sound muted add the following line: set sound::options(mute) 1 Shchepin, et al. [Page 34] Tkabber 0.11.1 June 2008 If you want _Tkabber_ to stop notifying you when you are not online (in away or dnd state) add the following line: set sound::options(notify_online) 1 If you want _Tkabber_ to mute sound when it is focued (and you are paying enough attention to it) add the following line: set sound::options(mute_if_focus) 1 You can also mute sounds of delayed groupchat messages and delayed personal chat messages: set sound::options(mute_groupchat_delayed) 1 set sound::options(mute_chat_delayed) 0 If you want to use external program for playing sounds and possibly this program's options, then also add something like this (these options are suitable for Linux users with ALSA installed): set sound::options(external_play_program) /usr/bin/aplay set sound::options(external_play_program_options) -q You can also set minimal interval (in milliseconds) between playing different sounds. set sound::options(delay) 200 _Tkabber_ allows you to specify the filename it will play notifying about some more or less important events. These are: o "sound::options(connected_sound)" -- sound playing when _Tkabber_ is connected to the server; o "sound::options(presence_available_sound)" -- sound playing when available presence is coming; o "sound::options(presence_unavailable_sound)" -- sound playing when unavailable presence is coming; o "sound::options(chat_my_message_sound)" -- sound playing when you send one-to-one chat message; o "sound::options(chat_their_message_sound)" -- sound playing when you receive one-to-one chat message; o "sound::options(groupchat_server_message_sound)" -- sound playing when you receive groupchat message from server; o "sound::options(groupchat_my_message_sound)" -- sound playing when you receive groupchat message from server; Shchepin, et al. [Page 35] Tkabber 0.11.1 June 2008 o "sound::options(groupchat_their_message_sound)" -- sound playing when you receive groupchat message from another user; o "sound::options(groupchat_their_message_to_me_sound)" -- sound playing when you receive highlighted (usually personally addressed) groupchat message from another user. If you want to disable sound notification for some of the events, then you can add line like this: set sound::options(connected_sound) "" set sound::options(presence_available_sound) "" set sound::options(presence_unavailable_sound) "" set sound::options(groupchat_server_message_sound) "" set sound::options(groupchat_their_message_to_me_sound) "" 6.3. Menu-load After _Tkabber_ invokes your "postload" procedure, it starts building the GUI. One of the most important things it does is build up a list that specifies its menu bar. It then invokes a procedure called "menuload", which is allowed to modify that specification before _Tkabber_ uses it. The default version of this procedure is the identity function, i.e.., proc menuload {description} { return $description } If you _really_ want to change the menubar specification, then here's how to get started: 1. Go to where you installed the _BWidget_ library and take a look at the file called ""BWman/MainFrame.html"". The documentation for the ""-menu"" option explains the syntax of the specification. 2. Go to where you installed _Tkabber_ and take a look at the file called ""iface.tcl"". Look for the line that starts with ""set descmenu"". This will show you the specification given to your "menuload" procedure. 3. Go to where you installed _Tkabber_ and take a look at the file called ""examples/mtr-config.tcl"". Look at the "menuload" procedure defined there. It lays out _Tkabber's_ menu bar similar to _Gabber's_. Shchepin, et al. [Page 36] Tkabber 0.11.1 June 2008 4. Finally, study the procedures listed here. 6.3.1. The Avatar Module The procedure called "avatar::store_on_server" stores your avatar on the server. 6.3.2. The Browser Module The procedure called "browser::open" opens a new browser window. 6.3.3. The Groupchat Module The procedure called "add_group_dialog" displays a dialog window when you want to add a groupchat to your roster. Similarly, the procedure called "join_group_dialog" displays a dialog window when you want to join a groupchat. 6.3.4. The Login Module The procedure called "show_login_dialog" displays a dialog window when you want to login to the server. (Prior to attempting to login, if necessary it will logout). Naturally, the procedure called "logout" does just that; however, if you want get a dialog window for confirmation, use "show_logout_dialog" instead. 6.3.5. The Message Module If you want to send a message to someone, the procedure called "message::send_dialog" will put up a dialog window. It takes upto three optional arguments: the recipient JID, the subject, and the thread. If you want to get added to someone's roster, the procedure called "message::send_subscribe_dialog" will put up a dialog window. It takes one optional argument: the recipient JID. If you want to adjust your message filters, the procecure called "filters::open" will put up a dialog window. 6.3.6. The Presence Module If you want to display information about a user, the procecure called "userinfo::open" will put up a dialog window. It takes two optional arguments: the user's JID; and, whether or not the dialog window should be editable. Shchepin, et al. [Page 37] Tkabber 0.11.1 June 2008 Obviously, the second argument makes sense only if it's your own information, i.e., global loginconf userinfo::open \ ${loginconf(user)}@$loginconf(server)/$loginconf(resource) 1 There are also two variables that you can use to set your own presence: "userstatus" and "textstatus". The first variable takes one of five values: o available; o chat; o away; o xa; o dnd; or, o invisible. The second variable takes any textual value. Changes to your presence information are propagated only when "userstatus" is changed. Accordingly, if you make a change to "textstatus", be sure to write "userstatus" immediately afterwards, even if it's a no-op, e.g., global userstatus textstatus set textstatus "Out to lunch" set userstatus $userstatus 6.3.7. Miscellany Finally, you can use the procedure named "help_window" to display some textual help. This procedure takes two arguments: the title for the window; and, the text to display. Also, instead of calling "exit" to terminate _Tkabber_, please use the "quit" procedure instead. 6.4. Final-Load Finally, right before _Tkabber_ goes to display the login dialog, it Shchepin, et al. [Page 38] Tkabber 0.11.1 June 2008 invokes a procedure called "finload", which does whatever you want it to. Shchepin, et al. [Page 39] Tkabber 0.11.1 June 2008 7. Extensibility In addition to various configuration mechanisms, _Tkabber_ lets you define procedures, termed "hooks" that get run when certain events happen. Here's an example. When _Tkabber_ receives a chat message, how does it know what to process and what to draw? The short answer is that it doesn't need to know anything, all it does is: hook::run draw_message_hook $chatid $from $type $body $extras The "hook::run" procedure invokes whatever hooks have been defined for "draw_message_hook". In fact, more than ten procedures may get invoked to satisfy this hook! Here's how it works: _Tkabber_ comes with a number of plugins, which get loaded automatically. Each plugin makes one or more calls that look like this: hook::add draw_message_hook [namespace current]::my_draw_hook $prio where the last two parameters are: the name of a procedure to run; and, a relative integer priority. When "hook::run" is invoked for "draw_message_hook", each of these procedures is called, in the priority order (from smallest to largest). If one of the procedures wants to prevent the later procedures from being called, it returns the string ""stop"". Shchepin, et al. [Page 40] Tkabber 0.11.1 June 2008 To continue with the example, in between the pre-load and post-load stages of configuration, the following calls get made by different plugins: hook::add draw_message_hook [list ...::events::process_x 0] 0 hook::add draw_message_hook ...::chatstate::process_x 1 hook::add draw_message_hook ...::check_draw_empty_body 4 hook::add draw_message_hook ...::chat_open_window 5 hook::add draw_message_hook [list ...::events::process_x 1] 6 hook::add draw_message_hook ...::draw_signed 6 hook::add draw_message_hook ...::draw_encrypted 7 hook::add draw_message_hook ...::handle_error 10 hook::add draw_message_hook ...::handle_info 10 hook::add draw_message_hook ...::draw_timestamp 15 hook::add draw_message_hook ::logger::log_message 15 hook::add draw_message_hook muc::set_message_timestamp 15 hook::add draw_message_hook ...::add_number_of_messages_to_title 18 hook::add draw_message_hook ...::chat_message_notify19 hook::add draw_message_hook ...::handle_server_message 20 hook::add draw_message_hook ...::roster::update_chat_activity 50 hook::add draw_message_hook ...::check_nick 60 hook::add draw_message_hook ::wmdock::msg_recv 70 hook::add draw_message_hook ...::handle_last_nick 79 hook::add draw_message_hook ...::::add_bookmark 80 hook::add draw_message_hook ...::handle_me 83 hook::add draw_message_hook ...::xhtml::draw_xhtml_message 85 hook::add draw_message_hook ...::draw_normal_message 87 Many of these procedures look at the incoming chat message and operate on only certain kinds of messages. Some of these procedures may return ""stop"", e.g., "handle_me" which handles chat bodies that start with ""/me"" and draw_xhtml_message which visualizes _XHTML_ formatted messages. (In this example, the actual namespaces were replaced with ""...:"" to make it more readable). Now let's look at the different kind of hooks that _Tkabber_ knows about. 7.1. Chat Hooks When _Tkabber_ decides that it needs to open a (tabbed) window for a chat or groupchat, two hooks are run: open_chat_pre_hook $chatid $type open_chat_post_hook $chatid $type Both hooks are given two parameters: the chatid (ID of the chat or conference room window, you always can obtain JID using Shchepin, et al. [Page 41] Tkabber 0.11.1 June 2008 "chat::get_jid" and connection ID using "chat::get_connid" routines); and, and the type of chat (either ""chat"" or ""groupchat""). Similarly, when _Tkabber_ encounters activity on a tabbed window, a hook is run: raise_chat_tab_hook $path $chatid The hook is given two parameters: the path of the _Tk_ widget for the tabbed window; and, the chatid of the chat or conference room window. When you want to send a chat message, a hook is run: chat_send_message_hook $chatid $user $body $type The hook is given four parameters: the chatid of the recipient; the localpart of your login identity; the body of the message; and, the type of chat. draw_message_hook $chatid $from $type $body $extras The hook is given five parameters: the chatid of the sender window (JID includes a resource); the JID of the sender (without the resource); the type of chat; the body of the message; and, a nested- list of additional payload elements. (This last parameter isn't documented in this version of the documentation.) Chat windows have menubuttons, and two hooks are used to add items in menu: chat_create_user_menu_hook $path $connid $jid chat_create_conference_menu_hook $path $connid $jid The first is used in user chat windows, and second in groupchat ones. Hooks are given three parameters: the path of the _Tk_ menu widget; connection ID; and, the JID of user or conference. In groupchat windows it is possible to complete participants' nicks or commands by pressing TAB key. List of completions is generated by running this hook: generate_completions_hook $chatid $compsvar $wordstart $line The hook is given four parameters: the chatid of conference window; name of global variable, in which current list of possible completions is stored; index of position where completion must be inserted; and content of text widget where completion is requested. Shchepin, et al. [Page 42] Tkabber 0.11.1 June 2008 When someone enters/exits conference, the following hooks are called: chat_user_enter $group $nick chat_user_exit $group $nick The hooks are given two parameters: chatid of conference and nick of participant. 7.2. Login Hooks Two hooks are invoked whenever a session is connected or disconnected: connected_hook $connid disconnected_hook $connid Both hooks are given one parameter: connection ID (_Tkabber_ allows several connections at once). 7.3. Presence Hooks When our presence status changes, a hook is run: change_our_presence_post_hook $status The hook is given one parameter: the new presence status value, i.e., one of: o available; o chat; o away; o xa; o dnd; or o unavailable. Similarly, when someone else's presence changes, a hook is run: on_change_user_presence_hook $label $status The hook is given two parameters: the label associated with the JID (e.g., "fred") or the JID itself (e.g., "fred@example.com") if no label exists in the roster; and, the user's new status. Shchepin, et al. [Page 43] Tkabber 0.11.1 June 2008 And for all received presence packets, a hook is run: client_presence_hook $connid $from $type $x $args The hook is given four parameters: connection ID, who send this presence, type of presence (e.g., "error", "unavailable"), list of extended subtags and parameters of this presence (e.g., "-show xa -status online"). 7.4. Roster Hooks When an item is added to the roster window, one of the four hooks is run to add stuff to the menu associated with that item: roster_conference_popup_menu_hook $path $connid $jid roster_service_popup_menu_hook $path $connid $jid roster_jid_popup_menu_hook $path $connid $jid roster_group_popup_menu_hook $path $connid $name When run, each hook is given three parameters: the path of the _Tk_ menu widget; the connection ID; and, a JID of the roster item (or the name of the roster group for the last one). Also the following hook is run to add stuff to the menu in groupchats: roster_create_groupchat_user_menu_hook $path $connid $jid The hook is given three parameters: the path of the _Tk_ menu widget; the connection ID; and, a JID of user. The following hook is run to add stuff to the popup balloon for each roster item: roster_user_popup_info_hook $varname $connid $jid The hook is given three parameters: the variable name in which current popup text is stored, the connection ID, and the JID of the roster item. Shchepin, et al. [Page 44] Tkabber 0.11.1 June 2008 7.5. Miscellaneous Hooks There are three "obvious" hooks: postload_hook finload_hook quit_hook The first two, by default, run the "postload" and "finload" procedures, respectively. _postload_hook_ is run after all code has been loaded and before initializing main _Tkabber_ window. After that _finload_hook_ is run. The final hook is called just before _Tkabber_ terminates (cf., Section 6.3.7). You can add custom pages to userinfo window using userinfo_hook $path $connid $jid $editable Shchepin, et al. [Page 45] Tkabber 0.11.1 June 2008 8. User Interface basics 8.1. Searching Search panel may be invoked in certain classes of _Tkabber_ windows using the "<>" Tk virtual event which is bound by default to the "" keyboard command. Search panel can be dismissed by pressing the "" key and the default search action ("search down") is activated by pressing the "" key while entering the search pattern. Search panel is currenlty available in: o Chat and groupchat windows; o Service discovery window; o Chat history logs; o All windows of the "Chats history" tool. Searching may be customized using the settings located under the _Plugins --> Search_ group of the _Customize_ window. These setings are: o "::plugins::search::options(case)": perform case-sensitive searching (_off_ by default); o "::plugins::search::options(mode)": selects searching mode which can be one of: * _substring_ -- use simple substring search: the typed search string is taken verbatim and then the attempt to locate it is performed. This is the default mode. * _glob_ -- uses "glob-style" (or "shell-style") matching: special symbols are recognized and they provide for "wildcarding": + _*_ matches zero or more characters; + _?_ matches exactly one character; + _[_ and _]_ define character classes, e.g., "[A-Z]" will match any character in the series "A", "B", ... "Z". The full syntax is described in Tcl string manual page. That Shchepin, et al. [Page 46] Tkabber 0.11.1 June 2008 is, this search mode can be convenient for those who want more general yet simple approach to searching and is familiar with the "shell globbing" concept found in Unix shells. * _regexp_ -- provides for searching using full-blown regular expressions engine. The full syntax is described in Tcl re_syntax manual page [25]. Shchepin, et al. [Page 47] Tkabber 0.11.1 June 2008 Appendix A. Releases History A.1. Main changes in 0.11.1 o New default sound theme by Serge Yudin o Added new plugins: quotelastmsg, singularity, stripes o Many fixes and enhancements A.2. Main changes in 0.11.0 o New tabbed user interface. Tab headers now occupy several rows and tab bar can be docked to the left and right sides of chat window o Roster filter o Added support for pixmaps (in particular emoticons) JISP archives (XEP-0038) o Added support for SOCKS4a and SOCKS5 proxy for the main connection o Added user location support (XEP-0080) o Added user mood support (XEP-0107) o Added user activity support (XEP-0108) o Added user tune support (XEP-0118) o Added entity capabilities (XEP-0115 v.1.5, only reporting) support o Added basic robot challenges support (XEP-0158, v.0.9) o Added partial data forms media element support (XEP-0221, v.0.2, URIs and images only) o Roster is now exported to XML instead of Tcl list o Added support for entity time (XEP-0202) o Tkabber version is now reported in disco#info (XEP-0232) o Moved deprecated Jabber Browser (XEP-0011) to an external plugin o Moved Jidlink file transfer to an external plugin Shchepin, et al. [Page 48] Tkabber 0.11.1 June 2008 o Added several new plugins: attline, ctcomp, custom-urls, floatinglog, gmail, openurl, presencecmd, receipts o Many fixes and enhancements A.3. Main changes in 0.10.0 o New artwork by Artem Bannikov o Mediated SOCKS5 connection support for file transfer (XEP-0065) o Blocking communicaation with users not in roster (using XEP-0016 via simple interface) o Translatable outgoing error messages support (based on recipient's xml:lang) o Remote controlling clients support (XEP-0146) o Extended stanza addressing support (XEP-0033) o New chats history tool with search over the all chatlog files o Roster item icons are chosen based on Disco queries to item server o Search in Disco, Browser, Headlines, RawXML, and Customize windows o New internal plugins: abbrev allows to abbreviate words in chat input windows, postpone stores/restores current input window content o New external plugins (aniemoticons, latex, tkabber-khim, traffic, renju) o Emoticons theme now can be loaded using GUI o Most Tkabber's tabs can now be stored on exit and restored on start o XMPP ping support (XEP-0199). Reconnecting based on XMPP ping replies o Delayed delivery now recognizes XEP-0203 timestamps o Added optional 'My Resources' roster group, which contains other connected resources of the same JID Shchepin, et al. [Page 49] Tkabber 0.11.1 June 2008 o Many fixes and enhancements A.4. Main changes in 0.9.9 o Improved privacy lists interface o Support for stream compression (XEP-0138) o Support for SRV DNS-records o Support for TXT DNS-records (XEP-0156) o Support for ad-hoc commands (XEP-0050) o Improved headlines support o Chat state notification support (XEP-0085) o Many fixes and enhancements A.5. Main changes in 0.9.8 o Support for STARTTLS o Reorganized menu o Support for searching in chat window o Support for annotations about roster items (XEP-0145) o Support for conference rooms bookmarks (XEP-0048) o Added multilogin support for GPGME o Better support for xml:lang o Support for service discovery extensions (XEP-0128) o Support for NTLM authentication o Many fixes and enhancements A.6. Main changes in 0.9.7beta o Updated support for file transfer (XEP-0095, XEP-0096, XEP-0047, XEP-0065) Shchepin, et al. [Page 50] Tkabber 0.11.1 June 2008 o Support for colored nicks and messages in conference o Better multiple logins support o Updated support for xml:lang o Support for IDNA (RFC3490) o Many fixes and enhancements A.7. Main changes in 0.9.6beta o Multiple logins support o History now splitted by month o Animated emoticons support o Many user interface improvements o More XMPP support o More translations o Bugfixes A.8. Main changes in 0.9.5beta o Nested roster groups o Messages emphasizing o User interface improvements o Support for XMPP/Jabber MIME Type o Bugfixes Shchepin, et al. [Page 51] Tkabber 0.11.1 June 2008 Appendix B. Tk option database resources Here is list of the most essential _Tkabber_-specific _Tk option database_ resources that you need to change look: Tkabber.geometry Geometry of main window. *Chat.chatgeometry *Chat.groupchatgeometry *Customize.geometry *RawXML.geometry *Stats.geometry *Messages.geometry *JDisco.geometry Geometry of various windows (when not using tabs). *mainRosterWidth The width of the main roster window. *Chat.inputheight *RawXML.inputheight Height of input windows in chat and raw XML windows. *Balloon.background *Balloon.foreground Background and foreground colors of popup balloon. *Balloon.style Behaviour of popup balloon: can be "delay" (balloon appeared after some time) and "follow" (balloon appeared immediately and follows mouse). *JDisco.fill Color of service discovery browser item name. *JDisco.identitycolor Color of service discovery browser item identity. *JDisco.featurecolor Color of service discovery browser entity feature. Shchepin, et al. [Page 52] Tkabber 0.11.1 June 2008 *JDisco*Tree*background Background of service discovery browser. *Chat.meforeground Color of user's messages in chat windows. *Chat.theyforeground Color of other peoples messages in chat windows. *Chat.serverlabelforeground Color of label before server message. *Chat.serverforeground Color of server messages in chat windows. *Chat.errforeground Color of error messages in chat windows. *Chat.urlforeground Color of URLs in chat windows. *Chat.urlactiveforeground Color of mouse highlighted URLs in chat windows. *JDisco.fill Default color of items in Service Discovery Browser. *JDisco.featurecolor Default color of feature items in Service Discovery Browser. *JDisco.identitycolor Default color of identity items in Service Discovery Browser. *JDisco.optioncolor Default color of option items in Service Discovery Browser. *JDisco*Tree*background Default color of background in Service Discovery Browser. *NoteBook.alertColor0 *NoteBook.alertColor1 *NoteBook.alertColor2 *NoteBook.alertColor3 Tabs alert colors. *Roster.cbackground Roster background color. *Roster.groupindent Indentation for group title. *Roster.groupiconindent Indentation for group icon. Shchepin, et al. [Page 53] Tkabber 0.11.1 June 2008 *Roster.jidindent Indentation for item name. *Roster.jidmultindent Indentation for item with multiple resources. *Roster.subjidindent Indentation for item resource. *Roster.iconindent Indentation for item icon. *Roster.subitemtype *Roster.subiconindent Indentation for resource icon. *Roster.textuppad Top pad for item's names. *Roster.textdownpad Bottom pad for item's names. *Roster.linepad Vertical distance between items. *Roster.foreground Color of item's names. *Roster.jidfill Background of roster item. *Roster.jidhlfill Background of roster item when mouse is over. *Roster.jidborder Color of item's border. *Roster.groupfill *Roster.grouphlfill *Roster.groupborder The same to roster groups. *Roster.groupcfill Background color of collapsed group. *Roster.stalkerforeground *Roster.unavailableforeground *Roster.dndforeground *Roster.xaforeground *Roster.awayforeground *Roster.availableforeground Shchepin, et al. [Page 54] Tkabber 0.11.1 June 2008 *Roster.chatforeground Colors of item name for different presences. Shchepin, et al. [Page 55] Tkabber 0.11.1 June 2008 Appendix C. Documentation TODO The next revision of this documentation should discuss: o Pre-load: * "browseurl" o Post-load: * "chat_height" and "chat_width" (appear to be no-ops). o Menu-load: * "change_password_dialog" * "conference::create_room_dialog" * "disco::browser::open_win" * "message::send_msg" * "privacy::request_lists" * "rawxml::open_window" * "userinfo::show_info_dialog" o Hooks: the additional payload format. Shchepin, et al. [Page 56] Tkabber 0.11.1 June 2008 Appendix D. Acknowledgements Rebecca Malamud was kind enough to design the "enlightened feather" motif used in the _Tkabber_ look-and-feel. The "new look" appeared in the 0.10.0 release ("golden feather" and "blue feather" pixmap themes and the "Earth bulb" logo) was designed by Artem Bannikov. The new sound theme appeared in 0.11.1 release was created by Serge Yudin Shchepin, et al. [Page 57] Tkabber 0.11.1 June 2008 Appendix E. Copyrights Copyright (c) 2002-2008 Alexey Shchepin _Tkabber_ is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. _Tkabber_ is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. Shchepin, et al. [Page 58] Tkabber 0.11.1 June 2008 Authors' Addresses Alexey Yurievich Shchepin Process-One Email: alexey@process-one.net Marshall T. Rose Dover Beach Consulting, Inc. POB 255268 Sacramento, CA 95865-5268 US Phone: +1 916 483 8878 Fax: +1 916 483 8848 Email: mrose@dbc.mtview.ca.us Sergei Golovan New Economic School Email: sgolovan@nes.ru Michail Yurievich Litvak Colocall Ltd. Email: mci@shadow.in.ua Konstantin Khomoutov Service 007 Email: khomoutov@gmail.com Shchepin, et al. [Page 59] tkabber-0.11.1/msgs/0000755000175000017500000000000011076120366013475 5ustar sergeisergeitkabber-0.11.1/msgs/pt.msg0000644000175000017500000015246211014357121014633 0ustar sergeisergei# $Id: pt.msg 1433 2008-05-19 20:08:49Z sergei $ # portuguese messages file # Author:Miguel / maiguel @ netvisao . pt # Please notify me of errors or incoherencies # avatars.tcl ::msgcat::mcset pt "No avatar to store" "Não existem avatares para guardar" # browser.tcl ::msgcat::mcset pt "JBrowser" "Explorador Jabber" ::msgcat::mcset pt "JID:" "JID:" ::msgcat::mcset pt "Browse" "Explorar" ::msgcat::mcset pt "%s: %s/%s, Description: %s, Version: %s\nNumber of children: %s" "%s: %s/%s, Descrição: %s, Versão: %s\nNúmero de filhos: %s" ::msgcat::mcset pt "List of browsed JIDs." "Lista de JIDs explorados." ::msgcat::mcset pt "Join Group Chat..." "Entrar em grupo de conversa..." ::msgcat::mcset pt "Add Group..." "Adicionar grupo..." ::msgcat::mcset pt "Browse error: %s" "Erro ao explorar: %s" # chats.tcl ::msgcat::mcset pt ">>> Unable to decipher data: %s <<<" ">>> Não foi possível decifrar os dados: %s <<<" ::msgcat::mcset pt "Error %s: %s" "Erro %s: %s" ::msgcat::mcset pt "Chat with %s" "Conversar com %s" ::msgcat::mcset pt "Toggle encryption" "Activar/Desactivar encriptação" ::msgcat::mcset pt "To:" "Para:" ::msgcat::mcset pt "Subject:" "Assunto:" ::msgcat::mcset pt "Error %s" "Erro %s" ::msgcat::mcset pt "Disconnected" "Desligado" ::msgcat::mcset pt "Invite %s to conferences" "Convidar %s para conferência" ::msgcat::mcset pt "Invite users..." "Convidar utilizadores..." ::msgcat::mcset pt "Invite" "Convidar" ::msgcat::mcset pt "Please join %s" "Por favor, junta-te a %s" ::msgcat::mcset pt "Invite users to %s" "Convidar utilizadores para %s" ::msgcat::mcset pt "No conferences in progress..." "Não existem conferências em curso..." ::msgcat::mcset pt "Send custom presence" "Enviar presença personalizada" ::msgcat::mcset pt "Display description of user status in chat windows." "Mostrar descrição do estado do utilizador na janela de conversa." ::msgcat::mcset pt "Default message type (if not specified explicitly)." "Tipo de mensagem por omissão(se não for explicitamente indicado)." ::msgcat::mcset pt "Normal" "Normal" # custom.tcl ::msgcat::mcset pt "Customization of the One True Jabber Client." "Configuração do Verdadeiro Cliente de Jabber." ::msgcat::mcset pt "Open" "Abrir" ::msgcat::mcset pt "Parent group:" "Grupo pai:" ::msgcat::mcset pt "Parent groups:" "Grupos pai:" ::msgcat::mcset pt "State" "Estado" ::msgcat::mcset pt "you have edited the value, but you have not set the option." "Editaste o valor, mas não activaste a opção." ::msgcat::mcset pt "this option is unchanged from its standard setting." "esta opção não foi alterada da sua definição standard." ::msgcat::mcset pt "you have set this option, but not saved it for future sessions." "activaste esta opção mas não a guardaste para sessões futuras." ::msgcat::mcset pt "this option has been set and saved." "esta opção foi definida e guardada." ::msgcat::mcset pt "Set for Current Session" "Activar para a sessão actual" ::msgcat::mcset pt "Set for Future Sessions" "Activar para sessões futuras" ::msgcat::mcset pt "Reset to Current" "Restabelecer para valor actual" ::msgcat::mcset pt "Reset to Saved" "Restabelecer para valor guardado" ::msgcat::mcset pt "Reset to Default" "Restabelecer para valor por omissão" ::msgcat::mcset pt "Chat options." "Opções de conversa." ::msgcat::mcset pt "Enable chat window autoscroll only when last message is shown." "Activar autoscroll na janela apenas quando for mostrada a última mensagem" ::msgcat::mcset pt "Stop chat window autoscroll." "Desactivar o autoscroll da janela de conversa." ::msgcat::mcset pt "Enable messages emphasize." "Activar ênfase das mensagens." ::msgcat::mcset pt "/me has changed the subject to: %s" "/me mudou o tema para: %s" ::msgcat::mcset pt "Moderators" "Moderadores" ::msgcat::mcset pt "Participants" "Participantes" ::msgcat::mcset pt "Visitors" "Visitantes" ::msgcat::mcset pt "Users" "Utilizadores" # datagathering.tcl ::msgcat::mcset pt "Error requesting data: %s" "Erro ao pedir dados: %s" ::msgcat::mcset pt "Error submitting data: %s" "Erro ao submeter dados: %s" ::msgcat::mcset pt "First Name:" "Nome:" ::msgcat::mcset pt "Last Name:" "Apelido:" ::msgcat::mcset pt "Email:" "Email:" ::msgcat::mcset pt "Zip:" "Código Postal:" ::msgcat::mcset pt "Phone:" "Telefone:" ::msgcat::mcset pt "Date:" "Data:" ::msgcat::mcset pt "Misc:" "Outros:" ::msgcat::mcset pt "Text:" "Texto:" ::msgcat::mcset pt "Key:" "Chave:" ::msgcat::mcset pt "Instructions" "Instruções" # plugins/general/httpconn.tcl ::msgcat::mcset pt "Minimum Poll Time." "Tempo mínimo de espera activa." ::msgcat::mcset pt "Maximum Poll Time." "Tempo máximo de espera activa." ::msgcat::mcset pt "Url to connect to." "Url de ligação." ::msgcat::mcset pt "Do http poll" "Fazer espera activa http" ::msgcat::mcset pt "Url:" "Url:" # plugins/general/tkcon.tcl ::msgcat::mcset pt "Show Console" "Mostrar Consola" # plugins/general/stats.tcl ::msgcat::mcset pt "Statistics monitor" "Monitor de estatísticas" ::msgcat::mcset pt "Statistics" "Estatísticas" ::msgcat::mcset pt "Timer" "Temporizador" ::msgcat::mcset pt "Request" "Pedido" ::msgcat::mcset pt "Set" "Activar" ::msgcat::mcset pt "Open statistics monitor" "Abrir monitor de estatísticas" # disco.tcl ::msgcat::mcset pt "Jabber Discovery" "Procura Jabber" ::msgcat::mcset pt "Node:" "Nó:" ::msgcat::mcset pt "Error getting info: %s" "Erro ao obter informação: %s" ::msgcat::mcset pt "Error getting items: %s" "Erro ao obter items: %s" ::msgcat::mcset pt "Error negotiate: %s" "Erro na negociação: %s" # emoticons.tcl # filetransfer.tcl ::msgcat::mcset pt "Send file to %s" "Enviar ficheiro para %s" ::msgcat::mcset pt "File to Send:" "Ficheiro a enviar:" ::msgcat::mcset pt "Browse..." "Explorar..." ::msgcat::mcset pt "Description:" "Descrição:" ::msgcat::mcset pt "IP address:" "Endereço IP:" ::msgcat::mcset pt "File not found or not regular file: %s" "Ficheiro não encontrado ou não é um ficheiro normal" ::msgcat::mcset pt "Receive file from %s" "Receber ficheiro de %s" ::msgcat::mcset pt "Save as:" "Guardar como:" ::msgcat::mcset pt "Receive" "Receber" ::msgcat::mcset pt "Request failed: %s" "O pedido falhou: %s" ::msgcat::mcset pt "Transfering..." "A Transferir..." ::msgcat::mcset pt "Size:" "Tamanho:" ::msgcat::mcset pt "Connection closed" "Ligação encerrada" ::msgcat::mcset pt "File Transfer options." "Opções de transferência de ficheiros." ::msgcat::mcset pt "Default directory for downloaded files." "Directoria por omissão para guardar ficheiros." ::msgcat::mcset pt "Transferring..." "A Transferir..." # filters.tcl ::msgcat::mcset pt "I'm not online" "Não estou ligado" ::msgcat::mcset pt "the message is from" "a mensagem é de" ::msgcat::mcset pt "the message is sent to" "a mensagem é para" ::msgcat::mcset pt "the subject is" "o assunto é" ::msgcat::mcset pt "the body is" "o corpo da mensagem é" ::msgcat::mcset pt "my status is" "o meu estado é" ::msgcat::mcset pt "the message type is" "o tipo da mensagem é" ::msgcat::mcset pt "change message type to" "mudar tipo da mensagem para" ::msgcat::mcset pt "forward message to" "reenviar mensagem para" ::msgcat::mcset pt "reply with" "responder com" ::msgcat::mcset pt "store this message offline" "guardar esta mensagem" ::msgcat::mcset pt "continue processing rules" "continuar a processar regras" ::msgcat::mcset pt "Filters" "Filtros" ::msgcat::mcset pt "Add" "Adicionar" ::msgcat::mcset pt "Edit" "Editar" ::msgcat::mcset pt "Remove" "Eliminar" ::msgcat::mcset pt "Move up" "Mover para cima" ::msgcat::mcset pt "Move down" "Mover para baixo" ::msgcat::mcset pt "Edit rule" "Editar regra" ::msgcat::mcset pt "Rule Name:" "Nome da regra:" ::msgcat::mcset pt "Empty rule name" "Nome de regra vazio" ::msgcat::mcset pt "Rule name already exists" "O nome da regra já existe" ::msgcat::mcset pt "Condition" "Condição" ::msgcat::mcset pt "Action" "Acção" ::msgcat::mcset pt "Requesting filter rules: %s" "A pedir regras de filtros: %s" # gpgme.tcl ::msgcat::mcset pt "Encrypt traffic" "Cifrar tráfego" ::msgcat::mcset pt "Change security preferences for %s" "Mudar preferências de segurança para %s" ::msgcat::mcset pt "Select Key for Signing Traffic" "Seleccionar a chave para assinar o tráfego" ::msgcat::mcset pt "Select" "Seleccionar" ::msgcat::mcset pt "Please enter passphrase" "Por favor, introduz a frase-chave" ::msgcat::mcset pt "Please try again" "Por favor, tenta novamente" ::msgcat::mcset pt "Key ID" "ID da chave" ::msgcat::mcset pt "User ID" "ID de utilizador" ::msgcat::mcset pt "Passphrase:" "Frase-chave:" ::msgcat::mcset pt "Error in signature verification software: %s." "Erro no software de verificação de assinatura: %s." ::msgcat::mcset pt "%s purportedly signed by %s can't be verified.\n\n%s." "%s supostamente assinada por %s não pode ser verificada.\n\n%s." ::msgcat::mcset pt "Unable to sign presence information: %s.\n\nPresence will be sent, but signing traffic is now disabled." "Não foi possível assinar informação de presença: %s.\n\nA presençaa vai ser enviada, mas o tráfego assinado está agora desactivado." ::msgcat::mcset pt "Unable to sign message body: %s.\n\nSigning traffic is now disabled.\n\nSend it WITHOUT a signature?" "Não foi possível assinar o corpo da mensagem: %s.\n\nO tráfego assinado está agora desactivado.\n\nEnviar SEM assinatura?" ::msgcat::mcset pt "Data purported sent by %s can't be deciphered.\n\n%s." "Dados supostamente enviados por %s não puderam ser decifrados.\n\n%s." ::msgcat::mcset pt "Unable to encipher data for %s: %s.\n\nEncrypting traffic to this user is now disabled.\n\nSend it as PLAINTEXT?" "Não foi possível cifrar dados para %s: %s.\n\nO envio de dados cifrados para este utilizador está agora desactivado.\n\nEnviar em TEXTO LIMPO?" ::msgcat::mcset pt "" "" # iface.tcl ::msgcat::mcset pt "Options for main interface." "Opções para o interface principal." ::msgcat::mcset pt "Raise new tab." "Criar nova aba." ::msgcat::mcset pt "Colors for tab alert levels." "Cores para os níveis de alerta das abas." ::msgcat::mcset pt "Presence" "Presença" ::msgcat::mcset pt "Online" "Ligado" ::msgcat::mcset pt "Free to chat" "Disponível para conversar" ::msgcat::mcset pt "Away" "Ausente" ::msgcat::mcset pt "Extended Away" "Ausência Prolongada" ::msgcat::mcset pt "Do not disturb" "Não perturbar" ::msgcat::mcset pt "Invisible" "Invisível" ::msgcat::mcset pt "Log in..." "Iniciar sessão..." ::msgcat::mcset pt "Log out" "Fechar sessão" ::msgcat::mcset pt "Log out with reason..." "Fechar sessão com uma razão..." ::msgcat::mcset pt "Customize" "Configurar" ::msgcat::mcset pt "Profile on" "Perfil" ::msgcat::mcset pt "Profile report" "Relatório de perfil" ::msgcat::mcset pt "Quit" "Sair" ::msgcat::mcset pt "Services" "Serviços" ::msgcat::mcset pt "Send message..." "Enviar mensagem..." ::msgcat::mcset pt "Roster" "Lista de Contactos" ::msgcat::mcset pt "Add user..." "Adicionar utilizador..." ::msgcat::mcset pt "Add conference..." "Adicionar conferência..." ::msgcat::mcset pt "Add group by regexp on JIDs..." "Adicionar grupo por regexp sobre JID..." ::msgcat::mcset pt "Show online users only" "Mostrar apenas utilizadores ligados" ::msgcat::mcset pt "Use aliases" "Usar aliases" ::msgcat::mcset pt "Export roster..." "Exportar lista de contactos..." ::msgcat::mcset pt "Import roster..." "Importar lista de contactos..." ::msgcat::mcset pt "Periodically browse roster conferences" "Inspeccionar periodicamente conferências da lista de contactos" ::msgcat::mcset pt "Browser" "Explorar" ::msgcat::mcset pt "Discovery" "Descoberta" ::msgcat::mcset pt "Join group..." "Aderir a grupo..." ::msgcat::mcset pt "Chats" "Conversas" ::msgcat::mcset pt "Create room..." "Criar sala de conversas" ::msgcat::mcset pt "Generate event messages" "Gerar mensagens de eventos" ::msgcat::mcset pt "Stop autoscroll" "Parar o autoscroll automático" ::msgcat::mcset pt "Sound" "Som" ::msgcat::mcset pt "Mute" "Silêncio" ::msgcat::mcset pt "Filters..." "Filtros..." ::msgcat::mcset pt "Privacy rules..." "Regras de privacidade..." ::msgcat::mcset pt "Message archive" "Arquivo de mensagens" ::msgcat::mcset pt "Change password..." "Mudar palavra-chave..." ::msgcat::mcset pt "Show user info..." "Mostrar informação de utilizador..." ::msgcat::mcset pt "Edit my info..." "Editar a minha informação..." ::msgcat::mcset pt "Avatar" "Avatar" ::msgcat::mcset pt "Announce" "Anunciar" ::msgcat::mcset pt "Allow downloading" "Permitir download" ::msgcat::mcset pt "Send to server" "Enviar ao servidor" ::msgcat::mcset pt "Jidlink" ::msgcat::mcset pt "Admin tools" "ferramentas de administração" ::msgcat::mcset pt "Open raw XML window" "Abrir janela de XML bruto" ::msgcat::mcset pt "Send broadcast message..." "Enviar mensagem de difusão..." ::msgcat::mcset pt "Send message of the day..." "Enviar mensagem do dia..." ::msgcat::mcset pt "Update message of the day..." "Actualizar mensagem do dia..." ::msgcat::mcset pt "Delete message of the day" "Eliminar mensagem do dia" ::msgcat::mcset pt "Help" "Ajuda" ::msgcat::mcset pt "Quick help" "Ajuda rápida" ::msgcat::mcset pt "Quick Help" "Ajuda Rápida" ::msgcat::mcset pt "Main window:" "Janela principal:" ::msgcat::mcset pt "Tabs:" "Abas:" ::msgcat::mcset pt "Chats:" "Conversas:" ::msgcat::mcset pt "Close tab" "Fechar aba" ::msgcat::mcset pt "Previous/Next tab" "Aba anterior/seguinte" ::msgcat::mcset pt "Hide/Show roster" "Mostrar/Esconder lista" ::msgcat::mcset pt "Complete nickname" "Completar nick" ::msgcat::mcset pt "Previous/Next history message" "Mensagem anterior/seguinte" ::msgcat::mcset pt "Show emoticons" "Mostrar emoticons" ::msgcat::mcset pt "Undo" "Desfazer" ::msgcat::mcset pt "Redo" "Refazer" ::msgcat::mcset pt "Scroll chat window up/down" "Deslizar janela de conversa para cima/baixo" ::msgcat::mcset pt "Correct word" "Corrigir palavra" ::msgcat::mcset pt "About" "Acerca de" ::msgcat::mcset pt "Authors:" "Autores:" ::msgcat::mcset pt "Alexey Shchepin" "Alexey Shchepin" ::msgcat::mcset pt "Marshall T. Rose" "Marshall T. Rose" ::msgcat::mcset pt "Sergei Golovan" "Sergei Golovan" ::msgcat::mcset pt "Michail Litvak" "Michail Litvak" ::msgcat::mcset pt "Add new user..." "Adicionar novo utilizador..." ::msgcat::mcset pt "Jabber Browser" "Explorador Jabber" #::msgcat::mcset pt "Join group..." "Aderir a grupo..." ::msgcat::mcset pt "Toggle showing offline users" "Activar/Desactivar a vista de utilizadores desligados" ::msgcat::mcset pt "Toggle signing" "Activar/Desactivar assinatura" ::msgcat::mcset pt "Toggle encryption (when possible)" "Activar/Desactivar a cifragem (quando for possível)" ::msgcat::mcset pt "Cancel" "Cancelar" ::msgcat::mcset pt "Close" "Fechar" ::msgcat::mcset pt "Close other tabs" "Fechar as outras abas" ::msgcat::mcset pt "Close all tabs" "Fechar todas as abas" ::msgcat::mcset pt "Send" "Enviar" ::msgcat::mcset pt "Smart autoscroll" "Autoscroll inteligente" ::msgcat::mcset pt "Show number of unread messages in tab titles." "Mostrar número de mensagens por ler no título das abas." ::msgcat::mcset pt "Delay between getting focus and updating window or tab title in milliseconds." "Tempo, em milisegundos, entre a obtenção de focus e a actualização do título da aba." ::msgcat::mcset pt "Emphasize" "Enfatizar" ::msgcat::mcset pt "SSL Info" ::msgcat::mcset pt "%s SSL Certificate Info" "Informação de Certificado SSL de %s" ::msgcat::mcset pt "Issuer:" "Responsável:" ::msgcat::mcset pt "Begin date:" "Data de início:" ::msgcat::mcset pt "Expiry date:" "Data em que expira:" ::msgcat::mcset pt "Serial number:" "Número de série:" ::msgcat::mcset pt "Cipher:" "Cifra:" ::msgcat::mcset pt "SSL certificate expired" "Certificado SSL expirado" ::msgcat::mcset pt "Extended away" "Ausência prolongada" ::msgcat::mcset pt "Issuer" "Emissor" ::msgcat::mcset pt "Begin date" "Data de início" ::msgcat::mcset pt "Expiry date" "Data em que expira" ::msgcat::mcset pt "Serial number" "Número de série" ::msgcat::mcset pt "Cipher" "Cifra" ::msgcat::mcset pt "Enabled\n" "Activado\n" ::msgcat::mcset pt "Disabled\n" "Desactivado\n" # itemedit.tcl ::msgcat::mcset pt "Edit properties for %s" "Editar propriedades para %s" ::msgcat::mcset pt "Edit nickname for %s" "Editar nick para %s" ::msgcat::mcset pt "Nickname:" "Nickname:" ::msgcat::mcset pt "Edit groups for %s" "Editar grupos para %s" ::msgcat::mcset pt "Available groups" "Grupos disponíveis" ::msgcat::mcset pt "Group:" "Grupo:" ::msgcat::mcset pt "Current groups" "Grupos actuais" ::msgcat::mcset pt "Add ->" "Adicionar ->" ::msgcat::mcset pt "<- Remove" "<- Eliminar" # jabberlib-tclxml/jabberlib.tcl ::msgcat::mcset pt "Authentication failed" "Falhou a Autenticação" ::msgcat::mcset pt "Authentication successful" "Autenticação bem sucedida" ::msgcat::mcset pt "Waiting for authentication mechanisms" "À espera dos mecanismos de autenticação" ::msgcat::mcset pt "Got authentication mechanisms" "Mecanismos de autenticação obtidos" ::msgcat::mcset pt "Waiting for authentication results" "À espera dos resultados da autenticação" ::msgcat::mcset pt "Waiting for Stream" "À espera do 'Stream'" ::msgcat::mcset pt "Got Stream" "'Stream' obtido" ::msgcat::mcset pt "Got roster" "Lista de contactos obtida" ::msgcat::mcset pt "Waiting for roster" "À espera da lista de contactos" # jidlink.tcl ::msgcat::mcset pt "Opening Jidlink connection" "A abrir ligação Jidlink" ::msgcat::mcset pt "Jidlink connection closed" "Ligação Jidlink fechada" # joingrdialog.tcl ::msgcat::mcset pt "Join group" "Aderir a grupo" ::msgcat::mcset pt "Join group dialog data (nicks)." ::msgcat::mcset pt "Join group dialog data (groups)." ::msgcat::mcset pt "Join group dialog data (servers)." ::msgcat::mcset pt "Nick:" "Nick:" ::msgcat::mcset pt "Group:" "Grupo:" ::msgcat::mcset pt "Server:" "Servidor:" ::msgcat::mcset pt "use v2 protocol" "usar protocolo v2" ::msgcat::mcset pt "Password (v2 only):" "Palavra-chave (apenas v2)" ::msgcat::mcset pt "Join" "Entrar" ::msgcat::mcset pt "Add group" "Adicionar grupo" ::msgcat::mcset pt "Get conference info failed: %s" "O pedido de informação da conferência falhou: %s" ::msgcat::mcset pt "Join failed: %s" "Erro na adesão: %s" ::msgcat::mcset pt "Create Room" "Criar sala" ::msgcat::mcset pt "Address:" "Endereço:" ::msgcat::mcset pt "Nickname:" "Nickname:" ::msgcat::mcset pt "Password:" "Palavra-chave:" ::msgcat::mcset pt "Name: " "Nome:" ::msgcat::mcset pt "Description:" "Descrição:" ::msgcat::mcset pt "Create" "Criar" ::msgcat::mcset pt "Connection:" "Ligação:" # login.tcl ::msgcat::mcset pt "Login options." "Opções de início de sessão." ::msgcat::mcset pt "User name." "Nome do utilizador." ::msgcat::mcset pt "Password." "Palavra-Chave." ::msgcat::mcset pt "Resource." "Recurso." ::msgcat::mcset pt "Server name." "Servidor." ::msgcat::mcset pt "Server port." "Porto." ::msgcat::mcset pt "Priority." "Prioridade." ::msgcat::mcset pt "Use SSL to connect to server." "Usar SSL para a ligação." ::msgcat::mcset pt "SSL port." "Porto SSL." ::msgcat::mcset pt "Use HTTP proxy to connect." "Usar proxy HTTP para a ligação." ::msgcat::mcset pt "HTTP proxy address." "Endereço do proxy HTTP." ::msgcat::mcset pt "HTTP proxy port." "Porto do proxy HTTP." ::msgcat::mcset pt "HTTP proxy username." "Utilizador do proxy HTTP." ::msgcat::mcset pt "HTTP proxy password." "Palavra-Chave do proxy HTTP." ::msgcat::mcset pt "Use explicitly-specified server address." "Usar explicitamente o endereço do servidor especificado.." ::msgcat::mcset pt "Server name or IP-address." "Nome do servidor ou endereço IP." ::msgcat::mcset pt "Login" "Iniciar sessão" ::msgcat::mcset pt "Username:" "Utilizador:" ::msgcat::mcset pt "Password:" "Palavra-Chave:" ::msgcat::mcset pt "Server:" "Servidor:" ::msgcat::mcset pt "Resource:" "Recurso:" ::msgcat::mcset pt "Port:" "Porto:" ::msgcat::mcset pt "Use hashed password" "Usar palavra-chave hashed" ::msgcat::mcset pt "Connect via alternate server" "Ligar através de servidor alternativo" ::msgcat::mcset pt "Use SSL" "Usar SSL" ::msgcat::mcset pt "SSL Port:" "Porto SSL:" ::msgcat::mcset pt "Use Proxy" "Usar Proxy" ::msgcat::mcset pt "Proxy Server:" "Servidor Proxy:" ::msgcat::mcset pt "Proxy Port:" "Porto do Proxy:" ::msgcat::mcset pt "Proxy Login:" "Utilizador do Proxy:" ::msgcat::mcset pt "Proxy Password:" "Palavra-chave do Proxy:" ::msgcat::mcset pt "Profiles" "Perfis" ::msgcat::mcset pt "Profile" "Perfil" ::msgcat::mcset pt "Authentication failed: %s\nCreate new account?" "A autenticação falhou: %s\nCriar nova conta?" ::msgcat::mcset pt "Registration failed: %s" "O registo falhou: %s" ::msgcat::mcset pt "Change password" "Alterar palavra-chave" ::msgcat::mcset pt "Old password:" "Palavra-chave antiga:" ::msgcat::mcset pt "New password:" "Nova palavra-chave:" ::msgcat::mcset pt "Repeat new password:" "Repete a nova palavra-chave:" ::msgcat::mcset pt "Old password is incorrect" "A palavra-chave antiga está incorrecta" ::msgcat::mcset pt "New passwords do not match" "As novas palavras-chaves não coincidem" ::msgcat::mcset pt "Password is changed" "Palavra-chave alterada" ::msgcat::mcset pt "Password change failed: %s" "A alteração de palavra-chave falhou: %s" ::msgcat::mcset pt "Logout with reason" "Encerrar sessão com razão" ::msgcat::mcset pt "Reason:" "Razão:" ::msgcat::mcset pt "Priority:" "Prioridade:" ::msgcat::mcset pt "Replace opened connections." "Substituir sessões abertas." ::msgcat::mcset pt "List of logout reasons." "Lista de razões para abandonar sessão." ::msgcat::mcset pt "SSL enabled" "SSL activado" ::msgcat::mcset pt "SSL disabled" "SSL desactivado" ::msgcat::mcset pt "Replace opened connections" "Substituir sessões abertas" ::msgcat::mcset pt "Logout" "Encerrar Sessão" ::msgcat::mcset pt "Use hashed password transmission." "Usar transmissão de chave hashed." ::msgcat::mcset pt "Can't authenticate: Remote server doesn't support\nplain or digest authentication method" "Não é possível fazer a autenticação: o servidor remoto não suporta\nmétodos de autenticação simple ou digest" ::msgcat::mcset pt "Warning: Remote server doesn't support\nhashed password authentication.\n\nProceed with PLAINTEXT authentication?" "Aviso: o servidor remoto não suporta\nautenticação com chaves hashed.\n\nContinuar com autenticação em TEXTO LIMPO?" ::msgcat::mcset pt "SSL certificate file (optional)." "Ficheiro de certificado SSL (opcional)." ::msgcat::mcset pt "Use HTTP poll connection method." "Usar método de ligação por polling HTTP." ::msgcat::mcset pt "URL to connect to." "URL para ligação." ::msgcat::mcset pt "Use HTTP poll client security keys (recommended)." "Usar chaves de segurança do cliente de polling HTTP (recomendado)." ::msgcat::mcset pt "Account" "Conta" ::msgcat::mcset pt "Connection" "Ligação" ::msgcat::mcset pt "Server Port:" "Porto do servidor:" ::msgcat::mcset pt "SSL" ::msgcat::mcset pt "SSL Certificate:" "Certificado SSL:" ::msgcat::mcset pt "Proxy" ::msgcat::mcset pt "HTTP Poll" "Polling HTTP" ::msgcat::mcset pt "Connect via HTTP polling" "Ligar através de polling HTTP" ::msgcat::mcset pt "URL to poll:" "URL para polling:" ::msgcat::mcset pt "Use client security keys" "Usar chaves de segurança do cliente" ::msgcat::mcset pt "Warning display options." "Opções de mensagens de aviso." ::msgcat::mcset pt "Display SSL warnings." "Mostrar avisos relativos ao SSL." ::msgcat::mcset pt "Retry to connect forever." "Tentar sempre ligar novamente." ::msgcat::mcset pt "SSL CA file (optional)." "Ficheiro SSL CA (opcional)." ::msgcat::mcset pt "SSL private key file (optional)." "Ficheiro de chave SSL privada (opcional)." ::msgcat::mcset pt "Minimum Poll Interval." "Intervalo mínimo de 'Poll'." ::msgcat::mcset pt "Maximum Poll Interval." "Intervalo máximo de 'Poll'." ::msgcat::mcset pt "Use SASL authentification." "Usar autentificação SASL." ::msgcat::mcset pt "Failed to connect: %s" "Erro ao ligar: %s" ::msgcat::mcset pt "Keep trying" "Continuar a tentar" ::msgcat::mcset pt ". Proceed?\n\n" ". Continuar?\n\n" ::msgcat::mcset pt "SASL" ::msgcat::mcset pt "Use SASL authentification" "Usar autentificação SASL" ::msgcat::mcset pt "SASL Port:" "Porto SASL:" ::msgcat::mcset pt "SASL Certificate:" "Certificado SASL:" # messages.tcl ::msgcat::mcset pt "Message from %s" "Mensagem de %s" ::msgcat::mcset pt "Message from" "Mensagem de" ::msgcat::mcset pt "Extras from %s" "Extras de %s" ::msgcat::mcset pt "Extras from" "Extras de" ::msgcat::mcset pt "Reply" "Responder" ::msgcat::mcset pt "Attached user:" "Utilizador anexo:" ::msgcat::mcset pt "Attached file:" "Ficheiro anexo:" ::msgcat::mcset pt "Invited to:" "Convidado para:" ::msgcat::mcset pt "Message body" "Corpo da mensagem" ::msgcat::mcset pt "Send message to %s" "Enviar mensagem a %s" ::msgcat::mcset pt "Send message" "Enviar mensagem" ::msgcat::mcset pt "This message is encrypted." "Esta mensagem está cifrada." ::msgcat::mcset pt "Subscribe request from %s" "Subscrever pedido de %s" ::msgcat::mcset pt "Subscribe request from" "Subscrever pedido de" ::msgcat::mcset pt "Subscribe" "Subscrever" ::msgcat::mcset pt "Unsubscribe" "Remover subscrição" ::msgcat::mcset pt "Send subscription" "Enviar subscrição" ::msgcat::mcset pt "Send subscription to %s" "Enviar subscrição a %s" ::msgcat::mcset pt "Send subscription to " "Enviar subscrição a " ::msgcat::mcset pt "Headlines" "Cabeçalhos" ::msgcat::mcset pt "Toggle seen" "Activar/Desactivar Visibilidade" ::msgcat::mcset pt "Sort" "Ordenar" ::msgcat::mcset pt "Chat" "Conversar" ::msgcat::mcset pt "Quote" "Citar" ::msgcat::mcset pt "Reply subject:" "Assunto da resposta:" ::msgcat::mcset pt "%s invites you to conference room %s" "%s convida-te para a sala de conferência %s" ::msgcat::mcset pt "\nReason is: %s" "\nA razão é: %s" ::msgcat::mcset pt "%s Headlines" "Cabeçalhos de %s" ::msgcat::mcset pt "Delete" "Eliminar" ::msgcat::mcset pt "Forward..." "Reenviar..." ::msgcat::mcset pt "Mark all seen" "Marcar todos como lidos" ::msgcat::mcset pt "Mark all unseen" "Marcar todos como não lidos" ::msgcat::mcset pt "Delete seen" "Apagar os lidos" ::msgcat::mcset pt "Delete all" "Apagar todos" ::msgcat::mcset pt "Forward headline" "Reenviar cabeçalho" ::msgcat::mcset pt "List of message destination JIDs." "Lista dos JID destinatários." ::msgcat::mcset pt "List of JIDs to whom headlines have been sent." "Lista dos JIDs para os quais foram enviados os cabeçalhos." ::msgcat::mcset pt "Forward to %s" "Reenviar a %s" ::msgcat::mcset pt "Message and Headline options." "Opcções de Mensagem e Cabeçalhos." ::msgcat::mcset pt "Cache headlines on exit and restore on start." "Guardar cabeçalhos ao sair e recuperar ao iniciar." ::msgcat::mcset pt "Display headlines in single/multiple windows." "Mostrar cabeçalhos numa ou várias janelas." ::msgcat::mcset pt "Single window" "Uma janela" ::msgcat::mcset pt "One window per JID" "Uma janela por JID" ::msgcat::mcset pt "One window per JID/resource" "Uma janela por cada JID/recurso" ::msgcat::mcset pt "Do not display headline descriptions as tree nodes." "Não mostrar descrições de cabeçalhos em árvore." # muc.tcl ::msgcat::mcset pt "Whois" "Quem é?" ::msgcat::mcset pt "Kick" "Chutar" ::msgcat::mcset pt "Ban" "Banir" ::msgcat::mcset pt "Grant Voice" "Dar Voz" ::msgcat::mcset pt "Revoke Voice" "Retirar Voz" ::msgcat::mcset pt "Grant Membership" "Dar Privilégios de Membro" ::msgcat::mcset pt "Revoke Membership" "Retirar Privilégios de Membro" ::msgcat::mcset pt "Grant Moderator Privilege" "Dar Privilégios de Moderador" ::msgcat::mcset pt "Revoke Moderator Privilege" "Retirar Privilégios de Moderador" ::msgcat::mcset pt "MUC" "MUC" ::msgcat::mcset pt "Configure" "Configurar" ::msgcat::mcset pt "Edit admin list" "Editar lista de administrador" ::msgcat::mcset pt "Edit moderator list" "Editar lista de moderador" ::msgcat::mcset pt "Edit ban list" "Editar lista de bans" ::msgcat::mcset pt "Edit member list" "Editar lista de membros" ::msgcat::mcset pt "Edit voice list" "Editar lista de vozes" ::msgcat::mcset pt "Destroy" "Destruir" ::msgcat::mcset pt "Generate event messages in MUC compatible conference rooms." "Gerar mensagens de eventos em salas de conferências compatíveis com MUC." ::msgcat::mcset pt "Grant Administrative Privilege" "Dar privilégios de administrador" ::msgcat::mcset pt "Revoke Administrative Privilege" "Retirar privilégios de administrador" ::msgcat::mcset pt "Grant Ownership Privilege" "Dar privilégios de dono" ::msgcat::mcset pt "Revoke Ownership Privilege" "Retirar privilégios de dono" ::msgcat::mcset pt "Edit owner list" "Editar lista de donos" ::msgcat::mcset pt " by %s" " por %s" ::msgcat::mcset pt "%s is now known as %s" "%s é agora conhecido por %s" ::msgcat::mcset pt "%s has become available" "%s está agora disponível" ::msgcat::mcset pt "%s has left" "%s saiu" ::msgcat::mcset pt "\n\tJID: %s" "\n\tJID: %s" ::msgcat::mcset pt "\n\tAffiliation: %s" "\n\tAfiliação: %s" #::msgcat::mcset pt "Edit $val list" "Editar a lista $val" # plugins/chat/logger.tcl ::msgcat::mcset pt "Logging options." "Opções de log de mensagens." ::msgcat::mcset pt "Directory to store logs." "Directoria onde guardar logs." ::msgcat::mcset pt "Store private chats logs." "Guardar logs de conversas privadas." ::msgcat::mcset pt "Store group chats logs." "Guardar logs de conversas em grupo." ::msgcat::mcset pt "Go" "Ir" ::msgcat::mcset pt "Do search" "Procurar" ::msgcat::mcset pt "Match case..." "Maiúsculas/Minúsculas..." ::msgcat::mcset pt "Match by regexp" "Padrão para regexp" ::msgcat::mcset pt "Search direction" "Direcção de procura" ::msgcat::mcset pt "History for %s" "Historial de %s" ::msgcat::mcset pt "Export to XHTML" "Exportar para XHTML" # /home/alexey/src/tkabber-cvs/tkabber/plugins/chat/draw_xhtml_message.tcl ::msgcat::mcset pt "Enable rendering of XHTML messages." "Activar a visualização de mensagens XHTML." # presence.tcl ::msgcat::mcset pt "Not logged in" "Sessão não iniciada" #::msgcat::mcset pt "Online" "Ligado" #::msgcat::mcset pt "Free to chat" "Disponível para conversar" #::msgcat::mcset pt "Away" "Ausente" #::msgcat::mcset pt "Extended Away" "Ausência Prolongada" #::msgcat::mcset pt "Do not disturb" "Não perturbar" #::msgcat::mcset pt "Invisible" "Invisível" ::msgcat::mcset pt "Offline" "Desligado" ::msgcat::mcset pt "invalid userstatus value " "valor inválido do estado de utilizador " ::msgcat::mcset pt "Change priority..." "Modificar prioridade..." ::msgcat::mcset pt "Change Presence Priority" "Modificar Prioridade da Presença" # privacy.tcl ::msgcat::mcset pt "Requesting privacy rules: %s" "A pedir regras de privacidade: %s" ::msgcat::mcset pt "Zebra lists" "Listas Zebra" ::msgcat::mcset pt "Add list" "Adicionar lista" ::msgcat::mcset pt "No active" "Não activa" ::msgcat::mcset pt "Type:" "Tipo:" ::msgcat::mcset pt "Subscription:" "Subscrição:" ::msgcat::mcset pt "Zebra list: %s" "Lista Zebra: %s" ::msgcat::mcset pt "Active" "Activa" ::msgcat::mcset pt "Remove list" "Eliminar lista" ::msgcat::mcset pt "Add item" "Adicionar item" ::msgcat::mcset pt "No default list" "Não existe uma lista por omissão" ::msgcat::mcset pt "No active list" "No existe uma lista activa" ::msgcat::mcset pt "Value:" "Valor:" ::msgcat::mcset pt "Action:" "Acção:" ::msgcat::mcset pt "Default" "Por omissão" ::msgcat::mcset pt "Edit list" "Editar lista" ::msgcat::mcset pt "Requesting privacy list: %s" "A pedir lista de privacidade: %s" # register.tcl ::msgcat::mcset pt "Register in %s" "Registar em %s" ::msgcat::mcset pt "Unsubscribed from %s" "Sem subscrição em %s" ::msgcat::mcset pt "We unsubscribed from %s" "Eliminámos subscrição em %s" ::msgcat::mcset pt "Registration: %s" "Registo: %s" ::msgcat::mcset pt "Successful!" "Sucesso!" ::msgcat::mcset pt "Registration is successful!" "Registo bem sucedido!" ::msgcat::mcset pt "Registration is successful!" "Registo bem sucedido!" # roster.tcl ::msgcat::mcset pt "Undefined" "Indefinido" ::msgcat::mcset pt "is now" "está agora" #::msgcat::mcset pt "Show online & offline users" "Mostrar utilizadores ligados & desligados" #::msgcat::mcset pt "Show online users only" "Mostrar apenas utilizadores ligados" ::msgcat::mcset pt "Are you sure to remove %s from roster?" "Tens a certeza que queres remover %s da lista de contactos?" ::msgcat::mcset pt "Add roster group by JID regexp" "Adicionar grupo à lista de contactos por regexp sobre JID" ::msgcat::mcset pt "New group name:" "Nome do novo grupo:" ::msgcat::mcset pt "JID regexp:" "JID regexp:" ::msgcat::mcset pt "Start chat" "Começar a conversar" #::msgcat::mcset pt "Send message..." "Enviar mensagem..." ::msgcat::mcset pt "Invite to conference..." "Convidar para conferência..." ::msgcat::mcset pt "Resubscribe" "Subscrever novamente" ::msgcat::mcset pt "Send users..." "Enviar utilizadores..." ::msgcat::mcset pt "Send file..." "Enviar ficheiro..." ::msgcat::mcset pt "Send file via Jidlink..." "Enviar ficheiro através de Jidlink..." ::msgcat::mcset pt "Show info" "Mostrar informação" ::msgcat::mcset pt "Show history" "Mostrar historial" ::msgcat::mcset pt "Edit item..." "Editar item..." ::msgcat::mcset pt "Edit security..." "Editar segurança..." ::msgcat::mcset pt "Remove..." "Eliminar..." ::msgcat::mcset pt "Join..." "Aderir..." ::msgcat::mcset pt "Log in" "Iniciar sessão" ::msgcat::mcset pt "Log out" "Fechar sessão" ::msgcat::mcset pt "Send contacts to" "Enviar contactos a" ::msgcat::mcset pt "Send" "Enviar" ::msgcat::mcset pt "No users in roster..." "Não existem utilizadores na lista de contactos..." ::msgcat::mcset pt "Contact Information" "Informação de contacto" ::msgcat::mcset pt "Raw XML input" "Entrada em XML bruto" ::msgcat::mcset pt "Rename..." "Alterar nome..." ::msgcat::mcset pt "Resubscribe to all users in group..." "Subscrever novamente todos os utilizadores do grupo..." ::msgcat::mcset pt "Roster options." "Opções da lista de contactos." ::msgcat::mcset pt "Are you sure to remove group '%s' from roster?" "Tens a certeza de que queres eliminar o grupo '%s' da lista de contactos?" ::msgcat::mcset pt "Rename roster group" "Alterar nome do grupo da lista de contactos" ::msgcat::mcset pt "Roster Files" "Ficheiros da lista de contactos" ::msgcat::mcset pt "All Files" "Todos os ficheiros" ::msgcat::mcset pt "Roster of %s" "Lista de contactos de %s" ::msgcat::mcset pt "Show only online users in roster." "Mostrar apenas utilizadores da lista que estão ligados" ::msgcat::mcset pt "Show native icons for transports/services in roster." "Mostrar ícones nativos para transportes/serviços na lista de contactos." ::msgcat::mcset pt "Show native icons for contacts, connected to transports/services in roster." "Mostrar ícones nativos para os contactos ligados ligados a transportes/serviços da lista de contactos." ::msgcat::mcset pt "Default nested roster group delimiter." "Delimitador por omissão de sub-grupos da lista de contactos." ::msgcat::mcset pt "Add chats group in roster." "Adicionar grupo de conversas à lista de contactos" ::msgcat::mcset pt "Show subscription type in roster item tooltips." "Mostrar tipo de subscrição em 'tooltips' na lista de contactos." ::msgcat::mcset pt "Show detailed info on conference room members in roster item tooltips." "Mostrar informação detalhada sobre os membros de uma sala de conferência nos 'tooltips' da lista de contactos." ::msgcat::mcset pt "Active Chats" "Conversas activas" ::msgcat::mcset pt "Show offline users" "Mostrar contactos desligados" # roster_nested.tcl ::msgcat::mcset pt "Enable nested roster groups." "Activar subgrupos na lista de contactos." # search.tcl ::msgcat::mcset pt "#" "#" ::msgcat::mcset pt "Search in" "Procurar em" ::msgcat::mcset pt "Search again" "Procurar novamente" ::msgcat::mcset pt "OK" "OK" ::msgcat::mcset pt "Try again" "Tentar novamente" ::msgcat::mcset pt "An error is occurred when searching in %s\n\n%s" "Ocorreu um erro ao procurar em %s\n\n%s" ::msgcat::mcset pt "Search in %s" "Procurar em %s" ::msgcat::mcset pt "Search: %s" "Procurar: %s" ::msgcat::mcset pt "An error occurred when searching in %s\n\n%s" "Ocorreu um erro durante a pesquisa em %s\n\n%s" ::msgcat::mcset pt "Search in %s: No items found" "Pesquisa em %s: Nenhum item encontrado" # splash.tcl ::msgcat::mcset pt "auto-away" "Ausência automática" ::msgcat::mcset pt "avatars" "avatares" ::msgcat::mcset pt "balloon help" "ajuda contextual" ::msgcat::mcset pt "browsing" "navegação" ::msgcat::mcset pt "configuration" "configuração" ::msgcat::mcset pt "connections" "ligações" ::msgcat::mcset pt "cryptographics" "criptografia" ::msgcat::mcset pt "emoticons" "emoticons" ::msgcat::mcset pt "extension management" "gestão de extensões" ::msgcat::mcset pt "file transfer" "transferência de ficheiros" ::msgcat::mcset pt "jabber chat" "conversa jabber" ::msgcat::mcset pt "jabber groupchats" "grupos de conversa jabber" ::msgcat::mcset pt "jabber iq" "iq jabber" ::msgcat::mcset pt "jabber presence" "presença jabber" ::msgcat::mcset pt "jabber registration" "registo jabber" ::msgcat::mcset pt "jabber xml" "Jabber XML" ::msgcat::mcset pt "kde" ::msgcat::mcset pt "message filters" "filtros de mensagens" ::msgcat::mcset pt "message/headline" "mensagem/cabeçalho" ::msgcat::mcset pt "plugin management" "gestão de plugins" ::msgcat::mcset pt "presence" "presença" ::msgcat::mcset pt "rosters" "listas de contactos" ::msgcat::mcset pt "searching" "a procurar" ::msgcat::mcset pt "text undo" "Desfazer texto" ::msgcat::mcset pt "user interface" "interface do utilizador" ::msgcat::mcset pt "utilities" "ferramentas" ::msgcat::mcset pt "wmaker" ::msgcat::mcset pt "bwidget workarounds" "soluções para o bwidget" ::msgcat::mcset pt "service discovery" "Procura de serviços" ::msgcat::mcset pt "multi-user chat" "conversas multi-utilizador" ::msgcat::mcset pt "negotiation" "negociação" ::msgcat::mcset pt "privacy rules" "regras de privacidade" ::msgcat::mcset pt "sound" "som" ::msgcat::mcset pt "jidlink" # sound.tcl ::msgcat::mcset pt "Sound options." "Opções de som." ::msgcat::mcset pt "Mute sound notifying." "Desactivar notificações sonoras." ::msgcat::mcset pt "External program, which is to be executed to play sound. If empty, Snack library is required to play sound." "Programa externo que será executado para reproduzir sons. Se deixares vazio, é necessária a biblioteca Snack para reproduzir sons." ::msgcat::mcset pt "Sound theme. If it starts with \"/\" or \"~\" then it is considered as theme directory. Otherwise theme is loaded from \"sounds\" directory of Tkabber tree." "Tema do som. Se começar com \"/\" ou \"~\", é considerado como sendo uma directoria de tema. Caso contrário, o tema é carregado da directoria \"sounds\" na árvore do Tkabber." ::msgcat::mcset pt "Time interval before playing next sound (in milliseconds)." "Intervalo de tempo entre reproduções de som (em milisegundos)." ::msgcat::mcset pt "Mute sound when displaying delayed groupchat messages." "Desactivar notificações sonoras para mensagens de conversas em grupo atrasadas." ::msgcat::mcset pt "Mute sound when displaying delayed personal chat messages." "Desactivar notificações sonoras para mensagens de conversas privadas atrasadas." ::msgcat::mcset pt "Options for external play program" "Opções para o programa de reprodução externo" ::msgcat::mcset pt "Mute sound notification." "Desactivar notificações sonoras." ::msgcat::mcset pt "Use sound notification only when being available." "Usar notificações sonoras apenas quanto estiveres disponível." # userinfo.tcl ::msgcat::mcset pt "Show user info" "Mostrar informação do utilizador" ::msgcat::mcset pt "Show" "Mostrar" ::msgcat::mcset pt "%s info" "Informação de %s" ::msgcat::mcset pt "Personal" "Pessoal" ::msgcat::mcset pt "Name" "Nome" ::msgcat::mcset pt "Full Name:" "Nome completo:" ::msgcat::mcset pt "Family Name:" "Apelido:" ::msgcat::mcset pt "Name:" "Nome:" ::msgcat::mcset pt "Middle Name:" "Segundo nome:" ::msgcat::mcset pt "Prefix:" "Prefixo:" ::msgcat::mcset pt "Suffix:" "Sufixo:" ::msgcat::mcset pt "Nickname:" "Nickname:" ::msgcat::mcset pt "Information" "Informação" ::msgcat::mcset pt "E-mail:" ::msgcat::mcset pt "Web Site:" "Página web:" ::msgcat::mcset pt "JID:" ::msgcat::mcset pt "UID:" ::msgcat::mcset pt "Phones" "Telefones" ::msgcat::mcset pt "Telephone numbers" "Números de telefone" ::msgcat::mcset pt "Home:" "Casa:" ::msgcat::mcset pt "Work:" "Trabalho:" ::msgcat::mcset pt "Voice:" "Voz:" ::msgcat::mcset pt "Fax:" "Fax:" ::msgcat::mcset pt "Pager:" "Pager:" ::msgcat::mcset pt "Message Recorder:" "Gravador de Mensagens:" ::msgcat::mcset pt "Cell:" "Telemóvel:" ::msgcat::mcset pt "Video:" "Vídeo:" ::msgcat::mcset pt "BBS:" ::msgcat::mcset pt "Modem:" "Modem:" ::msgcat::mcset pt "ISDN:" "RDIS:" ::msgcat::mcset pt "PCS:" ::msgcat::mcset pt "Preferred:" "Preferido:" ::msgcat::mcset pt "Location" "Lugar" ::msgcat::mcset pt "Address" "Endereço" ::msgcat::mcset pt "Address:" "Endereço:" ::msgcat::mcset pt "Address 2:" "Endereço 2:" ::msgcat::mcset pt "City:" "Cidade:" ::msgcat::mcset pt "State:" "Estado/Província:" ::msgcat::mcset pt "Postal Code:" "Código Postal:" ::msgcat::mcset pt "Country:" "País:" ::msgcat::mcset pt "Geographical position" "Posição geográfica" ::msgcat::mcset pt "Latitude:" "Latitude:" ::msgcat::mcset pt "Longitude:" "Longitude:" ::msgcat::mcset pt "Organization" "Organização" ::msgcat::mcset pt "Details" "Detalhes" # Space at the end of the next word is to distinguish it from another "Name:" ::msgcat::mcset pt "Name: " "Nome: " ::msgcat::mcset pt "Unit:" "Unidade:" # Space at the end of the next word is to distinguish it from another "Personal" ::msgcat::mcset pt "Personal " "Pessoal " ::msgcat::mcset pt "Title:" "Cargo:" ::msgcat::mcset pt "Role:" "Papel:" # Space at the end of the next word is to distinguish it from another "About" ::msgcat::mcset pt "About " "Acerca de " ::msgcat::mcset pt "Birthday" "Data de nascimento" ::msgcat::mcset pt "Birthday:" "Data de nascimento:" ::msgcat::mcset pt "Year:" "Ano:" ::msgcat::mcset pt "Month:" "Mês:" ::msgcat::mcset pt "Day:" "Dia:" ::msgcat::mcset pt "Photo" "Foto" ::msgcat::mcset pt "URL:" "URL:" ::msgcat::mcset pt "URL" "URL" ::msgcat::mcset pt "Image" "Imagem" ::msgcat::mcset pt "None" "Nenhuma" ::msgcat::mcset pt "Load Image" "Carregar imagem" ::msgcat::mcset pt "Avatar" "Avatar" ::msgcat::mcset pt "Client Info" "Informação do cliente" ::msgcat::mcset pt "Client" "Cliente" ::msgcat::mcset pt "Client:" "Cliente:" ::msgcat::mcset pt "Version:" "Versão:" ::msgcat::mcset pt "Last Activity or Uptime" "Última actividade ou tempo de actividade" ::msgcat::mcset pt "Interval:" "Intervalo:" ::msgcat::mcset pt "Description:" "Descrição:" ::msgcat::mcset pt "Computer" "Computador" ::msgcat::mcset pt "OS:" "SO:" ::msgcat::mcset pt "Time:" "Hora:" ::msgcat::mcset pt "Time Zone:" "Zona horária:" ::msgcat::mcset pt "UTC:" ::msgcat::mcset pt "Presence" "Presença" ::msgcat::mcset pt "Presence id signed" "ID de presença assinado" ::msgcat::mcset pt " by " " por " ::msgcat::mcset pt "List of users for userinfo." "Lista de utilizadores por userinfo." ::msgcat::mcset pt "Presence is signed" "A presença está assinada" # utils.tcl ::msgcat::mcset pt "day" "dia" ::msgcat::mcset pt "days" "dias" ::msgcat::mcset pt "hour" "hora" ::msgcat::mcset pt "hours" "horas" ::msgcat::mcset pt "minute" "minuto" ::msgcat::mcset pt "minutes" "minutos" ::msgcat::mcset pt "second" "segundo" ::msgcat::mcset pt "seconds" "segundos" # plugins/chat/clear.tcl ::msgcat::mcset pt "Clear chat window" "Limpar janela de conversa" # plugins/jidlink/dtcp.tcl ::msgcat::mcset pt "Opening DTCP active connection" "A abrir ligação activa DTCP" ::msgcat::mcset pt "Opening DTCP passive connection" "A abrir ligação passiva DTCP" # plugins/jidlink/ibb.tcl ::msgcat::mcset pt "Opening IBB connection" "A abrir ligação IBB" # plugins/clientinfo.tcl ::msgcat::mcset pt "\n\tClient: %s" "\n\tCliente: %s" ::msgcat::mcset pt "\n\tOS: %s" "\n\tSO: %s" ::msgcat::mcset pt "\n\tName: %s" "\n\tNome: %s" # plugins/general/autoaway.tcl # "Automatically away due to idle" goes to textstatus (probably no needs to translate) ::msgcat::mcset pt "Automatically away due to idle" "Automaticamente ausente devido a inactividade" # rest should be translated ::msgcat::mcset pt "Returning from auto-away" "De volta da ausência automática" ::msgcat::mcset pt "Moving to extended away" "A passar para Ausência Prolongada" ::msgcat::mcset pt "Starting auto-away" "A passar para Ausência Automática" ::msgcat::mcset pt "Idle for %s" "Inactivo durante %s" ::msgcat::mcset pt "Options for module that automatically marks you as away after idle threshold." "Opções para o módulo que te passa a ausente de forma automática depois algum tempo inactivo." ::msgcat::mcset pt "Idle threshold in milliseconds after that Tkabber marks you as away." "Intervalo de inactividade para que Tkabber te ponha em estado Ausente automaticamente." ::msgcat::mcset pt "Idle threshold in milliseconds after that Tkabber marks you as extended away." "Intervalo de inactividade para que Tkabber te ponha em estado Ausência Prolongada automaticamente." ::msgcat::mcset pt "Text status, which is set when Tkabber is moving in away state." "Estado textual que é utilizado pelo Tkabber quando passa ao estado Ausente." ::msgcat::mcset pt "Tkabber will set priority to 0 when moving in extended away state." "O Tkabber irá colocar a prioridade a 0 ao passar ao estado Ausência Prolongada." # plugins/general/conferenceinfo.tcl ::msgcat::mcset pt "Options for Conference Info module, that allows you to see list of participants in roster popup, regardless of whether you are currently joined with the conference." "Opções para o módulo de Informação sobre Conferência, que te permite ver a lista de participantes na janela, independentemente de participares ou não nela." ::msgcat::mcset pt "Use this module" "Usar este módulo" ::msgcat::mcset pt "Interval between requests of participants list" "Intervalo entre pedidos da lista de participantes" ::msgcat::mcset pt "Interval after error reply on request of participants list" "Intervalo depois de ter sido obtido um erro ao pedir a lista de participantes" ::msgcat::mcset pt "\n\tCan't browse: %s" "\n\tNão é possível navegar: %s" ::msgcat::mcset pt "\nRoom participants at %s:" "\nParticipantes da sala %s:" ::msgcat::mcset pt "\nRoom is empty at %s" "\nA sala %s está vazia" # plugins/general/message_archive.tcl ::msgcat::mcset pt "Messages" "Mensagens" ::msgcat::mcset pt "Received/Sent" "Enviadas/Recebidas" ::msgcat::mcset pt "Dir" "Dir" ::msgcat::mcset pt "From/To" "De/Para" ::msgcat::mcset pt "From:" "De:" ::msgcat::mcset pt "To:" "Para:" ::msgcat::mcset pt "Subject" "Assunto" # plugins/general/rawxml.tcl ::msgcat::mcset pt "Options for Raw XML Input module, which allows you to monitor incoming/outgoing traffic from connection to server and send custom XML stanzas." "Opções para o módulo de entrada de XML em bruto, que permite monitorizar o tráfego que entra e que sai na ligação ao servidor e enviar blocos XML" ::msgcat::mcset pt "Pretty print incoming and outgoing XML stanzas." "Imprimir os blocos de XML que entram e que saem com cores." ::msgcat::mcset pt "Indentation for pretty-printed XML subtags." "Indentação para as marcas XML." ::msgcat::mcset pt "Raw XML" "XML em bruto" ::msgcat::mcset pt "Pretty print XML" "Mostrar XML com cores" ::msgcat::mcset pt "Templates" "Modelos" ::msgcat::mcset pt "Clear" "Limpar" # plugins/unix/dockingtray.tcl ::msgcat::mcset pt "Hide Main Window" "Esconder janela principal" ::msgcat::mcset pt "Show Main Window" "Mostrar janela principal" # plugins/unix/ispell.tcl ::msgcat::mcset pt "- nothing -" "- nada -" ::msgcat::mcset pt "Spell check options." "Opções de correcção ortográfica." ::msgcat::mcset pt "Path to the ispell executable." "Caminho para o executável do ispell." ::msgcat::mcset pt "Check spell after every entered symbol." "Verificar erros ortográficos depois de cada símbolo." ::msgcat::mcset pt "Ispell dictionary. If it is empty, default dictionary is used." "Dicionário ispell. Se ficar vazio é utilizado o dicionário por omissão." ::msgcat::mcset pt "Ispell dictionary encoding. If it is empty, system encoding is used." "Codificação do dicionário ispell. Se ficar vazio é utlizada a codificação do sistema." # plugins/chat/events.tcl ::msgcat::mcset pt "Message stored on the server" "Mensagem guardada no servidor" ::msgcat::mcset pt "Message stored on %s's server" "Mensagem guardada no servidor de %s" ::msgcat::mcset pt "Message delivered" "Mensagem entregue" ::msgcat::mcset pt "Message delivered to %s" "Mensagem entregue a %s" ::msgcat::mcset pt "Message displayed" "Mensagem mostrada" ::msgcat::mcset pt "Message displayed to %s" "Mensagem mostrada a %s" ::msgcat::mcset pt "Composing a reply" "A escrever uma resposta" ::msgcat::mcset pt "%s is composing a reply" "%s está a escrever uma resposta" # plugins/chat/info_commands.tcl # new 20030924 ::msgcat::mcset pt "Message stored on the server" "Mensagem guardada no servidor" ::msgcat::mcset pt "Full Name" "Nome completo" ::msgcat::mcset pt "Family Name" "Apelido" ::msgcat::mcset pt "Middle Name" "Segundo nome" ::msgcat::mcset pt "Prefix" "Prefixo" ::msgcat::mcset pt "Suffix" "Sufixo" ::msgcat::mcset pt "Nickname" "Nickname" ::msgcat::mcset pt "E-mail" ::msgcat::mcset pt "Web Site" "Página web" ::msgcat::mcset pt "JID" ::msgcat::mcset pt "UID" ::msgcat::mcset pt "City" "Cidade" ::msgcat::mcset pt "State " "Estado " ::msgcat::mcset pt "Country" "País" ::msgcat::mcset pt "vCard items to display in chat windows when using /vcard command." "elementos vCard a mostrar nas janelas de conversação quando se usa o comando /vcard." ::msgcat::mcset pt "time %s%s: %s" "tempo %s%s: %s" ::msgcat::mcset pt "time %s%s:" "tempo %s%s:" ::msgcat::mcset pt "last %s%s: %s" "último %s%s: %s" ::msgcat::mcset pt "last %s%s:" "último %s%s:" ::msgcat::mcset pt "version %s%s: %s" "versão %s%s: %s" ::msgcat::mcset pt "version %s%s:" "versão %s%s:" ::msgcat::mcset pt "vcard %s%s: %s" "vcard %s%s: %s" ::msgcat::mcset pt "vcard %s%s:" "vcard %s%s:" # unix/wmdock.tcl ::msgcat::mcset pt "%s msgs" "%s mensagens" ::msgcat::mcset pt "%s is %s" "%s está %s" # error messages ::msgcat::mcset pt "Redirect" "Redireccionar" ::msgcat::mcset pt "Bad Request" "Pedido Inválido" ::msgcat::mcset pt "Unauthorized" "Não autorizado" ::msgcat::mcset pt "Payment Required" "É necessário pagar" ::msgcat::mcset pt "Forbidden" "Proibido" ::msgcat::mcset pt "Not Found" "Não encontrado" ::msgcat::mcset pt "Not Allowed" "Não é permitido" ::msgcat::mcset pt "Not Acceptable" "Não é aceitável" ::msgcat::mcset pt "Registration Required" "É necessário registo" ::msgcat::mcset pt "Request Timeout" "Esgotou-se o tempo de espera do pedido" ::msgcat::mcset pt "Username Not Available" "O nome do utilizador não está disponível" ::msgcat::mcset pt "Conflict" "Conflito" ::msgcat::mcset pt "Internal Server Error" "Erro interno do servidor" ::msgcat::mcset pt "Not Implemented" "Não implementado" ::msgcat::mcset pt "Remote Server Error" "Erro do servidor remoto" ::msgcat::mcset pt "Service Unavailable" "Serviço indisponível" ::msgcat::mcset pt "Remote Server Timeout" "Esgotou-se o tempo de espera do servidor remoto" # plugins/chat/complete_last_nick.tcl ::msgcat::mcset pt "Number of groupchat messages to expire nick completion according to the last personally addressed message." "Número de mensagens na sala de conferência para expirar a utilização da conclusão automática do nick a partir da sua saída." # plugins/chat/highlight.tcl ::msgcat::mcset pt "Groupchat message highlighting plugin options." "Opções do plugin de destaque de mensagens de salas de conferência." ::msgcat::mcset pt "Enable highlighting plugin." "Activar plugin de destaque de mensagens." ::msgcat::mcset pt "Highlight current nickname in messages." "Destacar o nick actual nas mensagens." ::msgcat::mcset pt "Substrings to highlight in messages." "Sílabas a destacar nas mensagens." ::msgcat::mcset pt "Highlight only whole words in messages." "Destacar apenas palavras completas nas mensagens." # plugins/general/presenceinfo.tcl ::msgcat::mcset pt "\n\tPresence is signed:" "\n\tA presença está assinada:" # /root/instala/tkabber/tkabber-plugins/whiteboard/whiteboard.tcl ::msgcat::mcset pt "Whiteboard" "Quadro" ::msgcat::mcset pt "%s whiteboard" "%s quadro" ::msgcat::mcset pt "PolyLine" "Poli-linha" ::msgcat::mcset pt "FreeHand" "Livre" ::msgcat::mcset pt "Move" "Mover" ::msgcat::mcset pt "Color" "Cor" # /root/instala/tkabber/tkabber-plugins/georoster/georoster.tcl ::msgcat::mcset pt "GeoRoster options." "Opções do Georoster." ::msgcat::mcset pt "Automatically open GeoRoster window." "Abrir automaticamente a janela do GeoRoster." ::msgcat::mcset pt "Default country to use when looking at a vCard." "País a usar, por omissão, quando se procura num vCard." ::msgcat::mcset pt "GeoRoster" "GeoRoster" ::msgcat::mcset pt "Store" "Armazenar" ::msgcat::mcset pt "Show cities" "Mostrar cidades" ::msgcat::mcset pt "Latitude: %.2f Longitude: %.2f" "Latitude: %.2f Longitude: %.2f" ::msgcat::mcset pt "Send contacts to %s" "Enviar contactos a %s" # /root/instala/tkabber/tkabber-plugins/chess/chess.tcl ::msgcat::mcset pt "Let's play chess, %s!" "Vamos jogar xadrez, %s!" ::msgcat::mcset pt "Opponent %s refuse our request: %s" "O oponente %s recusou o teu pedido: %s" ::msgcat::mcset pt "%s want to play chess!" "%s quere jogar xadrez!" ::msgcat::mcset pt "Play" "Jogar" ::msgcat::mcset pt "White" "Brancas" ::msgcat::mcset pt "Chess with %s" "Xadrez com %s" ::msgcat::mcset pt "Allow illegal moves" "Permitir movimentos ilegais" ::msgcat::mcset pt "Move: " "Mover: " ::msgcat::mcset pt "History" "História" ::msgcat::mcset pt "Black" "Pretas" ::msgcat::mcset pt "Pawn promotion" "Promoção de peão" ::msgcat::mcset pt "Chess" "Xadrez" # /root/instala/tkabber/tkabber-plugins/ejabberd/ejabberd.tcl ::msgcat::mcset pt "List of ejabberd servers." "Lista de servidores ejabberd." ::msgcat::mcset pt "Administrate ejabberd" "Administrar ejabberd" ::msgcat::mcset pt "ejabberd server" "servidor ejabberd" ::msgcat::mcset pt "Administrate" "Administrar" ::msgcat::mcset pt "%s administration" "Administração de %s" ::msgcat::mcset pt "Reload" "Recarregar" ::msgcat::mcset pt "Integral" "Integral" tkabber-0.11.1/msgs/pl.msg0000644000175000017500000035241411074056250014627 0ustar sergeisergei# Polish messages file # Author: Irek Chmielowiec # Contact: xmpp:irek@chrome.pl :: mailto:irek.ch@gmail.com # Please notify me of errors or incoherencies # browser.tcl ::msgcat::mcset pl "JID:" "JID:" ::msgcat::mcset pl "Browse" "PrzeglÄ…daj" ::msgcat::mcset pl "%s: %s/%s, Description: %s, Version: %s\nNumber of children: %s" "%s: %s/%s\nOpis: %s\nWersja: %s\nLiczba elementów: %s" ::msgcat::mcset pl {Number of children:} {Ilość elementów:} ::msgcat::mcset pl "Sort" "Sortuj" # plugins/general/message_archive.tcl ::msgcat::mcset pl "To:" "Do:" ::msgcat::mcset pl "From:" "Od:" ::msgcat::mcset pl "Messages" "WiadomoÅ›ci" ::msgcat::mcset pl "Subject:" "Temat:" ::msgcat::mcset pl "Received/Sent" "Odebrane/WysÅ‚ane" ::msgcat::mcset pl "Dir" "<->" ::msgcat::mcset pl "From/To" "Od/Do" ::msgcat::mcset pl "Subject" "Temat" ::msgcat::mcset pl "#" "#" # register.tcl ::msgcat::mcset pl "Register in %s" "Rejestracja w %s" ::msgcat::mcset pl "OK" "OK" ::msgcat::mcset pl "Cancel" "Anuluj" ::msgcat::mcset pl "Registration: %s" "Rejestracja: %s" ::msgcat::mcset pl "Registration is successful!" "Rejestracja powiodÅ‚a siÄ™!" ::msgcat::mcset pl "Close" "Zamknij" ::msgcat::mcset pl "Register" "Zarejestruj" ::msgcat::mcset pl "Unregister" "Wyrejestruj" # presence.tcl ::msgcat::mcset pl "Unsubscribed from %s" "Subskrypcja od %s anulowana" ::msgcat::mcset pl "Not logged in" "Rozłączony" ::msgcat::mcset pl "Free to chat" "ChÄ™tny do rozmowy" ::msgcat::mcset pl "Away" "Zaraz wracam" ::msgcat::mcset pl "Extended away" "Nieobecny" ::msgcat::mcset pl "Do not disturb" "Nie przeszkadzać" ::msgcat::mcset pl "Invisible" "Niewidoczny" ::msgcat::mcset pl "invalid userstatus value " "nieprawidÅ‚owy status " ::msgcat::mcset pl "Change Presence Priority" "ZmieÅ„ priorytet statusu" ::msgcat::mcset pl "Available" "DostÄ™pny" ::msgcat::mcset pl "Unavailable" "Rozłączony" ::msgcat::mcset pl "Stored user priority." "ZapamiÄ™tany priorytet użytkownika." ::msgcat::mcset pl "Stored user status." "ZapamiÄ™tany status użytkownika." ::msgcat::mcset pl "Stored user text status." "ZapamiÄ™tany opis statusu użytkownika." ::msgcat::mcset pl "You are unsubscribed from %s" "Twoja subskrypcja od %s zostaÅ‚a anulowana" # filetransfer.tcl ::msgcat::mcset pl "File Transfer options." "Ustawienia przesyÅ‚ania plików." ::msgcat::mcset pl "Default directory for downloaded files." "DomyÅ›lny katalog dla Å›ciÄ…ganych plików." ::msgcat::mcset pl "Send file to %s" "WyÅ›lij plik do %s" ::msgcat::mcset pl "Browse..." "PrzeglÄ…daj..." ::msgcat::mcset pl "Description:" "Opis:" ::msgcat::mcset pl "IP address:" "Nazwa lub adres IP:" ::msgcat::mcset pl "Send" "WyÅ›lij" ::msgcat::mcset pl "Receive file from %s" "Odbierz plik od %s" ::msgcat::mcset pl "URL:" "URL:" ::msgcat::mcset pl "Save as:" "Zapisz jako:" ::msgcat::mcset pl "Receive" "Odbierz" ::msgcat::mcset pl "Request failed: %s" "WywoÅ‚anie nie powiodÅ‚o siÄ™: %s" ::msgcat::mcset pl "Transferring..." "PrzesyÅ‚anie..." ::msgcat::mcset pl "Name:" "Nazwa:" ::msgcat::mcset pl "Size:" "Rozmiar:" ::msgcat::mcset pl "unknown" "nieznany" ::msgcat::mcset pl "Default protocol for sending files." "DomyÅ›lny protokół wysyÅ‚ania plików." ::msgcat::mcset pl "Can't open file \"%s\": %s" "Nie można otworzyć pliku \"%s\": %s" ::msgcat::mcset pl "Protocol:" "Protokół:" # default.tcl ::msgcat::mcset pl "Error displaying %s in browser\n\n%s" "WystÄ…piÅ‚ błąd podczas otwierania %s w przeglÄ…darce\n\n%s" ::msgcat::mcset pl "Please define environment variable BROWSER" "Należy ustawić zmiennÄ… systemowÄ… BROWSER" # plugins/general/ispell.tcl ::msgcat::mcset pl "Spell check options." "Ustawienia sprawdzania pisowni." ::msgcat::mcset pl "Path to the ispell executable." "Åšcieżka do programu ispell." ::msgcat::mcset pl "Check spell after every entered symbol." "Sprawdzaj pisowniÄ™ po każdym wprowadzonym znaku." ::msgcat::mcset pl "Ispell dictionary encoding. If it is empty, system encoding is used." "Kodowanie sÅ‚ownika ispell. Jeżeli niewypeÅ‚nione, użyte zostanÄ… ustawienia systemu." ::msgcat::mcset pl "- nothing -" "- nic -" ::msgcat::mcset pl "Plugins options." "Ustawienia wtyczek." ::msgcat::mcset pl "Could not start ispell server. Check your ispell path and dictionary name. Ispell is disabled now" "Nie udaÅ‚o siÄ™ wystartować programu ispell. Sprawdź Å›cieżkÄ™ do programu i nazwÄ™ sÅ‚ownika. Ispell jest w tej chwili wyłączony" ::msgcat::mcset pl "Enable spellchecker in text input windows." "Włącz sprawdzanie pisowni w oknach gdzie wpisuje siÄ™ tekst." ::msgcat::mcset pl "Ispell options. See ispell manual for details.\n\nExamples:\n -d russian\n -d german -T latin1\n -C -d english" "Parametry programu ispell. DokÅ‚adny opis znajduje siÄ™ w dokumentacji programu. \n\nPrzykÅ‚ady:\n -d russian\n -d german -T latin1\n -C -d english" # plugins/chat/events.tcl ::msgcat::mcset pl "Message stored on the server" "Wiadomość zapamiÄ™tana na serwerze" ::msgcat::mcset pl "Message stored on %s's server" "Wiadomość zapamiÄ™tana na serwerze %s" ::msgcat::mcset pl "Message delivered" "Wiadomość dostarczona" ::msgcat::mcset pl "Message delivered to %s" "Wiadomość dostarczona do %s" ::msgcat::mcset pl "Message displayed" "Wiadomość przeczytana" ::msgcat::mcset pl "Message displayed to %s" "%s przeczytaÅ‚(a) wiadomość" ::msgcat::mcset pl "Composing a reply" "Pisze odpowiedź" ::msgcat::mcset pl "%s is composing a reply" "%s pisze odpowiedź" ::msgcat::mcset pl "Chat message events plugin options." "Ustawienia wtyczki zdarzeÅ„ wiadomoÅ›ci." ::msgcat::mcset pl "Enable sending chat message events." "Włącz wysyÅ‚anie zdarzeÅ„ wiadomoÅ›ci w rozmowach." # plugins/chat/chatstate.tcl ::msgcat::mcset pl "Chat message window state plugin options." "Ustawienia wtyczki stanu okna rozmowy." ::msgcat::mcset pl "Enable sending chat state notifications." "Włącz wysyÅ‚anie powiadomieÅ„ o stanie okna rozmowy." ::msgcat::mcset pl "Chat window is active" "Okno rozmowy jest aktywne" ::msgcat::mcset pl "%s has activated chat window" "%s aktywowaÅ‚ okno rozmowy" ::msgcat::mcset pl "Paused a reply" "Wstrzymanie odpowiedzi" ::msgcat::mcset pl "%s is paused a reply" "%s wstrzymaÅ‚ odpowiedź" ::msgcat::mcset pl "Chat window is inactive" "Okno rozmowy jest nieaktywne" ::msgcat::mcset pl "%s has inactivated chat window" "%s deaktywowaÅ‚ okno rozmowy" ::msgcat::mcset pl "Chat window is gone" "Okno rozmowy jest wyłączone" ::msgcat::mcset pl "%s has gone chat window" "%s wyłączyÅ‚ okno rozmowy" # search.tcl ::msgcat::mcset pl "Try again" "Ponów" ::msgcat::mcset pl "Search again" "Szukaj ponownie" ::msgcat::mcset pl "Start chat" "Rozmowa" ::msgcat::mcset pl "Send message..." "WyÅ›lij wiadomość..." ::msgcat::mcset pl "Invite to conference..." "ZaproÅ› do konferencji..." ::msgcat::mcset pl "Send users..." "WyÅ›lij kontakty..." ::msgcat::mcset pl "Send file..." "WyÅ›lij plik..." ::msgcat::mcset pl "Show info" "Pokaż wizytówkÄ™" ::msgcat::mcset pl "Show history" "Historia wiadomoÅ›ci" ::msgcat::mcset pl "Search in %s" "Wyszukiwanie w %s" ::msgcat::mcset pl "Search: %s" "Wyszukiwanie: %s" ::msgcat::mcset pl "An error occurred when searching in %s\n\n%s" "WystÄ…piÅ‚ błąd podczas wyszukiwania w %s\n\n%s" ::msgcat::mcset pl "Search in %s: No matching items found" "Wyszukiwanie w %s: Nie znaleziono pasujÄ…cych elementów" ::msgcat::mcset pl "Search" "Szukaj" # privacy.tcl ::msgcat::mcset pl "Requesting privacy rules: %s" "Pobieranie listy zasad z serwera: %s" ::msgcat::mcset pl "Add list" "Dodaj listÄ™" ::msgcat::mcset pl "Remove" "UsuÅ„" ::msgcat::mcset pl "Active" "Aktywna" ::msgcat::mcset pl "Remove list" "UsuÅ„ listÄ™" ::msgcat::mcset pl "Add item" "Dodaj regułę" ::msgcat::mcset pl "Name: " "Nazwa: " ::msgcat::mcset pl "No default list" "Brak domyÅ›lnej listy" ::msgcat::mcset pl "No active list" "Brak aktywnej listy" ::msgcat::mcset pl "Default" "DomyÅ›lna" ::msgcat::mcset pl "Edit list" "Edytuj listÄ™" ::msgcat::mcset pl "Requesting privacy list: %s" "Pobieranie listy zasad: %s" ::msgcat::mcset pl "Blocking communication options." "Ustawienia ochrony prywatnoÅ›ci." ::msgcat::mcset pl "Privacy lists" "Listy zasad ochrony prywatnoÅ›ci" ::msgcat::mcset pl "List name" "Nazwa listy" ::msgcat::mcset pl "Edit privacy list" "Edycja list z zasadami ochrony prywatnoÅ›ci" ::msgcat::mcset pl "Type" "Typ" ::msgcat::mcset pl "Presence-in" "Status-przych." ::msgcat::mcset pl "Presence-out" "Status-wych." ::msgcat::mcset pl "IQ" "IQ" ::msgcat::mcset pl "Up" "Wyżej" ::msgcat::mcset pl "Down" "Niżej" ::msgcat::mcset pl "Add JID" "Dodaj JID" ::msgcat::mcset pl "Remove from list" "UsuÅ„ z listy" ::msgcat::mcset pl "Waiting for activating privacy list" "Oczekiwanie na aktywacjÄ™ listy z zasadami ochrony prywatnoÅ›ci" ::msgcat::mcset pl "Privacy list is activated" "Lista zasad ochrony prywatnoÅ›ci aktywna" ::msgcat::mcset pl "Privacy list is not activated" "Lista zasad ochrony prywatnoÅ›ci nieaktywna" ::msgcat::mcset pl "Requesting ignore list: %s" "Pobieranie listy ignorowanych: %s" ::msgcat::mcset pl "Requesting invisible list: %s" "Pobieranie listy niewidocznoÅ›ci: %s" ::msgcat::mcset pl "Requesting visible list: %s" "Pobieranie listy widocznoÅ›ci: %s" ::msgcat::mcset pl "Sending ignore list: %s" "WysyÅ‚anie listy ignorowanych: %s" ::msgcat::mcset pl "Sending invisible list: %s" "WysyÅ‚anie listy niewidocznoÅ›ci: %s" ::msgcat::mcset pl "Sending visible list: %s" "WysyÅ‚anie listy widocznoÅ›ci: %s" ::msgcat::mcset pl "Ignore list" "Lista ignorowanych" ::msgcat::mcset pl "Invisible list" "Lista niewidocznoÅ›ci" ::msgcat::mcset pl "Visible list" "Lista widocznoÅ›ci" ::msgcat::mcset pl "Blocking communication (XMPP privacy lists) options." "Ustawienia blokady komunikacji (listy zasad prywatnoÅ›ci XMPP)." ::msgcat::mcset pl "Privacy lists are not implemented" "Listy zasad prywatnoÅ›ci nie sÄ… zaimplementowane" ::msgcat::mcset pl "Privacy lists are unavailable" "Listy zasad prywatnoÅ›ci sÄ… niedostÄ™pne" ::msgcat::mcset pl "Creating default privacy list" "Tworzenie domyÅ›lnej listy zasad prywatnoÅ›ci" ::msgcat::mcset pl "Privacy list is not created" "Lista zasad prywatnoÅ›ci nie zostaÅ‚a utworzona" ::msgcat::mcset pl "Privacy lists error" "Błąd list zasad prywatnoÅ›ci" ::msgcat::mcset pl "Creating default privacy list failed: %s\n\nTry to reconnect. If problem persists, you may want to disable privacy list activation at start" "Tworzenie domyÅ›lnej listy zasad prywatnoÅ›ci nie powiodÅ‚o siÄ™: %s\n\nSpróbuj połączyć siÄ™ ponownie. Jeżeli problem bÄ™dzie nadal wystÄ™powaÅ‚, być może konieczne bÄ™dzie wyłączenie aktywacji list przy starcie programu" ::msgcat::mcset pl "Activating privacy list failed: %s\n\nTry to reconnect. If problem persists, you may want to disable privacy list activation at start" "Aktywacja listy zasad prywatnoÅ›ci nie powiodÅ‚a siÄ™: %s\n\nSpróbuj połączyć siÄ™ ponownie. Jeżeli problem bÄ™dzie nadal wystÄ™powaÅ‚, być może konieczne bÄ™dzie wyłączenie aktywacji list przy starcie programu" ::msgcat::mcset pl "Edit ignore list" "Edycja listy ignorowanych" ::msgcat::mcset pl "Edit invisible list" "Edycja listy niewidocznoÅ›ci" ::msgcat::mcset pl "Activate visible/invisible/ignore/conference lists before sending initial presence." "Aktywuj listy widocznoÅ›ci/niewidocznoÅ›ci/ignorowania/konferecji przed wysÅ‚aniem poczÄ…tkowego statusu." ::msgcat::mcset pl "Edit conference list" "Edytuj listÄ™ konferencji" ::msgcat::mcset pl "Requesting conference list: %s" "Pobieranie listy konferecji: %s" ::msgcat::mcset pl "Sending conference list: %s" "WysyÅ‚anie listy konferencji: %s" ::msgcat::mcset pl "Changing accept messages from roster only: %s" "Zmiana akceptowania wiadomoÅ›ci tylko od osób z listy kontaktów: %s" # plugins/chat/draw_xhtml_message.tcl ::msgcat::mcset pl "Enable rendering of XHTML messages." "Włącz obsÅ‚ugÄ™ XHTML w wiadomoÅ›ciach." # plugins/chat/draw_timestamp.tcl ::msgcat::mcset pl "Format of timestamp in chat message. Refer to Tcl documentation of 'clock' command for description of format.\n\nExamples:\n \[%R\] - \[20:37\]\n \[%T\] - \[20:37:12\]\n \[%a %b %d %H:%M:%S %Z %Y\] - \[Thu Jan 01 03:00:00 MSK 1970\]" "Format czasu i daty w wiadomoÅ›ciach. DokÅ‚adny opis formatu w dokumentacji Tcl dla polecenia 'clock'.\n\nPrzykÅ‚ady:\n \[%R\] \u2013 \[20:37\]\n \[%T\] \u2013 \[20:37:12\]\n \[%a %b %d %H:%M:%S %Z %Y\] \u2013 \[Wto Sty 01 03:00:00 CET 1970\]" ::msgcat::mcset pl "Format of timestamp in delayed chat messages delayed for more than 24 hours." "Format czasu i daty w wiadomoÅ›ciach dostarczonych z opóźnieniem wiÄ™kszym niż 24 godziny." # roster.tcl ::msgcat::mcset pl "Roster options." "Ustawienia listy kontaktów." ::msgcat::mcset pl "Are you sure to remove %s from roster?" "Czy na pewno chcesz usunąć %s ze swojej listy?" ::msgcat::mcset pl "Edit item..." "Edytuj kontakt..." ::msgcat::mcset pl "Edit security..." "Ustawienia zabezpieczeÅ„..." ::msgcat::mcset pl "Join..." "Dołącz do..." ::msgcat::mcset pl "Log in" "Zaloguj..." ::msgcat::mcset pl "Log out" "Wyloguj..." ::msgcat::mcset pl "Resubscribe to all users in group..." "PoproÅ› ponownie o subskrypcjÄ™ od wszystkich w grupie..." ::msgcat::mcset pl "Rename roster group" "ZmieÅ„ nazwÄ™ grupy" ::msgcat::mcset pl "New group name:" "Nazwa nowej grupy:" ::msgcat::mcset pl "Undefined" "Niezdefiniowane" ::msgcat::mcset pl "Add roster group by JID regexp" "Grupa wg wyrażenia regularnego dla JID-ów" ::msgcat::mcset pl "JID regexp:" "Wyrażenie regularne:" ::msgcat::mcset pl "No users in roster..." "Brak użytkowników na liÅ›cie..." ::msgcat::mcset pl "Contact Information" "Wizytówka użytkownika" ::msgcat::mcset pl "Roster Files" "Pliki listy kontaktów" ::msgcat::mcset pl "All Files" "Wszystkie pliki" ::msgcat::mcset pl "Roster of %s" "Lista kontaktów dla %s" ::msgcat::mcset pl "Send custom presence" "WyÅ›lij status" ::msgcat::mcset pl "Roster" "Lista kontaktów" ::msgcat::mcset pl "Add conference..." "Dodaj konferencjÄ™..." ::msgcat::mcset pl "Add group by regexp on JIDs..." "Dodaj grupÄ™ wg wyrażenia" ::msgcat::mcset pl "Show online users only" "Pokaż tylko użytkowników dostÄ™pnych" ::msgcat::mcset pl "Export roster..." "Eksportuj listÄ™..." ::msgcat::mcset pl "Import roster..." "Importuj listÄ™..." ::msgcat::mcset pl {Send contacts to} {WyÅ›lij kontakty do} ::msgcat::mcset pl "Show only online users in roster." "Pokaż tylko użytkowników dostÄ™pnych." ::msgcat::mcset pl "Show native icons for transports/services in roster." "Pokaż wÅ‚asne ikony transportów/agentów." ::msgcat::mcset pl "Show native icons for contacts, connected to transports/services in roster." "Pokaż wÅ‚asne ikony kontaktów, połączonych przez transporty/agenty." ::msgcat::mcset pl "Show offline users" "Pokaż użytkowników rozłączonych" ::msgcat::mcset pl "Add chats group in roster." "Pokaż grupÄ™ 'Aktywne rozmowy' z listÄ… aktualnie prowadzonych rozmów i konferencji." ::msgcat::mcset pl "Active Chats" "Aktywne rozmowy" ::msgcat::mcset pl "Show subscription type in roster item tooltips." "Pokaż typ subskrybcji w dymku podpowiedzi dla kontaktu." ::msgcat::mcset pl "Show detailed info on conference room members in roster item tooltips." "Pokaż szczegółowe informacje w dymku podpowiedzi dla aktywnej konferencji, o użytkownikach biorÄ…cych w niej udziaÅ‚." ::msgcat::mcset pl "Send contacts to %s" "WyÅ›lij kontakty do %s" ::msgcat::mcset pl "Use aliases to show multiple users in one roster item." "Używaj aliasów do łączenia wielu kontaktów w jednÄ… pozycjÄ™ na liÅ›cie (metakontakty)." ::msgcat::mcset pl "Roster item may be dropped not only over group name but also over any item in group." "Elementy listy przenoszone metodÄ… drag&drop mogÄ… być upuszczone nie tylko na pozycjÄ™ z nazwÄ… grupy, ale także na każdy inny element tej grupy." ::msgcat::mcset pl "is available" "ma status DostÄ™pny" ::msgcat::mcset pl "is free to chat" "ma status ChÄ™tny do rozmowy" ::msgcat::mcset pl "is away" "ma status Zaraz wracam" ::msgcat::mcset pl "is extended away" "ma status Nieobecny" ::msgcat::mcset pl "doesn't want to be disturbed" "ma status Nie przeszkadzać" ::msgcat::mcset pl "is invisible" "ma status Niewidoczny" ::msgcat::mcset pl "is unavailable" "ma status Rozłączony" # plugins/chat/clear.tcl ::msgcat::mcset pl "Clear chat window" "Wyczyść okno rozmów" # gpgme.tcl ::msgcat::mcset pl "Select" "Wybierz" ::msgcat::mcset pl "Please enter passphrase" "Wprowadź hasÅ‚o do klucza" ::msgcat::mcset pl "Please try again" "Spróbuj jeszcze raz" ::msgcat::mcset pl "Key ID" "ID klucza" ::msgcat::mcset pl "Passphrase:" "HasÅ‚o:" ::msgcat::mcset pl "Error in signature verification software: %s." "Błąd programu weryfikujÄ…cego podpis: %s." ::msgcat::mcset pl "%s purportedly signed by %s can't be verified.\n\n%s." "%s podpisany przez %s nie może być zweryfikowany.\n\n%s." ::msgcat::mcset pl "Unable to sign presence information: %s.\n\nPresence will be sent, but signing traffic is now disabled." "Nie można podpisać statusu widocznoÅ›ci: %s.\n\nStatus zostanie wysÅ‚any, ale podpisywanie wiadmoÅ›ci jest wyłączone." ::msgcat::mcset pl "Unable to sign message body: %s.\n\nSigning traffic is now disabled.\n\nSend it WITHOUT a signature?" "Nie można podpisać treÅ›ci: %s.\n\nPodpisywanie wiadmoÅ›ci jest wyłączone.\n\nCzy chcesz wysÅ‚ać BEZ podpisu?" ::msgcat::mcset pl "Data purported sent by %s can't be deciphered.\n\n%s." "Dane wysÅ‚ane przez %s nie mogÄ… być odszyfrowane.\n\n%s." ::msgcat::mcset pl "Unable to encipher data for %s: %s.\n\nEncrypting traffic to this user is now disabled.\n\nSend it as PLAINTEXT?" "Nie można zaszyfrować danych dla %s: %s.\n\nSzyfrowanie wiadomoÅ›ci do tego użytkownika jest wyłączone.\n\nCzy chcesz wysÅ‚ać wiadomość jako ZWYKÅY TEKST?" ::msgcat::mcset pl "Change security preferences for %s" "ZmieÅ„ ustawienia zabezpieczeÅ„ dla %s" ::msgcat::mcset pl "Encrypt traffic" "Szyfruj wiadomoÅ›ci" ::msgcat::mcset pl "User ID" "ID użytkownika" ::msgcat::mcset pl "Select Key for Signing %s Traffic" "Wybierz klucz do podpisywania wiadomoÅ›ci od %s" ::msgcat::mcset pl "Fetch GPG key" "Pobierz klucz GPG z serwera kluczy" ::msgcat::mcset pl "GPG options (signing and encryption)." "Ustwienia GPG (podpisywanie i szyfrowanie wiadomoÅ›ci)." ::msgcat::mcset pl "Use the same passphrase for signing and decrypting messages." "Używaj tego samego hasÅ‚a do podpisywania i odszyfrowania wiadomoÅ›ci." ::msgcat::mcset pl "GPG-sign outgoing messages and presence updates." "Podpisz za pomocÄ… GPG wychodzÄ…ce wiadomoÅ›ci i zmiany statusu." ::msgcat::mcset pl "GPG-encrypt outgoing messages where possible." "Szyfruj za pomocÄ… GPG wychodzÄ…ce wiadomoÅ›ci jeżeli to możliwe." ::msgcat::mcset pl "Use specified key ID for signing and decrypting messages." "Podaj ID klucza do podpisywania i odszyfrowania wiadomoÅ›ci." ::msgcat::mcset pl "No information available" "Brak informacji" ::msgcat::mcset pl "Invalid signature" "Niepoprawny podpis" ::msgcat::mcset pl "Signature not processed due to missing key" "Podpis nie zostaÅ‚ zweryfikowany z powodu braku klucza" ::msgcat::mcset pl "Malformed signature block" "Wadliwy blok podpisu" ::msgcat::mcset pl "Error in signature processing" "Błąd podczas weryfikacji podpisu" ::msgcat::mcset pl "Multiple signatures having different authenticity" "Wiele podpisów majÄ…cych różnÄ… wiarygodność" ::msgcat::mcset pl "The signature is good but has expired" "Podpis jest prawidÅ‚owy ale ulegÅ‚ przedawnieniu" ::msgcat::mcset pl "The signature is good but the key has expired" "Podpis jest prawidÅ‚owy ale klucz podpisujÄ…cy ulegÅ‚ przedawnieniu" ::msgcat::mcset pl "Presence information" "Informacje o statusie" ::msgcat::mcset pl "Display warning dialogs when signature verification fails." "Pokazuj okno z ostrzeżeniem gdy nie powiedzie siÄ™ weryfikacja podpisu." ::msgcat::mcset pl "Encrypt traffic (when possible)" "Szyfruj wiadomoÅ›ci (kiedy możliwe)" ::msgcat::mcset pl "Encryption" "Szyfrowanie" ::msgcat::mcset pl "Sign traffic" "Podpisuj wiadomoÅ›ci" # roster_nested.tcl ::msgcat::mcset pl "Enable nested roster groups." "Włącz wielopoziomowe grupy na liÅ›cie kontaktów." ::msgcat::mcset pl "Default nested roster group delimiter." "DomyÅ›lny separator dla wielopoziomowych grup." # login.tcl ::msgcat::mcset pl "Login options." "Ustawienia logowania." ::msgcat::mcset pl "User name." "Użytkownik." ::msgcat::mcset pl "Password." "HasÅ‚o." ::msgcat::mcset pl "Resource." "Zasób." ::msgcat::mcset pl "Server name." "Serwer." ::msgcat::mcset pl "Server port." "Port serwera." ::msgcat::mcset pl "Priority." "Priorytet." ::msgcat::mcset pl "HTTP proxy address." "Adres proxy HTTP." ::msgcat::mcset pl "HTTP proxy port." "Port proxy HTTP." ::msgcat::mcset pl "HTTP proxy username." "Nazwa użytkownika proxy HTTP." ::msgcat::mcset pl "HTTP proxy password." "HasÅ‚o użytkownika proxy HTTP." ::msgcat::mcset pl "Server name or IP-address." "Nazwa alternatywnego serwera lub jego adres IP" ::msgcat::mcset pl "Replace opened connections." "ZastÄ…p otwarte połączenia." ::msgcat::mcset pl "List of logout reasons." "Lista opisów wylogowania." ::msgcat::mcset pl "Login" "Zaloguj" ::msgcat::mcset pl "Username:" "Użytkownik:" ::msgcat::mcset pl "Server:" "Serwer:" ::msgcat::mcset pl "Port:" "Port:" ::msgcat::mcset pl "Password:" "HasÅ‚o:" ::msgcat::mcset pl "Resource:" "Zasób:" ::msgcat::mcset pl "Priority:" "Priorytet:" ::msgcat::mcset pl "Use Proxy" "Użyj serwera proxy" ::msgcat::mcset pl "Proxy Server:" "Adres serwera proxy:" ::msgcat::mcset pl "Proxy Port:" "Port proxy:" ::msgcat::mcset pl "Proxy Login:" "Użytkownik proxy:" ::msgcat::mcset pl "Proxy Password:" "HasÅ‚o proxy:" ::msgcat::mcset pl "Replace opened connections" "ZastÄ…p otwarte połączenia" ::msgcat::mcset pl "Logout" "Wyloguj" ::msgcat::mcset pl "Authentication failed: %s\nCreate new account?" "Uwierzytelnianie nie powiodÅ‚o siÄ™: %s\nCzy chcesz zarejestrować nowe konto?" ::msgcat::mcset pl "Registration failed: %s" "Rejestracja nie udaÅ‚a siÄ™: %s" ::msgcat::mcset pl "Change password" "Zmiana hasÅ‚a" ::msgcat::mcset pl "Old password:" "Stare hasÅ‚o:" ::msgcat::mcset pl "New password:" "Nowe hasÅ‚o:" ::msgcat::mcset pl "Repeat new password:" "Powtórz nowe hasÅ‚o:" ::msgcat::mcset pl "Old password is incorrect" "Stare hasÅ‚o nie zgadza siÄ™" ::msgcat::mcset pl "New passwords do not match" "Nowe hasÅ‚a nie pasujÄ…" ::msgcat::mcset pl "Password is changed" "HasÅ‚o zostaÅ‚o zmienione" ::msgcat::mcset pl "Password change failed: %s" "Zmiana hasÅ‚a nie udaÅ‚a siÄ™: %s" ::msgcat::mcset pl "Logout with reason" "Wyloguj z opisem" ::msgcat::mcset pl "Reason:" "Opis:" ::msgcat::mcset pl "Profiles" "Profile" ::msgcat::mcset pl "Profile" "Profil" ::msgcat::mcset pl "SSL certificate file (optional)." "Plik certyfikatu SSL (opcjonalnie)." ::msgcat::mcset pl "Use HTTP poll connection method." "Użyj pasywnego połączenia przez serwer HTTP (polling)." ::msgcat::mcset pl "URL to connect to." "URL połączenia." ::msgcat::mcset pl "Use HTTP poll client security keys (recommended)." "Używaj kluczy klienta przy połączeniu typu HTTP poll (zalecane)." ::msgcat::mcset pl "Account" "Konto" ::msgcat::mcset pl "Connection" "Połączenie" ::msgcat::mcset pl "SSL" "SSL" ::msgcat::mcset pl "SSL Certificate:" "Certyfikat SSL:" ::msgcat::mcset pl "Proxy" "Proxy" ::msgcat::mcset pl "HTTP Poll" "HTTP poll" ::msgcat::mcset pl "Connect via HTTP polling" "Połącz przez sewrer HTTP" ::msgcat::mcset pl "URL to poll:" "URL połączenia:" ::msgcat::mcset pl "Use client security keys" "Używaj kluczy klienta" ::msgcat::mcset pl "Retry to connect forever." "Ponawiaj próby połączena w nieskoÅ„czoność." ::msgcat::mcset pl "Failed to connect: %s" "Połączenie nie udaÅ‚o siÄ™: %s" ::msgcat::mcset pl "SSL certification authority file or directory (optional)." "Katalog lub plik urzÄ™du certyfikujÄ…cego SSL (opcjonalnie)." ::msgcat::mcset pl "SSL private key file (optional)." "Plik z kluczem prywatnym SSL (opcjonalnie)." ::msgcat::mcset pl "Warning display options." "Ustawienia wyÅ›wietlania ostrzeżeÅ„." ::msgcat::mcset pl "Display SSL warnings." "WyÅ›wietlaj ostrzeżenia SSL/TLS." ::msgcat::mcset pl "Minimum poll interval." "Minimalny odstÄ™p czasu dla odwoÅ‚aÅ„ HTTP poll." ::msgcat::mcset pl "Maximum poll interval." "Maksymalny odstÄ™p czasu dla odwoÅ‚aÅ„ HTTP poll." ::msgcat::mcset pl "Keep trying" "Ponów próbÄ™" ::msgcat::mcset pl ". Proceed?\n\n" ". Kontynuować?\n\n" ::msgcat::mcset pl "Number of HTTP poll client security keys to send before creating new key sequence." "Ilość kluczy klienta wysyÅ‚anych przed utworzeniem nowej serii kluczy." ::msgcat::mcset pl "Timeout for waiting for HTTP poll responses (if set to zero, Tkabber will wait forever)." "Czas oczekiwania na odpowiedzi HTTP poll (0 oznacza czekanie w nieskoÅ„czoność)." ::msgcat::mcset pl "Authentication failed: %s" "Uwierzytelnianie nie powiodÅ‚o siÄ™: %s" ::msgcat::mcset pl "User-Agent string." "Identyfikator przeglÄ…darki (User-Agent)." ::msgcat::mcset pl "Use SASL authentication." "Włącz uwierzytelnianie SASL." ::msgcat::mcset pl "Allow plaintext authentication mechanisms (when password is transmitted unencrypted)." "Włącz mechanizmy uwierzytelniania zwykÅ‚ym tekstem (hasÅ‚o jest wysyÅ‚ane niezaszyfrowane)." ::msgcat::mcset pl "XMPP stream options when connecting to server." "Opcje strumienia XMPP przy połączeniu z serwerem." ::msgcat::mcset pl "Use explicitly-specified server address and port." "RÄ™czne ustawienie portu i nazwy serwera do połączenia." ::msgcat::mcset pl "HTTPS" "HTTPS" ::msgcat::mcset pl "Proxy type to connect." "Typ serwera proxy." ::msgcat::mcset pl "SOCKS4a" "SOCKS4a" ::msgcat::mcset pl "SOCKS5" "SOCKS5" ::msgcat::mcset pl "Certificate has expired" "Certyfikat straciÅ‚ ważność" ::msgcat::mcset pl "Self signed certificate" "Certyfikat typu self-signed" # plugins/unix/wmdock.tcl ::msgcat::mcset pl "Message from %s" "Wiadomość od %s" ::msgcat::mcset pl "%s msgs" "%s wiad" ::msgcat::mcset pl "%s is %s" "%s - %s" # plugins/unix/systray.tcl ::msgcat::mcset pl "Enable freedesktop systray icon." "Włącz obsÅ‚ugÄ™ ikony zasobnika freedesktop." # plugins/unix/tktray.tcl ::msgcat::mcset pl "Enable freedesktop system tray icon." "Włącz obsÅ‚ugÄ™ ikony zasobnika freedesktop." # plugins/general/autoaway.tcl ::msgcat::mcset pl "Options for module that automatically marks you as away after idle threshold." "Ustawienia moduÅ‚u, który automatycznie ustawia status nieobecnoÅ›ci po okreÅ›lonym czasie bezczynnoÅ›ci." ::msgcat::mcset pl "Idle threshold in minutes after that Tkabber marks you as away." "OdstÄ™p czasu w minutach, po którym Tkabber ustawi status 'Zaraz wracam'." ::msgcat::mcset pl "Idle threshold in minutes after that Tkabber marks you as extended away." "OdstÄ™p czasu w minutach, po którym Tkabber ustawi status 'Nieobecny'." ::msgcat::mcset pl "Automatically away due to idle" "Automatyczny status 'Zaraz wracam' z powodu bezczynnoÅ›ci" ::msgcat::mcset pl "Text status, which is set when Tkabber is moving to away state." "Opis statusu, który bÄ™dzie ustawiony po przejÅ›ciu w stan 'Zaraz wracam'." ::msgcat::mcset pl "Returning from auto-away" "Wyłączanie autostatusu 'Zaraz wracam'" ::msgcat::mcset pl "Moving to extended away" "Zmiana autostatusu na 'Nieobecny'" ::msgcat::mcset pl "Starting auto-away" "Włączanie autostausu 'Zaraz wracam'" ::msgcat::mcset pl "Idle for %s" "Bezczynny przez %s" ::msgcat::mcset pl "Set priority to 0 when moving to extended away state." "Ustaw priorytet na 0 przy przejÅ›ciu do statusu 'Nieobecny'." # plugins/general/clientinfo.tcl ::msgcat::mcset pl "\n\tName: %s" "\n\tNazwa: %s" ::msgcat::mcset pl "\n\tClient: %s" "\n\tKlient: %s" ::msgcat::mcset pl "\n\tOS: %s" "\n\tSystem: %s" # userinfo.tcl ::msgcat::mcset pl "List of users for userinfo." "Lista użytkowników." ::msgcat::mcset pl "Show user or service info" "Pokaż wizytówkÄ™ użytkownika, usÅ‚ugi" ::msgcat::mcset pl "Show" "Pokaż" ::msgcat::mcset pl "%s info" "Wizytówka dla %s" ::msgcat::mcset pl "Personal" "Osobiste" ::msgcat::mcset pl "Name" "Dane osobowe" ::msgcat::mcset pl "Full Name:" "PeÅ‚na nazwa:" ::msgcat::mcset pl "Family Name:" "Nazwisko:" ::msgcat::mcset pl "Name:" "ImiÄ™:" ::msgcat::mcset pl "Middle Name:" "Drugie imiÄ™:" ::msgcat::mcset pl "Prefix:" "Prefiks:" ::msgcat::mcset pl "Suffix:" "Sufiks:" ::msgcat::mcset pl "Nickname:" "Pseudonim:" ::msgcat::mcset pl "Information" "Informacje" ::msgcat::mcset pl "E-mail:" "E-mail:" ::msgcat::mcset pl "Web Site:" "Strona domowa:" ::msgcat::mcset pl "UID:" "UID:" ::msgcat::mcset pl "Phones" "Telefony" ::msgcat::mcset pl "Telephone numbers" "Numery telefonów" ::msgcat::mcset pl "Home:" "Domowy:" ::msgcat::mcset pl "Work:" "Praca:" ::msgcat::mcset pl "Voice:" "Voice:" ::msgcat::mcset pl "Fax:" "Fax:" ::msgcat::mcset pl "Pager:" "Pager:" ::msgcat::mcset pl "Message Recorder:" "Aut. sekretarka:" ::msgcat::mcset pl "Cell:" "Komórkowy:" ::msgcat::mcset pl "Video:" "Video:" ::msgcat::mcset pl "BBS:" "BBS:" ::msgcat::mcset pl "Modem:" "Modem:" ::msgcat::mcset pl "ISDN:" "ISDN:" ::msgcat::mcset pl "PCS:" "PCS:" ::msgcat::mcset pl "Preferred:" "Preferowany:" ::msgcat::mcset pl "Location" "Miejsce zamieszkania" ::msgcat::mcset pl "Address" "Adres" ::msgcat::mcset pl "Address:" "Adres:" ::msgcat::mcset pl "Address 2:" "Adres 2:" ::msgcat::mcset pl "City:" "Miasto:" ::msgcat::mcset pl "State:" "Województwo:" ::msgcat::mcset pl "Postal Code:" "Kod pocztowy:" ::msgcat::mcset pl "Country:" "PaÅ„stwo:" ::msgcat::mcset pl "Geographical position" "PoÅ‚ożenie geograficzne" ::msgcat::mcset pl "Latitude:" "Szerokość:" ::msgcat::mcset pl "Longitude:" "DÅ‚ugość:" ::msgcat::mcset pl "Organization" "Organizacja" ::msgcat::mcset pl "Details" "Szczegóły" ::msgcat::mcset pl "Name: " "Nazwa:" ::msgcat::mcset pl "Unit:" "Jednostka:" ::msgcat::mcset pl "Personal " "Osobiste " ::msgcat::mcset pl "Title:" "TytuÅ‚:" ::msgcat::mcset pl "Role:" "Stanowisko:" ::msgcat::mcset pl "About " "Dodatkowe " ::msgcat::mcset pl "Birthday" "Urodziny" ::msgcat::mcset pl "Birthday:" "Data urodzin:" ::msgcat::mcset pl "Year:" "Rok:" ::msgcat::mcset pl "Month:" "MiesiÄ…c:" ::msgcat::mcset pl "Day:" "DzieÅ„:" ::msgcat::mcset pl "Photo" "ZdjÄ™cie" ::msgcat::mcset pl "URL" "URL" ::msgcat::mcset pl "Image" "Obraz" ::msgcat::mcset pl "None" "Wyłącz" ::msgcat::mcset pl "Load Image" "Åaduj obraz" ::msgcat::mcset pl "Avatar" "Awatar" ::msgcat::mcset pl "Client" "Program" ::msgcat::mcset pl "Client:" "Nazwa:" ::msgcat::mcset pl "Version:" "Wersja:" ::msgcat::mcset pl "Last Activity or Uptime" "Ostatnia aktywność / czas dziaÅ‚ania" ::msgcat::mcset pl "Interval:" "OdstÄ™p czasu:" ::msgcat::mcset pl "Description:" "Opis:" ::msgcat::mcset pl "OS:" "System:" ::msgcat::mcset pl "Time:" "Czas:" ::msgcat::mcset pl "Time Zone:" "Strefa cz.:" ::msgcat::mcset pl "UTC:" "UTC:" ::msgcat::mcset pl "Presence is signed" "Status podpisany" ::msgcat::mcset pl " by " " przez " ::msgcat::mcset pl "User info" "Informacje o użytkowniku" ::msgcat::mcset pl "Last activity" "Ostatnia aktywność" ::msgcat::mcset pl "Time" "Czas" ::msgcat::mcset pl "Version" "Wersja" ::msgcat::mcset pl "Service info" "Wizytówka" ::msgcat::mcset pl "Uptime" "Ostatnia aktywność/czas dziaÅ‚ania" ::msgcat::mcset pl "GIF images" "Obrazy GIF" ::msgcat::mcset pl "All files" "Wszystkie pliki" ::msgcat::mcset pl "JPEG images" "Obrazy JPEG" ::msgcat::mcset pl "PNG images" "Obrazy PNG" ::msgcat::mcset pl "Loading photo failed: %s." "Nie udaÅ‚o siÄ™ wczytać zdjÄ™cia: %s." ::msgcat::mcset pl "Update" "Aktualizuj" # datagathering.tcl ::msgcat::mcset pl "Error requesting data: %s" "Błąd przy pobieraniu danych: %s" ::msgcat::mcset pl "First Name:" "ImiÄ™:" ::msgcat::mcset pl "Last Name:" "Nazwisko:" ::msgcat::mcset pl "Email:" "Email:" ::msgcat::mcset pl "Zip:" "Kod pocztowy:" ::msgcat::mcset pl "Phone:" "Telefon:" ::msgcat::mcset pl "Date:" "Data:" ::msgcat::mcset pl "Misc:" "Różne:" ::msgcat::mcset pl "Text:" "Tekst:" ::msgcat::mcset pl "Key:" "Klucz:" ::msgcat::mcset pl "Instructions" "Instrukcje" ::msgcat::mcset pl "Data form" "Konfiguracja/dane" ::msgcat::mcset pl "Configure service" "Konfiguracja usÅ‚ugi" # custom.tcl ::msgcat::mcset pl "Customization of the One True Jabber Client." "Ustawienia dla Jednynego Prawdziwego Klienta Jabbera." ::msgcat::mcset pl "Customize" "Ustawienia" ::msgcat::mcset pl "Group:" "Grupa:" ::msgcat::mcset pl "Open" "Otwórz" ::msgcat::mcset pl "Parent group" "NadrzÄ™dna grupa" ::msgcat::mcset pl "Parent groups" "NadrzÄ™dne grupy" ::msgcat::mcset pl "State" "Stan" ::msgcat::mcset pl "value is changed, but the option is not set." "wartość edytowana, ale nie zapamiÄ™tano stanu opcji." ::msgcat::mcset pl "the option is set and saved." "opcja zostaÅ‚a zmieniona i zapamiÄ™tana." ::msgcat::mcset pl "the option is set, but not saved." "opcja zostaÅ‚a zmieniona, ale nie zapamiÄ™tana." ::msgcat::mcset pl "the option is taken from config file." "opcja ma warość z pliku ustawieÅ„." ::msgcat::mcset pl "the option is set to its default value." "opcja ma wartość domyÅ›lnÄ…." ::msgcat::mcset pl "Set for current session only" "ZapamiÄ™taj dla obecnej sesji" ::msgcat::mcset pl "Set for current and future sessions" "ZapamiÄ™taj dla obecnej i przyszÅ‚ych sesji" ::msgcat::mcset pl "Reset to current value" "Przywróć aktualnÄ… wartość" ::msgcat::mcset pl "Reset to saved value" "Przywróć zapisanÄ… wartość" ::msgcat::mcset pl "Reset to value from config file" "Przywróć wartość z pliku ustawieÅ„" ::msgcat::mcset pl "Reset to default value" "Przywróć domyÅ›lnÄ… wartość" # muc.tcl ::msgcat::mcset pl "Generate status messages when occupants enter/exit MUC compatible conference rooms." "Generuj wiadomoÅ›ci o statusie użytkowników wchodzÄ…cych/wychodzÄ…cych w pokojach konferencyjnych zgodnych z MUC." ::msgcat::mcset pl "Generate groupchat messages when occupant changes his/her status and/or status message" "Generuj wiadomoÅ›ci kiedy uczestnik konferencji zmienia swój status lub opis statusu" ::msgcat::mcset pl "Whois" "Kim jest" ::msgcat::mcset pl "Kick" "Wyrzuć" ::msgcat::mcset pl "Ban" "ZabroÅ„ wstÄ™pu" ::msgcat::mcset pl "Grant Voice" "Przyznaj prawo gÅ‚osu" ::msgcat::mcset pl "Revoke Voice" "Odbierz prawo gÅ‚osu" ::msgcat::mcset pl "Grant Membership" "Przyznaj prawa czÅ‚onka" ::msgcat::mcset pl "Revoke Membership" "Odbierz prawa czÅ‚onka" ::msgcat::mcset pl "Grant Moderator Privileges" "Przyznaj prawa moderatora" ::msgcat::mcset pl "Revoke Moderator Privileges" "Odbierz prawa moderatora" ::msgcat::mcset pl "Grant Admin Privileges" "Przyznaj prawa administratora" ::msgcat::mcset pl "Revoke Admin Privileges" "Odbierz prawa administratora" ::msgcat::mcset pl "Grant Owner Privileges" "Przyznaj prawa wÅ‚aÅ›ciciela" ::msgcat::mcset pl "Revoke Owner Privileges" "Odbierz prawa wÅ‚aÅ›ciciela" ::msgcat::mcset pl "MUC" "Polecenia MUC" ::msgcat::mcset pl "Edit moderator list" "Lista moderatorów" ::msgcat::mcset pl "Edit ban list" "Lista bez prawa wstÄ™pu" ::msgcat::mcset pl "Edit member list" "Lista czÅ‚onków" ::msgcat::mcset pl "Edit voice list" "Lista z prawem gÅ‚osu" ::msgcat::mcset pl "Edit admin list" "Lista administratorów" ::msgcat::mcset pl "Edit owner list" "Lista wÅ‚aÅ›cicieli" ::msgcat::mcset pl "Add" "Dodaj" ::msgcat::mcset pl " by %s" " przez %s" ::msgcat::mcset pl "%s is now known as %s" "%s nazywa siÄ™ teraz %s" ::msgcat::mcset pl "%s has left" "%s wyszedÅ‚" ::msgcat::mcset pl "%s has been banned" "Zablokowano wstÄ™p dla %s" ::msgcat::mcset pl "%s has been kicked" "%s zostaÅ‚ wyrzucony" ::msgcat::mcset pl "\n\tJID: %s" "\n\tJID: %s" ::msgcat::mcset pl "\n\tAffiliation: %s" "\n\tPrzynależność: %s" ::msgcat::mcset pl "Report the list of current MUC rooms on disco#items query." "WysyÅ‚aj listÄ™ aktywnych pokoi MUC przy zapytaniu disco#items." ::msgcat::mcset pl "Join conference" "Dołącz do konferencji" ::msgcat::mcset pl "Join groupchat" "Dołącz do konferencji" ::msgcat::mcset pl "Maximum number of characters in the history in MUC compatible conference rooms." "Maksymalna liczba znaków historii pokoi konferencyjnych MUC." ::msgcat::mcset pl "Maximum number of stanzas in the history in MUC compatible conference rooms." "Maksymalna liczba zwrotek historii pokoi konferencyjnych MUC." ::msgcat::mcset pl "Request only unseen (which aren't displayed in the chat window) messages in the history in MUC compatible conference rooms." "Pobierz tylko nieprzeczytane (niewidoczne w oknie rozmowy) wiadomoÅ›ci historii pokoi konferencyjnych MUC." ::msgcat::mcset pl "Destroy room" "Zamknij pokój" ::msgcat::mcset pl "Nick" "Pseudonim" ::msgcat::mcset pl "Role" "Rola" ::msgcat::mcset pl "Affiliation" "Przynależność" ::msgcat::mcset pl "Reason" "Powód" ::msgcat::mcset pl "Conference room %s will be destroyed permanently.\n\nProceed?" "Pokój konferencyjny \"%s\" zostanie usuniÄ™ty na staÅ‚e.\n\nKontynuować?" ::msgcat::mcset pl "Propose to configure newly created MUC room. If set to false then the default room configuration is automatically accepted." "Proponuj konfigurowanie nowo tworzonych pokoi konferencyjnych MUC. Jeżeli opcja bÄ™dzie wyłączona, to domyÅ›lna konfiguracja zostanie zaakceptowana automatycznie." ::msgcat::mcset pl "whois %s: %s" "whois %s: %s" ::msgcat::mcset pl "whois %s: no info" "whois %s: brak informacji" ::msgcat::mcset pl "User already %s" "Użytkownik już %s" ::msgcat::mcset pl "Sending %s %s list" "WysyÅ‚anie listy %s %s" ::msgcat::mcset pl "Room is created" "Pokój zostaÅ‚ utworzony" ::msgcat::mcset pl "Room %s is successfully created" "Pokój %s zostaÅ‚ pomyÅ›lnie utworzony" ::msgcat::mcset pl "Configure room" "Konfiguracja pokoju" ::msgcat::mcset pl "Accept default config" "Akceptuj domyÅ›lnÄ… konfiguracjÄ™" ::msgcat::mcset pl "Configure form: %s" "Próba konfiguracji od: %s" ::msgcat::mcset pl "Sending configure form" "WysyÅ‚anie formularza konfiguracji" ::msgcat::mcset pl "\nReason: %s" "\nPrzyczyna: %s" ::msgcat::mcset pl "\nAlternative venue: %s" "\nAlternatywne miejsce: %s" ::msgcat::mcset pl "%s has been kicked because of membership loss" "%s zostaÅ‚ wyrzucony z powodu utraty praw czÅ‚onka" ::msgcat::mcset pl "%s has been kicked because room became members-only" "%s zostaÅ‚ wyrzucony, ponieważ pokój konferencyjny jest tylko dla użytkowników z prawami czÅ‚onka" ::msgcat::mcset pl "Room is destroyed" "Pokój zostaÅ‚ zamkniÄ™ty" ::msgcat::mcset pl "%s has entered" "%s dołączyÅ‚ do konferencji" ::msgcat::mcset pl "and" "i" ::msgcat::mcset pl "Cancelling configure form" "Anulowanie konfiguracji od" ::msgcat::mcset pl "%s has been assigned a new affiliation: %s" "%s otrzymaÅ‚ nowÄ… przynależność: %s" ::msgcat::mcset pl "%s has been assigned a new role: %s" "%s otrzymaÅ‚ nowÄ… rolÄ™: %s" ::msgcat::mcset pl "%s has been assigned a new room position: %s/%s" "%s otrzymaÅ‚ nowe stanowisko w konferencji: %s/%s" ::msgcat::mcset pl "Generate groupchat messages when occupant changes his/her status and/or status message." "Generuj wiadomoÅ›ci w pokoju konferencyjnym, kiedy uczestnik zmienia swój status lub opis statusu." ::msgcat::mcset pl "Generate groupchat messages when occupant's room position (affiliation and/or role) changes." "Generuj wiadomoÅ›ci w pokoju konferencyjnym, kiedy uczestnik zmienia swoje stanowisko (przynależność lub rolÄ™)." ::msgcat::mcset pl "admin" "administrator" ::msgcat::mcset pl "as %s/%s" "jako %s/%s" ::msgcat::mcset pl "member" "czÅ‚onek" ::msgcat::mcset pl "moderator" "moderator" ::msgcat::mcset pl "none" "brak" ::msgcat::mcset pl "outcast" "wyrzucony" ::msgcat::mcset pl "owner" "wÅ‚aÅ›ciciel" ::msgcat::mcset pl "participant" "uczestnik" ::msgcat::mcset pl "visitor" "gość" ::msgcat::mcset pl "A new room is created" "Utworzono nowy pokój konferencyjny" ::msgcat::mcset pl "Add new item" "Dodaj nowe elementy" ::msgcat::mcset pl "All items:" "Wszystkie elementy:" # itemedit.tcl ::msgcat::mcset pl "Edit properties for %s" "Edycja wÅ‚aÅ›ciwoÅ›ci dla %s" ::msgcat::mcset pl "Edit nickname for %s" "ZmieÅ„ nazwÄ™ dla %s" ::msgcat::mcset pl "Edit groups for %s" "ZmieÅ„ grupy dla %s" ::msgcat::mcset pl "Available groups" "DostÄ™pne grupy" ::msgcat::mcset pl "Current groups" "Aktualnie przypisane" ::msgcat::mcset pl "Add ->" "Dodaj ->" ::msgcat::mcset pl "<- Remove" "<- UsuÅ„" # plugins/general/stats.tcl ::msgcat::mcset pl "Statistics monitor" "Monitor statystyki" ::msgcat::mcset pl "Statistics" "Statystyka" ::msgcat::mcset pl "Node" "WÄ™zeÅ‚" ::msgcat::mcset pl "Name " "Nazwa " ::msgcat::mcset pl "Value" "Wartość" ::msgcat::mcset pl "Units" "Jednostka" ::msgcat::mcset pl "Timer" "Timer" ::msgcat::mcset pl "Request" "Pobierz" ::msgcat::mcset pl "Set" "Ustaw" ::msgcat::mcset pl "Open statistics monitor" "Otwórz monitor statystyki" ::msgcat::mcset pl "Service statistics" "Statystyka usÅ‚ugi" # messages.tcl ::msgcat::mcset pl "Extras from %s" "%s" ::msgcat::mcset pl "Toggle signing" "GPG - włącz podpisywanie wiadomoÅ›ci" ::msgcat::mcset pl "Toggle encryption" "GPG - włącz szyfrowanie wiadomoÅ›ci" ::msgcat::mcset pl "Reply" "Odpowiedz" ::msgcat::mcset pl "Chat" "Rozmowa" ::msgcat::mcset pl "Quote" "Cytuj" ::msgcat::mcset pl "Reply subject:" "Temat odpowiedzi:" ::msgcat::mcset pl "%s invites you to conference room %s" "%s zaprasza CiÄ™ do konferencji w pokoju %s" ::msgcat::mcset pl "\nReason is: %s" "\nPrzyczyna: %s" ::msgcat::mcset pl "Attached user:" "Załączony kontakt:" ::msgcat::mcset pl "Invited to:" "Zaproszony do:" ::msgcat::mcset pl "Message body" "Treść wiadomoÅ›ci" ::msgcat::mcset pl "Send message to %s" "%s" ::msgcat::mcset pl "Send message" "WyÅ›lij wiadomość" ::msgcat::mcset pl "This message is encrypted." "Ta wiadomość jest zaszyfrowana." ::msgcat::mcset pl "Subscribe" "Subskrybuj" ::msgcat::mcset pl "Headlines" "Nagłówki" ::msgcat::mcset pl "%s Headlines" "%s Nagłówki" ::msgcat::mcset pl "Toggle seen" "Zazanacz/Odznacz jako przeczytany" ::msgcat::mcset pl "Delete" "UsuÅ„" ::msgcat::mcset pl "Forward..." "Przekaż..." ::msgcat::mcset pl "Mark all seen" "Oznacz wszystkie jako przeczytane" ::msgcat::mcset pl "Mark all unseen" "Oznacz wszystkie jako nieprzeczytane" ::msgcat::mcset pl "Delete seen" "UsuÅ„ przeczytane" ::msgcat::mcset pl "Delete all" "UsuÅ„ wszystkie" ::msgcat::mcset pl "Forward headline" "Przekaż nagłówek" ::msgcat::mcset pl "List of message destination JIDs." "Lista odbiorców wiadomoÅ›ci" ::msgcat::mcset pl "List of JIDs to whom headlines have been sent." "Lista odbiorców do których przesÅ‚ano nagłówki." ::msgcat::mcset pl "Forward to %s" "Przekaż do %s" ::msgcat::mcset pl "Message and Headline options." "Ustawienia wiadomoÅ›ci i nagłówków." ::msgcat::mcset pl "Cache headlines on exit and restore on start." "Zapisuj nagłówki przy zamykaniu programu i przywracaj przy starcie." ::msgcat::mcset pl "Do not display headline descriptions as tree nodes." "Nie pokazuj opisów nagłówków jako elementów drzewka (pokazuj tylko tytuÅ‚)." ::msgcat::mcset pl "Display headlines in single/multiple windows." "Pokazuj nagłówki w jednym/wielu oknach." ::msgcat::mcset pl "Single window" "Jedno okno" ::msgcat::mcset pl "One window per bare JID" "Jedno okno na JID" ::msgcat::mcset pl "One window per full JID" "Jedno okno na JID/zasób" ::msgcat::mcset pl "Copy URL to clipboard" "Kopiuj URL do schowka" ::msgcat::mcset pl "Send message to group %s" "WyÅ›lij wiadomość do grupy %s" ::msgcat::mcset pl "Send message to group" "WyÅ›lij wiadomość do grupy" ::msgcat::mcset pl "Copy headline to clipboard" "Kopiuj nagłówek do schowka" ::msgcat::mcset pl "Message from:" "Wiadomość od:" ::msgcat::mcset pl "Extras from:" "Wiadomość od:" ::msgcat::mcset pl "Received by:" "Otrzymana przez:" ::msgcat::mcset pl "From: " "Od: " ::msgcat::mcset pl "Group: " "Grupa: " ::msgcat::mcset pl "To: " "Do: " ::msgcat::mcset pl "Subject: " "Temat: " ::msgcat::mcset pl "Send subscription to: " "ProÅ›ba o subskrypcjÄ™ do: " ::msgcat::mcset pl "I would like to add you to my roster." "Witam! ChcÄ™ dodać CiÄ™ do mojej listy kontaktów." ::msgcat::mcset pl "Attached URL:" "Załączone odnoÅ›niki:" ::msgcat::mcset pl "Approve subscription" "Zaakceptuj proÅ›bÄ™ o subskrypcjÄ™" ::msgcat::mcset pl "Decline subscription" "Odrzuć proÅ›bÄ™ o subskrypcjÄ™" ::msgcat::mcset pl "Grant subscription" "WyÅ›lij subskrypcjÄ™" ::msgcat::mcset pl "Request subscription" "PoproÅ› o subskrypcjÄ™" ::msgcat::mcset pl "Send request to: " "WyÅ›lij proÅ›bÄ™ do: " ::msgcat::mcset pl "Send subscription request" "WyÅ›lij proÅ›bÄ™ o subskrypcjÄ™" ::msgcat::mcset pl "Send subscription request to %s" "WyÅ›lij proÅ›bÄ™ o subskrypcjÄ™ do %s" ::msgcat::mcset pl "Subscription request from %s" "ProÅ›ba o subskrypcjÄ™ od %s" ::msgcat::mcset pl "Subscription request from:" "ProÅ›ba o subskrypcjÄ™ od:" # iface.tcl ::msgcat::mcset pl "Options for main interface." "Ustawienia wyglÄ…du i zachowania aplikacji." ::msgcat::mcset pl "Raise new tab." "Otwieraj nowe karty na wierzchu." ::msgcat::mcset pl "Show number of unread messages in tab titles." "Pokaż ilość nieprzeczytanych wiadomoÅ›ci w tytuÅ‚ach kart." ::msgcat::mcset pl "Presence" "Status" ::msgcat::mcset pl "Log in..." "Zaloguj..." ::msgcat::mcset pl "Log out with reason..." "Wyloguj z opisem..." ::msgcat::mcset pl "Profile on" "Włącz profil" ::msgcat::mcset pl "Profile report" "Raport profilu" ::msgcat::mcset pl "Quit" "ZakoÅ„cz" ::msgcat::mcset pl "Browser" "PrzeglÄ…darka usÅ‚ug" ::msgcat::mcset pl "Service Discovery" "PrzeglÄ…darka usÅ‚ug (protokół Discovery)" ::msgcat::mcset pl "Discovery" "Informacje Discovery" ::msgcat::mcset pl "Join group..." "Dołącz do konferencji..." ::msgcat::mcset pl "Sound" "DźwiÄ™ki" ::msgcat::mcset pl "Chats" "Rozmowy i konferencje" ::msgcat::mcset pl "Smart autoscroll" "Inteligentne autoprzewijanie" ::msgcat::mcset pl "Stop autoscroll" "Zatrzymaj autoprzewijanie" ::msgcat::mcset pl "Emphasize" "WyÅ›wietl formatowanie dla słów pomiÄ™dzy * / i _" ::msgcat::mcset pl "Change password..." "ZmieÅ„ hasÅ‚o..." ::msgcat::mcset pl "Message archive" "Archiwum wiadomoÅ›ci" ::msgcat::mcset pl "Show user or service info..." "Pokaż wizytówkÄ™ użytkownika, usÅ‚ugi..." ::msgcat::mcset pl "Edit my info..." "Edytuj wÅ‚asnÄ… wizytówkÄ™..." ::msgcat::mcset pl "Announce" "Włącz" ::msgcat::mcset pl "Allow downloading" "Pozwól na Å›ciÄ…ganie" ::msgcat::mcset pl "Send to server" "WyÅ›lij na serwer" ::msgcat::mcset pl "Admin tools" "NarzÄ™dzia administracyjne" ::msgcat::mcset pl "Send broadcast message..." "WyÅ›lij wiadomość do wszystkich..." ::msgcat::mcset pl "Send message of the day..." "Ustaw Wiadomość Dnia (MOTD)..." ::msgcat::mcset pl "Update message of the day..." "Aktualizuj MOTD..." ::msgcat::mcset pl "Delete message of the day" "UsuÅ„ MOTD" ::msgcat::mcset pl "Help" "Pomoc" ::msgcat::mcset pl "Quick help" "Szybka Pomoc" ::msgcat::mcset pl "Quick Help" "Szybka Pomoc" ::msgcat::mcset pl "About" "O programie" ::msgcat::mcset pl "Disconnected" "Rozłączony" ::msgcat::mcset pl "%s SSL Certificate Info" "Informacje o certyfikacie SSL z %s" ::msgcat::mcset pl "Add new user..." "Dodaj nowy kontakt..." ::msgcat::mcset pl "Toggle showing offline users" "Pokaż/Ukryj rozłączonych" ::msgcat::mcset pl "Toggle encryption (when possible)" "GPG - Włącz szyfrowanie rozmów (kiedy możliwe)" ::msgcat::mcset pl "Close other tabs" "Zamknij pozostaÅ‚e karty" ::msgcat::mcset pl "Close all tabs" "Zamknij wszystkie karty" ::msgcat::mcset pl "Tabs:" "Karty:" ::msgcat::mcset pl "Chats:" "Rozmowy i konferecje:" ::msgcat::mcset pl "Authors:" "Autorzy:" ::msgcat::mcset pl "SSL Info" "Informacje o SSL" ::msgcat::mcset pl "Delay between getting focus and updating window or tab title in milliseconds." "Opóźnienie w milisekundach pomiÄ™dzy otrzymaniem fokusu a odÅ›wieżeniem tytuÅ‚u okna lub karty." ::msgcat::mcset pl "Extended away" "Nieobecny" ::msgcat::mcset pl "Change priority..." "ZmieÅ„ priorytet..." ::msgcat::mcset pl "Issuer" "Wydawca" ::msgcat::mcset pl "Begin date" "Data wydania" ::msgcat::mcset pl "Expiry date" "Data ważnoÅ›ci" ::msgcat::mcset pl "Serial number" "Numer seryjny" ::msgcat::mcset pl "Cipher" "Algorytm szyfru" ::msgcat::mcset pl "Enabled\n" "Włączony\n" ::msgcat::mcset pl "Disabled\n" "Wyłączony\n" ::msgcat::mcset pl "Use Tabbed Interface (you need to restart)." "Włącz interfejs z kartami w jednym oknie (wymagany restart)." ::msgcat::mcset pl "Show Toolbar." "Pokaż pasek przycisków." ::msgcat::mcset pl "Generate enter/exit messages" "Generuj wiadomoÅ›ci przy wejÅ›ciu/wyjÅ›ciu" ::msgcat::mcset pl "SHA1 hash" "Skrót SHA1" ::msgcat::mcset pl "Session key bits" "Liczba bitów klucza sesji" # plugins/chat/info_commands.tcl ::msgcat::mcset pl "Full Name" "PeÅ‚na nazwa" ::msgcat::mcset pl "Family Name" "Nazwisko" ::msgcat::mcset pl "Middle Name" "Drugie imiÄ™" ::msgcat::mcset pl "Prefix" "Prefiks" ::msgcat::mcset pl "Suffix" "Sufiks" ::msgcat::mcset pl "Nickname" "Pseudonim" ::msgcat::mcset pl "E-mail" "E-mail" ::msgcat::mcset pl "Web Site" "Strona domowa" ::msgcat::mcset pl "JID" "JID" ::msgcat::mcset pl "UID" "UID" ::msgcat::mcset pl "City" "Miasto" ::msgcat::mcset pl "State " "Województwo " ::msgcat::mcset pl "Country" "PaÅ„stwo" ::msgcat::mcset pl "Phone Home" "Telefon domowy" ::msgcat::mcset pl "Phone Work" "Telefon w pracy" ::msgcat::mcset pl "Phone Voice" "Poczta gÅ‚osowa" ::msgcat::mcset pl "Phone Fax" "Fax" ::msgcat::mcset pl "Phone Pager" "Pager" ::msgcat::mcset pl "Phone Message Recorder" "Automatyczna sekretarka" ::msgcat::mcset pl "Phone Cell" "Telefon komórkowy" ::msgcat::mcset pl "Phone Video" "Videotelefon" ::msgcat::mcset pl "Phone BBS" "Telefon BBS" ::msgcat::mcset pl "Phone Modem" "Modem" ::msgcat::mcset pl "Phone ISDN" "ISDN" ::msgcat::mcset pl "Phone PCS" "Telefon PCS" ::msgcat::mcset pl "Phone Preferred" "Telefon preferowany" ::msgcat::mcset pl "Address 2" "Adres 2" ::msgcat::mcset pl "Postal Code" "Kod pocztowy" ::msgcat::mcset pl "Latitude" "Szerokość geograficzna" ::msgcat::mcset pl "Longitude" "DÅ‚ugość geograficzna" ::msgcat::mcset pl "Organization Name" "Ogranizacja" ::msgcat::mcset pl "Organization Unit" "Jednostka" ::msgcat::mcset pl "Title" "TytuÅ‚" ::msgcat::mcset pl "time %s%s: %s" "czas dla %s%s: %s" ::msgcat::mcset pl "time %s%s:" "czas dla %s%s:" ::msgcat::mcset pl "last %s%s: %s" "ostatnio aktywny %s%s: %s" ::msgcat::mcset pl "last %s%s:" "ostatnio aktywny %s%s:" ::msgcat::mcset pl "version %s%s: %s" "wersja klienta %s%s: %s" ::msgcat::mcset pl "version %s%s:" "wersja klienta %s%s:" ::msgcat::mcset pl "vcard %s%s: %s" "wizytówka dla %s%s: %s" ::msgcat::mcset pl "vcard %s%s:" "wizytówka dla %s%s:" ::msgcat::mcset pl "vCard display options in chat windows." "Ustawienia wyÅ›wietlania elementów wizytówki w oknach rozmów." ::msgcat::mcset pl "Display %s in chat window when using /vcard command." "Pokaż pole \"%s\" w oknie rozmowy po wykonaniu polecenia /vcard." # plugins/chat/logger.tcl ::msgcat::mcset pl "Logging options." "Ustawienia historii rozmów." ::msgcat::mcset pl "Directory to store logs." "Katalog przechowywania plików historii." ::msgcat::mcset pl "Store private chats logs." "Zapisuj historiÄ™ prywatnych rozmów." ::msgcat::mcset pl "Store group chats logs." "Zapisuj historiÄ™ rozmów w pokojach konferencyjnych." ::msgcat::mcset pl "History for %s" "Historia dla %s" ::msgcat::mcset pl "Export to XHTML" "Zapisz jako XHTML" ::msgcat::mcset pl "Search up" "Szukaj w górÄ™" ::msgcat::mcset pl "Search down" "Szukaj w dół" ::msgcat::mcset pl "Select month:" "Wybierz miesiÄ…c: " ::msgcat::mcset pl "All" "Wszystkie" ::msgcat::mcset pl "April" "KwiecieÅ„" ::msgcat::mcset pl "August" "SierpieÅ„" ::msgcat::mcset pl "Chats history is converted.\nBackup of the old history is stored in %s" "Historia rozmów zostaÅ‚a przekonwertowana.\nKopia zapasowa starej historii zostaÅ‚a zapisana w %s" ::msgcat::mcset pl "Conversion is finished" "Konwersja zakoÅ„czona" ::msgcat::mcset pl "Converting Log Files" "Konwersja plików historii" ::msgcat::mcset pl "December" "GrudzieÅ„" ::msgcat::mcset pl "February" "Luty" ::msgcat::mcset pl "File %s is corrupt. History for %s (%s) is NOT converted\n" "Plik %s jest uszkodzony. Historia dla %s (%s) NIE zostaÅ‚a przekonwertowana\n" ::msgcat::mcset pl "File %s is corrupt. History for %s is NOT converted\n" "Plik %s jest uszkodzony. Historia dla %s NIE zostaÅ‚a przekonwertowana\n" ::msgcat::mcset pl "January" "StyczeÅ„" ::msgcat::mcset pl "July" "Lipiec" ::msgcat::mcset pl "June" "Czerwiec" ::msgcat::mcset pl "March" "Marzec" ::msgcat::mcset pl "May" "Maj" ::msgcat::mcset pl "November" "Listopad" ::msgcat::mcset pl "October" "Październik" ::msgcat::mcset pl "Please, be patient while chats history is being converted to new format" "ProszÄ™ czekać, historia rozmów jest konwertowana do nowego formatu" ::msgcat::mcset pl "September" "WrzesieÅ„" ::msgcat::mcset pl "File %s cannot be opened: %s. History for %s (%s) is NOT converted\n" "Nie można otworzyć pliku %s: %s. Historia dla %s (%s) NIE jest przekonwertowana\n" ::msgcat::mcset pl "File %s cannot be opened: %s. History for %s is NOT converted\n" "Nie można otworzyć pliku %s: %s. Historia dla %s NIE jest przekonwertowana\n" ::msgcat::mcset pl "You're using root directory %s for storing Tkabber logs!\n\nI refuse to convert logs database." "Używasz katalogu głównego %s do przechowywania plików historii Tkabbera!\n\nW tym przypadku nie zostanie przeprowadzona konwersja historii." # plugins/chat/nick_colors.tcl ::msgcat::mcset pl "Use colored nicks in chat windows." "Koloruj pseudonimy w oknach rozmów." ::msgcat::mcset pl "Color message bodies in chat windows." "Koloruj treść wiadomoÅ›ci w oknach rozmów." ::msgcat::mcset pl "Use colored nicks" "Koloruj pseudonimy w oknie rozmowy" ::msgcat::mcset pl "Use colored messages" "Koloruj treść wiadomoÅ›ci w oknie rozmowy" ::msgcat::mcset pl "Edit nick colors..." "Przypisz kolory użytkownikom..." ::msgcat::mcset pl "Edit chat user colors" "Przypisywanie kolorów" ::msgcat::mcset pl "Use colored nicks in groupchat rosters." "Koloruj pseudonimy listy uczestników konferencji." ::msgcat::mcset pl "Use colored roster nicks" "Koloruj pseudonimy listy kontaktów" ::msgcat::mcset pl "Edit %s color" "Edycja koloru dla %s" ::msgcat::mcset pl "Edit nick color..." "Edycja koloru..." # plugins/chat/complete_last_nick.tcl ::msgcat::mcset pl "Number of groupchat messages to expire nick completion according to the last personally addressed message." "Ilość wiadomoÅ›ci, po których wygasa uzupeÅ‚nianie pseudonimu zgodnie z ostatniÄ… nadanÄ… do tej osoby wiadomoÅ›ciÄ…." # plugins/chat/highlight.tcl ::msgcat::mcset pl "Groupchat message highlighting plugin options." "Ustawienia wyÅ›wietlania wiadomoÅ›ci w pokojach konferencyjnych." ::msgcat::mcset pl "Enable highlighting plugin." "Włącz kolorowanie." ::msgcat::mcset pl "Highlight current nickname in messages." "Koloruj aktualny pseudonim w wiadomoÅ›ciach." ::msgcat::mcset pl "Substrings to highlight in messages." "Koloruj wybrane fragmenty wiadomoÅ›ci." ::msgcat::mcset pl "Highlight only whole words in messages." "Koloruj tylko caÅ‚e wyrazy w wiadomoÅ›ciach." # plugins/chat/bookmark_highlighted.tcl ::msgcat::mcset pl "Prev highlighted" "Poprzednie zaznaczenie" ::msgcat::mcset pl "Next highlighted" "NastÄ™pne zaznaczenie" # plugins/chat/popupmenu.tcl ::msgcat::mcset pl "Copy selection to clipboard" "Kopiuj do schowka" ::msgcat::mcset pl "Google selection" "Znajdź w Google" ::msgcat::mcset pl "Set bookmark" "Dodaj do zakÅ‚adek" ::msgcat::mcset pl "Prev bookmark" "Poprzednia zakÅ‚adka" ::msgcat::mcset pl "Next bookmark" "NastÄ™pna zakÅ‚adka" ::msgcat::mcset pl "Clear bookmarks" "UsuÅ„ zakÅ‚adki" # sound.tcl ::msgcat::mcset pl "Sound options." "Ustawienia dźwiÄ™ków aplikacji." ::msgcat::mcset pl "Mute sound notification." "Nie odtwarzaj dźwiÄ™ków." ::msgcat::mcset pl "Use sound notification only when being available." "Włącz powiadomienia dźwiÄ™kowe tylko przy statusie DostÄ™pny." ::msgcat::mcset pl "Mute sound when displaying delayed groupchat messages." "Wyłącz dźwiÄ™ki dla wiadomoÅ›ci wyÅ›wietlanych z opóźnieniem w pokojach konferencyjnych." ::msgcat::mcset pl "Mute sound when displaying delayed personal chat messages." "Wyłącz dźwiÄ™ki dla prywatnych wiadomoÅ›ci wyÅ›wietlanych z opóźnieniem." ::msgcat::mcset pl "External program, which is to be executed to play sound. If empty, Snack library is used (if available) to play sound." "ZewnÄ™trzny program do odtwarzania dźwiÄ™ków. Jeżeli puste, do odtwarzania używana jest biblioteka Snack (instalowana oddzielnie)." ::msgcat::mcset pl "Options for external play program" "Parametry dla zewnÄ™trznego programu odtwarzajÄ…cego dźwiÄ™k" ::msgcat::mcset pl "Time interval before playing next sound (in milliseconds)." "OdstÄ™p czasu przed odtworzeniem nastÄ™pnego dźwiÄ™ku (w milisekundach)." ::msgcat::mcset pl "Sound to play when connected to Jabber server." "DźwiÄ™k odtwarzany po nawiÄ…zaniu połączenia z serwerem." ::msgcat::mcset pl "Sound to play when disconnected from Jabber server." "DźwiÄ™k odtwarzany po rozłączeniu siÄ™ z serwerem." ::msgcat::mcset pl "Sound to play when available presence is received." "DźwiÄ™k odtwarzany kiedy kontakt staje siÄ™ dostÄ™pny." ::msgcat::mcset pl "Sound to play when unavailable presence is received." "DźwiÄ™k odtwarzany kiedy kontakt rozłącza siÄ™." ::msgcat::mcset pl "Sound to play when sending personal chat message." "DźwiÄ™k odtwarzany przy wysyÅ‚aniu wiadomoÅ›ci." ::msgcat::mcset pl "Sound to play when personal chat message is received." "DźwiÄ™k odtwarzany po otrzymaniu wiadomoÅ›ci." ::msgcat::mcset pl "Sound to play when groupchat server message is received." "DźwiÄ™k odtwarzany po otrzymaniu wiadomoÅ›ci systemowej." ::msgcat::mcset pl "Sound to play when groupchat message from me is received." "DźwiÄ™k odtwarzany po otrzymaniu wiadomoÅ›ci ode mnie w pokoju konferencyjnym." ::msgcat::mcset pl "Sound to play when groupchat message is received." "DźwiÄ™k odtwarzany po otrzymaniu wiadomoÅ›ci w pokoju konferencyjnym." ::msgcat::mcset pl "Sound to play when highlighted (usually addressed personally) groupchat message is received." "DźwiÄ™k odtwarzany po otrzymaniu wiadomoÅ›ci z wyróżnionym fragmentem (ustawiane oddzielnie) w pokoju konferencyjnym." ::msgcat::mcset pl "Notify only when available" "Powiadamiaj tylko gdy mam status DostÄ™pny" ::msgcat::mcset pl "Mute sound if Tkabber window is focused." "Wyłącz dźwiÄ™k jeżeli okno Tkabbera jest aktywne." # joingrdialog.tcl ::msgcat::mcset pl "Join group dialog data (nicks)." "Dołącz do konferencji (pseudonimy)." ::msgcat::mcset pl "Join group dialog data (groups)." "Dołącz do konferencji (pokoje)." ::msgcat::mcset pl "Join group dialog data (servers)." "Dołącz do konferencji (serwery)." ::msgcat::mcset pl "Join group" "Dołącz do konferencji" ::msgcat::mcset pl "Nick:" "Pseudonim:" ::msgcat::mcset pl "Connection:" "Połączenie:" ::msgcat::mcset pl "Join" "Dołącz" # filters.tcl ::msgcat::mcset pl "I'm not online" "nie jestem dostÄ™pny" ::msgcat::mcset pl "the message is from" "wiadomość jest od" ::msgcat::mcset pl "the message is sent to" "wiadomość jest do" ::msgcat::mcset pl "the subject is" "temat" ::msgcat::mcset pl "the body is" "treść" ::msgcat::mcset pl "my status is" "status" ::msgcat::mcset pl "the message type is" "typ wiadomoÅ›ci" ::msgcat::mcset pl "change message type to" "zmieÅ„ typ wiadomoÅ›ci na" ::msgcat::mcset pl "forward message to" "przekaż wiadomość do" ::msgcat::mcset pl "reply with" "odpowiedz na" ::msgcat::mcset pl "store this message offline" "zachowaj wiadomość" ::msgcat::mcset pl "continue processing rules" "kontynuuj przetwarzanie reguÅ‚" ::msgcat::mcset pl "Requesting filter rules: %s" "Pobieranie reguÅ‚ filtrowania: %s" ::msgcat::mcset pl "Filters" "Filtry" ::msgcat::mcset pl "Edit" "Edytuj" ::msgcat::mcset pl "Move up" "Do góry" ::msgcat::mcset pl "Move down" "Na dół" ::msgcat::mcset pl "Edit rule" "Edytuj regułę" ::msgcat::mcset pl "Rule Name:" "Nazwa reguÅ‚y:" ::msgcat::mcset pl "Condition" "Warunek" ::msgcat::mcset pl "Action" "Akcja" ::msgcat::mcset pl "Empty rule name" "Wyczyść nazwÄ™ reguÅ‚y" ::msgcat::mcset pl "Rule name already exists" "ReguÅ‚a o takiej nazwie już istnieje" ::msgcat::mcset pl "Enable jabberd 1.4 mod_filter support (obsolete)." "Włącz obsÅ‚ugÄ™ moduÅ‚u mod_filter serwera jabberd 1.4 (przestarzaÅ‚y)." ::msgcat::mcset pl "Edit message filters" "Edycja filtrów wiadomoÅ›ci" # plugins/general/rawxml.tcl ::msgcat::mcset pl "Options for Raw XML Input module, which allows you to monitor incoming/outgoing traffic from connection to server and send custom XML stanzas." "Ustawienia moduÅ‚u Konsoli XML, który umożliwia monitorowanie wchodzÄ…cego/wychodzÄ…cego ruchu pomiÄ™dzy klientem a serwerm, oraz wysyÅ‚anie wÅ‚asnych komunikatów." ::msgcat::mcset pl "Pretty print incoming and outgoing XML stanzas." "Formatuj i koloruj znaczniki przychodzÄ…cego/wychodzÄ…cego strumienia XML." ::msgcat::mcset pl "Indentation for pretty-printed XML subtags." "Rozmiar wcięć dla formatowanych znaczników XML." ::msgcat::mcset pl "Raw XML" "Konsola XML" ::msgcat::mcset pl "Pretty print XML" "Formatuj/koloruj znaczniki XML" ::msgcat::mcset pl "Templates" "Wzorce" ::msgcat::mcset pl "Open raw XML window" "Otwórz KonsolÄ™ XML" ::msgcat::mcset pl "Clear" "Wyczyść" ::msgcat::mcset pl "Normal message" "ZwykÅ‚a wiadomość" ::msgcat::mcset pl "Chat message" "Rozmowa" ::msgcat::mcset pl "Headline message" "Nagłówek" ::msgcat::mcset pl "Available presence" "Status DostÄ™pny" ::msgcat::mcset pl "Unavailable presence" "Status NiedostÄ™pny" ::msgcat::mcset pl "Generic IQ" "Ogólne zapytania IQ" ::msgcat::mcset pl "Pub/sub" "Pub/sub" ::msgcat::mcset pl "Create node" "Utwórz wÄ™zęł" ::msgcat::mcset pl "Publish node" "Publikuj wÄ™zęł" ::msgcat::mcset pl "Retract node" "Wycofaj wÄ™zęł" ::msgcat::mcset pl "Subscribe to a node" "Subskrybuj wÄ™zęł" ::msgcat::mcset pl "Unsubscribe from a node" "Anuluj subskrypcjÄ™ wÄ™zÅ‚a" ::msgcat::mcset pl "Get items" "Pobierz elementy" ::msgcat::mcset pl "Not connected" "Rozłączony" # disco.tcl ::msgcat::mcset pl "List of discovered JIDs." "Lista JID-ów." ::msgcat::mcset pl "List of discovered JID nodes." "Lista elementów." ::msgcat::mcset pl "Node:" "WÄ™zeÅ‚:" ::msgcat::mcset pl "Error getting info: %s" "Błąd przy pobieraniu informacji: %s" ::msgcat::mcset pl "Error getting items: %s" "Błąd przy pobieraniu elementów: %s" ::msgcat::mcset pl "Error negotiate: %s" "Błąd negocjacji: %s" ::msgcat::mcset pl "Sort items by name" "Sortuj wedÅ‚ug nazwy" ::msgcat::mcset pl "Sort items by JID/node" "Sortuj wedÅ‚ug JID/wÄ™zÅ‚a" ::msgcat::mcset pl "Delete current node and subnodes" "UsuÅ„ zanaczony wÄ™zeÅ‚ i podwÄ™zÅ‚y" ::msgcat::mcset pl "Delete subnodes" "UsuÅ„ podwÄ™zÅ‚y" ::msgcat::mcset pl "Clear window" "Wyczyść okno" # avatars.tcl ::msgcat::mcset pl "No avatar to store" "Brak awatara do wysÅ‚ania" # plugins/jidlink/ibb.tcl ::msgcat::mcset pl "Opening IBB connection" "Otwieranie połącznia IBB" # plugins/general/conferenceinfo.tcl ::msgcat::mcset pl "Options for Conference Info module, that allows you to see list of participants in roster popup, regardless of whether you are currently joined with the conference." "Ustawienia moduÅ‚u, który pozwala oglÄ…dać listÄ™ uczestników konferencji umieszczonych na liÅ›cie kontaktów, niezależnie od tego czy aktualnie bierzemy w niej udziaÅ‚." ::msgcat::mcset pl "Use this module" "Włącz informacje o konferencjach" ::msgcat::mcset pl "Interval (in minutes) between requests of participants list." "OdstÄ™p czasu (w minutach) przy sprawdzaniu listy uczestników." ::msgcat::mcset pl "Interval (in minutes) after error reply on request of participants list." "OdstÄ™p czasu (w minutach) po otrzymaniu komunikatu błędu przy sprawdzaniu listy uczestników." ::msgcat::mcset pl "\n\tCan't browse: %s" "\n\tNie można przeglÄ…dać: %s" ::msgcat::mcset pl "\nRoom participants at %s:" "\nUczestnicy konferencji o godz. %s:" ::msgcat::mcset pl "\nRoom is empty at %s" "\nPokój jest pusty o godz. %s" ::msgcat::mcset pl "Periodically browse roster conferences" "Okresowo przeglÄ…daj konferencje z listy kontaktów" # plugins/roster/conferences.tcl ::msgcat::mcset pl "Add Conference to Roster" "Dodaj konferencjÄ™ do listy kontaktów" ::msgcat::mcset pl "Conference:" "Konferencja:" ::msgcat::mcset pl "Roster group:" "Grupa na liÅ›cie:" ::msgcat::mcset pl "Storing conferences failed: %s" "Zapisanie konferencji nie powiodÅ‚o siÄ™: %s" ::msgcat::mcset pl "Automatically join conference upon connect" "Automatycznie dołącz do konferencji po połączeniu" ::msgcat::mcset pl "Conferences" "Konferencje" # plugins/general/presenceinfo.tcl ::msgcat::mcset pl "\n\tPresence is signed:" "\n\tStatus podpisano:" # plugins/general/subscribe_gateway.tcl ::msgcat::mcset pl "Send subscription at %s" "WyÅ›lij subskrypcjÄ™ do %s" ::msgcat::mcset pl "Enter screenname of contact you want to add" "Wprowadź identyfikator kontaktu, który chcesz dodać" ::msgcat::mcset pl "Screenname conversion" "Konwersja identyfikatora" ::msgcat::mcset pl "Convert" "Konwertuj" ::msgcat::mcset pl "Screenname:" "Identyfikator:" ::msgcat::mcset pl "Error while converting screenname: %s." "Błąd podczas konwersji identyfikatora: %s." ::msgcat::mcset pl "Screenname: %s\n\nConverted JID: %s" "Identyfikator: %s\n\nJID po konwersji: %s" ::msgcat::mcset pl "Convert screenname" "Konwertuj identyfikator" # iq.tcl ::msgcat::mcset pl "Info/Query options." "Ustawienia Informacji/ZapytaÅ„." ::msgcat::mcset pl "Show IQ requests in the status line." "Pokazuj zapytania IQ na pasku statusu." ::msgcat::mcset pl "Strip leading \"http://jabber.org/protocol/\" from IQ namespaces in the status line." "Usuwaj fragment \"http://jabber.org/protocol/\" z przestrzeni nazw IQ pokazywanych na pasku statusu." ::msgcat::mcset pl "%s request from %s" "Zapytanie %s od %s" # plugins/iq/last.tcl ::msgcat::mcset pl "Reply to idle time (jabber:iq:last) requests." "Odpowiadaj na zapytania o ostatniÄ… aktywność/czas dziaÅ‚ania (jabber:iq:last)." # plugins/iq/version.tcl ::msgcat::mcset pl "Reply to version (jabber:iq:version) requests." "Odpowiadaj na zapytania o wersjÄ™ klienta (jabber:iq:version)." ::msgcat::mcset pl "Include operating system info into a reply to version (jabber:iq:version) requests." "Dodaj informacjÄ™ o systemie operacyjnym do zapytaÅ„ o wersjÄ™ klienta (jabber:iq:version)." # plugins/iq/time.tcl ::msgcat::mcset pl "Reply to current time (jabber:iq:time) requests." "Odpowiadaj na zapytania o aktualny czas (jabber:iq:time)." # splash.tcl ::msgcat::mcset pl "Save To Log" "Zapisz do pliku dziennika" ::msgcat::mcset pl "customization" "dostosowanie" ::msgcat::mcset pl "pixmaps management" "zarzÄ…dzanie obrazkami" ::msgcat::mcset pl "auto-away" "autostatus" ::msgcat::mcset pl "avatars" "awatary" ::msgcat::mcset pl "balloon help" "dymki pomocy" ::msgcat::mcset pl "browsing" "przeglÄ…danie" ::msgcat::mcset pl "bwidget workarounds" "dodatki do bwidget" ::msgcat::mcset pl "configuration" "konfiguracja" ::msgcat::mcset pl "utilities" "użytki" ::msgcat::mcset pl "service discovery" "informacje discovery" ::msgcat::mcset pl "kde" "kde" ::msgcat::mcset pl "emoticons" "emotikonki" ::msgcat::mcset pl "file transfer" "transfer plików" ::msgcat::mcset pl "message filters" "filtry wiadomoÅ›ci" ::msgcat::mcset pl "cryptographics" "kryptografia" ::msgcat::mcset pl "extension management" "zarzÄ…dzanie dodatkami" ::msgcat::mcset pl "user interface" "intrerfejs użytkownika" ::msgcat::mcset pl "jabber iq" "jabber iq" ::msgcat::mcset pl "jabber xml" "jabber xml" ::msgcat::mcset pl "connections" "połączenia" ::msgcat::mcset pl "jabber messages" "obsÅ‚uga wiadomoÅ›ci" ::msgcat::mcset pl "jabber chat/muc" "obsÅ‚uga rozmów/konferencji" ::msgcat::mcset pl "negotiation" "negocjacja" ::msgcat::mcset pl "plugin management" "zarzÄ…dzanie wtyczkami" ::msgcat::mcset pl "jabber presence" "jabber presence" ::msgcat::mcset pl "privacy rules" "zasady ochrony prywatnoÅ›ci" ::msgcat::mcset pl "jabber registration" "jabber rejestracja" ::msgcat::mcset pl "jabber roster" "lista kontaktów" ::msgcat::mcset pl "searching" "wyszukiwanie" ::msgcat::mcset pl "sound" "dźwiÄ™k" ::msgcat::mcset pl "presence" "status" ::msgcat::mcset pl "wmaker" "wmaker" ::msgcat::mcset pl "general plugins" "podstawowe wtyczki" ::msgcat::mcset pl "roster plugins" "wtyczki listy kontaktów" ::msgcat::mcset pl "search plugins" "wtyczki wyszukiwania" ::msgcat::mcset pl "unix plugins" "wtyczki dla systemu Unix" ::msgcat::mcset pl "windows plugins" "wtyczki dla systemu Windows" ::msgcat::mcset pl "macintosh plugins" "wtyczki dla systemu Mac" ::msgcat::mcset pl "%s plugin" "wtyczka %s" # chats.tcl ::msgcat::mcset pl "Chat options." "Ustawienia rozmów i konferencji." ::msgcat::mcset pl "Enable chat window autoscroll only when last message is shown." "Włącz autoprzewijanie okna tylko kiedy widać ostatniÄ… wiadomość." ::msgcat::mcset pl "Stop chat window autoscroll." "Zatrzymaj autoprzewijanie okna rozmów." ::msgcat::mcset pl ">>> Unable to decipher data: %s <<<" ">>> Nie można odszyfrować danych: %s <<<" ::msgcat::mcset pl "/me has set the subject to: %s" "/me zmieniÅ‚ temat na: %s" ::msgcat::mcset pl "Subject is set to: %s" "Temat konferencji to: %s" ::msgcat::mcset pl "Chat with %s" "%s" ::msgcat::mcset pl "Invite users..." "ZaproÅ›..." ::msgcat::mcset pl "Error %s" "Błąd %s" ::msgcat::mcset pl "Moderators" "Moderatorzy" ::msgcat::mcset pl "Participants" "Uczestnicy" ::msgcat::mcset pl "Visitors" "GoÅ›cie" ::msgcat::mcset pl "Users" "Użytkownicy" ::msgcat::mcset pl "Invite %s to conferences" "ZaproÅ› '%s' do konferencji" ::msgcat::mcset pl "Invite" "ZaproÅ›" ::msgcat::mcset pl "No conferences for %s in progress..." "Brak aktywnych konferencji dla %s..." ::msgcat::mcset pl "No users in %s roster..." "Brak kontaktów na liÅ›cie %s..." ::msgcat::mcset pl "Invite users to %s" "ZaproÅ› użytkowników do %s" ::msgcat::mcset pl "Please join %s" "Zaproszenie do konferencji %s" ::msgcat::mcset pl "Display description of user status in chat windows." "Pokaż status użytkownika na górnym pasku okna rozmowy (opis statusu w dymku podpowiedzi)" ::msgcat::mcset pl "Default message type (if not specified explicitly)." "DomyÅ›lny typ wiadomoÅ›ci (jeżeli nie okreÅ›lono)." ::msgcat::mcset pl "Normal" "ZwykÅ‚a" ::msgcat::mcset pl "Chat " "Rozmowa" ::msgcat::mcset pl "List of users for chat." "Lista uczestników rozmowy." ::msgcat::mcset pl "Remove from roster..." "UsuÅ„ z listy kontaktów..." ::msgcat::mcset pl "Open chat" "Rozpocznij rozmowÄ™" ::msgcat::mcset pl "Generate chat messages when chat peer changes his/her status and/or status message" "Generuj wiadomoÅ›ci kiedy uczestnik rozmowy zmienia swój status lub opis statusu" ::msgcat::mcset pl "Opens a new chat window for the new nick of the room occupant" "Otwiera nowe okno rozmowy z nowym pseudonimem uczestnika konferencji" ::msgcat::mcset pl "%s has changed nick to %s." "%s zmieniÅ‚ pseudonim na %s." ::msgcat::mcset pl "Open new conversation" "Otwórz nowÄ… rozmowÄ™" # plugins/windows/taskbar.tcl ::msgcat::mcset pl "Hide Main Window" "Ukryj główne okno" ::msgcat::mcset pl "Show Main Window" "Pokaż główne okno" ::msgcat::mcset pl "Enable windows tray icon." "Włącz obsÅ‚ugÄ™ ikony zasobnika systemowego Windows." # plugins/unix/dockingtray.tcl ::msgcat::mcset pl "Enable KDE tray icon." "Włącz obsÅ‚ugÄ™ ikony zasobnika systemowego KDE." # ifacetk/systray.tcl ::msgcat::mcset pl "Systray icon options." "Ustawienia ikony zasobnika systemowego." ::msgcat::mcset pl "Display status tooltip when main window is minimized to systray." "Pokazuj dymek podpowiedzi ze statusem nad ikonÄ… w zasobniku systemowym." ::msgcat::mcset pl "Systray icon blinks when there are unread messages." "MigajÄ…ca ikonka w zasobniku systemowym dla nieprzeczytanych wiadomoÅ›ci." ::msgcat::mcset pl "Tkabber Systray" "Ikona Tkabber" # plugins/windows/console.tcl ::msgcat::mcset pl "Show console" "Pokaż konsolÄ™" # jabberlib-tclxml/jabberlib.tcl ::msgcat::mcset pl "Authentication failed" "Uwierzytelnianie nie powiodÅ‚o siÄ™" ::msgcat::mcset pl "Authentication successful" "Uwierzytelnianie powiodÅ‚o siÄ™" ::msgcat::mcset pl "Waiting for authentication results" "Oczekiwanie na wyniki uwierzytelniania" ::msgcat::mcset pl "Got roster" "Lista kontaktów wczytana" ::msgcat::mcset pl "Waiting for roster" "Oczekiwanie na listÄ™ kontaktów" ::msgcat::mcset pl "Resource Constraint" "Brak zasobów systemowych na serwerze" ::msgcat::mcset pl "Server haven't provided SASL authentication feature" "Serwer nie oferuje mechanizmu uwierzytelniania SASL" ::msgcat::mcset pl "Server haven't provided non-SASL authentication feature" "Serwer nie oferuje mechanizmu uwierzytelniania innego niż SASL" ::msgcat::mcset pl "Server haven't provided STARTTLS feature" "Serwer nie oferuje mechanizmu STARTTLS" ::msgcat::mcset pl "Timeout" "Limit czasu" # jabberlib-tclxml/jlibsasl.tcl ::msgcat::mcset pl "Aborted" "Przerwano" ::msgcat::mcset pl "Incorrect encoding" "NieprawidÅ‚owe kodowanie" ::msgcat::mcset pl "Invalid authzid" "NieprawidÅ‚owy authzid" ::msgcat::mcset pl "Invalid mechanism" "NieprawidÅ‚owy mechanizm uwierzytelniania" ::msgcat::mcset pl "Mechanism too weak" "Mechanizm uwierzytelniania zbyt sÅ‚aby" ::msgcat::mcset pl "Temporary auth failure" "Tymczasowy błąd uwierzytelniania" ::msgcat::mcset pl "Server haven't provided SASL authentication feature" "Serwer nie udostÄ™pnia protokoÅ‚u uwierzytelniania SASL" ::msgcat::mcset pl "SASL auth error: %s" "Błąd uwierzytelniania SASL: %s" ::msgcat::mcset pl "no mechanism available" "brak dostÄ™pnych mechanizmów" ::msgcat::mcset pl "SASL auth error:\n%s" "Błąd uwierzytelniania SASL:\n%s" ::msgcat::mcset pl "Server provided mechanism %s. It is forbidden" "Serwer udostÄ™pniÅ‚ mechanizm %s. Jest on niedozwolony" ::msgcat::mcset pl "Server provided mechanisms %s. They are forbidden" "Serwer udostÄ™pniÅ‚ mechanizmy %s. SÄ… one niedozwolone" ::msgcat::mcset pl "Server provided no SASL mechanisms" "Serwer nie udostÄ™pnia żadnych mechanizmów SASL" # jabberlib-tclxml/jlibtls.tcl ::msgcat::mcset pl "STARTTLS failed" "Uruchomienie STARTTLS nie powiodÅ‚o siÄ™" ::msgcat::mcset pl "STARTTLS successful" "Uruchomienie STARTTLS powiodÅ‚o siÄ™" # jabberlib-tclxml/streamerror.tcl ::msgcat::mcset pl "Bad Format" "ZÅ‚e formatowanie" ::msgcat::mcset pl "Bad Namespace Prefix" "ZÅ‚y prefiks przestrzeni nazw" ::msgcat::mcset pl "Connection Timeout" "Przekroczony czas oczekiwania na połączenie" ::msgcat::mcset pl "Host Gone" "Serwer wyłączony" ::msgcat::mcset pl "Host Unknown" "Serwer nieznany" ::msgcat::mcset pl "Improper Addressing" "NieprawidÅ‚owe adresowanie" ::msgcat::mcset pl "Invalid From" "NieprawidÅ‚owy atrybut From" ::msgcat::mcset pl "Invalid ID" "NieprawidÅ‚owy atrybut ID" ::msgcat::mcset pl "Invalid Namespace" "NieprawidÅ‚owa przestrzen nazw" ::msgcat::mcset pl "Invalid XML" "NieprawidÅ‚owy XML" ::msgcat::mcset pl "Policy Violation" "Naruszenie polityki bezpieczeÅ„stwa" ::msgcat::mcset pl "Remote Connection Failed" "Zdalne połączenie nie powiodÅ‚o siÄ™" ::msgcat::mcset pl "Restricted XML" "Ograniczony XML" ::msgcat::mcset pl "See Other Host" "Sprawdź inny serwer" ::msgcat::mcset pl "System Shutdown" "System w trakcie zamykania" ::msgcat::mcset pl "Unsupported Encoding" "NieobsÅ‚ugiwane kodowanie" ::msgcat::mcset pl "Unsupported Stanza Type" "NieobsÅ‚ugiwany typ zwrotki XML" ::msgcat::mcset pl "Unsupported Version" "NieobsÅ‚ugiwana wersja protokoÅ‚u" ::msgcat::mcset pl "XML Not Well-Formed" "Niepoprawnie sformatowany XML" ::msgcat::mcset pl "Stream Error%s%s" "Błąd strumienia %s%s" # jabberlib-tclxml/jlibcomponent.tcl ::msgcat::mcset pl "Waiting for handshake results" "Oczekiwanie na wynik wymiany potwierdzeÅ„" ::msgcat::mcset pl "Handshake failed" "Wymiana potwierdzeÅ„ nie powiodÅ‚a siÄ™" ::msgcat::mcset pl "Handshake successful" "Wymiana potwierdzeÅ„ powiodÅ‚a siÄ™" # jabberlib-tclxml/jlibauth.tcl ::msgcat::mcset pl "Server haven't provided non-SASL authentication feature" "Serwer nie oferuje mechanizmu uwierzytelniania innego niż SASL" ::msgcat::mcset pl "Server doesn't support hashed password authentication" "Serwer nie obsÅ‚uguje uwierzytelniania za pomocÄ… haseÅ‚ przeksztaÅ‚conych funkcjÄ… mieszajÄ…cÄ…" ::msgcat::mcset pl "Server doesn't support plain or digest authentication" "Serwer nie obsÅ‚uguje uwierzytelniania za pomocÄ… zwykÅ‚ego tekstu lub funkcji skrótu" # jabberlib-tclxml/jlibcompress.tcl ::msgcat::mcset pl "Server haven't provided compress feature" "Serwer nie obsÅ‚uguje kompresji strumienia XMPP" ::msgcat::mcset pl "Server haven't provided supported compress method" "Serwer nie obsÅ‚uguje wybranej metody kompresji strumienia XMPP" ::msgcat::mcset pl "Compression negotiation failed" "Uruchomienie kompresji strumienia XMPP nie powiodÅ‚o siÄ™" ::msgcat::mcset pl "Compression negotiation successful" "Kompresja strumienia XMPP uruchomiona" ::msgcat::mcset pl "Compression setup failed" "Konfiguracja kompresji strumienia XMPP nie powiodÅ‚a siÄ™" ::msgcat::mcset pl "Unsupported compression method" "NieobsÅ‚ugiwana metoda kompresji strumienia XMPP" # error types ::msgcat::mcset pl "Authentication Error" "Błąd uwierzytelniania" ::msgcat::mcset pl "Unrecoverable Error" "Błąd nienaprawialny" ::msgcat::mcset pl "Request Error" "Błąd żądania" ::msgcat::mcset pl "Temporary Error" "Błąd tymczasowy" # error messages ::msgcat::mcset pl "Bad Request" "Błędne żądanie" ::msgcat::mcset pl "Conflict" "Konflikt" ::msgcat::mcset pl "Feature Not Implemented" "WÅ‚aÅ›ciwość niezaimplementowana" ::msgcat::mcset pl "Forbidden" "DostÄ™p zabroniony" ::msgcat::mcset pl "Gone" "Obiekt zmieniÅ‚ adres" ::msgcat::mcset pl "Internal Server Error" "WewnÄ™trzny błąd serwera" ::msgcat::mcset pl "JID Malformed" "NieprawidÅ‚owy JID" ::msgcat::mcset pl "Item Not Found" "Element nie znaleziony" ::msgcat::mcset pl "Not Allowed" "Brak dostÄ™pu" ::msgcat::mcset pl "Recipient Unavailable" "Odbiorca niedostÄ™pny" ::msgcat::mcset pl "Registration Required" "Wymagana rejestracja" ::msgcat::mcset pl "Remote Server Not Found" "Nie znaleziono serwera" ::msgcat::mcset pl "Remote Server Timeout" "Przekroczono czas oczekiwania na odpowiedź serwera" ::msgcat::mcset pl "Service Unavailable" "UsÅ‚uga niedostÄ™pna" ::msgcat::mcset pl "Redirect" "Przekierowanie" ::msgcat::mcset pl "Payment Required" "Wymagana opÅ‚ata" ::msgcat::mcset pl "Not Acceptable" "Nie zaakceptowane" ::msgcat::mcset ru "Not Authorized" "Brak autoryzacji" ::msgcat::mcset pl "Subscription Required" "Wymagana subskrypcja" ::msgcat::mcset pl "Undefined Condition" "Niezdefinowany warunek" ::msgcat::mcset pl "Unexpected Request" "Nieoczekiwane żądanie" # ifaceck/widgets.tcl ::msgcat::mcset pl "Message" "Wiadomość" ::msgcat::mcset pl "Warning" "Ostrzeżenie" # ifacetk/iroster.tcl ::msgcat::mcset pl "Stored collapsed roster groups." "Lista pamiÄ™tanych zwiniÄ™tych grup listy kontaktów." ::msgcat::mcset pl "Stored show offline roster groups." "Lista pamiÄ™tanych grup z widokiem kontaków rozłączonych." ::msgcat::mcset pl "Send message to all users in group..." "WyÅ›lij wiadomość do wszystkich w grupie..." ::msgcat::mcset pl "Rename group..." "ZmieÅ„ nazwÄ™ grupy..." ::msgcat::mcset pl "Remove group..." "UsuÅ„ grupÄ™..." ::msgcat::mcset pl "Remove all users in group..." "UsuÅ„ wszystkie kontakty z grupy..." ::msgcat::mcset pl "Are you sure to remove group '%s' from roster? \n(Users which are in this group only, will be in undefined group.)" "Czy na pewno usunąć grupÄ™ '%s' z listy kontaktów? \n(Kontakty, które sÄ… tylko w tej grupie, znajdÄ… siÄ™ w grupie 'Niezdefiniowane'.)" ::msgcat::mcset pl "Are you sure to remove all users in group '%s' from roster? \n(Users which are in another groups too, will not be removed from the roster.)" "Czy na pewno usunąć z listy wszystkie kontakty z grupy '%s'? \n(Kontakty przypisane równoczeÅ›nie do innych grup nie zostanÄ… usuniÄ™te.)" ::msgcat::mcset pl "My Resources" "Moje zasoby" ::msgcat::mcset pl "Ask:" "ProÅ›ba:" ::msgcat::mcset pl "Subscription:" "Subskrypcja:" ::msgcat::mcset pl "Match contact JIDs in addition to nicknames in roster filter." "Filtruj wg JID użytkowników (dodmuatkowo obok filtrowania wg nazwy kontaktu)." ::msgcat::mcset pl "Roster filter." "Filtr listy kontaktów." ::msgcat::mcset pl "Use roster filter." "Włącz filtr listy kontaktów." # ifacetk/iface.tcl ::msgcat::mcset pl "Privacy rules" "Ochrona prywatnoÅ›ci" ::msgcat::mcset pl "Edit visible list" "Edycja listy widocznoÅ›ci" ::msgcat::mcset pl "Edit invisible list " "Edycja listy niewidocznoÅ›ci" ::msgcat::mcset pl "Edit ignore list " "Edycja listy ignorowanych" ::msgcat::mcset pl "Activate lists at startup" "Aktywuj listy podczas uruchomienia" ::msgcat::mcset pl "Show menu tearoffs when possible." "Włącz odrywane menu." ::msgcat::mcset pl "Show presence bar." "Pokaż pasek wyboru statusu." ::msgcat::mcset pl "Do nothing" "Nic nie rób" ::msgcat::mcset pl "Command to be run when you click a URL in a message. '%s' will be replaced with this URL (e.g. \"galeon -n %s\")." "Polecenie uruchamiane po klikniÄ™ciu adresu URL w wiadomoÅ›ciach. '%s' zostanie zastÄ…pione adresem URL (n.p. \"firefox %s\")." ::msgcat::mcset pl "Mute sound" "Wyłącz dźwiÄ™ki powiadomieÅ„" ::msgcat::mcset pl "Add user to roster..." "Dodaj kontakt do listy..." ::msgcat::mcset pl "Add conference to roster..." "Dodaj konferencjÄ™ do listy..." ::msgcat::mcset pl "Plugins" "Wtyczki" ::msgcat::mcset pl "Stored main window state (normal or zoomed)" "Przechowywany widok głównego okna (normalny lub powiÄ™kszony)" ::msgcat::mcset pl "Show status bar." "Pokaż pasek stanu aplikacji." ::msgcat::mcset pl "View" "Widok" ::msgcat::mcset pl "Toolbar" "Pasek narzÄ™dzi" ::msgcat::mcset pl "Presence bar" "Pasek wyboru statusu" ::msgcat::mcset pl "Status bar" "Pasek stanu" ::msgcat::mcset pl "Open chat..." "Rozpocznij rozmowÄ™..." ::msgcat::mcset pl "Manually edit rules" "RÄ™czna edycja reguÅ‚" ::msgcat::mcset pl "What action does the close button." "Akcja dla przycisku zamykania okna." ::msgcat::mcset pl "Close Tkabber" "Zamknij Tkabbera" ::msgcat::mcset pl "Minimize" "Minimalizuj do paska zadaÅ„" ::msgcat::mcset pl "Iconize" "Minimalizuj do ikony w zasobniku" ::msgcat::mcset pl "Minimize to systray (if systray icon is enabled, otherwise do nothing)" "Minimalizuj do ikony w zasobniku (jeżeli ikona jest wyłączona to nic nie rób)" ::msgcat::mcset pl "&Services" "&UsÅ‚ugi" ::msgcat::mcset pl "&Help" "&Pomoc" ::msgcat::mcset pl "Activate search panel" "Włącz panel wyszukiwania" ::msgcat::mcset pl "Common:" "Wspólne:" ::msgcat::mcset pl "Middle mouse button" "Åšrodkowy przycisk myszy" ::msgcat::mcset pl "Show palette of emoticons" "Pokaż zestaw emotikonek" ::msgcat::mcset pl "Accept messages from roster users only" "Akceptuj wiadomoÅ›ci tylko od osób z listy kontaktów" ::msgcat::mcset pl "Edit conference list " "Edytuj listÄ™ konferencji " ::msgcat::mcset pl "Complete nickname or command" "UzupeÅ‚nij pseudonim lub polecenie" ::msgcat::mcset pl "Show own resources" "Pokaż wÅ‚asne zasoby" ::msgcat::mcset pl "Bottom" "Dół" ::msgcat::mcset pl "Left" "Lewa" ::msgcat::mcset pl "Maximum width of tab buttons in tabbed mode." "Maksymalna szerokość przycisku karty w trybie interfejsu z kartami." ::msgcat::mcset pl "Minimum width of tab buttons in tabbed mode." "Minimalna szerokość przycisku karty w trybie interfejsu z kartami." ::msgcat::mcset pl "Right" "Prawa" ::msgcat::mcset pl "Side where to place tabs in tabbed mode." "Miejsce umieszczenia kart w głównym oknie programu w trybie interfejsu z kartami." ::msgcat::mcset pl "Top" "Góra" ::msgcat::mcset pl "Hide main window" "Ukryj główne okno" ::msgcat::mcset pl "Left mouse button" "Lewy przycisk myszy" ::msgcat::mcset pl "Popup menu" "Pokaż menu" ::msgcat::mcset pl "Show main window" "Pokaż główne okno" ::msgcat::mcset pl "Systray:" "Zasobnik systemowy:" ::msgcat::mcset pl "Use roster filter" "Włącz filtr listy kontaktów" ::msgcat::mcset pl "Font to use in chat windows." "Czcionka używana w oknach rozmów." ::msgcat::mcset pl "Font to use in roster windows." "Czcionka używana w oknie listy kontaktów." ::msgcat::mcset pl "If set then open chat window/tab when user doubleclicks roster item. Otherwise open normal message window." "Opcja włączona oznacza że podwójne klikniÄ™cie na element listy kontaktów otwiera okno/kartÄ™ rozmowy. W przeciwnym przypadku otwierane jest okno wiadomoÅ›ci." ::msgcat::mcset pl "Clear history" "Wyczyść historiÄ™" ::msgcat::mcset pl "History of availability status messages" "Historia używanych opisów statusu" ::msgcat::mcset pl "Maximum number of status messages to keep. If the history size reaches this threshold, the oldest message will be deleted automatically when a new one is recorded." "Maksymalna liczba pamiÄ™tanych w historii opisów. Jeżeli rozmiar historii przekracza ten próg, automatycznie usuwane sÄ… najstarsze opisy podczas dodawania nowego." ::msgcat::mcset pl "Show only the number of personal unread messages in window title." "Pokaż tylko ilość wiadomoÅ›ci osobistych na pasku tytuÅ‚owym okna." # ifacetk/iroster.tcl ::msgcat::mcset pl "Main window:" "Okno Główne:" ::msgcat::mcset pl "Close tab" "Zamknij kartÄ™" ::msgcat::mcset pl "Previous/Next tab" "Poprzedna/nastÄ™pna karta" ::msgcat::mcset pl "Move tab left/right" "PrzesuÅ„ kartÄ™ w lewo/prawo" ::msgcat::mcset pl "Switch to tab number 1-9,10" "Przełącz na kartÄ™ nr 1-9,10" ::msgcat::mcset pl "Hide/Show roster" "Ukryj/pokaż listÄ™ kontaktów" ::msgcat::mcset pl "Previous/Next history message" "NastÄ™pna/poprzednia wiadomość w historii" ::msgcat::mcset pl "Show emoticons" "Pokaż zestaw emotikonek" ::msgcat::mcset pl "Undo" "Cofnij" ::msgcat::mcset pl "Redo" "Ponów" ::msgcat::mcset pl "Scroll chat window up/down" "PrzewiÅ„ okno rozmów w górÄ™/w dół" ::msgcat::mcset pl "Right mouse button" "Prawy przycisk myszy" ::msgcat::mcset pl "Correct word" "Korekta sÅ‚owa (ispell)" ::msgcat::mcset pl "Alexey Shchepin" "Alexey Shchepin" ::msgcat::mcset pl "Marshall T. Rose" "Marshall T. Rose" ::msgcat::mcset pl "Sergei Golovan" "Sergei Golovan" ::msgcat::mcset pl "Michail Litvak" "Michail Litvak" ::msgcat::mcset pl "Konstantin Khomoutov" "Konstantin Khomoutov" # ifacetk/ilogin.tcl ::msgcat::mcset pl "Use SASL authentication" "Włącz uwierzytelnianie SASL" ::msgcat::mcset pl "Compression" "Kompresja" ::msgcat::mcset pl "Explicitly specify host and port to connect" "RÄ™czne ustawienie portu i nazwy serwera do połączenia" ::msgcat::mcset pl "Host:" "Serwer:" ::msgcat::mcset pl "Authentication" "Uwierzytelnianie" ::msgcat::mcset pl "Allow plaintext authentication mechanisms" "Włącz mechanizmy uwierzytelniania zwykÅ‚ym tekstem" ::msgcat::mcset pl "SSL & Compression" "Kompresja i SSL" ::msgcat::mcset pl "Plaintext" "ZwykÅ‚y tekst" ::msgcat::mcset pl "Encryption (legacy SSL)" "Szyfrowanie SSL" ::msgcat::mcset pl "Encryption (STARTTLS)" "Szyfrowanie STARTTLS" ::msgcat::mcset pl "Proxy password:" "HasÅ‚o proxy:" ::msgcat::mcset pl "Proxy port:" "Port proxy:" ::msgcat::mcset pl "Proxy server:" "Nazwa serwera proxy:" ::msgcat::mcset pl "Proxy type:" "Typ proxy:" ::msgcat::mcset pl "Proxy username:" "Użytkownik proxy:" ::msgcat::mcset pl "SSL certificate:" "Certyfikat SSL:" ::msgcat::mcset pl "Address type not supported by SOCKS proxy" "NieobsÅ‚ugiwany przez SOCKS proxy typ adresu" ::msgcat::mcset pl "Connection refused by destination host" "Połączenie odrzucone przez serwer docelowy" ::msgcat::mcset pl "Host unreachable" "Serwer niedostÄ™pny" ::msgcat::mcset pl "Incorrect SOCKS version" "NieprawidÅ‚owa wersja SOCKS" ::msgcat::mcset pl "Network failure" "Awaria sieci" ::msgcat::mcset pl "Network unreachable" "Sieć nieosiÄ…galna" ::msgcat::mcset pl "Proxy authentication required" "Wymagane uwierzytelnianie proxy" ::msgcat::mcset pl "SOCKS authentication failed" "Uwierzytelnianie SOCKS nie powiodÅ‚o siÄ™" ::msgcat::mcset pl "SOCKS command not supported" "NieobsÅ‚ugiwane polecenie SOCKS" ::msgcat::mcset pl "SOCKS connection not allowed by ruleset" "Połączenie SOCKS zablokowane przez reguÅ‚y dostÄ™pu" ::msgcat::mcset pl "SOCKS request failed" "OdwoÅ‚anie SOCKS nie powiodÅ‚o siÄ™" ::msgcat::mcset pl "SOCKS server cannot identify username" "Serwer SOCKS nie może zidentyfikować nazwy użytkownika" ::msgcat::mcset pl "SOCKS server username identification failed" "Identyfikacja nazwy użytkownika serwera SOCKS nie powiodÅ‚a siÄ™" ::msgcat::mcset pl "TTL expired" "TTL wygasÅ‚o" ::msgcat::mcset pl "Unknown address type" "Nieznany typ adresu" ::msgcat::mcset pl "Unknown error" "Nieznany błąd" ::msgcat::mcset pl "Unsupported SOCKS authentication method" "NieobsÅ‚ugiwana metoda uwierzytelniania SOCKS" ::msgcat::mcset pl "Unsupported SOCKS method" "NieobsÅ‚ugiwana metoda SOCKS" ::msgcat::mcset pl "Allow X-GOOGLE-TOKEN authentication mechanisms. It requires connection to Google via HTTPS." "Włącz mechanizm uwierzytelniania X-GOOGLE-TOKEN. Wymaga to połączenia do serwerów Google przez HTTPS." ::msgcat::mcset pl "Allow X-GOOGLE-TOKEN SASL mechanism" "WlÄ…cz mechanizm X-GOOGLE-TOKEN w SASL" # pixmaps.tcl ::msgcat::mcset pl "Tkabber icon theme. To make new theme visible for Tkabber put it to some subdirectory of %s." "Motyw ikon Tkabbera. Aby nowy motyw byÅ‚ widoczny w Tkabberze, należy umieÅ›cić go jako podkatalog katalogu %s." # si.tcl ::msgcat::mcset pl "Opening SI connection" "Otwieranie połączenia SI" ::msgcat::mcset pl "Stream method negotiation failed" "Nie powiodÅ‚a siÄ™ negocjacja strumienia" ::msgcat::mcset pl "SI connection closed" "Połączenie SI zakoÅ„czone" ::msgcat::mcset pl "Enable SI transport %s." "Włącz transport SI %s." ::msgcat::mcset pl "File transfer aborted" "PrzesyÅ‚anie pliku zostaÅ‚o przerwane" # plugins/si/socks5.tcl ::msgcat::mcset pl "Opening SOCKS5 listening socket" "Otwieranie gniazda SOCKS5" ::msgcat::mcset pl "Use mediated SOCKS5 connection if proxy is available." "Włącz negocjacjÄ™ połączenia SOCKS5 jeżeli dostÄ™pny jest serwer proxy." ::msgcat::mcset pl "List of proxy servers for SOCKS5 bytestreams (all available servers will be tried for mediated connection)." "Rozdzielona spacjami lista serwerów proxy do połączeÅ„ SOCKS5 (wszystkie wymienione serwery zostanÄ… sprawdzone przy połączeniu negocjowanym)." ::msgcat::mcset pl "Illegal result" "NieprawidÅ‚owy wynik" ::msgcat::mcset pl "Cannot connect to proxy" "Nie można połączyć siÄ™ z serwerem proxy" ::msgcat::mcset pl "Cannot negotiate proxy connection" "Nie udaÅ‚o siÄ™ wynegocjować połączenia proxy" # plugins/si/iqibb.tcl ::msgcat::mcset pl "Opening IQ-IBB connection" "Otwieranie połączenia IQ-IBB" # plugins/filetransfer/si.tcl ::msgcat::mcset pl "Stream initiation options." "Ustawienia protokoÅ‚u inicjacji strumienia (SI)." ::msgcat::mcset pl "Transfer failed: %s" "Nie udaÅ‚o siÄ™ przesÅ‚ać pliku: %s" ::msgcat::mcset pl "Receive error: Stream ID is in use" "Błąd odbioru: ID strumienia jest w użuciu" # plugins/filetransfer/http.tcl ::msgcat::mcset pl "File path:" "Plik:" ::msgcat::mcset pl "HTTP options." "Ustawienia protokoÅ‚u HTTP." ::msgcat::mcset pl "Can't receive file: %s" "Nie udaÅ‚o siÄ™ odebrać pliku: %s" ::msgcat::mcset pl "Port for outgoing HTTP file transfers (0 for assigned automatically). This is useful when sending files from behind a NAT with a forwarded port." "Numer portu przy wysyÅ‚aniu plików przez HTTP (jeżeli 0 to port zostanie przypisany automatycznie). Jest to przydatne przy wysyÅ‚aniu plików z sieci ukrytej za NAT z przekierowanym portem (forwarding)." ::msgcat::mcset pl "Force advertising this hostname (or IP address) for outgoing HTTP file transfers." "WymuÅ› rozgÅ‚aszanie nazwy tego hosta (lub adresu IP) przy wysyÅ‚aniu plików przez HTTP." # plugins/general/offline.tcl ::msgcat::mcset pl "Retrieve offline messages using POP3-like protocol." "Pobierz nieprzeczytane wiadomoÅ›ci z serwera używajÄ…c protokoÅ‚u podobnego do POP3." ::msgcat::mcset pl "Offline Messages" "WiadomoÅ›ci nieprzeczytane" ::msgcat::mcset pl "Sort by from" "Sortuj wg nadawcy" ::msgcat::mcset pl "Sort by node" "Sortuj wg powiÄ…zaÅ„" ::msgcat::mcset pl "Sort by type" "Sortuj wg typu" ::msgcat::mcset pl "Fetch unseen messages" "Pobierz nieoglÄ…dane wiadomoÅ›ci" ::msgcat::mcset pl "Fetch all messages" "Pobierz wszystkie wiadomoÅ›ci" ::msgcat::mcset pl "Purge seen messages" "UsuÅ„ oglÄ…dane wiadomoÅ›ci" ::msgcat::mcset pl "Purge all messages" "UsuÅ„ wszystkie wiadomoÅ›ci" ::msgcat::mcset pl "Fetch message" "Pobierz wiadomość" ::msgcat::mcset pl "Purge message" "UsuÅ„ wiadomość" # plugins/general/annotations.tcl ::msgcat::mcset pl "Storing roster notes failed: %s" "Zapis notatki dla pozycji listy kontaktów nie powiódÅ‚ siÄ™: %s" ::msgcat::mcset pl "Edit roster notes for %s" "Edycja notatki dla %s" ::msgcat::mcset pl "Created: %s" "Utworzono: %s" ::msgcat::mcset pl "Modified: %s" "Zmodyfikowano: %s" ::msgcat::mcset pl "Edit item notes..." "Edytuj notatkÄ™..." ::msgcat::mcset pl "Notes" "Notatki" ::msgcat::mcset pl "Roster Notes" "Notatki dla pozycji w liÅ›cie kontaktów" ::msgcat::mcset pl "Store" "Zapisz" # plugins/general/headlines.tcl ::msgcat::mcset pl "Format of timestamp in headline tree view. Set to empty string if you don't want to see timestamps." "Format znacznika czasu w oknie nagłówków wiadomoÅ›ci. Zostawienie tego pola pustego spowoduje wyłączenie znaczników czasu." ::msgcat::mcset pl "Sort by date" "Sortuj wg daty" ::msgcat::mcset pl "Show balloons with headline messages over tree nodes." "Pokazuj dymki podpowiedzi z treÅ›ciÄ… nagłówka nad elemetami drzewka nagłówków." ::msgcat::mcset pl "Read on..." "Czytaj dalej..." ::msgcat::mcset pl "" "" # plugins/search/search.tcl ::msgcat::mcset pl "Search in Tkabber windows options." "Ustawienia wyszukiwania w oknach Tkabbera." ::msgcat::mcset pl "Match case while searching in chat, log or disco windows." "Rozróżniaj wielkość liter podczas wyszukiwania w oknach rozmowy, historii i przeglÄ…darki usÅ‚ug." ::msgcat::mcset pl "Specifies search mode while searching in chat, log or disco windows. \"substring\" searches exact substring, \"glob\" uses glob style matching, \"regexp\" allows to match regular expression." "OkreÅ›la tryb wyszukiwania w rozmowach, historii i przeglÄ…darce usÅ‚ug. \"substring\" wyszukuje dokÅ‚adny podciÄ…g znaków, \"glob\" używa stylu dopasowaÅ„ glob, \"regexp\" pozwala na używanie wyrażeÅ„ regularnych." # plugins/roster/cache_categories.tcl ::msgcat::mcset pl "Cached service categories and types (from disco#info)." "Typy i kategorie usÅ‚ug przechowywane w pamiÄ™ci podrÄ™cznej (z disco#info)." # plugins/general/xaddress.tcl ::msgcat::mcset pl "Original from" "Oryginalny nadawca" ::msgcat::mcset pl "Original to" "Oryginalny adresat" ::msgcat::mcset pl "Reply to" "Odpowiedź do" ::msgcat::mcset pl "Reply to room" "Odpowiedź do pokoju" ::msgcat::mcset pl "No reply" "Bez odpowiedzi" ::msgcat::mcset pl "To" "Do" ::msgcat::mcset pl "Carbon copy" "Kopia" ::msgcat::mcset pl "Blind carbon copy" "Ukryta kopia" ::msgcat::mcset pl "This message was forwarded by %s\n" "Ta wiadomość zostaÅ‚a przekazana przez %s\n" ::msgcat::mcset pl "This message was sent by %s\n" "Ta wiadomość zostaÅ‚a wysÅ‚ana przez %s\n" ::msgcat::mcset pl "Extended addressing fields:" "Rozszerzone pola adresowe:" ::msgcat::mcset pl "Forwarded by:" "Przekazane przez:" # plugins/general/xcommands.tcl ::msgcat::mcset pl "Commands" "Polecenia" ::msgcat::mcset pl "Error executing command: %s" "Błąd przy uruchamianiu polecenia: %s" ::msgcat::mcset pl "Submit" "WyÅ›lij" ::msgcat::mcset pl "Prev" "NastÄ™pne" ::msgcat::mcset pl "Next" "Poprzednie" ::msgcat::mcset pl "Finish" "ZakoÅ„cz" ::msgcat::mcset pl "Warning:" "Ostrzeżenie:" ::msgcat::mcset pl "Error:" "Błąd:" ::msgcat::mcset pl "Info:" "Informacja:" ::msgcat::mcset pl "Error completing command: %s" "Błąd przy uzupeÅ‚nianiu polecenia: %s" ::msgcat::mcset pl "Execute command" "Uruchom polecenie" # plugins/general/remote.tcl ::msgcat::mcset pl "Remote control options." "Ustawienia zdalnego sterowania Tkabberem." ::msgcat::mcset pl "Enable remote control." "Włącz obsÅ‚ugÄ™ zdalnego sterownia." ::msgcat::mcset pl "Accept connections from my own JID." "Akceptuj połączenia z wÅ‚asnego JID." ::msgcat::mcset pl "Accept connections from the listed JIDs." "Akceptuj połączenia od nastÄ™pujÄ…cych JID (pozycje listy oddziel spacjami)." ::msgcat::mcset pl "Show my own resources in the roster." "Pokaż wÅ‚asne zasoby na liÅ›cie kontaktów." ::msgcat::mcset pl "This message was forwarded to %s" "Ta wiadomość zostaÅ‚a przekazana do %s" ::msgcat::mcset pl "All unread messages were forwarded to %s." "Wszystkie nieprzeczytane wiadomoÅ›ci zostaÅ‚y przekazane do %s." # plugins/chat/log_on_open.tcl ::msgcat::mcset pl "Maximum number of log messages to show in newly opened chat window (if set to negative then the number is unlimited)." "Maksymalna liczba wiadomoÅ›ci historii, pokazywana w nowo otwieranych oknach rozmów (liczba ujemna oznacza brak limitu)." ::msgcat::mcset pl "Maximum interval length in hours for which log messages should be shown in newly opened chat window (if set to negative then the interval is unlimited)." "Maksymalny odstÄ™p czasu od ostatniej rozmowy (w godzinach), dla którego wiadomoÅ›ci historii pokazywane bÄ™dÄ… w nowo otwartych oknach (liczba ujemna oznacza brak limitu)" # plugins/richtext/stylecodes.tcl ::msgcat::mcset pl "Handling of \"stylecodes\". Stylecodes are (groups of) special formatting symbols used to emphasize parts of the text by setting them with boldface, italics or underlined styles, or as combinations of these." "ObsÅ‚uga znaków formatujÄ…cych. Znaki formatujÄ…ce sÄ… (grupujÄ…cymi tekst) znakami specjalnymi, używanymi do wyróżnienia części tekstu przez \*wytÅ‚uszczenie\*, \\kursywÄ™\\, \_podkreÅ›lenie\_ lub kombinacjÄ™ tych trzech opcji." ::msgcat::mcset pl "Emphasize stylecoded messages using different fonts." "Formatuj wyróżnione części tekstu używajÄ…c różnych czcionek." ::msgcat::mcset pl "Hide characters comprising stylecode markup." "Ukryj znaki formatujÄ…ce tekst." # richtext.tcl ::msgcat::mcset pl "Settings of rich text facility which is used to render chat messages and logs." "Ustawienia mechanizmu formatowania tekstu, który jest używany do wyÅ›wietlania wiadomoÅ›ci w rozmowach i historii." # plugins/richtext/emoticons.tcl ::msgcat::mcset pl "Handling of \"emoticons\". Emoticons (also known as \"smileys\") are small pictures resembling a human face used to represent user's emotion. They are typed in as special mnemonics like :) or can be inserted using menu." "ObsÅ‚uga \"emotikon\". Emotikony (nazywane także \"buźkami\") to maÅ‚e obrazki przypominajÄ…ce ludzkÄ… twarz, używane do wyrażania uczuć osoby piszÄ…cej. Wstawiane sÄ… poprzez wpisanie specjalnych skrótów np. :) lub przez wybranie z menu." ::msgcat::mcset pl "Tkabber emoticons theme. To make new theme visible for Tkabber put it to some subdirectory of %s." "Motyw emotikon Tkabbera. Aby nowy motyw byÅ‚ widoczny w Tkabberze, należy umieÅ›cić go jako podkatalog katalogu %s." ::msgcat::mcset pl "Use only whole words for emoticons." "Zamieniaj tylko caÅ‚e wyrazy na emotikony." ::msgcat::mcset pl "Handle ROTFL/LOL smileys -- those like :))) -- by \"consuming\" all that parens and rendering the whole word with appropriate icon." "ObsÅ‚uga emotikonek ROTFL/LOL -- typu :))) -- przez obciÄ™cie nadmiarowych znaków i wyÅ›wietlenie caÅ‚ego wyrazu za pomocÄ… odpowiedniej ikony." ::msgcat::mcset pl "Show images for emoticons." "Pokaż obrazki emotikon." # utils.tcl ::msgcat::mcset pl "second" "sekunda" ::msgcat::mcset pl "seconds" "sekund" ::msgcat::mcset pl "minute" "minuta" ::msgcat::mcset pl "minutes" "minut" ::msgcat::mcset pl "hour" "godzina" ::msgcat::mcset pl "hours" "godzin" ::msgcat::mcset pl "day" "dzieÅ„" ::msgcat::mcset pl "days" "dni" # pubsub.tcl ::msgcat::mcset pl "Owner" "WÅ‚aÅ›ciciel" ::msgcat::mcset pl "Publisher" "Wydawca" ::msgcat::mcset pl "Outcast" "Wyrzutek" ::msgcat::mcset pl "Pending" "OczekujÄ…cy" ::msgcat::mcset pl "Unconfigured" "Nieskonfigurowany" ::msgcat::mcset pl "Subscribed" "Zasubskrybowany" ::msgcat::mcset pl "Edit entities affiliations: %s" "Edytuj przynależnoÅ›ci obiektów: %s" ::msgcat::mcset pl "Jabber ID" "Jabber ID" ::msgcat::mcset pl "SubID" "SubID" ::msgcat::mcset pl "Subscription" "Subskrypcja" # plugins/roster/fetch_nicknames.tcl ::msgcat::mcset pl "Fetch nickname" "Pobierz pseudonim" ::msgcat::mcset pl "Fetch user nicknames" "Pobierz pseudonimy kontaktów" ::msgcat::mcset pl "Fetch nicknames of all users in group" "Pobierz pseudonimy dla wszystkich w grupie" # plugins/general/session.tcl ::msgcat::mcset pl "Load state on Tkabber start." "Wczytaj zapisanÄ… sesjÄ™ przy starcie Tkabbera." ::msgcat::mcset pl "Load state on start" "Wczytaj zapisanÄ… sesjÄ™ przy starcie" ::msgcat::mcset pl "Save state" "Zapisz sesjÄ™ teraz" ::msgcat::mcset pl "Save state on Tkabber exit." "Zapisz sesjÄ™ przy zamkniÄ™ciu Tkabbera." ::msgcat::mcset pl "Save state on exit" "Zapisz sesjÄ™ przy zamkniÄ™ciu" ::msgcat::mcset pl "Tkabber save state options." "Ustawienia zapisu sesji Tkabbera." # config.tcl ::msgcat::mcset pl "Attention" "Uwaga" ::msgcat::mcset pl "Please stand by..." "ProszÄ™ czekać..." ::msgcat::mcset pl "Please, be patient while Tkabber configuration directory is being transferred to the new location" "ProszÄ™ czekać, katalog konfiguracyjny Tkabbera jest przenoszony do nowej lokalizacji" ::msgcat::mcset pl "Tkabber configuration directory transfer failed with:\n%s\n Tkabber will use the old directory:\n%s" "Nie udaÅ‚o siÄ™ przenieść katalogu konfiguracyjnego Tkabbera:\n%s\n Zostanie użyty stary katalog:\n%s" ::msgcat::mcset pl "Your new Tkabber config directory is now:\n%s\nYou can delete the old one:\n%s" "Nowy katalog konfiguracyjny Tkabber to teraz:\n%s\nMoża już usunąć stary katalog:\n%s" # plugins/general/tkcon.tcl ::msgcat::mcset pl "Show TkCon console" "Pokaż konsolÄ™ TkCon" # plugins/general/copy_jid.tcl ::msgcat::mcset pl "Copy JID to clipboard" "Kopiuj JID do schowka" ::msgcat::mcset pl "Copy real JID to clipboard" "Kopiuj prawdziwy JID do schowka" # plugins/iq/ping.tcl ::msgcat::mcset pl "Reply to ping (urn:xmpp:ping) requests." "Odpowiadaj na zapytania ping (urn:xmpp:ping)." ::msgcat::mcset pl "Ping server using urn:xmpp:ping requests." "Sprawdzaj serwer za pomocÄ… zapytaÅ„ urn:xmpp:ping." ::msgcat::mcset pl "Reconnect to server if it does not reply (with result or with error) to ping (urn:xmpp:ping) request in specified time interval (in seconds)." "Połącz siÄ™ ponownie z serwerem, jeżeli nie odpowiada on (wynikiem lub błędem) na zapytania ping (urn:xmpp:ping) po okreÅ›lonym (w sekundach) odstÄ™pnie czasu." # plugins/chat/muc_ignore.tcl ::msgcat::mcset pl "Edit MUC ignore rules" "Edycja reguÅ‚ ignorowania w MUC" ::msgcat::mcset pl "Error loading MUC ignore rules, purged." "Błąd podczas wczytywania reguÅ‚ ignorowania w MUC, reguÅ‚y sÄ… puste." ::msgcat::mcset pl "Ignore chat messages" "Ignoruj wiadomoÅ›ci w rozmowach" ::msgcat::mcset pl "Ignore groupchat messages" "Ignoruj wiadomoÅ›ci w konferencjach" ::msgcat::mcset pl "Ignoring groupchat and chat messages from selected occupants of multi-user conference rooms." "Ignorowanie wiadomoÅ›ci w rozmowach i konferencjach od wybranych uczestników pokoi konferencyjnych." ::msgcat::mcset pl "MUC Ignore" "Ignorowanie w MUC" ::msgcat::mcset pl "MUC Ignore Rules" "ReguÅ‚y ignorowania w MUC" ::msgcat::mcset pl "When set, all changes to the ignore rules are applied only until Tkabber is closed\; they are not saved and thus will be not restored at the next run." "Jeżeli ustawiono, to wszystkie zmiany reguÅ‚ ignorowania sÄ… widoczne tylko do czasu nastÄ™pnego uruchomienia Tkabbera\; reguÅ‚y nie sÄ… zapisywane i nie bÄ™dÄ… odtworzone przy nastÄ™pnym uruchomieniu." ::msgcat::mcset pl "Ignore" "Ignoruj" # plugins/chat/histool.tcl ::msgcat::mcset pl "Chats History" "Archiwum rozmów" ::msgcat::mcset pl "Chats history" "Archiwum rozmów" ::msgcat::mcset pl "Full-text search" "Wyszukiwanie" ::msgcat::mcset pl "JID list" "Lista JID" ::msgcat::mcset pl "Logs" "Dzienniki" ::msgcat::mcset pl "Unsupported log dir format" "NieobsÅ‚ugiwany format katalogu historii" ::msgcat::mcset pl "Client message" "Wiadomość klienta" ::msgcat::mcset pl "Server message" "Wiadomość serwera" ::msgcat::mcset pl "WARNING: %s\n" "UWAGA: %s\n" # plugins/chat/abbrev.tcl ::msgcat::mcset pl "Abbreviations:" "Skróty:" ::msgcat::mcset pl "Added abbreviation:\n%s: %s" "Dodano skrót:\n%s: %s" ::msgcat::mcset pl "Deleted abbreviation: %s" "UsuniÄ™to skrót: %s" ::msgcat::mcset pl "No such abbreviation: %s" "Nie ma takiego skrótu: %s" ::msgcat::mcset pl "Purged all abbreviations" "UsuniÄ™to wszystkie skróty" ::msgcat::mcset pl "Usage: /abbrev WHAT FOR" "Użycie: /abbrev SKRÓT DO_CZEGO" ::msgcat::mcset pl "Usage: /unabbrev WHAT" "Użycie: /unabbrev SKRÓT" # pep.tcl ::msgcat::mcset pl "Personal Eventing" "Zdarzenia osobiste" ::msgcat::mcset pl "Personal eventing" "Zdarzenia osobiste" ::msgcat::mcset pl "Personal eventing via pubsub plugins options." "Ustawienia zdarzeÅ„ osobistych obsÅ‚ugiwanych przez wtyczki pubsub." # plugins/pep/user_mood.tcl ::msgcat::mcset pl "%s's mood changed to %s" "%s zmieniÅ‚ nastrój na %s" ::msgcat::mcset pl "Cannot publish empty mood" "Nie można opublikować pustego nastroju" ::msgcat::mcset pl "Error" "Błąd" ::msgcat::mcset pl "Mood" "Nastrój" ::msgcat::mcset pl "Mood:" "Nastrój:" ::msgcat::mcset pl "Publish user mood..." "Publikuj nastrój użytkownika..." ::msgcat::mcset pl "Publishing is only possible while being online" "Publikowanie jest możliwe dopiero po nawiÄ…zaniu połączenia" ::msgcat::mcset pl "Unsubscribe" "Anuluj subskrypcjÄ™" ::msgcat::mcset pl "Use connection:" "Użyj połączenia:" ::msgcat::mcset pl "User mood" "Nastrój użytkownika" ::msgcat::mcset pl "User mood publishing failed: %s" "Publikacja nastroju użytkownika nie udaÅ‚a siÄ™: %s" ::msgcat::mcset pl "\n\tMood: %s" "\n\tNastrój: %s" ::msgcat::mcset pl "\n\tUser mood subscription: %s" "\n\tSubskrypcja nastroju użytkownika: %s" ::msgcat::mcset pl "afraid" "przestraszony" ::msgcat::mcset pl "amazed" "zdumiony" ::msgcat::mcset pl "angry" "zÅ‚y" ::msgcat::mcset pl "annoyed" "zirytowany" ::msgcat::mcset pl "anxious" "zaniepokojony" ::msgcat::mcset pl "aroused" "pobudzony" ::msgcat::mcset pl "ashamed" "zawstydzony" ::msgcat::mcset pl "bored" "znudzony" ::msgcat::mcset pl "brave" "dzielny" ::msgcat::mcset pl "calm" "spokojny" ::msgcat::mcset pl "cold" "lodowaty" ::msgcat::mcset pl "confused" "rozkojarzony" ::msgcat::mcset pl "contented" "zadowolony" ::msgcat::mcset pl "cranky" "drażliwy" ::msgcat::mcset pl "curious" "zaciekawiony" ::msgcat::mcset pl "depressed" "przybity" ::msgcat::mcset pl "disappointed" "rozczarowany" ::msgcat::mcset pl "disgusted" "zdegustowany" ::msgcat::mcset pl "distracted" "strapiony" ::msgcat::mcset pl "embarrassed" "zakÅ‚opotany" ::msgcat::mcset pl "excited" "podniecony" ::msgcat::mcset pl "flirtatious" "kokieteryjny" ::msgcat::mcset pl "frustrated" "sfrustrowany" ::msgcat::mcset pl "grumpy" "zrzÄ™dliwy" ::msgcat::mcset pl "guilty" "winny" ::msgcat::mcset pl "happy" "szczęśliwy" ::msgcat::mcset pl "hot" "napalony" ::msgcat::mcset pl "humbled" "skromny" ::msgcat::mcset pl "humiliated" "upokorzony" ::msgcat::mcset pl "hungry" "gÅ‚odny" ::msgcat::mcset pl "hurt" "zraniony" ::msgcat::mcset pl "impressed" "pod_wrażeniem" ::msgcat::mcset pl "in_awe" "zatrwożony" ::msgcat::mcset pl "in_love" "zakochany" ::msgcat::mcset pl "indignant" "oburzony" ::msgcat::mcset pl "interested" "zainteresowany" ::msgcat::mcset pl "intoxicated" "odurzony" ::msgcat::mcset pl "invincible" "niezwyciężony" ::msgcat::mcset pl "jealous" "zazdrosny" ::msgcat::mcset pl "lonely" "samotny" ::msgcat::mcset pl "mean" "wredny" ::msgcat::mcset pl "moody" "kapryÅ›ny" ::msgcat::mcset pl "nervous" "nerwowy" ::msgcat::mcset pl "neutral" "neutralny" ::msgcat::mcset pl "offended" "obrażony" ::msgcat::mcset pl "playful" "figlarny" ::msgcat::mcset pl "proud" "dumny" ::msgcat::mcset pl "relieved" "beznadziejny" ::msgcat::mcset pl "remorseful" "skruszony" ::msgcat::mcset pl "restless" "niespokojny" ::msgcat::mcset pl "sad" "smutny" ::msgcat::mcset pl "sarcastic" "sarkastyczny" ::msgcat::mcset pl "serious" "poważny" ::msgcat::mcset pl "shocked" "zaszokowany" ::msgcat::mcset pl "shy" "nieÅ›miaÅ‚y" ::msgcat::mcset pl "sick" "chory" ::msgcat::mcset pl "sleepy" "Å›piÄ…cy" ::msgcat::mcset pl "stressed" "zestresowany" ::msgcat::mcset pl "surprised" "zaskoczony" ::msgcat::mcset pl "thirsty" "spragniony" ::msgcat::mcset pl "worried" "zmartwiony" ::msgcat::mcset pl "%s's mood is unset" "Użytkownik %s nie ustawiÅ‚ nastroju" ::msgcat::mcset pl "Unpublish user mood..." "Anuluj publikacjÄ™ nastroju..." ::msgcat::mcset pl "Unpublish user mood" "Anuluj publikacjÄ™ nastroju" ::msgcat::mcset pl "User mood unpublishing failed: %s" "Anulowanie publikacji nastroju nie udaÅ‚o siÄ™: %s" ::msgcat::mcset pl "Auto-subscribe to other's user mood" "Automatycznie subskrybuj nastrój innego użytkownika" ::msgcat::mcset pl "Auto-subscribe to other's user mood notifications." "Automatycznie subskrybuj powiadomienia o nastroju innego użytkownika." # plugins/pep/user_tune.tcl ::msgcat::mcset pl "%s's tune changed to %s - %s" "%s zmieniÅ‚ melodiÄ™ na %s - %s" ::msgcat::mcset pl "%s's tune is unset" "Użytkownik %s nie ustawiÅ‚ melodii" ::msgcat::mcset pl "Artist:" "Artysta:" ::msgcat::mcset pl "Length:" "DÅ‚ugość:" ::msgcat::mcset pl "Publish" "Publikuj" ::msgcat::mcset pl "Publish user tune..." "Publikuj melodiÄ™ użytkownika..." ::msgcat::mcset pl "Source:" "Å»ródÅ‚o:" ::msgcat::mcset pl "Track:" "Åšcieżka:" ::msgcat::mcset pl "URI:" "URI:" ::msgcat::mcset pl "Unpublish" "Anuluj publikacjÄ™" ::msgcat::mcset pl "Unpublish user tune..." "Anuluj publikacjÄ™ melodii..." ::msgcat::mcset pl "Unpublish user tune" "Anuluj publikacjÄ™ melodii" ::msgcat::mcset pl "Unpublishing is only possible while being online" "Anulowanie publikacji jest możliwe dopiero po nawiÄ…zaniu połączenia" ::msgcat::mcset pl "User tune" "Melodia użytkownika" ::msgcat::mcset pl "User tune publishing failed: %s" "Publikacja melodii nie udaÅ‚a siÄ™: %s" ::msgcat::mcset pl "User tune unpublishing failed: %s" "Anulowanie publikacji melodii nie udaÅ‚o siÄ™: %s" ::msgcat::mcset pl "\n\tTune: %s - %s" "\n\tMelodia: %s - %s" ::msgcat::mcset pl "\n\tUser tune subscription: %s" "\n\tSubskrypcja melodii użytkownika: %s" ::msgcat::mcset pl "Auto-subscribe to other's user tune" "Automatycznie subskrybuj melodiÄ™ innego użytkownika" ::msgcat::mcset pl "Auto-subscribe to other's user tune notifications." "Automatycznie subskrybuj powiadomienia o melodii innego użytkownika." ::msgcat::mcset pl "%s's tune has stopped playing" "Odtwarzanie melodii %s zostaÅ‚o zatrzymane" ::msgcat::mcset pl "Publish \"playback stopped\" instead" "Publikuj \"odtwarzanie zatrzymane\" zamiast tego" ::msgcat::mcset pl "Rating:" "Ocena:" # plugins/pep/user_activity.tcl ::msgcat::mcset pl "%s's activity changed to %s" "%s zmieniÅ‚ czynność na %s" ::msgcat::mcset pl "%s's activity is unset" "Użytkownik %s nie ustawiÅ‚ czynnoÅ›ci" ::msgcat::mcset pl "Activity" "Czynność" ::msgcat::mcset pl "Activity:" "Czynność:" ::msgcat::mcset pl "Cannot publish empty activity" "Nie można opublikować pustej czynnoÅ›ci" ::msgcat::mcset pl "Publish user activity..." "Publikuj czynność użytkownika..." ::msgcat::mcset pl "Subactivity" "Czynność podrzÄ™dna" ::msgcat::mcset pl "Subactivity:" "Czynność podrzÄ™dna:" ::msgcat::mcset pl "Unpublish user activity..." "Anuluj publikacjÄ™ czynnoÅ›ci..." ::msgcat::mcset pl "Unpublish user activity" "Anuluj publikacjÄ™ czynnoÅ›ci" ::msgcat::mcset pl "User activity" "Czynność użytkownika" ::msgcat::mcset pl "User activity publishing failed: %s" "Publikacja czynnoÅ›ci nie udaÅ‚a siÄ™: %s" ::msgcat::mcset pl "User activity unpublishing failed: %s" "Anulowanie publikacji czynnoÅ›ci nie udaÅ‚o siÄ™: %s" ::msgcat::mcset pl "\n\tActivity: %s" "\n\tCzynność: %s" ::msgcat::mcset pl "\n\tUser activity subscription: %s" "\n\tSubskrypcja czynnoÅ›ci użytkownika: %s" ::msgcat::mcset pl "at the spa" "jestem w uzdrowisku" ::msgcat::mcset pl "brushing teeth" "myjÄ™ zÄ™by" ::msgcat::mcset pl "buying groceries" "kupujÄ™ jedzenie" ::msgcat::mcset pl "cleaning" "sprzÄ…tam" ::msgcat::mcset pl "coding" "kodujÄ™" ::msgcat::mcset pl "commuting" "w drodze do pracy" ::msgcat::mcset pl "cooking" "gotujÄ™" ::msgcat::mcset pl "cycling" "jeżdżę na rowerze" ::msgcat::mcset pl "day off" "dzieÅ„ wolny" ::msgcat::mcset pl "doing chores" "prace domowe" ::msgcat::mcset pl "doing maintenance" "pielÄ™gnujÄ™ siÄ™" ::msgcat::mcset pl "doing the dishes" "myjÄ™ naczynia" ::msgcat::mcset pl "doing the laundry" "robiÄ™ pranie" ::msgcat::mcset pl "drinking" "pijÄ™" ::msgcat::mcset pl "driving" "jadÄ™ samochodem" ::msgcat::mcset pl "eating" "jem" ::msgcat::mcset pl "exercising" "gimnastykujÄ™ siÄ™" ::msgcat::mcset pl "gaming" "gram" ::msgcat::mcset pl "gardening" "uprawiam ogród" ::msgcat::mcset pl "getting a haircut" "obcinam wÅ‚osy" ::msgcat::mcset pl "going out" "na wychodnym" ::msgcat::mcset pl "grooming" "higiena osobista" ::msgcat::mcset pl "hanging out" "na pogaduszkach" ::msgcat::mcset pl "having a beer" "pijÄ™ piwo" ::msgcat::mcset pl "having a snack" "jem zakÄ…skÄ™" ::msgcat::mcset pl "having appointment" "mam wizytÄ™" ::msgcat::mcset pl "having breakfast" "jem Å›niadanie" ::msgcat::mcset pl "having coffee" "pijÄ™ kawÄ™" ::msgcat::mcset pl "having dinner" "jem kolacjÄ™" ::msgcat::mcset pl "having lunch" "jem obiad" ::msgcat::mcset pl "having tea" "pijÄ™ herbatÄ™" ::msgcat::mcset pl "hiking" "wÄ™drujÄ™" ::msgcat::mcset pl "in a car" "w samochodzie" ::msgcat::mcset pl "in a meeting" "na spotkaniu" ::msgcat::mcset pl "in real life" "żyjÄ™ w rzeczywistoÅ›ci" ::msgcat::mcset pl "inactive" "brak aktywnoÅ›ci" ::msgcat::mcset pl "jogging" "jogging" ::msgcat::mcset pl "on a bus" "jadÄ™ autobusem" ::msgcat::mcset pl "on a plane" "lecÄ™ samolotem" ::msgcat::mcset pl "on a train" "jadÄ™ pociÄ…giem" ::msgcat::mcset pl "on a trip" "w podróży" ::msgcat::mcset pl "on the phone" "przy telefonie" ::msgcat::mcset pl "on vacation" "na wakacjach" ::msgcat::mcset pl "on video phone" "rozmowa wideo" ::msgcat::mcset pl "partying" "imprezujÄ™" ::msgcat::mcset pl "playing sports" "uprawiam sport" ::msgcat::mcset pl "reading" "czytam" ::msgcat::mcset pl "rehearsing" "robiÄ™ próbÄ™" ::msgcat::mcset pl "relaxing" "odpoczywam" ::msgcat::mcset pl "running" "biegam" ::msgcat::mcset pl "running an errand" "biegam z przesyÅ‚kami" ::msgcat::mcset pl "scheduled holiday" "zaplanowane wakacje" ::msgcat::mcset pl "shaving" "golÄ™ siÄ™" ::msgcat::mcset pl "shopping" "robiÄ™ zakupy" ::msgcat::mcset pl "skiing" "jeżdżę na nartach" ::msgcat::mcset pl "sleeping" "Å›piÄ™" ::msgcat::mcset pl "socializing" "udzielam siÄ™ towarzysko" ::msgcat::mcset pl "studying" "studiujÄ™" ::msgcat::mcset pl "sunbathing" "opalam siÄ™" ::msgcat::mcset pl "swimming" "pÅ‚ywam" ::msgcat::mcset pl "taking a bath" "biorÄ™ kÄ…piel" ::msgcat::mcset pl "taking a shower" "biorÄ™ prysznic" ::msgcat::mcset pl "talking" "rozmawiam" ::msgcat::mcset pl "traveling" "podróżujÄ™" ::msgcat::mcset pl "walking" "spacerujÄ™" ::msgcat::mcset pl "walking the dog" "wyprowadzam psa" ::msgcat::mcset pl "watching a movie" "oglÄ…dam film" ::msgcat::mcset pl "watching tv" "oglÄ…dam tv" ::msgcat::mcset pl "working" "pracujÄ™" ::msgcat::mcset pl "working out" "trenujÄ™" ::msgcat::mcset pl "writing" "piszÄ™" ::msgcat::mcset pl "Auto-subscribe to other's user activity" "Automatycznie subskrybuj czynność innego użytkownika" ::msgcat::mcset pl "Auto-subscribe to other's user activity notifications." "Automatycznie subskrybuj powiadomienia o czynnoÅ›ci innego użytkownika." # plugins/general/caps.tcl ::msgcat::mcset pl "Enable announcing entity capabilities in every outgoing presence." "Włącz rozgÅ‚aszanie wÅ‚asnych możliwoÅ›ci w każdej wychodzÄ…cej informacji o statusie." ::msgcat::mcset pl "Options for entity capabilities plugin." "Ustawenia wtyczki rozgÅ‚aszania wÅ‚asnych możliwoÅ›ci." ::msgcat::mcset pl "Use the specified function to hash supported features list." "Użyj wybranej funkcji do utworzenia skrótu listy obsÅ‚ugiwanych cech." # plugins/iq/time2.tcl ::msgcat::mcset pl "Reply to entity time (urn:xmpp:time) requests." "WysyÅ‚aj odpowiedzi na zapytanie o wÅ‚asny czas (urn:xmpp:time)." # plugins/pep/user_location.tcl ::msgcat::mcset pl "%s's location changed to %s : %s" "Lokalizacja użytkownika %s zmieniÅ‚a siÄ™ na %s : %s" ::msgcat::mcset pl "%s's location is unset" "Użytkownik %s nie ustawiÅ‚ lokalizacji" ::msgcat::mcset pl "Altitude:" "Wysokość:" ::msgcat::mcset pl "Area:" "Strefa:" ::msgcat::mcset pl "Auto-subscribe to other's user location" "Automatycznie subskrybuj lokalizacjÄ™ innego użytkownika" ::msgcat::mcset pl "Auto-subscribe to other's user location notifications." "Automatycznie subskrybuj powiadomienia o lokalizacji innego użytkownika." ::msgcat::mcset pl "Bearing:" "Namiar:" ::msgcat::mcset pl "Building:" "Budynek:" ::msgcat::mcset pl "GPS datum:" "UkÅ‚ad odniesienia GPS:" ::msgcat::mcset pl "Horizontal GPS error:" "Błąd horyzontalny GPS:" ::msgcat::mcset pl "Floor:" "PiÄ™tro:" ::msgcat::mcset pl "Locality:" "Miejscowość:" ::msgcat::mcset pl "Postal code:" "Kod pocztowy:" ::msgcat::mcset pl "Publish user location..." "Publikuj swojÄ… lokalizacjÄ™..." ::msgcat::mcset pl "Region:" "Region:" ::msgcat::mcset pl "Room:" "Pokój:" ::msgcat::mcset pl "Speed:" "PrÄ™dkość:" ::msgcat::mcset pl "Street:" "Ulica:" ::msgcat::mcset pl "Timestamp:" "Zmacznik czasu:" ::msgcat::mcset pl "Unpublish user location..." "Anuluj publikacjÄ™ swojej lokalizacji..." ::msgcat::mcset pl "Unpublish user location" "Anuluj publikacjÄ™ swojej lokalizacji" ::msgcat::mcset pl "User location" "Lokalizacja użytkownika" ::msgcat::mcset pl "User location publishing failed: %s" "Publikacja lokalizacji nie udaÅ‚a siÄ™: %s" ::msgcat::mcset pl "User location unpublishing failed: %s" "Anulowanie publikacji lokalizacji nie udaÅ‚o siÄ™: %s" ::msgcat::mcset pl "\n\tLocation: %s : %s" "\n\tLokalizacja: %s : %s" ::msgcat::mcset pl "\n\tUser location subscription: %s" "\n\tSubskrypcja lokalizacji użytkownika: %s" # plugins/roster/bkup_annotations.tcl ::msgcat::mcset pl "Error restoring annotations: %s" "Błąd podczas przywracania notatek: %s" # plugins/roster/bkup_conferences.tcl ::msgcat::mcset pl "Error restoring conference bookmarks: %s" "Błąd podczas przywracania zakÅ‚adek z konferencjami: %s" # plugins/roster/backup.tcl ::msgcat::mcset pl "Error restoring roster contacts: %s" "Błąd podczas przywracania listy kontaktów: %s" ::msgcat::mcset pl "Roster restoration completed" "Przywracanie listy kontaktów zakoÅ„czone" # jabberlib/stanzaerror.tcl ::msgcat::mcset pl "Access Error" "Błąd dostÄ™pu" ::msgcat::mcset pl "Address Error" "Błąd adresu" ::msgcat::mcset pl "Application Error" "Błąd aplikacji" ::msgcat::mcset pl "Format Error" "Błąd formatu" ::msgcat::mcset pl "Not Found" "Nie znaleziono" ::msgcat::mcset pl "Not Implemented" "Nie zaimplementowano" ::msgcat::mcset pl "Recipient Error" "Błąd odbiorcy" ::msgcat::mcset pl "Remote Server Error" "Błąd zdalnego serwera" ::msgcat::mcset pl "Request Timeout" "Przekroczony limit czasu oczekiwania na odpowiedź" ::msgcat::mcset pl "Server Error" "Błąd serwera" ::msgcat::mcset pl "Unauthorized" "Nie uwierzytelniono" ::msgcat::mcset pl "Username Not Available" "Nazwa użytkownia niedostÄ™pna" tkabber-0.11.1/msgs/es.msg0000644000175000017500000034252511073745017014632 0ustar sergeisergei# $Id: es.msg 1508 2008-10-10 21:33:03Z sergei $ #1 Spanish messages file #2 Author: Luis Peralta / jaxp - peralta @ aditel . org #3 http://spisa.act.uji.es/~peralta JID: al019409@mi.uji.es #4 Please notify me of errors or incoherencies #5 Updates: Badlop ( JID: badlop AT jabberes.org ) ::msgcat::mcset es " by " " por " ::msgcat::mcset es " by %s" " por %s" ::msgcat::mcset es "#" "#" ::msgcat::mcset es "%s Headlines" "Titulares de %s" ::msgcat::mcset es "%s SSL Certificate Info" "Información de Certificado SSL de %s" ::msgcat::mcset es "%s has activated chat window" "%s ha activado la ventana de charla" ::msgcat::mcset es "%s has been assigned a new affiliation: %s" "%s tiene una nueva afiliación: %s" ::msgcat::mcset es "%s has been assigned a new role: %s" "%s tiene un nuevo rol: %s" ::msgcat::mcset es "%s has been assigned a new room position: %s/%s" "%s tiene una nueva posición en la sala: %s/%s" ::msgcat::mcset es "%s has been banned" "%s ha sido bloqueado" ::msgcat::mcset es "%s has been kicked because of membership loss" "%s ha sido expulsado porque ya no es miembro" ::msgcat::mcset es "%s has been kicked because room became members-only" "%s ha sido expulsado porque la sala es ahora solo para miembros" ::msgcat::mcset es "%s has been kicked" "%s ha sido expulsado" ::msgcat::mcset es "%s has changed nick to %s." "%s ha cambiado el apodo a %s." ::msgcat::mcset es "%s has entered" "%s ha entrado" ::msgcat::mcset es "%s has gone chat window" "%s se ha ido de la ventana de charla" ::msgcat::mcset es "%s has inactivated chat window" "%s ha desactivado la ventana de charla" ::msgcat::mcset es "%s has left" "%s se ha ido" ::msgcat::mcset es "%s info" "Información de %s" ::msgcat::mcset es "%s invites you to conference room %s" "%s te invita a la sala de charla %s" ::msgcat::mcset es "%s is %s" "%s está %s" ::msgcat::mcset es "%s is composing a reply" "%s está escribiendo una respuesta" ::msgcat::mcset es "%s is now known as %s" "%s es ahora %s" ::msgcat::mcset es "%s is paused a reply" "%s ha pausado una respuesta" ::msgcat::mcset es "%s msgs" "%s mensajes" ::msgcat::mcset es "%s plugin" "plugin %s" ::msgcat::mcset es "%s purportedly signed by %s can't be verified.\n\n%s." "%s supuestamente firmado pero no puede ser verificado.\n\n%s." ::msgcat::mcset es "%s request from %s" "Petición %s de %s" ::msgcat::mcset es "%s's activity changed to %s" "La actividad de %s ha cambiado a %s" ::msgcat::mcset es "%s's activity is unset" "La actividad de %s se ha desactivado" ::msgcat::mcset es "%s's location changed to %s : %s" "La localización de %s ha cambiado a %s : %s" ::msgcat::mcset es "%s's location is unset" "La localización de %s se ha desactivado" ::msgcat::mcset es "%s's mood changed to %s" "El estado de ánimo del usuario %s ha cambiado a %s" ::msgcat::mcset es "%s's mood is unset" "Se ha desactivado el estado de ánimo de %s" ::msgcat::mcset es "%s's tune changed to %s - %s" "La canción de %s ha cambiado a %s - %s" ::msgcat::mcset es "%s's tune has stopped playing" "La canción de %s se ha detenido" ::msgcat::mcset es "%s's tune is unset" "La canción de %s ha sido desactivada" ::msgcat::mcset es "%s: %s/%s, Description: %s, Version: %s\nNumber of children: %s" "%s: %s/%s, Descripción: %s, Versión: %s\nNúmero de hijos: %s" ::msgcat::mcset es "&Help" "&Ayuda" ::msgcat::mcset es "&Services" "&Servicios" ::msgcat::mcset es "- nothing -" "- nada -" ::msgcat::mcset es ". Proceed?\n\n" ". ¿Proceder?\n\n" ::msgcat::mcset es "/me has set the subject to: %s" "/me ha puesto el asunto a: %s" ::msgcat::mcset es "<- Remove" "<- Eliminar" ::msgcat::mcset es "" "" ::msgcat::mcset es ">>> Unable to decipher data: %s <<<" ">>> No ha sido posible descifrar los datos: %s <<<" ::msgcat::mcset es "A new room is created" "Se ha creado una sala nueva" ::msgcat::mcset es "Abbreviations:" "Abreviaturas:" ::msgcat::mcset es "Aborted" "Abortado" ::msgcat::mcset es "About " "Acerca de " ::msgcat::mcset es "About" "Acerca de" ::msgcat::mcset es "Accept connections from my own JID." "Aceptar conexiones de mi propio JID." ::msgcat::mcset es "Accept connections from the listed JIDs." "Aceptar conexiones de los JIDs listados." ::msgcat::mcset es "Accept default config" "Aceptar la configuración por defecto" ::msgcat::mcset es "Accept messages from roster users only" "Aceptar mensajes solo de contactos de la lista" ::msgcat::mcset es "Access Error" "Error de acceso" ::msgcat::mcset es "Account" "Cuenta" ::msgcat::mcset es "Action" "Acción" ::msgcat::mcset es "Activate lists at startup" "Activar listas en el inicio" ::msgcat::mcset es "Activate search panel" "Activar panel de búsqueda" ::msgcat::mcset es "Activate visible/invisible/ignore/conference lists before sending initial presence." "Activar listas de visible/invisible/ignorar/conferencia antes de enviar la presencia inicial." ::msgcat::mcset es "Activating privacy list failed: %s\n\nTry to reconnect. If problem persists, you may want to disable privacy list activation at start" "Falló la activación de lista de privacidad: %s\n\nIntenta reconectar. Si el problema persiste, quizá tengas que deshabilitar la activación de listas de privacidad al inicio" ::msgcat::mcset es "Active Chats" "Salas activas" ::msgcat::mcset es "Active" "Activa" ::msgcat::mcset es "Activity" "Actividad" ::msgcat::mcset es "Activity:" "Actividad:" ::msgcat::mcset es "Add ->" "Añadir ->" ::msgcat::mcset es "Add Conference to Roster" "Añadir sala a la lista de contactos" ::msgcat::mcset es "Add JID" "Añadir JID" ::msgcat::mcset es "Add chats group in roster." "Añadir temporalmente grupos de charla activos a la lista de contactos" ::msgcat::mcset es "Add conference to roster..." "Añadir conferencia..." ::msgcat::mcset es "Add conference..." "Añadir charla en grupo..." ::msgcat::mcset es "Add group by regexp on JIDs..." "Crear grupo por regexp sobre JID..." ::msgcat::mcset es "Add item" "Añadir elemento" ::msgcat::mcset es "Add list" "Añadir lista" ::msgcat::mcset es "Add new item" "Añadir nuevo elemento" ::msgcat::mcset es "Add new user..." "Añadir nuevo usuario..." ::msgcat::mcset es "Add roster group by JID regexp" "Añadir grupo a la lista por regexp sobre JID" ::msgcat::mcset es "Add user to roster..." "Añadir usuario..." ::msgcat::mcset es "Add user..." "Añadir usuario..." ::msgcat::mcset es "Add" " Añadir " ::msgcat::mcset es "Added abbreviation:\n%s: %s" "Añadir abreviatura:\n%s: %s" ::msgcat::mcset es "Address 2" "Dirección 2" ::msgcat::mcset es "Address 2:" "Dirección 2:" ::msgcat::mcset es "Address Error" "Error de dirección" ::msgcat::mcset es "Address type not supported by SOCKS proxy" "Tipo de dirección no soportada por el proxy SOCKS" ::msgcat::mcset es "Address" "Dirección" ::msgcat::mcset es "Address:" "Dirección:" ::msgcat::mcset es "Admin tools" "Administración" ::msgcat::mcset es "Affiliation" "Afiliación" ::msgcat::mcset es "Alexey Shchepin" "Alexey Shchepin" ::msgcat::mcset es "All Files" "Todos los ficheros" ::msgcat::mcset es "All files" "Todos los ficheros" ::msgcat::mcset es "All items:" "Todos los elementos:" ::msgcat::mcset es "All unread messages were forwarded to %s." "Todos los mensajes no leídos fueron reenviados a %s." ::msgcat::mcset es "All" "Todos" ::msgcat::mcset es "Allow X-GOOGLE-TOKEN SASL mechanism" "Permitir el mecanismo SASL: X-GOOGLE-TOKEN" ::msgcat::mcset es "Allow X-GOOGLE-TOKEN authentication mechanisms. It requires connection to Google via HTTPS." "Permitir los mecanismos de autenticación X-GOOGLE-TOKEN. Se conecta a Google usando HTTPS." ::msgcat::mcset es "Allow downloading" "Permitir descargar" ::msgcat::mcset es "Allow plaintext authentication mechanisms (when password is transmitted unencrypted)." "Permitir mecanismos de autenticación de texto plano (donde la contraseña se envía sin cifrar)." ::msgcat::mcset es "Allow plaintext authentication mechanisms" "Permitir mecanismos de autenticación de texto plano" ::msgcat::mcset es "Altitude:" "Altitud:" ::msgcat::mcset es "An error occurred when searching in %s\n\n%s" "Un error ocurrió buscando en %s\n\n%s" ::msgcat::mcset es "Announce" "Anunciar" ::msgcat::mcset es "Application Error" "Error de aplicación" ::msgcat::mcset es "Approve subscription" "Aprobar subscripción" ::msgcat::mcset es "April" "Abril" ::msgcat::mcset es "Are you sure to remove %s from roster?" "¿Estás seguro de querer eliminar %s de tu lista?" ::msgcat::mcset es "Are you sure to remove all users in group '%s' from roster? \n(Users which are in another groups too, will not be removed from the roster.)" "¿Estás seguro de que quieres eliminar todos los usuarios del grupo '%s'? \n(Los usuarios que están también en otros grupos no se eliminarán de tu lista de contactos)" ::msgcat::mcset es "Are you sure to remove group '%s' from roster? \n(Users which are in this group only, will be in undefined group.)" "¿Estás seguro de que quieres eliminar el grupo '%s'? \n(Los usuarios que están solo en este grupo se moverán al grupo 'Indefinido')" ::msgcat::mcset es "Are you sure to remove group '%s' from roster?" "¿Estás seguro de que quieres eliminar el grupo '%s' de la lista de contactos?" ::msgcat::mcset es "Area:" "Ãrea:" ::msgcat::mcset es "Artist:" "Artista:" ::msgcat::mcset es "Ask:" "Preguntar:" ::msgcat::mcset es "Attached URL:" "URL adjunta:" ::msgcat::mcset es "Attached user:" "Usuario adjunto:" ::msgcat::mcset es "Attention" "Atención" ::msgcat::mcset es "August" "Agosto" ::msgcat::mcset es "Authentication Error" "Error en la autenticación" ::msgcat::mcset es "Authentication failed" "Autenticación fallida" ::msgcat::mcset es "Authentication failed: %s" "Ha fallado la autenticación: %s" ::msgcat::mcset es "Authentication failed: %s\nCreate new account?" "Autenticación fallida: %s\n¿Crear cuenta nueva?" ::msgcat::mcset es "Authentication successful" "Autenticación exitosa" ::msgcat::mcset es "Authentication" "Autenticación" ::msgcat::mcset es "Authors:" "Autores:" ::msgcat::mcset es "Auto-subscribe to other's user activity notifications." "Auto subscribirse a las notificaciones de actividad de otros usuarios" ::msgcat::mcset es "Auto-subscribe to other's user activity" "Auto subscribirse a la actividad de otros usuarios" ::msgcat::mcset es "Auto-subscribe to other's user location notifications." "Auto subscribirse a las notificaciones de localización de otros usuarios" ::msgcat::mcset es "Auto-subscribe to other's user location" "Auto subscribirse a la localización de otros usuarios" ::msgcat::mcset es "Auto-subscribe to other's user mood notifications." "Auto subscribirse a las notificaciones de estado de ánimo de otros usuarios" ::msgcat::mcset es "Auto-subscribe to other's user mood" "Auto subscribirse al estado de ánimo de otros usuarios" ::msgcat::mcset es "Auto-subscribe to other's user tune notifications." "Auto subscribirse a las notificaciones de canción de otros usuarios." ::msgcat::mcset es "Auto-subscribe to other's user tune" "Auto subscribirse a las canciones de otros usuarios" ::msgcat::mcset es "Automatically away due to idle" "Automáticamente ausente debido a inactividad" ::msgcat::mcset es "Automatically join conference upon connect" "Entrar en la sala automáticamente al conectar" ::msgcat::mcset es "Available groups" "Grupos disponibles" ::msgcat::mcset es "Available presence" "Presencia: disponible" ::msgcat::mcset es "Available" "Disponible" ::msgcat::mcset es "Avatar" "Avatar" ::msgcat::mcset es "Away" "Ausente" ::msgcat::mcset es "BBS:" ::msgcat::mcset es "Bad Format" "Mal Formato" ::msgcat::mcset es "Bad Namespace Prefix" "Mal Prefijo de Espacio de Nombres" ::msgcat::mcset es "Bad Request" "Mala petición" ::msgcat::mcset es "Ban" "Bloquear" ::msgcat::mcset es "Bearing:" "Bearing:" ::msgcat::mcset es "Begin date" "Fecha de inicio" ::msgcat::mcset es "Birthday" "Fecha de nacimiento" ::msgcat::mcset es "Birthday:" "Fecha de nacimiento:" ::msgcat::mcset es "Blind carbon copy" "Copia carbón ciega (BCC)" ::msgcat::mcset es "Blocking communication (XMPP privacy lists) options." "Opciones para bloquear comunicaciones (listas de privacidad)." ::msgcat::mcset es "Blocking communication options." "Opciones de bloqueo de comunicación." ::msgcat::mcset es "Bottom" "Abajo" ::msgcat::mcset es "Browse" "Explorar" ::msgcat::mcset es "Browse..." "Explorar..." ::msgcat::mcset es "Building:" "Edificio:" ::msgcat::mcset es "Cache headlines on exit and restore on start." "Guardar titulares al terminar y recuperar al iniciar." ::msgcat::mcset es "Cached service categories and types (from disco#info)." "Categorías de servicio y tipos cacheados (de disco#info)." ::msgcat::mcset es "Can't open file \"%s\": %s" "No se puede abrir el fichero \"%s\": %s" ::msgcat::mcset es "Can't receive file: %s" "No se puede recibir fichero: %s" ::msgcat::mcset es "Cancel" " Cancelar " ::msgcat::mcset es "Cancelling configure form" "Cancelando el formulario de configuración" ::msgcat::mcset es "Cannot connect to proxy" "No se puede conectar al proxy" ::msgcat::mcset es "Cannot negotiate proxy connection" "No se puede negociar la conexión al proxy" ::msgcat::mcset es "Cannot publish empty activity" "No se puede publicar una actividad vacía" ::msgcat::mcset es "Cannot publish empty mood" "No se puede publicar un estado de ánimo vacío" ::msgcat::mcset es "Carbon copy" "Copia carbón" ::msgcat::mcset es "Cell:" "Móvil:" ::msgcat::mcset es "Certificate has expired" "El certificado ha expirado" ::msgcat::mcset es "Change Presence Priority" "Cambiar Prioridad" ::msgcat::mcset es "Change password" "Cambiar contraseña" ::msgcat::mcset es "Change password..." "Cambiar contraseña..." ::msgcat::mcset es "Change priority..." "Cambiar prioridad..." ::msgcat::mcset es "Change security preferences for %s" "Cambiar las preferencias de seguridad para %s" ::msgcat::mcset es "Changing accept messages from roster only: %s" "Cambiando mensajes de aceptar solo para la lista de contacto: %s" ::msgcat::mcset es "Chat " "Charla " ::msgcat::mcset es "Chat message events plugin options." "Opciones del plugin de eventos de mensajes de charla." ::msgcat::mcset es "Chat message window state plugin options." "Opciones del plugin de estado de las ventanas de mensaje de charla." ::msgcat::mcset es "Chat message" "Mensaje de charla" ::msgcat::mcset es "Chat options." "Opciones de charla." ::msgcat::mcset es "Chat window is active" "La ventana de charla está activa" ::msgcat::mcset es "Chat window is gone" "La ventana de charla se ha ido" ::msgcat::mcset es "Chat window is inactive" "Ventana de charla inactiva" ::msgcat::mcset es "Chat with %s" "Charlar con %s" ::msgcat::mcset es "Chat" "Charlar" ::msgcat::mcset es "Chats History" "Historial de Charlas" ::msgcat::mcset es "Chats history is converted.\nBackup of the old history is stored in %s" "Los historiales de charla se han convertido.\nUna copia de seguridad de los viejos historiales se ha guardado en %s" ::msgcat::mcset es "Chats history" "Historial de charlas" ::msgcat::mcset es "Chats" "Charlas" ::msgcat::mcset es "Chats:" "Charlas:" ::msgcat::mcset es "Check spell after every entered symbol." "Corregir ortografía después de cada símbolo." ::msgcat::mcset es "Cipher" "Cifra" ::msgcat::mcset es "City" "Ciudad" ::msgcat::mcset es "City:" "Población:" ::msgcat::mcset es "Clear bookmarks" "Borrar marcadores" ::msgcat::mcset es "Clear chat window" "Limpiar ventana de charla" ::msgcat::mcset es "Clear history" "Limpiar historial" ::msgcat::mcset es "Clear window" "Limpiar ventana" ::msgcat::mcset es "Clear" "Limpiar" ::msgcat::mcset es "Client message" "Mensaje del cliente" ::msgcat::mcset es "Client" "Cliente" ::msgcat::mcset es "Client:" "Cliente:" ::msgcat::mcset es "Close Tkabber" "Cerrar Tkabber" ::msgcat::mcset es "Close all tabs" "Cerrar todas las pestañas" ::msgcat::mcset es "Close other tabs" "Cerrar las otras pestañas" ::msgcat::mcset es "Close tab" "Cerrar pestaña" ::msgcat::mcset es "Close" "Cerrar" ::msgcat::mcset es "Color message bodies in chat windows." "Color de los mensajes en las ventanas de charla" ::msgcat::mcset es "Command to be run when you click a URL in a message. '%s' will be replaced with this URL (e.g. \"galeon -n %s\")." "Comando a ejecutar cuando se pulsa una URL en un mensaje. Se reemplazará '%s' con la URL (e.g. \"galeon -n %s\")." ::msgcat::mcset es "Commands" "Comandos" ::msgcat::mcset es "Common:" "Común:" ::msgcat::mcset es "Complete nickname or command" "Completar apodo o comando" ::msgcat::mcset es "Complete nickname" "Completar apodo" ::msgcat::mcset es "Composing a reply" "Escribiendo una respuesta" ::msgcat::mcset es "Compression negotiation failed" "Falló la negociación de la compresión" ::msgcat::mcset es "Compression negotiation successful" "Negociación de la compresión exitosa" ::msgcat::mcset es "Compression setup failed" "Falló la configuración de compresión" ::msgcat::mcset es "Compression" "Compresión" ::msgcat::mcset es "Condition" "Condición" ::msgcat::mcset es "Conference room %s will be destroyed permanently.\n\nProceed?" "La sala de charla %s será destruida permanentemente.\n\n¿Proceder?" ::msgcat::mcset es "Conference:" "Sala de charla" ::msgcat::mcset es "Conferences" "Conferencias" ::msgcat::mcset es "Configure form: %s" "Formulario de configuración: %s" ::msgcat::mcset es "Configure room" "Configurar sala" ::msgcat::mcset es "Configure service" "Configurar servicio" ::msgcat::mcset es "Conflict" "Conflicto" ::msgcat::mcset es "Connect via HTTP polling" "Conectar via HTTP Polling" ::msgcat::mcset es "Connect via alternate server" "Conectar a través de servidor alternativo" ::msgcat::mcset es "Connection Timeout" "Timeout en la Conexión" ::msgcat::mcset es "Connection refused by destination host" "Conexión rechazada por la máquina destinataria" ::msgcat::mcset es "Connection" "Conexión" ::msgcat::mcset es "Connection:" "Conexión:" ::msgcat::mcset es "Contact Information" "Información de contacto" ::msgcat::mcset es "Conversion is finished" "Conversión finalizada" ::msgcat::mcset es "Convert screenname" "Convertir dirección de contacto" ::msgcat::mcset es "Convert" "Convertir" ::msgcat::mcset es "Converting Log Files" "Convirtiendo ficheros de historiales de conversación" ::msgcat::mcset es "Copy JID to clipboard" "Copiar JID al portapapeles" ::msgcat::mcset es "Copy URL to clipboard" "Copiar URL al portapapeles" ::msgcat::mcset es "Copy headline to clipboard" "Copiar titular al portapapeles" ::msgcat::mcset es "Copy real JID to clipboard" "Copiar JID real al portapapeles" ::msgcat::mcset es "Copy selection to clipboard" "Copiar selección al portapapeles" ::msgcat::mcset es "Correct word" "Corregir palabra" ::msgcat::mcset es "Could not start ispell server. Check your ispell path and dictionary name. Ispell is disabled now" "No se pudo iniciar el servidor Ispell. Comprueba la ruta a Ispell y el nombre del diccionario. Ispell está desactivado ahora." ::msgcat::mcset es "Country" "País" ::msgcat::mcset es "Country:" "País:" ::msgcat::mcset es "Create node" "Crear nodo" ::msgcat::mcset es "Created: %s" "Creado: %s" ::msgcat::mcset es "Creating default privacy list failed: %s\n\nTry to reconnect. If problem persists, you may want to disable privacy list activation at start" "Ocurrió un fallo al crear una lista de privacidad: %s\n\nIntenta reconectar. Si el problema persiste, quizá quieras desactivar la activación automática de listas al conectar" ::msgcat::mcset es "Creating default privacy list" "Creando lista de privacidad inicial" ::msgcat::mcset es "Current groups" "Grupos actuales" ::msgcat::mcset es "Customization of the One True Jabber Client." "Personalización del Cliente de Jabber Verdadero." ::msgcat::mcset es "Customize" "Personalizar" ::msgcat::mcset es "Data form" "Formulario de datos" ::msgcat::mcset es "Data purported sent by %s can't be deciphered.\n\n%s." "Datos supuestamente enviados por %s no pueden ser descifrados.\n\n%s." ::msgcat::mcset es "Date:" "Fecha:" ::msgcat::mcset es "Day:" "Día:" ::msgcat::mcset es "December" "Diciembre" ::msgcat::mcset es "Decline subscription" "Declinar subscripción" ::msgcat::mcset es "Default directory for downloaded files." "Directorio por defecto para la descarga de ficheros." ::msgcat::mcset es "Default message type (if not specified explicitly)." "Tipo de mensaje por defecto (si no se especifica explícitamente)." ::msgcat::mcset es "Default nested roster group delimiter." "Delimitador de grupos anidados en la lista de contactos." ::msgcat::mcset es "Default protocol for sending files." "Protocolo de envío de ficheros por defecto." ::msgcat::mcset es "Default" "Por defecto" ::msgcat::mcset es "Delay between getting focus and updating window or tab title in milliseconds." "Retraso en milisegundos entre la recepción del foco y la actualización de la ventana o pestaña." ::msgcat::mcset es "Delete all" "Borrar todos" ::msgcat::mcset es "Delete current node and subnodes" "Borrar nodos y subnodos actuales" ::msgcat::mcset es "Delete message of the day" "Eliminar mensaje del día" ::msgcat::mcset es "Delete seen" "Borrar los leídos" ::msgcat::mcset es "Delete subnodes" "Borrar subnodos" ::msgcat::mcset es "Delete" "Eliminar" ::msgcat::mcset es "Deleted abbreviation: %s" "Borrar abreviatura: %s" ::msgcat::mcset es "Description:" "Descripción:" ::msgcat::mcset es "Destroy room" "Destruir sala" ::msgcat::mcset es "Details" "Detalles" ::msgcat::mcset es "Dir" "Dir" ::msgcat::mcset es "Directory to store logs." "Directorio donde guardar históricos." ::msgcat::mcset es "Disabled\n" "Desactivado\n" ::msgcat::mcset es "Disconnected" "Desconectado" ::msgcat::mcset es "Discovery" "Descubridor" ::msgcat::mcset es "Display %s in chat window when using /vcard command." "Mostrar %s en la ventana de charla al usar el comando /vcard." ::msgcat::mcset es "Display SSL warnings." "Mostrar advertencias respecto a SSL." ::msgcat::mcset es "Display description of user status in chat windows." "Mostrar descripción del estado del usuario en la ventana de charla." ::msgcat::mcset es "Display headlines in single/multiple windows." "Mostrar titulares en un o muchas ventanas." ::msgcat::mcset es "Display status tooltip when main window is minimized to systray." "Mostrar mensajes de estado cuando la ventana está minimizada en la bandeja de sistema." ::msgcat::mcset es "Display warning dialogs when signature verification fails." "Mostrar diálogos de aviso cuando falla la verificación de la firma." ::msgcat::mcset es "Do not display headline descriptions as tree nodes." "No mostrar descripciones de los titulares como nodos del árbol." ::msgcat::mcset es "Do not disturb" "No molestar" ::msgcat::mcset es "Do nothing" "No hacer nada" ::msgcat::mcset es "Down" "Abajo" ::msgcat::mcset es "E-mail" "Correo-e" ::msgcat::mcset es "E-mail:" "Correo-e:" ::msgcat::mcset es "Edit %s color" "Editar color %s" ::msgcat::mcset es "Edit MUC ignore rules" "Editar reglas MUC de ignorados" ::msgcat::mcset es "Edit admin list" "Editar la lista de Administradores" ::msgcat::mcset es "Edit ban list" "Editar la lista de Bloqueados" ::msgcat::mcset es "Edit chat user colors" "Editar colores de los usuarios" ::msgcat::mcset es "Edit conference list " "Editar lista de conferencia " ::msgcat::mcset es "Edit conference list" "Editar lista de conferencias" ::msgcat::mcset es "Edit entities affiliations: %s" "Editar las afiliaciones de las entidades: %s" ::msgcat::mcset es "Edit groups for %s" "Editar grupos de %s" ::msgcat::mcset es "Edit ignore list " "Editar la lista de ignorados " ::msgcat::mcset es "Edit ignore list" "Editar la lista de ignorados" ::msgcat::mcset es "Edit invisible list " "Editar lista de invisibles " ::msgcat::mcset es "Edit invisible list" "Editar la lista de invisibles" ::msgcat::mcset es "Edit item notes..." "Editar notas..." ::msgcat::mcset es "Edit item..." "Editar elemento..." ::msgcat::mcset es "Edit list" "Editar lista" ::msgcat::mcset es "Edit member list" "Editar la lista de Miembros" ::msgcat::mcset es "Edit message filters" "Editar filtros de mensajes" ::msgcat::mcset es "Edit moderator list" "Editar la lista de Moderadores" ::msgcat::mcset es "Edit my info..." "Editar mi información..." ::msgcat::mcset es "Edit nick color..." "Editar color del apodo..." ::msgcat::mcset es "Edit nick colors..." "Editar colores de los apodos..." ::msgcat::mcset es "Edit nickname for %s" "Editar apodo de %s" ::msgcat::mcset es "Edit owner list" "Editar la lista de Dueños" ::msgcat::mcset es "Edit privacy list" "Editar lista de privacidad" ::msgcat::mcset es "Edit properties for %s" "Editar propiedades de %s" ::msgcat::mcset es "Edit roster notes for %s" "Editar notas de %s" ::msgcat::mcset es "Edit rule" "Editar regla" ::msgcat::mcset es "Edit security..." "Editar seguridad..." ::msgcat::mcset es "Edit visible list" "Editando la lista de visibles" ::msgcat::mcset es "Edit voice list" "Editar la lista de Voces" ::msgcat::mcset es "Edit" "Editar" ::msgcat::mcset es "Emphasize stylecoded messages using different fonts." "Enfatizar mensajes con códigos de estilo usando diferentes fuentes." ::msgcat::mcset es "Emphasize" "Enfatizar" ::msgcat::mcset es "Empty rule name" "Nombre de la regla vacío" ::msgcat::mcset es "Enable KDE tray icon." "Usar icono en la bandeja de sistema de KDE." ::msgcat::mcset es "Enable SI transport %s." "Activar transporte SI %s." ::msgcat::mcset es "Enable announcing entity capabilities in every outgoing presence." "Anunciar en todos los mensajes de presencia enviados las capacidades de la entidad." ::msgcat::mcset es "Enable chat window autoscroll only when last message is shown." "Activar desplazamiento automático sólo cuando se ha mostrado el último mensaje." ::msgcat::mcset es "Enable freedesktop system tray icon." "Activar icono en bandeja de sistema Freedesktop" ::msgcat::mcset es "Enable freedesktop systray icon." "Activar el icono Freedesktop en la bandeja de sistema." ::msgcat::mcset es "Enable highlighting plugin." "Activar plugin de resaltado." ::msgcat::mcset es "Enable jabberd 1.4 mod_filter support (obsolete)." "Activar soporte de jabberd 1.4 mod_filter (obsoleto)." ::msgcat::mcset es "Enable nested roster groups." "Activar grupos anidados en la lista de contactos." ::msgcat::mcset es "Enable remote control." "Activar control remoto." ::msgcat::mcset es "Enable rendering of XHTML messages." "Mostrar los mensajes XHTML cuando sea posible." ::msgcat::mcset es "Enable sending chat message events." "Permitir el envío de eventos de mensaje de charla." ::msgcat::mcset es "Enable sending chat state notifications." "Permitir el envío de notificaciones de estado de la charla." ::msgcat::mcset es "Enable spellchecker in text input windows." "Activar corrector ortográfico en las ventanas de introducción de texto." ::msgcat::mcset es "Enable windows tray icon." "Activar icono en la bandeja de sistema." ::msgcat::mcset es "Enabled\n" "Activado\n" ::msgcat::mcset es "Encrypt traffic (when possible)" "Cifrar tráfico (cuando sea posible)" ::msgcat::mcset es "Encrypt traffic" "Cifrar tráfico" ::msgcat::mcset es "Encryption (STARTTLS)" "Cifrado (STARTTLS)" ::msgcat::mcset es "Encryption (legacy SSL)" "Cifrado (SSL antiguo)" ::msgcat::mcset es "Encryption" "Cifrado" ::msgcat::mcset es "Enter screenname of contact you want to add" "Introduce no dirección del usuario que quieres añadir" ::msgcat::mcset es "Error %s" "Error %s" ::msgcat::mcset es "Error completing command: %s" "Error completando el comando: %s" ::msgcat::mcset es "Error displaying %s in browser\n\n%s" "Error mostrando %s en el navegador\n\n%s" ::msgcat::mcset es "Error executing command: %s" "Error ejecutando el comando: %s" ::msgcat::mcset es "Error getting info: %s" "Error consiguiendo información: %s" ::msgcat::mcset es "Error getting items: %s" "Error obteniendo elementos: %s" ::msgcat::mcset es "Error in signature processing" "Error en el procesado de la firma" ::msgcat::mcset es "Error in signature verification software: %s." "Error en el software de verificación de firma: %s." ::msgcat::mcset es "Error loading MUC ignore rules, purged." "Ocurrió un error al cargar las reglas MUC de ignorados, purgado." ::msgcat::mcset es "Error negotiate: %s" "Error negociando: %s" ::msgcat::mcset es "Error requesting data: %s" "Error pidiendo datos: %s" ::msgcat::mcset es "Error restoring annotations: %s" "Error restaurando las anotaciones: %s" ::msgcat::mcset es "Error restoring conference bookmarks: %s" "Error restaurando marcadores de conferencias: %s" ::msgcat::mcset es "Error restoring roster contacts: %s" "Error restaurando la lista de contactos: %s" ::msgcat::mcset es "Error while converting screenname: %s." "Error al convertir la dirección de contacto: %s." ::msgcat::mcset es "Error" "Error" ::msgcat::mcset es "Error:" "Error:" ::msgcat::mcset es "Execute command" "Ejecutar comando" ::msgcat::mcset es "Expiry date" "Fecha de expiración" ::msgcat::mcset es "Explicitly specify host and port to connect" "Especificar explícitamente máquina y puerto a la que conectar" ::msgcat::mcset es "Export roster..." "Exportar lista de contactos..." ::msgcat::mcset es "Export to XHTML" "Exportar a XHTML" ::msgcat::mcset es "Extended addressing fields:" "Campos de direccionamiento extendido:" ::msgcat::mcset es "Extended away" "Muy ausente" ::msgcat::mcset es "External program, which is to be executed to play sound. If empty, Snack library is used (if available) to play sound." "Programa externo que se ejecutará para reproducir el sonido. Si se deja vacío, se usará la libreria Snack si está disponible." ::msgcat::mcset es "Extras from %s" "Extras de %s" ::msgcat::mcset es "Extras from:" "Extras de:" ::msgcat::mcset es "Failed to connect: %s" "Falló al conectar: %s" ::msgcat::mcset es "Family Name" "Apellido" ::msgcat::mcset es "Family Name:" "Apellido:" ::msgcat::mcset es "Fax:" "Fax:" ::msgcat::mcset es "Feature Not Implemented" "Característica no implementada" ::msgcat::mcset es "February" "Febrero" ::msgcat::mcset es "Fetch GPG key" "Conseguir clave GPG" ::msgcat::mcset es "Fetch all messages" "Recuperar todos los mensajes" ::msgcat::mcset es "Fetch message" "Recuperar mensaje" ::msgcat::mcset es "Fetch nickname" "Averiguar apodo" ::msgcat::mcset es "Fetch nicknames of all users in group" "Averiguar apodos de todos los usuarios en el grupo" ::msgcat::mcset es "Fetch unseen messages" "Recuperar mensajes no vistos" ::msgcat::mcset es "Fetch user nicknames" "Averiguar apodos de usuario" ::msgcat::mcset es "File %s cannot be opened: %s. History for %s (%s) is NOT converted\n" "No se pudo abrir el fichero %s: %s. El historial de %s (%s) NO se convirtió\n" ::msgcat::mcset es "File %s cannot be opened: %s. History for %s is NOT converted\n" "No se pudo abrir el fichero %s: %s. El historial de %s NO se convirtió\n" ::msgcat::mcset es "File %s is corrupt. History for %s (%s) is NOT converted\n" "El fichero %s está corrupto. El historial de %s (%s) NO se ha convertido\n" ::msgcat::mcset es "File %s is corrupt. History for %s is NOT converted\n" "El fichero %s está corrupto. El historial de %s NO se ha convertido\n" ::msgcat::mcset es "File Transfer options." "Opciones de transferencia de ficheros." ::msgcat::mcset es "File path:" "Ruta al fichero:" ::msgcat::mcset es "File transfer aborted" "Transferencia de ficheros abortada" ::msgcat::mcset es "Filters" "Filtros" ::msgcat::mcset es "Finish" "Terminar" ::msgcat::mcset es "First Name:" "Nombre:" ::msgcat::mcset es "Floor:" "Planta:" ::msgcat::mcset es "Font to use in chat windows." "Fuente a usar en las ventanas de charla." ::msgcat::mcset es "Font to use in roster windows." "Fuente a usar en la lista de contactos." ::msgcat::mcset es "Forbidden" "Prohibido" ::msgcat::mcset es "Force advertising this hostname (or IP address) for outgoing HTTP file transfers." "Forzar indicación del nombre de la máquina (o dirección IP) en las transferencias de fichero HTTP salientes." ::msgcat::mcset es "Format Error" "Error de formato" ::msgcat::mcset es "Format of timestamp in chat message. Refer to Tcl documentation of 'clock' command for description of format.\n\nExamples:\n \[%R\] - \[20:37\]\n \[%T\] - \[20:37:12\]\n \[%a %b %d %H:%M:%S %Z %Y\] - \[Thu Jan 01 03:00:00 MSK 1970\]" "Formatio de la fecha en un mensaje de charla. Consulta la documentación de Tcl sobre el comando 'clock' para obtener detalles del formato.\n\nEjemplos:\n \[%R\] - \[20:37\]\n \[%T\] - \[20:37:12\]\n \[%a %b %d %H:%M:%S %Z %Y\] - \[Thu Jan 01 03:00:00 MSK 1970\]" ::msgcat::mcset es "Format of timestamp in delayed chat messages delayed for more than 24 hours." "Formato de los tiempos en mensajes de charla retrasados por más de 24 horas." ::msgcat::mcset es "Format of timestamp in headline tree view. Set to empty string if you don't want to see timestamps." "Formato de fecha en la vista de árbol de los titulares. Si no quieres ver la fecha déjalo vacío." ::msgcat::mcset es "Forward headline" "Reenviar titular" ::msgcat::mcset es "Forward to %s" "Reenviar a %s" ::msgcat::mcset es "Forward..." "Reenviar..." ::msgcat::mcset es "Forwarded by:" "Reenviado por:" ::msgcat::mcset es "Free to chat" "Disponible para charlar" ::msgcat::mcset es "From/To" "De/Para" ::msgcat::mcset es "From: " "De: " ::msgcat::mcset es "From:" "De:" ::msgcat::mcset es "Full Name" "Nombre completo" ::msgcat::mcset es "Full Name:" "Nombre completo:" ::msgcat::mcset es "Full-text search" "Búsqueda de texto completo" ::msgcat::mcset es "GIF images" "GIF" ::msgcat::mcset es "GPG options (signing and encryption)." "Opciones de GPG (firma y cifrado)." ::msgcat::mcset es "GPG-encrypt outgoing messages where possible." "Cifrar con GPG los mensajes salientes siempre que sea posible." ::msgcat::mcset es "GPG-sign outgoing messages and presence updates." "Firmar con GPG los mensajes y presencias salientes." ::msgcat::mcset es "GPS datum:" "GPS datum:" ::msgcat::mcset es "Generate chat messages when chat peer changes his/her status and/or status message" "Generar mensajes de charla cuando el contacto cambia su estado o su mensaje de estado" ::msgcat::mcset es "Generate enter/exit messages" "Generar mensajes de entrada/salida" ::msgcat::mcset es "Generate groupchat messages when occupant changes his/her status and/or status message." "Generar mensajes de sala cuando un ocupante cambia su estado o su mensaje de estado." ::msgcat::mcset es "Generate groupchat messages when occupant's room position (affiliation and/or role) changes." "Generar mensaje de estado cuando cambia la posición de un ocupante (afiliación o rol)." ::msgcat::mcset es "Generate status messages when occupants enter/exit MUC compatible conference rooms." "Generar mensajes de estado cuando los ocupantes entran o salen de las salas de charla MUC." ::msgcat::mcset es "Generic IQ" "IQ genérico" ::msgcat::mcset es "Geographical position" "Posición geográfica" ::msgcat::mcset es "Get items" "Coger elementos" ::msgcat::mcset es "Gone" "Ido" ::msgcat::mcset es "Google selection" "Selección Google" ::msgcat::mcset es "Got roster" "Se consiguió la lista de contactos" ::msgcat::mcset es "Grant Admin Privileges" "Conceder privilegios de Administrador" ::msgcat::mcset es "Grant Membership" "Conceder Membresía" ::msgcat::mcset es "Grant Moderator Privileges" "Conceder privilegios de Moderador" ::msgcat::mcset es "Grant Owner Privileges" "Conceder privilegios de Dueño" ::msgcat::mcset es "Grant Voice" "Conceder Voz" ::msgcat::mcset es "Grant subscription" "Conceder subscripción" ::msgcat::mcset es "Group: " "Grupo: " ::msgcat::mcset es "Group:" "Grupo:" ::msgcat::mcset es "Groupchat message highlighting plugin options." "Opciones del plugin de resaltado de mensajes en salas de charla." ::msgcat::mcset es "HTTP Poll" ::msgcat::mcset es "HTTP options." "Opciones HTTP." ::msgcat::mcset es "HTTP proxy address." "Dirección del proxy HTTP." ::msgcat::mcset es "HTTP proxy password." "Contraseña del proxy HTTP." ::msgcat::mcset es "HTTP proxy port." "Puerto del proxy HTTP." ::msgcat::mcset es "HTTP proxy username." "Usuario del proxy HTTP." ::msgcat::mcset es "HTTPS" "HTTPS" ::msgcat::mcset es "Handle ROTFL/LOL smileys -- those like :))) -- by \"consuming\" all that parens and rendering the whole word with appropriate icon." "Manejar sonrisas ROTFL/LOL -- como estas :))) -- \"consumiendo\" todos los paréntesis y mostrando toda la palabra con el icono apropiado." ::msgcat::mcset es "Handling of \"emoticons\". Emoticons (also known as \"smileys\") are small pictures resembling a human face used to represent user's emotion. They are typed in as special mnemonics like :) or can be inserted using menu." "Manejo de\"emoticonos\". Emoticonos (también conocidos como \"smileys\") son pequeñas imágenes que parecen una cara humana y se usan para representar la emoción del usuario. Pueden insertar usando caracteres mnemónicos como :) o usando un menu." ::msgcat::mcset es "Handling of \"stylecodes\". Stylecodes are (groups of) special formatting symbols used to emphasize parts of the text by setting them with boldface, italics or underlined styles, or as combinations of these." "Manejo de \"códigos de estilo\". Son (grupos de) símbolos de formato especiales usados para enfatizar partes del texto, poniéndolo en negrita, itálica o subrayado, o una combinación de éstos." ::msgcat::mcset es "Handshake failed" "Handshake falló" ::msgcat::mcset es "Handshake successful" "Handshake exitoso" ::msgcat::mcset es "Headline message" "Mensaje de titular" ::msgcat::mcset es "Headlines" "Titulares" ::msgcat::mcset es "Help" "Ayuda" ::msgcat::mcset es "Hide characters comprising stylecode markup." "Esconder caracteres que correspondan a formato de texto." ::msgcat::mcset es "Hide main window" "Esconder ventana principal" ::msgcat::mcset es "Hide/Show roster" "Ocultar/mostrar lista de contactos" ::msgcat::mcset es "Highlight current nickname in messages." "Resaltar en los mensajes tu apodo actual." ::msgcat::mcset es "Highlight only whole words in messages." "Resaltar solo palabras completas en los mensajes." ::msgcat::mcset es "History for %s" "Historial de %s" ::msgcat::mcset es "History of availability status messages" "Historial de mensajes de estado de disponibilidad" ::msgcat::mcset es "Home:" "Casa:" ::msgcat::mcset es "Horizontal GPS error:" "Error de GPS horizontal:" ::msgcat::mcset es "Host Gone" "Host No Disponible" ::msgcat::mcset es "Host Unknown" "Host Desconocido" ::msgcat::mcset es "Host unreachable" "Máquina inlocalizable" ::msgcat::mcset es "Host:" "Máquina:" ::msgcat::mcset es "I would like to add you to my roster." "Me gustaría añadirte a mi lista de contactos." ::msgcat::mcset es "I'm not online" "No estoy conectado" ::msgcat::mcset es "IP address:" "Dirección IP:" ::msgcat::mcset es "IQ" "IQ" ::msgcat::mcset es "ISDN:" "RDSI:" ::msgcat::mcset es "Iconize" "Iconizar" ::msgcat::mcset es "Idle for %s" "Inactivo durante %s" ::msgcat::mcset es "Idle threshold in minutes after that Tkabber marks you as away." "Intervalo de inactividad tras el cual Tkabber te cambia a 'ausente'" ::msgcat::mcset es "Idle threshold in minutes after that Tkabber marks you as extended away." "Intervalo de inactividad tras el cual Tkabber te cambia a 'muy ausente'." ::msgcat::mcset es "If set then open chat window/tab when user doubleclicks roster item. Otherwise open normal message window." "Si está activado, cuando se pulse dos veces con el ratón sobre un contacto, se abrirá una ventana o pestaña de charla. Si no, se abrirá una ventana de mensaje normal." ::msgcat::mcset es "Ignore chat messages" "Ignorar mensajes de charla" ::msgcat::mcset es "Ignore groupchat messages" "Ignorar mensajes de charla de grupo" ::msgcat::mcset es "Ignore list" "Lista de ignorados" ::msgcat::mcset es "Ignore" "Ignorar" ::msgcat::mcset es "Ignoring groupchat and chat messages from selected occupants of multi-user conference rooms." "Ignorando mensajes de charla y mensajes de charla en grupo de los ocupantes seleccionados en las salas de charla." ::msgcat::mcset es "Illegal result" "Resultado ilegal" ::msgcat::mcset es "Image" "Imagen" ::msgcat::mcset es "Import roster..." "Importar lista de contactos..." ::msgcat::mcset es "Improper Addressing" "Dirección Incorrecta" ::msgcat::mcset es "Include operating system info into a reply to version (jabber:iq:version) requests." "Incluir información sobre tu sistema operativo en las respuestas a peticiones jabber:iq:version." ::msgcat::mcset es "Incorrect SOCKS version" "Versión incorrecta de SOCKS" ::msgcat::mcset es "Incorrect encoding" "Codificación incorrecta" ::msgcat::mcset es "Indentation for pretty-printed XML subtags." "Indentar las marcas XML en la versión en bonito." ::msgcat::mcset es "Info/Query options." "Opciones Info/Query." ::msgcat::mcset es "Info:" "Info:" ::msgcat::mcset es "Information" "Información" ::msgcat::mcset es "Instructions" "Instrucciones" ::msgcat::mcset es "Internal Server Error" "Error interno del servidor" ::msgcat::mcset es "Interval (in minutes) after error reply on request of participants list." "Intervalo (en minutos) si la respuesta a una petición de lista de participantes da error." ::msgcat::mcset es "Interval (in minutes) between requests of participants list." "Intervalo (en minutos) entre peticiones de la lista de participantes." ::msgcat::mcset es "Interval:" "Intervalo:" ::msgcat::mcset es "Invalid From" "Remitente Inválido" ::msgcat::mcset es "Invalid ID" "ID Inválido" ::msgcat::mcset es "Invalid Namespace" "Espacio de Nombres Inválido" ::msgcat::mcset es "Invalid XML" "XML Inválido" ::msgcat::mcset es "Invalid authzid" "Authzid incorrecta" ::msgcat::mcset es "Invalid mechanism" "Mecanismo incorrecto" ::msgcat::mcset es "Invalid signature" "Firma inválida" ::msgcat::mcset es "Invisible list" "Lista de invisibles" ::msgcat::mcset es "Invisible" "Invisible" ::msgcat::mcset es "Invite %s to conferences" "Invitar a %s a charla en grupo" ::msgcat::mcset es "Invite to conference..." "Invitar a charlar en grupo..." ::msgcat::mcset es "Invite users to %s" "Invitar usuarios a la sala %s" ::msgcat::mcset es "Invite users..." "Invitar usuarios..." ::msgcat::mcset es "Invite" " Invitar " ::msgcat::mcset es "Invited to:" "Invitado a:" ::msgcat::mcset es "Ispell dictionary encoding. If it is empty, system encoding is used." "Codificación del diccionario Ispell. Si está vacío se utilizará la codificación del sistema." ::msgcat::mcset es "Ispell options. See ispell manual for details.\n\nExamples:\n -d russian\n -d german -T latin1\n -C -d english" "Opciones de Ispell. Consulta el manual de Ispell para más detalles.\n\nEjemplos:\n -d russian\n -d german -T latin1\n -C -d english" ::msgcat::mcset es "Issuer" "Emisor" ::msgcat::mcset es "Item Not Found" "Elemento no encontrado" ::msgcat::mcset es "JID Malformed" "JID mal formado" ::msgcat::mcset es "JID list" "Lista de JID" ::msgcat::mcset es "JID regexp:" "JID regexp:" ::msgcat::mcset es "JID" "JID" ::msgcat::mcset es "JID:" "JID:" ::msgcat::mcset es "JPEG images" "JPEG" ::msgcat::mcset es "Jabber ID" "Jabber ID" ::msgcat::mcset es "January" "Enero" ::msgcat::mcset es "Join conference" "Unirse a la conferencia" ::msgcat::mcset es "Join group dialog data (groups)." "Datos del diálogo de entrada en sala (grupos)." ::msgcat::mcset es "Join group dialog data (nicks)." "Datos del diálogo de entrada en sala (apodos)." ::msgcat::mcset es "Join group dialog data (servers)." "Datos del diálogo de entrada en sala (servidores)." ::msgcat::mcset es "Join group" "Entrar en grupo" ::msgcat::mcset es "Join group..." "Entrar en grupo..." ::msgcat::mcset es "Join groupchat" "Unirse a la sala de charla" ::msgcat::mcset es "Join" "Entrar" ::msgcat::mcset es "Join..." "Entrar..." ::msgcat::mcset es "July" "Julio" ::msgcat::mcset es "June" "Junio" ::msgcat::mcset es "Keep trying" "Seguir intentándolo" ::msgcat::mcset es "Key ID" "ID de la llave" ::msgcat::mcset es "Key:" "Llave:" ::msgcat::mcset es "Kick" "Expulsar" ::msgcat::mcset es "Konstantin Khomoutov" "Konstantin Khomoutov" ::msgcat::mcset es "Last Activity or Uptime" "Última actividad o tiempo en marcha" ::msgcat::mcset es "Last Name:" "Apellido:" ::msgcat::mcset es "Last activity" "Última actividad" ::msgcat::mcset es "Latitude" "Latitud" ::msgcat::mcset es "Latitude:" "Latitud:" ::msgcat::mcset es "Left mouse button" "Botón izquierdo del ratón" ::msgcat::mcset es "Left" "Izquierda" ::msgcat::mcset es "Length:" "Duración:" ::msgcat::mcset es "List name" "Listar nombre" ::msgcat::mcset es "List of JIDs to whom headlines have been sent." "Lista de JID a los que se ha enviado titulares de noticia." ::msgcat::mcset es "List of discovered JID nodes." "Lista de nodos JID descubiertos." ::msgcat::mcset es "List of discovered JIDs." "Lista de JIDs descubiertos." ::msgcat::mcset es "List of logout reasons." "Lista de razones de cierre de sesión." ::msgcat::mcset es "List of message destination JIDs." "Lista de los JID destinatarios." ::msgcat::mcset es "List of proxy servers for SOCKS5 bytestreams (all available servers will be tried for mediated connection)." "Lista de servidores proxy para SOCKS5 bytestreams (todos los servidores disponibles serán probados para una conexión mediada)." ::msgcat::mcset es "List of users for chat." "Lista de usuarios para la charla." ::msgcat::mcset es "List of users for userinfo." "Lista de usuarios para userinfo." ::msgcat::mcset es "Load Image" "Cargar imagen" ::msgcat::mcset es "Load state on Tkabber start." "Cargar estado en el inicio de Tkabber." ::msgcat::mcset es "Load state on start" "Cargar estado al inicio" ::msgcat::mcset es "Loading photo failed: %s." "No se pudo cargar la imagen: %s." ::msgcat::mcset es "Locality:" "Localidad:" ::msgcat::mcset es "Location" "Lugar" ::msgcat::mcset es "Log in" " Iniciar " ::msgcat::mcset es "Log in..." "Iniciar sesión..." ::msgcat::mcset es "Log out with reason..." "Cerrar sesión con razón..." ::msgcat::mcset es "Log out" "Cerrar sesión" ::msgcat::mcset es "Logging options." "Opciones de registro de mensajes." ::msgcat::mcset es "Login options." "Opciones de inicio de sesión." ::msgcat::mcset es "Login" " Iniciar " ::msgcat::mcset es "Logout with reason" "Cerrar sesión con razón" ::msgcat::mcset es "Logout" "Cerrar sesión" ::msgcat::mcset es "Logs" "Historiales" ::msgcat::mcset es "Longitude" "Longitud" ::msgcat::mcset es "Longitude:" "Longitud:" ::msgcat::mcset es "MUC Ignore Rules" "Reglas de ignorar en MUC" ::msgcat::mcset es "MUC Ignore" "Ignorar en MUC" ::msgcat::mcset es "MUC" "MUC" ::msgcat::mcset es "Main window:" "Ventana principal:" ::msgcat::mcset es "Malformed signature block" "Bloque de firma mal formado" ::msgcat::mcset es "Manually edit rules" "Editar reglas manualmente" ::msgcat::mcset es "March" "Marzo" ::msgcat::mcset es "Mark all seen" "Marcar todos como leídos" ::msgcat::mcset es "Mark all unseen" "Marcar todos como no leídos" ::msgcat::mcset es "Marshall T. Rose" "Marshall T. Rose" ::msgcat::mcset es "Match case while searching in chat, log or disco windows." "Hacer coincidencia mayúsculas/minúsculas al buscar." ::msgcat::mcset es "Match contact JIDs in addition to nicknames in roster filter." "Concordar en el filtro de contactos no solo apodos, sino también direcciones Jabber (JID)." ::msgcat::mcset es "Maximum interval length in hours for which log messages should be shown in newly opened chat window (if set to negative then the interval is unlimited)." "Máxima longitud de intervalo en horas para el cual los mensajes del historial deberían mostrarse cuando se abre una nueva ventana de charla (si es negativo el intervalo será ilimitado)." ::msgcat::mcset es "Maximum number of characters in the history in MUC compatible conference rooms." "Máximo número de caracteres en el historial de las salas de charla MUC." ::msgcat::mcset es "Maximum number of log messages to show in newly opened chat window (if set to negative then the number is unlimited)." "Máximo número de mensajes de historial a mostrar en una ventana de charla nueva (si es negativo el intervalo será ilimitado)." ::msgcat::mcset es "Maximum number of stanzas in the history in MUC compatible conference rooms." "Máximo número de mensajes en el historial de las salas de charla MUC." ::msgcat::mcset es "Maximum number of status messages to keep. If the history size reaches this threshold, the oldest message will be deleted automatically when a new one is recorded." "Número máximo de mensajes de estado a mantener. Si el tamaño del historial excede este umbral, los mensajes antiguos se irán borrandp automáticamente según se vayan guardando mensajes nuevos." ::msgcat::mcset es "Maximum poll interval." "Intervalo máximo de Poll." ::msgcat::mcset es "Maximum width of tab buttons in tabbed mode." "Ancho máximo de los botones de pestaña en el modo de pestañas." ::msgcat::mcset es "May" "Mayo" ::msgcat::mcset es "Mechanism too weak" "Mecanismo demasiado débil" ::msgcat::mcset es "Message Recorder:" "Contestador:" ::msgcat::mcset es "Message and Headline options." "Opciones de Mensaje y Titulares." ::msgcat::mcset es "Message archive" "Archivo de mensajes" ::msgcat::mcset es "Message body" "Cuerpo del mensaje" ::msgcat::mcset es "Message delivered to %s" "Mensaje entregado a %s" ::msgcat::mcset es "Message delivered" "Mensaje entregado" ::msgcat::mcset es "Message displayed to %s" "Mensaje mostrado a %s" ::msgcat::mcset es "Message displayed" "Mensaje mostrado" ::msgcat::mcset es "Message from %s" "Mensaje de %s" ::msgcat::mcset es "Message from:" "Mensaje de:" ::msgcat::mcset es "Message stored on %s's server" "Mensaje guardado en el servidor de %s" ::msgcat::mcset es "Message stored on the server" "Mensaje guardado en el servidor" ::msgcat::mcset es "Message" "Mensaje" ::msgcat::mcset es "Messages" "Mensajes" ::msgcat::mcset es "Michail Litvak" "Michail Litvak" ::msgcat::mcset es "Middle Name" "Segundo nombre" ::msgcat::mcset es "Middle Name:" "Segundo nombre:" ::msgcat::mcset es "Middle mouse button" "Botón central del ratón" ::msgcat::mcset es "Minimize to systray (if systray icon is enabled, otherwise do nothing)" "Minimizar a la bandeja del sistema (si esto es posible, en otro caso no hacer nada)" ::msgcat::mcset es "Minimize" "Minimizar" ::msgcat::mcset es "Minimum poll interval." "Intervalo mínimo de Poll." ::msgcat::mcset es "Minimum width of tab buttons in tabbed mode." "Ancho mínimo de los botones de pestaña en el modo de pestañas." ::msgcat::mcset es "Misc:" "Misc:" ::msgcat::mcset es "Modem:" "Modem:" ::msgcat::mcset es "Moderators" "Moderadores" ::msgcat::mcset es "Modified: %s" "Modificado: %s" ::msgcat::mcset es "Month:" "Mes:" ::msgcat::mcset es "Mood" "Estado de ánimo" ::msgcat::mcset es "Mood:" "Estado de ánimo:" ::msgcat::mcset es "Move down" "Desplazar abajo" ::msgcat::mcset es "Move tab left/right" "Mover pestaña a izquierda/derecha" ::msgcat::mcset es "Move up" "Desplazar arriba" ::msgcat::mcset es "Moving to extended away" "Pasando a muy ausente" ::msgcat::mcset es "Multiple signatures having different authenticity" "Múltiples firmas con diferentes autenticidades" ::msgcat::mcset es "Mute sound if Tkabber window is focused." "Enmudecer el sonido si la ventana de Tkabber tiene el foco." ::msgcat::mcset es "Mute sound notification." "Enmudecer la notificación sonora." ::msgcat::mcset es "Mute sound when displaying delayed groupchat messages." "Enmudecer el sonido de mensajes de charla en grupo con retraso." ::msgcat::mcset es "Mute sound when displaying delayed personal chat messages." "Enmudecer el sonido de mensajes de charla privada con retraso." ::msgcat::mcset es "Mute sound" "Desactivar sonidos" ::msgcat::mcset es "My Resources" "Mis Recursos" ::msgcat::mcset es "Name " "Nombre " ::msgcat::mcset es "Name" "Nombre" ::msgcat::mcset es "Name: " "Nombre: " ::msgcat::mcset es "Name:" "Nombre:" ::msgcat::mcset es "Network failure" "Fallo en la red" ::msgcat::mcset es "Network unreachable" "Red inlocalizable" ::msgcat::mcset es "New group name:" "Nuevo nombre del grupo:" ::msgcat::mcset es "New password:" "Contraseña nueva:" ::msgcat::mcset es "New passwords do not match" "Las contraseñas nuevas no coinciden" ::msgcat::mcset es "Next bookmark" "Marcador siguiente" ::msgcat::mcset es "Next highlighted" "Siguiente resaltado" ::msgcat::mcset es "Next" "Sigu" ::msgcat::mcset es "Nick" "Apodo" ::msgcat::mcset es "Nick:" "Apodo:" ::msgcat::mcset es "Nickname" "Apodo" ::msgcat::mcset es "Nickname:" "Apodo:" ::msgcat::mcset es "No active list" "No hay lista activa" ::msgcat::mcset es "No avatar to store" "No hay avatar para guardar" ::msgcat::mcset es "No conferences for %s in progress..." "No hay conferencias para %s actualmente..." ::msgcat::mcset es "No default list" "No hay lista por defecto" ::msgcat::mcset es "No information available" "No hay información disponible" ::msgcat::mcset es "No reply" "No responder" ::msgcat::mcset es "No such abbreviation: %s" "No existe esa abreviatura: %s" ::msgcat::mcset es "No users in %s roster..." "No hay usuarios en la lista de contactos de %s..." ::msgcat::mcset es "No users in roster..." "No hay usuarios en la lista..." ::msgcat::mcset es "Node" "Nodo" ::msgcat::mcset es "Node:" "Nodo:" ::msgcat::mcset es "None" "Ninguna" ::msgcat::mcset es "Normal message" "Mensaje normal" ::msgcat::mcset es "Normal" "Normal" ::msgcat::mcset es "Not Acceptable" "No aceptable" ::msgcat::mcset es "Not Allowed" "No permitido" ::msgcat::mcset es "Not Authorized" "No autorizado" ::msgcat::mcset es "Not Found" "No encontrado" ::msgcat::mcset es "Not Implemented" "No implementado" ::msgcat::mcset es "Not connected" "No conectado" ::msgcat::mcset es "Not logged in" "No conectado" ::msgcat::mcset es "Notes" "Notas" ::msgcat::mcset es "Notify only when available" "Notificar solo cuando estoy disponible" ::msgcat::mcset es "November" "Noviembre" ::msgcat::mcset es "Number of HTTP poll client security keys to send before creating new key sequence." "Número de claves de seguridad del cliente de HTTP Poll que se envían antes de crear una nueva secuencia de clave." ::msgcat::mcset es "Number of groupchat messages to expire nick completion according to the last personally addressed message." "Número de mensajes en la sala de charla desde que un participante salió a partir del cual ya no se completa su apodo." ::msgcat::mcset es "OK" " Aceptar " ::msgcat::mcset es "OS:" "SO:" ::msgcat::mcset es "October" "Octubre" ::msgcat::mcset es "Offline Messages" "Mensajes diferidos" ::msgcat::mcset es "Old password is incorrect" "La contraseña antigua es incorrecta" ::msgcat::mcset es "Old password:" "Contraseña antigua:" ::msgcat::mcset es "One window per bare JID" "Una ventana por JID simple" ::msgcat::mcset es "One window per full JID" "Una ventana por JID completo" ::msgcat::mcset es "Open chat" "Abrir charla" ::msgcat::mcset es "Open chat..." "Abrir charla..." ::msgcat::mcset es "Open new conversation" "Abrir nueva conversación" ::msgcat::mcset es "Open raw XML window" "Abrir ventana de XML crudo" ::msgcat::mcset es "Open statistics monitor" "Abrir monitor de estadísticas" ::msgcat::mcset es "Open" "Abrir" ::msgcat::mcset es "Opening IBB connection" "Abriendo conexión IBB" ::msgcat::mcset es "Opening IQ-IBB connection" "Abrir conexión IQ-IBB" ::msgcat::mcset es "Opening SI connection" "Abriendo conexión SI" ::msgcat::mcset es "Opening SOCKS5 listening socket" "Abriendo socket de escucha SOCKS5" ::msgcat::mcset es "Opens a new chat window for the new nick of the room occupant" "Abre una nueva ventana de charla para el nuevo apodo del ocupante de la sala" ::msgcat::mcset es "Options for Conference Info module, that allows you to see list of participants in roster popup, regardless of whether you are currently joined with the conference." "Opciones para el módulo 'Información de Conferencias', que te permite ver la lista de participantes en las salas de conferencia de tu lista de contactos con un popup, sin necesidad de que participes ellas." ::msgcat::mcset es "Options for Raw XML Input module, which allows you to monitor incoming/outgoing traffic from connection to server and send custom XML stanzas." "Opciones para el módulo 'XML Crudo', que te permite monitorizar tráfico de entrada/salida en la conexión con el servidor y enviar tus propios mensajes XML." ::msgcat::mcset es "Options for entity capabilities plugin." "Opciones del plugin de capacidades de entidad." ::msgcat::mcset es "Options for external play program" "Opciones para el programa de reproducción externo" ::msgcat::mcset es "Options for main interface." "Opciones del interfaz principal." ::msgcat::mcset es "Options for module that automatically marks you as away after idle threshold." "Opciones del módulo 'Autoausencia', que te cambia a 'ausente' automáticamente después de un tiempo de inactividad." ::msgcat::mcset es "Organization Name" "Nombre de la organización" ::msgcat::mcset es "Organization Unit" "Unidad de la organización" ::msgcat::mcset es "Organization" "Organización" ::msgcat::mcset es "Original from" "Original de" ::msgcat::mcset es "Original to" "Original para" ::msgcat::mcset es "Outcast" "Bloquear" ::msgcat::mcset es "Owner" "Propietario" ::msgcat::mcset es "PCS:" ::msgcat::mcset es "PNG images" "PNG" ::msgcat::mcset es "Pager:" "Busca:" ::msgcat::mcset es "Parent group" "Grupo padre" ::msgcat::mcset es "Parent groups" "Grupos padres" ::msgcat::mcset es "Participants" "Participantes" ::msgcat::mcset es "Passphrase:" "Frase de clave:" ::msgcat::mcset es "Password change failed: %s" "Falló el cambio de contraseña: %s" ::msgcat::mcset es "Password is changed" "Contraseña cambiada" ::msgcat::mcset es "Password." "Contraseña." ::msgcat::mcset es "Password:" "Contraseña:" ::msgcat::mcset es "Path to the ispell executable." "Ruta para el ejecutable de Ispell." ::msgcat::mcset es "Paused a reply" "Se pausó una respuesta" ::msgcat::mcset es "Payment Required" "Se requiere pago" ::msgcat::mcset es "Pending" "Pendiente" ::msgcat::mcset es "Periodically browse roster conferences" "Inspeccionar periódicamente salas de charla de la lista" ::msgcat::mcset es "Personal " "Personal " ::msgcat::mcset es "Personal eventing via pubsub plugins options." "Opciones de Eventos Personales via PubSub (PEP)." ::msgcat::mcset es "Personal eventing" "Eventos personales" ::msgcat::mcset es "Personal" "Personal" ::msgcat::mcset es "Phone BBS" "Teléfono BBS" ::msgcat::mcset es "Phone Cell" "Teléfono móvil" ::msgcat::mcset es "Phone Fax" "Número de Fax" ::msgcat::mcset es "Phone Home" "Teléfono de casa" ::msgcat::mcset es "Phone ISDN" "Teléfono ISDN" ::msgcat::mcset es "Phone Message Recorder" "Teléfono del grabador de mensajes" ::msgcat::mcset es "Phone Modem" "Teléfono del módem" ::msgcat::mcset es "Phone PCS" "Teléfono PCS" ::msgcat::mcset es "Phone Pager" "Teléfono Pager" ::msgcat::mcset es "Phone Preferred" "Teléfono preferido" ::msgcat::mcset es "Phone Video" "Teléfono video" ::msgcat::mcset es "Phone Voice" "Teléfono de voz" ::msgcat::mcset es "Phone Work" "Teléfono del trabajo" ::msgcat::mcset es "Phone:" "Teléfono:" ::msgcat::mcset es "Phones" "Teléfonos" ::msgcat::mcset es "Photo" "Foto" ::msgcat::mcset es "Ping server using urn:xmpp:ping requests." "Hacer Ping al servidor usando peticiones urn:xmpp:ping." ::msgcat::mcset es "Plaintext" "Texto plano" ::msgcat::mcset es "Please define environment variable BROWSER" "Por favor define la variable de entorno BROWSER" ::msgcat::mcset es "Please enter passphrase" "Por favor, introduce la frase clave" ::msgcat::mcset es "Please join %s" "Por favor, entra en %s" ::msgcat::mcset es "Please try again" "Por favor, vuélvelo a intentar" ::msgcat::mcset es "Please, be patient while Tkabber configuration directory is being transferred to the new location" "Por favor, se paciente mientras el directorio de configuración de Tkabber se transfiere a la nueva localización" ::msgcat::mcset es "Please, be patient while chats history is being converted to new format" "Por favor, se paciente mientras los historiales de conversaciones son convertidos al nuevo formato" ::msgcat::mcset es "Plugins options." "Opciones de plugins." ::msgcat::mcset es "Plugins" "Plugins" ::msgcat::mcset es "Policy Violation" "Violación de la Política" ::msgcat::mcset es "Popup menu" "Menú emergente" ::msgcat::mcset es "Port for outgoing HTTP file transfers (0 for assigned automatically). This is useful when sending files from behind a NAT with a forwarded port." "Puerto para las transferencias de fichero HTTP salientes (0 para asignarlo automáticamente). Esto es útil cuando se envían ficheros desde de detrás de una NAT con una redirección de puerto." ::msgcat::mcset es "Port:" "Puerto:" ::msgcat::mcset es "Postal Code" "Código Postal" ::msgcat::mcset es "Postal Code:" "Código Postal:" ::msgcat::mcset es "Postal code:" "Código Postal:" ::msgcat::mcset es "Preferred:" "Preferido:" ::msgcat::mcset es "Prefix" "Prefijo" ::msgcat::mcset es "Prefix:" "Prefijo:" ::msgcat::mcset es "Presence bar" "Barra de presencia" ::msgcat::mcset es "Presence information" "Información de presencia" ::msgcat::mcset es "Presence is signed" "La presencia está firmada" ::msgcat::mcset es "Presence" "Presencia" ::msgcat::mcset es "Presence-in" "Presencia-entra" ::msgcat::mcset es "Presence-out" "Presencia-sale" ::msgcat::mcset es "Pretty print XML" "Mostrar XML bonito" ::msgcat::mcset es "Pretty print incoming and outgoing XML stanzas." "Mostrar el XML bonito para las stanzas XML." ::msgcat::mcset es "Prev bookmark" "Marcador anterior" ::msgcat::mcset es "Prev highlighted" "Resaltado anterior" ::msgcat::mcset es "Prev" "Prev" ::msgcat::mcset es "Previous/Next history message" "Mensaje de historial anterior/siguiente" ::msgcat::mcset es "Previous/Next tab" "Pestaña anterior/siguiente" ::msgcat::mcset es "Priority." "Prioridad." ::msgcat::mcset es "Priority:" "Prioridad:" ::msgcat::mcset es "Privacy list is activated" "La lista de privacidad está activada" ::msgcat::mcset es "Privacy list is not activated" "La lista de privacidad no está activada" ::msgcat::mcset es "Privacy list is not created" "La lista de privacidad no está creada" ::msgcat::mcset es "Privacy lists are not implemented" "Las listas de privacidad no están implementadas en el servidor" ::msgcat::mcset es "Privacy lists are unavailable" "Las listas de privacidad no están disponibles" ::msgcat::mcset es "Privacy lists error" "Error en las listas de privacidad" ::msgcat::mcset es "Privacy lists" "Listas de privacidad" ::msgcat::mcset es "Privacy rules" "Reglas de privacidad" ::msgcat::mcset es "Profile on" "Perfil" ::msgcat::mcset es "Profile report" "Informe de perfil" ::msgcat::mcset es "Profile" "Perfil" ::msgcat::mcset es "Profiles" "Perfiles" ::msgcat::mcset es "Propose to configure newly created MUC room. If set to false then the default room configuration is automatically accepted." "Proponer configurar la sala de charla MUC recién creada. Si se desactiva esta opción la configuración por defecto de la sala se aceptará automáticamente." ::msgcat::mcset es "Protocol:" "Protocolo:" ::msgcat::mcset es "Proxy authentication required" "Se requiere autenticación en el proxy" ::msgcat::mcset es "Proxy password:" "Contraseña del proxy:" ::msgcat::mcset es "Proxy port:" "Puerto del proxy:" ::msgcat::mcset es "Proxy server:" "Servidor proxy:" ::msgcat::mcset es "Proxy type to connect." "Tipo de proxy al que conectar." ::msgcat::mcset es "Proxy type:" "Tipo de proxy:" ::msgcat::mcset es "Proxy username:" "Nombre de usuario de proxy:" ::msgcat::mcset es "Proxy" "Proxy" ::msgcat::mcset es "Pub/sub" "Pub/sub" ::msgcat::mcset es "Publish \"playback stopped\" instead" "Publicar \"se ha detenido la canción\" en su lugar" ::msgcat::mcset es "Publish node" "Publicar nodo" ::msgcat::mcset es "Publish user activity..." "Publicar la actividad..." ::msgcat::mcset es "Publish user location..." "Publicar localización de usuario..." ::msgcat::mcset es "Publish user mood..." "Publicar estado de ánimo..." ::msgcat::mcset es "Publish user tune..." "Publicar canción de usuario..." ::msgcat::mcset es "Publish" "Publicado" ::msgcat::mcset es "Publisher" "Publicador" ::msgcat::mcset es "Publishing is only possible while being online" "Solo puedes publicar cuando estás conectado" ::msgcat::mcset es "Purge all messages" "Purgar todos los mensajes" ::msgcat::mcset es "Purge message" "Purgar mensaje" ::msgcat::mcset es "Purge seen messages" "Purgar mensajes vistos" ::msgcat::mcset es "Purged all abbreviations" "Purgadas todas las abreviaturas" ::msgcat::mcset es "Question" "Pregunta" ::msgcat::mcset es "Quick Help" "Ayuda rápida" ::msgcat::mcset es "Quick help" "Ayuda rápida" ::msgcat::mcset es "Quit" "Salir" ::msgcat::mcset es "Quote" "Cita" ::msgcat::mcset es "Raise new tab." "Levantar nueva pestaña." ::msgcat::mcset es "Rating:" "Valoración:" ::msgcat::mcset es "Raw XML" "XML crudo" ::msgcat::mcset es "Read on..." "Leer..." ::msgcat::mcset es "Reason" "Razón" ::msgcat::mcset es "Reason:" "Razón:" ::msgcat::mcset es "Receive error: Stream ID is in use" "Error en la recepción: Stream ID está en uso" ::msgcat::mcset es "Receive file from %s" "Recibir fichero de %s" ::msgcat::mcset es "Receive" "Recibir" ::msgcat::mcset es "Received by:" "Recibido por:" ::msgcat::mcset es "Received/Sent" "Recibido/Enviado" ::msgcat::mcset es "Recipient Error" "Error de recipiente" ::msgcat::mcset es "Recipient Unavailable" "Recipiente no disponible" ::msgcat::mcset es "Reconnect to server if it does not reply (with result or with error) to ping (urn:xmpp:ping) request in specified time interval (in seconds)." "Reconectar al servidor si este no responde (con resultado o con error) a la petición de Ping (urn:xmpp:ping) en el intervalo de tiempo especificado (en segundos)." ::msgcat::mcset es "Redirect" "Redirección" ::msgcat::mcset es "Redo" "Rehacer" ::msgcat::mcset es "Region:" "Región:" ::msgcat::mcset es "Register in %s" "Registrarse en %s" ::msgcat::mcset es "Register" "Registrar" ::msgcat::mcset es "Registration Required" "Registro requerido" ::msgcat::mcset es "Registration failed: %s" "El registro ha fallado: %s" ::msgcat::mcset es "Registration is successful!" "¡Registro exitoso!" ::msgcat::mcset es "Registration is successful!" "¡Registro satisfactorio!" ::msgcat::mcset es "Registration: %s" "Registro: %s" ::msgcat::mcset es "Remote Connection Failed" "Fallo en la Conexión Remota" ::msgcat::mcset es "Remote Server Error" "Error de servidor remoto" ::msgcat::mcset es "Remote Server Not Found" "Servidor remoto no encontrado" ::msgcat::mcset es "Remote Server Timeout" "Intervalo de espera sobrepasado esperando al Servidor remoto" ::msgcat::mcset es "Remote control options." "Opciones de control remoto." ::msgcat::mcset es "Remove all users in group..." "Eliminar todos los usuarios del grupo..." ::msgcat::mcset es "Remove from list" "Eliminar de la lista" ::msgcat::mcset es "Remove from roster..." "Borrar contacto..." ::msgcat::mcset es "Remove group..." "Eliminar grupo..." ::msgcat::mcset es "Remove item..." "Eliminar elemento..." ::msgcat::mcset es "Remove list" "Eliminar lista" ::msgcat::mcset es "Remove" "Eliminar" ::msgcat::mcset es "Rename group..." "Renombrar grupo..." ::msgcat::mcset es "Rename roster group" "Renombrar grupo de la lista de contactos" ::msgcat::mcset es "Repeat new password:" "Repite la contraseña nueva:" ::msgcat::mcset es "Replace opened connections" "Reemplazar conexiones abiertas" ::msgcat::mcset es "Replace opened connections." "Reemplazar conexiones abiertas." ::msgcat::mcset es "Reply subject:" "Tema de la respuesta:" ::msgcat::mcset es "Reply to current time (jabber:iq:time) requests." "Responder las peticiones sobre el tiempo actual (jabber:iq:time)." ::msgcat::mcset es "Reply to entity time (urn:xmpp:time) requests." "Responder a peticiones de 'fecha de la entidad' (urn:xmpp:time)." ::msgcat::mcset es "Reply to idle time (jabber:iq:last) requests." "Responder a peticiones sobre el tiempo que llevas ausente (jabber:iq:last)." ::msgcat::mcset es "Reply to ping (urn:xmpp:ping) requests." "Responder a peticiones de Ping (urn:xmpp:ping)." ::msgcat::mcset es "Reply to room" "Responder a la sala" ::msgcat::mcset es "Reply to version (jabber:iq:version) requests." "Responder a las peticiones sobre la versión del programa (jabber:iq:version)." ::msgcat::mcset es "Reply to" "Responder a" ::msgcat::mcset es "Reply" "Responder" ::msgcat::mcset es "Report the list of current MUC rooms on disco#items query." "Mostrar la lista de salas de charla MUC actuales en peticiones disco#items." ::msgcat::mcset es "Request Error" "Error en la petición" ::msgcat::mcset es "Request Timeout" "Timeout de la petición" ::msgcat::mcset es "Request failed: %s" "Petición fallida: %s" ::msgcat::mcset es "Request only unseen (which aren't displayed in the chat window) messages in the history in MUC compatible conference rooms." "Solicitar solo mensajes del historial de las salas de charla MUC que no se hayan visto (que no se muestran en la ventana de la charla." ::msgcat::mcset es "Request subscription" "Solicitar subscripción" ::msgcat::mcset es "Request" "Petición" ::msgcat::mcset es "Requesting conference list: %s" "Solicitando la lista de conferencias: %s" ::msgcat::mcset es "Requesting filter rules: %s" "Solicitando reglas de filtrado: %s" ::msgcat::mcset es "Requesting ignore list: %s" "Solicitando la lista de ignorados: %s" ::msgcat::mcset es "Requesting invisible list: %s" "Solicitando la lista de invisibles: %s" ::msgcat::mcset es "Requesting privacy list: %s" "Solicitando lista de privacidad: %s" ::msgcat::mcset es "Requesting privacy rules: %s" "Solicitando reglas de privacidad: %s" ::msgcat::mcset es "Requesting visible list: %s" "Solicitando la lista de visibles: %s" ::msgcat::mcset es "Reset to current value" "Devolver al valor actual" ::msgcat::mcset es "Reset to default value" "Devolver al valor por defecto" ::msgcat::mcset es "Reset to saved value" "Devolver al valor guardado" ::msgcat::mcset es "Reset to value from config file" "Devolver al valor del fichero de configuración" ::msgcat::mcset es "Resource Constraint" "Coacción en el recurso" ::msgcat::mcset es "Resource." "Recurso." ::msgcat::mcset es "Resource:" "Recurso:" ::msgcat::mcset es "Restricted XML" "XML Restringido" ::msgcat::mcset es "Resubscribe to all users in group..." "Resubscribir a todos los usuarios en el grupo..." ::msgcat::mcset es "Resubscribe" "Resubscribir" ::msgcat::mcset es "Retract node" "Retirar nodo" ::msgcat::mcset es "Retrieve offline messages using POP3-like protocol." "Recuperar mensajes diferidos usando un protocolo similar a POP3." ::msgcat::mcset es "Retry to connect forever." "Intentar reconectar infinitamente." ::msgcat::mcset es "Returning from auto-away" "Volviendo de auto ausencia" ::msgcat::mcset es "Revoke Admin Privileges" "Revocar privilegios de Administrador" ::msgcat::mcset es "Revoke Membership" "Revocar Membresía" ::msgcat::mcset es "Revoke Moderator Privileges" "Revocar privilegios de Moderador" ::msgcat::mcset es "Revoke Owner Privileges" "Revocar privilegios de Dueño" ::msgcat::mcset es "Revoke Voice" "Revocar Voz" ::msgcat::mcset es "Right mouse button" "Botón derecho del ratón" ::msgcat::mcset es "Right" "Derecha" ::msgcat::mcset es "Role" "Rol" ::msgcat::mcset es "Role:" "Rol:" ::msgcat::mcset es "Room %s is successfully created" "Se ha creado correctamente la sala %s" ::msgcat::mcset es "Room is created" "Se ha creado la sala" ::msgcat::mcset es "Room is destroyed" "Se ha destruido la sala" ::msgcat::mcset es "Room:" "Habitación:" ::msgcat::mcset es "Roster Files" "Archivos de lista de contactos" ::msgcat::mcset es "Roster Notes" "Notas" ::msgcat::mcset es "Roster filter." "Filtro de contactos." ::msgcat::mcset es "Roster group:" "Grupo de contactos:" ::msgcat::mcset es "Roster item may be dropped not only over group name but also over any item in group." "Al coger y arrastra elementos de la lista de contactos, se les puede soltar en cualquier parte de un grupo, no solo sobre el nombre del grupo." ::msgcat::mcset es "Roster of %s" "Lista de contactos de %s" ::msgcat::mcset es "Roster options." "Opciones de la lista de contactos." ::msgcat::mcset es "Roster restoration completed" "Completada la restauración de la lista de contactos" ::msgcat::mcset es "Roster" "Lista de contactos" ::msgcat::mcset es "Rule Name:" "Nombre de la regla:" ::msgcat::mcset es "Rule name already exists" "El nombre de la regla ya existe" ::msgcat::mcset es "SASL Certificate:" "Certificado SASL:" ::msgcat::mcset es "SASL Port:" "Puerto SASL:" ::msgcat::mcset es "SASL auth error:\n%s" "Error en la autenticación SASL:\n%s" ::msgcat::mcset es "SASL" ::msgcat::mcset es "SHA1 hash" "Hash SHA1" ::msgcat::mcset es "SI connection closed" "Conexión SI cerrada" ::msgcat::mcset es "SOCKS authentication failed" "Falló la autenticación SOCKS" ::msgcat::mcset es "SOCKS command not supported" "Comando SOCKS no soportado" ::msgcat::mcset es "SOCKS connection not allowed by ruleset" "Conexión SOCKS no permitida por las reglas" ::msgcat::mcset es "SOCKS request failed" "Falló la petición SOCKS" ::msgcat::mcset es "SOCKS server cannot identify username" "El servidor SOCKS no puede identificar el nombre de usuario" ::msgcat::mcset es "SOCKS server username identification failed" "Falló la identificación del nombre de usuario en el servidor SOCKS" ::msgcat::mcset es "SOCKS4a" "SOCKS4a" ::msgcat::mcset es "SOCKS5" "SOCKS5" ::msgcat::mcset es "SSL & Compression" "SSL y Compresión" ::msgcat::mcset es "SSL Info" ::msgcat::mcset es "SSL Port:" "Puerto SSL:" ::msgcat::mcset es "SSL certificate file (optional)." "Fichero de certificado SSL (opcional)." ::msgcat::mcset es "SSL certificate:" "Certificado SSL:" ::msgcat::mcset es "SSL certification authority file or directory (optional)." "Autoridad certificadora o directorio de SSL (opcional)." ::msgcat::mcset es "SSL private key file (optional)." "Fichero de clave SSL privada (opcional)." ::msgcat::mcset es "SSL" ::msgcat::mcset es "STARTTLS failed" "STARTTLS falló" ::msgcat::mcset es "STARTTLS successful" "STARTTLS exitoso" ::msgcat::mcset es "Save To Log" "Guardar en log" ::msgcat::mcset es "Save as:" "Guardar como:" ::msgcat::mcset es "Save state on Tkabber exit." "Guardar estado al cerra Tkabber." ::msgcat::mcset es "Save state on exit" "Guardar estado al salir" ::msgcat::mcset es "Save state" "Guardar estado" ::msgcat::mcset es "Screenname conversion" "Conversión de dirección" ::msgcat::mcset es "Screenname: %s\n\nConverted JID: %s" "Dirección del contacto: %s\n\nJID convertido: %s" ::msgcat::mcset es "Screenname:" "Dirección del contacto:" ::msgcat::mcset es "Scroll chat window up/down" "Desplazar ventana de charla arriba/abajo" ::msgcat::mcset es "Search again" "Otra búsqueda" ::msgcat::mcset es "Search down" "Buscar abajo" ::msgcat::mcset es "Search in %s" "Buscar en %s" ::msgcat::mcset es "Search in %s: No matching items found" "Búsqueda en %s: No se han encontrado elementos que coincidan" ::msgcat::mcset es "Search in Tkabber windows options." "Buscar en las opciones de ventana de Tkabber" ::msgcat::mcset es "Search up" "Buscar arriba" ::msgcat::mcset es "Search" "Buscar" ::msgcat::mcset es "Search: %s" "Buscar: %s" ::msgcat::mcset es "See Other Host" "Ver Otros Hosts" ::msgcat::mcset es "Select Key for Signing %s Traffic" "Seleccionar clave para firmar el tráfico de %s" ::msgcat::mcset es "Select month:" "Seleccionar mes:" ::msgcat::mcset es "Select" "Seleccionar" ::msgcat::mcset es "Self signed certificate" "Certificado auto firmado" ::msgcat::mcset es "Send broadcast message..." "Enviar mensaje de difusión..." ::msgcat::mcset es "Send contacts to %s" "Enviar contactos a %s" ::msgcat::mcset es "Send contacts to" "Enviar contactos a" ::msgcat::mcset es "Send custom presence" "Enviar presencia personalizada" ::msgcat::mcset es "Send file to %s" "Enviar fichero a %s" ::msgcat::mcset es "Send file..." "Enviar fichero..." ::msgcat::mcset es "Send message of the day..." "Enviar mensaje del día..." ::msgcat::mcset es "Send message to %s" "Enviar mensaje a %s" ::msgcat::mcset es "Send message to all users in group..." "Enviar mensaje a todos los usuarios del grupo..." ::msgcat::mcset es "Send message to group %s" "Enviar mensaje al grupo %s" ::msgcat::mcset es "Send message to group" "Enviar mensaje al grupo" ::msgcat::mcset es "Send message" "Enviar mensaje" ::msgcat::mcset es "Send message..." "Enviar mensaje..." ::msgcat::mcset es "Send request to: " "Enviar petición a: " ::msgcat::mcset es "Send subscription at %s" "Enviar subscripción a %s" ::msgcat::mcset es "Send subscription request to %s" "Enviar petición de subscripción a %s" ::msgcat::mcset es "Send subscription request" "Enviar petición de subscripción" ::msgcat::mcset es "Send subscription to: " "Enviar subscripción a: " ::msgcat::mcset es "Send to server" "Enviar al servidor" ::msgcat::mcset es "Send users..." "Enviar usuarios..." ::msgcat::mcset es "Send" " Enviar " ::msgcat::mcset es "Sending %s %s list" "Enviando %s la lista %s" ::msgcat::mcset es "Sending conference list: %s" "Enviando la lista de conferencias: %s" ::msgcat::mcset es "Sending configure form" "Enviando formulario de configuración" ::msgcat::mcset es "Sending ignore list: %s" "Enviando la lista de ignorados: %s" ::msgcat::mcset es "Sending invisible list: %s" "Enviando la lista de invisibles: %s" ::msgcat::mcset es "Sending visible list: %s" "Enviando la lista de visibles: %s" ::msgcat::mcset es "September" "Septiembre" ::msgcat::mcset es "Sergei Golovan" "Sergei Golovan" ::msgcat::mcset es "Serial number" "Número de serie" ::msgcat::mcset es "Server Error" "Error de servidor" ::msgcat::mcset es "Server Port:" "Puerto del servidor:" ::msgcat::mcset es "Server doesn't support hashed password authentication" "El servidor no permite autenticación por resumen de contraseña" ::msgcat::mcset es "Server doesn't support plain or digest authentication" "El servidor no permite autenticación simple o por resumen" ::msgcat::mcset es "Server haven't provided SASL authentication feature" "El servidor no ha proporcionado un mecanismo de autenticación SASL" ::msgcat::mcset es "Server haven't provided STARTTLS feature" "El servidor no ha anunciado soporte de STARTTLS" ::msgcat::mcset es "Server haven't provided compress feature" "El servidor no ha anunciado que soporte compresión" ::msgcat::mcset es "Server haven't provided non-SASL authentication feature" "El servidor no ha proporcionado característica de autenticación no-SASL" ::msgcat::mcset es "Server haven't provided supported compress method" "El servidor no ha anunciado el soporte de un método de compresión soportado" ::msgcat::mcset es "Server message" "Mensaje del servidor" ::msgcat::mcset es "Server name or IP-address." "Nombre del servidor o dirección IP." ::msgcat::mcset es "Server name." "Nombre del servidor." ::msgcat::mcset es "Server port." "Puerto del servidor." ::msgcat::mcset es "Server provided mechanism %s. It is forbidden" "El servidor proporcionó el mecanismo %s. Está prohibido" ::msgcat::mcset es "Server provided mechanisms %s. They are forbidden" "El servidor proporcionó los mecanismos %s. Están prohibidos" ::msgcat::mcset es "Server provided no SASL mechanisms" "El servidor no proporcionó ningún mecanismo SASL" ::msgcat::mcset es "Server:" "Servidor:" ::msgcat::mcset es "Service Discovery" "Descubridor de servicios" ::msgcat::mcset es "Service Unavailable" "Servicio no disponible" ::msgcat::mcset es "Service info" "Información del servicio" ::msgcat::mcset es "Service statistics" "Estadísticas del servicio" ::msgcat::mcset es "Session key bits" "Bits the la llave de sesión" ::msgcat::mcset es "Set bookmark" "Guardar marcador" ::msgcat::mcset es "Set for current and future sessions" "Modificar y guardar" ::msgcat::mcset es "Set for current session only" "Modificar solo para esta sesión (no guardar)" ::msgcat::mcset es "Set priority to 0 when moving to extended away state." "Ponerte prioridad 0 cuando te cambia a 'muy ausente'" ::msgcat::mcset es "Set" "Fijar" ::msgcat::mcset es "Settings of rich text facility which is used to render chat messages and logs." "Opciones de texto enriquecido cuando se muestran mensajes en ventanas de charla e historiales." ::msgcat::mcset es "Show IQ requests in the status line." "Mostrar peticiones IQ en la línea de estado." ::msgcat::mcset es "Show TkCon console" "Mostrar consola TkCon" ::msgcat::mcset es "Show Toolbar." "Mostrar Barra de Herramientas." ::msgcat::mcset es "Show balloons with headline messages over tree nodes." "Mostrar los mensajes de los titulares en globos sobre los nodos del árbol." ::msgcat::mcset es "Show console" "Mostrar consola" ::msgcat::mcset es "Show detailed info on conference room members in roster item tooltips." "Mostrar información detallada sobre los miembros de una sala de charla en los 'tooltips' de la lista de contactos." ::msgcat::mcset es "Show emoticons" "Mostrar emoticonos" ::msgcat::mcset es "Show history" "Mostrar historial" ::msgcat::mcset es "Show images for emoticons." "Mostrar imágenes de emoticonos." ::msgcat::mcset es "Show info" "Mostrar información" ::msgcat::mcset es "Show main window" "Mostrar ventana principal" ::msgcat::mcset es "Show menu tearoffs when possible." "Mostrar tiras en los menus cuando sea posible." ::msgcat::mcset es "Show my own resources in the roster." "Mostrar mis propios recursos en la lista de contactos." ::msgcat::mcset es "Show native icons for contacts, connected to transports/services in roster." "Mostrar iconos nativos para los contactos conectados a través de transportes en la lista de contactos." ::msgcat::mcset es "Show native icons for transports/services in roster." "Mostrar iconos nativos para transportes/servicios en la lista de contactos." ::msgcat::mcset es "Show number of unread messages in tab titles." "Mostrar cantidad de mensajes sin leer en el título de la pestaña." ::msgcat::mcset es "Show offline users" "Mostrar contactos desconectados" ::msgcat::mcset es "Show online users only" "Mostrar solo usuarios conectados" ::msgcat::mcset es "Show only online users in roster." "Mostrar solo contactos conectados." ::msgcat::mcset es "Show only the number of personal unread messages in window title." "Mostrar en el título de la ventana solamente el número de mensajes personales nuevos." ::msgcat::mcset es "Show own resources" "Mostrar los propios recursos" ::msgcat::mcset es "Show palette of emoticons" "Mostrar paleta de emoticonos" ::msgcat::mcset es "Show presence bar." "Mostrar barra de presencia." ::msgcat::mcset es "Show status bar." "Mostrar barra de estado." ::msgcat::mcset es "Show subscription type in roster item tooltips." "Mostrar tipo de subscripción en el globo informativo de la lista de contactos." ::msgcat::mcset es "Show user or service info" "Mostrar información de usuario o servicio" ::msgcat::mcset es "Show user or service info..." "Mostrar información de usuario o servicio..." ::msgcat::mcset es "Show" " Mostrar " ::msgcat::mcset es "Side where to place tabs in tabbed mode." "Lugar donde poner las pestañas en el modo de pestañas." ::msgcat::mcset es "Sign traffic" "Firmar tráfico" ::msgcat::mcset es "Signature not processed due to missing key" "Firma no procesada porque falta la llave" ::msgcat::mcset es "Single window" "Ventana individual" ::msgcat::mcset es "Size:" "Tamaño:" ::msgcat::mcset es "Smart autoscroll" "Desplazamiento automático inteligente" ::msgcat::mcset es "Sort by date" "Ordenar por fecha" ::msgcat::mcset es "Sort by from" "Ordenar por emisor" ::msgcat::mcset es "Sort by node" "Ordenar por nodo" ::msgcat::mcset es "Sort by type" "Ordenar por tipo" ::msgcat::mcset es "Sort items by JID/node" "Ordenar elementos por JID/nodo" ::msgcat::mcset es "Sort items by name" "Ordenar elementos por nombre" ::msgcat::mcset es "Sort" "Ordenar" ::msgcat::mcset es "Sound options." "Opciones de sonido." ::msgcat::mcset es "Sound to play when available presence is received." "Sonido a reproducir cuando se recibe una presencia 'conectado'." ::msgcat::mcset es "Sound to play when connected to Jabber server." "Sonido a reproducir cuando se conecta al servidor Jabber." ::msgcat::mcset es "Sound to play when disconnected from Jabber server." "Sonido a reproducir cuando se desconecte el servidor Jabber." ::msgcat::mcset es "Sound to play when groupchat message from me is received." "Sonido a reproducir cuando se recibe un mensaje de sala mio." ::msgcat::mcset es "Sound to play when groupchat message is received." "Sonido a reproducir cuando se recibe un mensaje de sala" ::msgcat::mcset es "Sound to play when groupchat server message is received." "Sonido a reproducir cuando se recibe un mensaje de sala del servidor." ::msgcat::mcset es "Sound to play when highlighted (usually addressed personally) groupchat message is received." "Sonido a reproducir cuando se recibe un mensaje de sala resaltado (normalmente dirigido a ti)." ::msgcat::mcset es "Sound to play when personal chat message is received." "Sonido a reproducir cuando se recibe un mensaje personal." ::msgcat::mcset es "Sound to play when sending personal chat message." "Sonido a reproducir cuando se envía un mensaje personal." ::msgcat::mcset es "Sound to play when unavailable presence is received." "Sonido a reproducir cuando se recibe una presencia 'desconectado'." ::msgcat::mcset es "Sound" "Sonido" ::msgcat::mcset es "Source:" "Fuente:" ::msgcat::mcset es "Specifies search mode while searching in chat, log or disco windows. \"substring\" searches exact substring, \"glob\" uses glob style matching, \"regexp\" allows to match regular expression." "Especifica el modo de búsqueda. \"substring\" busca la subcadena exacta, \"glob\" usa concordancia de estilo glob, \"regexp\" permite usar expresiones regulares." ::msgcat::mcset es "Speed:" "Velocidad:" ::msgcat::mcset es "Spell check options." "Opciones de correción ortográfica." ::msgcat::mcset es "Start chat" "Charlar en privado" ::msgcat::mcset es "Starting auto-away" "Pasando a auto ausencia" ::msgcat::mcset es "State " "Comunidad " ::msgcat::mcset es "State" "Estado" ::msgcat::mcset es "State:" "Estado/Provincia:" ::msgcat::mcset es "Statistics monitor" "Monitor de estadísticas" ::msgcat::mcset es "Statistics" "Estadísticas" ::msgcat::mcset es "Status bar" "Barra de estado" ::msgcat::mcset es "Stop autoscroll" "No desplazar automáticamente en vertical" ::msgcat::mcset es "Stop chat window autoscroll." "Desactivar el desplazamiento automático de la ventana de charla." ::msgcat::mcset es "Store group chats logs." "Guardar registro de charlas en grupo." ::msgcat::mcset es "Store private chats logs." "Guardar registro de charlas privadas." ::msgcat::mcset es "Store" "Guardar" ::msgcat::mcset es "Stored collapsed roster groups." "Almacenar el estado de los grupos colapsados en la lista de contactos." ::msgcat::mcset es "Stored main window state (normal or zoomed)" "Guardar estado de la ventana principal (normal o maximizado)" ::msgcat::mcset es "Stored show offline roster groups." "Almacenar si se muestra o no los grupos desconectados en la lista de contactos." ::msgcat::mcset es "Stored user priority." "Prioridad del usuario almacenada." ::msgcat::mcset es "Stored user status." "Estado del usuario almacenado." ::msgcat::mcset es "Stored user text status." "Texto de estado del usuario almacenado." ::msgcat::mcset es "Storing conferences failed: %s" "Fallo almacenando las salas de charla: %s" ::msgcat::mcset es "Storing roster notes failed: %s" "Falló el almacenamiento de notas: %s" ::msgcat::mcset es "Stream Error%s%s" "Error en el Stream%s%s" ::msgcat::mcset es "Stream initiation options." "Opciones de iniciación de Envío" ::msgcat::mcset es "Stream method negotiation failed" "Falló la negociación del método de Stream" ::msgcat::mcset es "Street:" "Calle:" ::msgcat::mcset es "Strip leading \"http://jabber.org/protocol/\" from IQ namespaces in the status line." "Quitar el \"http://jabber.org/protocol/\" del principio en los nombres de espacio de IQ en la línea de comandos." ::msgcat::mcset es "SubID" "SubID" ::msgcat::mcset es "Subactivity" "Subactividad" ::msgcat::mcset es "Subactivity:" "Subactividad:" ::msgcat::mcset es "Subject is set to: %s" "El asunto se ha puesto a: %s" ::msgcat::mcset es "Subject" "Asunto" ::msgcat::mcset es "Subject: " "Asunto: " ::msgcat::mcset es "Subject:" "Asunto:" ::msgcat::mcset es "Submit" "Enviar" ::msgcat::mcset es "Subscribe to a node" "Subscribir a nodo" ::msgcat::mcset es "Subscribe" "Subscribir" ::msgcat::mcset es "Subscribed" "Subscrito" ::msgcat::mcset es "Subscription Required" "Se requiere subscripción" ::msgcat::mcset es "Subscription request from %s" "Petición de subscripción de %s" ::msgcat::mcset es "Subscription request from:" "Petición de subscripción de:" ::msgcat::mcset es "Subscription" "Subscripción" ::msgcat::mcset es "Subscription:" "Subscripción:" ::msgcat::mcset es "Substrings to highlight in messages." "Sílabas a resaltar en los mensajes." ::msgcat::mcset es "Suffix" "Sufijo" ::msgcat::mcset es "Suffix:" "Sufijo:" ::msgcat::mcset es "Switch to tab number 1-9,10" "Cambiar a la pestaña número 1-9,10" ::msgcat::mcset es "System Shutdown" "Apagando Sistema" ::msgcat::mcset es "Systray icon blinks when there are unread messages." "El icono de la bandeja de sistema parpadea cuando hay mensajes sin leer." ::msgcat::mcset es "Systray icon options." "Opciones de la bandeja de sistema." ::msgcat::mcset es "Systray:" "Icono de la bandeja de sistema:" ::msgcat::mcset es "TTL expired" "Expiró el TTL" ::msgcat::mcset es "Tabs:" "Pestañas:" ::msgcat::mcset es "Telephone numbers" "Números de teléfono" ::msgcat::mcset es "Templates" "Plantillas" ::msgcat::mcset es "Temporary Error" "Error temporal" ::msgcat::mcset es "Temporary auth failure" "Fallo en la autenticación temporal" ::msgcat::mcset es "Text status, which is set when Tkabber is moving to away state." "Mensaje de estado que Tkabber te pone cuando te cambia a 'ausente' automáticamente." ::msgcat::mcset es "Text:" "Texto:" ::msgcat::mcset es "The signature is good but has expired" "La firma es buena pero ha expirado" ::msgcat::mcset es "The signature is good but the key has expired" "La firma es buena pero la llave ha expirado" ::msgcat::mcset es "This message is encrypted." "Este mensaje está cifrado." ::msgcat::mcset es "This message was forwarded by %s\n" "Este mensaje fue reenviado por %s\n" ::msgcat::mcset es "This message was forwarded to %s" "Este mensaje se reenvió a %s" ::msgcat::mcset es "This message was sent by %s\n" "Este mensaje fue enviado por %s\n" ::msgcat::mcset es "Time Zone:" "Zona horaria:" ::msgcat::mcset es "Time interval before playing next sound (in milliseconds)." "Intervalo de tiempo entre reproducción de sonidos (en milisegundos)." ::msgcat::mcset es "Time" "Hora" ::msgcat::mcset es "Time:" "Hora:" ::msgcat::mcset es "Timeout for waiting for HTTP poll responses (if set to zero, Tkabber will wait forever)." "Timeout a esperar para las respuestas de HTTP Poll (si se indica cero, Tkabber esperará para siempre)." ::msgcat::mcset es "Timeout" "Timeout" ::msgcat::mcset es "Timer" "Temporizador" ::msgcat::mcset es "Timestamp:" "Fecha:" ::msgcat::mcset es "Title" "Cargo" ::msgcat::mcset es "Title:" "Cargo:" ::msgcat::mcset es "Tkabber Systray" "Icono en la Bandeja de Sistema" ::msgcat::mcset es "Tkabber configuration directory transfer failed with:\n%s\n Tkabber will use the old directory:\n%s" "Falló la transferencia del directorio de configuración de Tkabber:\n%s\n Tkabber usará el directorio viejo:\n%s" ::msgcat::mcset es "Tkabber emoticons theme. To make new theme visible for Tkabber put it to some subdirectory of %s." "Tema de emoticonos de Tkabber. Para instalar un nuevo tema de emoticonos cópialo en un subdirectorio de %s." ::msgcat::mcset es "Tkabber icon theme. To make new theme visible for Tkabber put it to some subdirectory of %s." "Tema de iconos de Tkabber. Para instalar un tema nuevo, cópialo a un subdirectorio de %s." ::msgcat::mcset es "Tkabber save state options." "Opciones de guardado del estado de Tkabber." ::msgcat::mcset es "To" "Para" ::msgcat::mcset es "To: " "Para: " ::msgcat::mcset es "To:" "Para:" ::msgcat::mcset es "Toggle encryption (when possible)" "Activar/Desactivar el cifrado (cuando sea posible)" ::msgcat::mcset es "Toggle encryption" "Activar/Desactivar cifrado" ::msgcat::mcset es "Toggle seen" "Activar/Desactivar Leído" ::msgcat::mcset es "Toggle showing offline users" "Activar/Desactivar la vista de usuarios desconectados" ::msgcat::mcset es "Toggle signing" "Activar/Desactivar el firmado" ::msgcat::mcset es "Toolbar" "Barra de herramientas" ::msgcat::mcset es "Top" "Arriba" ::msgcat::mcset es "Track:" "Pista:" ::msgcat::mcset es "Transfer failed: %s" "La transferencia falló: %s" ::msgcat::mcset es "Transferring..." "Transfiriendo..." ::msgcat::mcset es "Try again" "Volver a intentarlo" ::msgcat::mcset es "Type" "Tipo" ::msgcat::mcset es "UID" ::msgcat::mcset es "UID:" ::msgcat::mcset es "URI:" "URI:" ::msgcat::mcset es "URL to connect to." "URL a la que conectar." ::msgcat::mcset es "URL to poll:" "URL para Poll:" ::msgcat::mcset es "URL" "URL" ::msgcat::mcset es "URL:" "URL:" ::msgcat::mcset es "UTC:" ::msgcat::mcset es "Unable to encipher data for %s: %s.\n\nEncrypting traffic to this user is now disabled.\n\nSend it as PLAINTEXT?" "No se ha podido cifrar los datos para %s: %s.\n\nSe ha desactivado el cifrado del tráfico con este usuario.\n\n¿Enviar sin cifrar?" ::msgcat::mcset es "Unable to sign message body: %s.\n\nSigning traffic is now disabled.\n\nSend it WITHOUT a signature?" "Imposible firmar el cuerpo del mensaje: %s.\n\n¿Enviar SIN firma?" ::msgcat::mcset es "Unable to sign presence information: %s.\n\nPresence will be sent, but signing traffic is now disabled." "Imposible firmar información de presencia: %s.\n\nLa presencia se enviará, pero el firmado de tráfico está ahora desactivado." ::msgcat::mcset es "Unauthorized" "No autorizado" ::msgcat::mcset es "Unavailable presence" "Presencia: desconectado" ::msgcat::mcset es "Unavailable" "No disponible" ::msgcat::mcset es "Unconfigured" "No configurado" ::msgcat::mcset es "Undefined Condition" "Condición no definida" ::msgcat::mcset es "Undefined" "Indefinido" ::msgcat::mcset es "Undo" "Deshacer" ::msgcat::mcset es "Unexpected Request" "Petición inesperada" ::msgcat::mcset es "Unit:" "Unidad:" ::msgcat::mcset es "Units" "Unidades" ::msgcat::mcset es "Unknown address type" "Tipo de dirección desconocida" ::msgcat::mcset es "Unknown error" "Error desconocido" ::msgcat::mcset es "Unpublish user activity" "Despublicar la actividad de usuario" ::msgcat::mcset es "Unpublish user activity..." "Despublicar la actividad..." ::msgcat::mcset es "Unpublish user location" "Despublicar la localización de usuario" ::msgcat::mcset es "Unpublish user location..." "Despublicar la localización de usuario..." ::msgcat::mcset es "Unpublish user mood" "Despublicar el estado de ánimo del usuario" ::msgcat::mcset es "Unpublish user mood..." "Despublicar el estado de ánimo..." ::msgcat::mcset es "Unpublish user tune" "Despublicar la canción de usuario" ::msgcat::mcset es "Unpublish user tune..." "Despublicar la canción de usuario..." ::msgcat::mcset es "Unpublish" "Despublicar" ::msgcat::mcset es "Unpublishing is only possible while being online" "Solo puedes despublicar cuando estás conectado" ::msgcat::mcset es "Unrecoverable Error" "Error irrecuperable" ::msgcat::mcset es "Unregister" "Desregistrar" ::msgcat::mcset es "Unsubscribe from a node" "Desubscribirse de un nodo" ::msgcat::mcset es "Unsubscribe" "Desubscribir" ::msgcat::mcset es "Unsubscribed from %s" "Desubscrito de %s" ::msgcat::mcset es "Unsupported Encoding" "Codificación No Soportada" ::msgcat::mcset es "Unsupported SOCKS authentication method" "Método de autenticación SOCKS no soportado" ::msgcat::mcset es "Unsupported SOCKS method" "Método SOCKS no soportado" ::msgcat::mcset es "Unsupported Stanza Type" "Tipo de Stanza No Soportado" ::msgcat::mcset es "Unsupported Version" "Versión No Soportada" ::msgcat::mcset es "Unsupported compression method" "Método de compresión no soportado" ::msgcat::mcset es "Unsupported log dir format" "Formato del directorio de históricos no soportado" ::msgcat::mcset es "Up" "Arriba" ::msgcat::mcset es "Update message of the day..." "Actualizar mensaje del día..." ::msgcat::mcset es "Update" "Actualizar" ::msgcat::mcset es "Uptime" "Tiempo activo" ::msgcat::mcset es "Usage: /abbrev WHAT FOR" "Usar: /abbrev ABREVIADO TEXTO" ::msgcat::mcset es "Usage: /unabbrev WHAT" "Usar: /unabbrev ABREVIADO" ::msgcat::mcset es "Use HTTP poll client security keys (recommended)." "Usar claves de seguridad del cliente HTTP Poll (recomendado)." ::msgcat::mcset es "Use HTTP poll connection method." "Usar método de conexión HTTP Poll." ::msgcat::mcset es "Use Proxy" "Usar Proxy" ::msgcat::mcset es "Use SASL authentication" "Usar autenticación SASL" ::msgcat::mcset es "Use SASL authentication." "Usar autenticación SASL." ::msgcat::mcset es "Use SSL" "Usar SSL" ::msgcat::mcset es "Use Tabbed Interface (you need to restart)." "Usar Tkabber en modo pestañas (necesitas reiniciar Tkabber)." ::msgcat::mcset es "Use aliases to show multiple users in one roster item." "Usar alias para mostrar múltiples usuarios en un solo elemento de la lista de contactos." ::msgcat::mcset es "Use aliases" "Usar apodos" ::msgcat::mcset es "Use client security keys" "Usar claves de seguridad del cliente" ::msgcat::mcset es "Use colored messages" "Usar mensajes coloreados" ::msgcat::mcset es "Use colored nicks in chat windows." "Usar apodos coloreados en ventanas de charla." ::msgcat::mcset es "Use colored nicks in groupchat rosters." "Usar apodos coloreados en la lista de participantes de una sala de charla." ::msgcat::mcset es "Use colored nicks" "Usar apodos coloreados" ::msgcat::mcset es "Use colored roster nicks" "Usar apodos coloreados en la lista de contactos" ::msgcat::mcset es "Use connection:" "Usar conexión:" ::msgcat::mcset es "Use explicitly-specified server address and port." "Usar dirección y puerto del servidor definidas explícitamente." ::msgcat::mcset es "Use hashed password" "Usar resumen de la contraseña" ::msgcat::mcset es "Use mediated SOCKS5 connection if proxy is available." "Usar conexión SOCKS5 mediada si el proxy está disponible." ::msgcat::mcset es "Use only whole words for emoticons." "Usar solo palabras completas para los emoticonos." ::msgcat::mcset es "Use roster filter" "Usar filtro de contactos" ::msgcat::mcset es "Use roster filter." "Usar filtro de contactos." ::msgcat::mcset es "Use sound notification only when being available." "Usar la notificación sonora sólo cuanto se está en estado 'disponible'." ::msgcat::mcset es "Use specified key ID for signing and decrypting messages." "Usar el ID de llave especificado para firmar y descifrar mensajes." ::msgcat::mcset es "Use the same passphrase for signing and decrypting messages." "Usar la misma contraseña para firmar y descifrar mensajes." ::msgcat::mcset es "Use the specified function to hash supported features list." "Usar la función especificada para hashear la lista de características disponibles." ::msgcat::mcset es "Use this module" "Usar este módulo" ::msgcat::mcset es "User ID" "ID de usuario" ::msgcat::mcset es "User activity publishing failed: %s" "Falló la publicación de la actividad de usuario: %s" ::msgcat::mcset es "User activity unpublishing failed: %s" "Falló la despublicación de la actividad de usuario: %s" ::msgcat::mcset es "User activity" "Actividad de usuario" ::msgcat::mcset es "User already %s" "El usuario ya está %s" ::msgcat::mcset es "User info" "Información del usuario" ::msgcat::mcset es "User location publishing failed: %s" "Fallo al publicar la localización del usuario: %s" ::msgcat::mcset es "User location unpublishing failed: %s" "Fallo al despublicar la localización del usuario: %s" ::msgcat::mcset es "User location" "Localización de usuario" ::msgcat::mcset es "User mood publishing failed: %s" "Falló la publicación del estado de ánimo de usuario: %s" ::msgcat::mcset es "User mood unpublishing failed: %s" "Falló la despublicación del estado de ánimo de usuario: %s" ::msgcat::mcset es "User mood" "Estado de ánimo del usuario" ::msgcat::mcset es "User name." "Nombre de usuario." ::msgcat::mcset es "User name." "Nombre de usuario." ::msgcat::mcset es "User tune publishing failed: %s" "Falló la publicación de la canción de usuario: %s" ::msgcat::mcset es "User tune unpublishing failed: %s" "Falló la despublicación de la canción de usuario: %s" ::msgcat::mcset es "User tune" "Canción de usuario" ::msgcat::mcset es "User-Agent string." "Cadena de identificación del usuario." ::msgcat::mcset es "Username Not Available" "Nombre de usuario no disponible" ::msgcat::mcset es "Username:" "Nombre de usuario:" ::msgcat::mcset es "Users" "Usuarios" ::msgcat::mcset es "Value" "Valor" ::msgcat::mcset es "Version" "Versión" ::msgcat::mcset es "Version:" "Versión:" ::msgcat::mcset es "Video:" "Video:" ::msgcat::mcset es "View" "Ver" ::msgcat::mcset es "Visible list" "Lista de visibles" ::msgcat::mcset es "Visitors" "Visitantes" ::msgcat::mcset es "Voice:" "Voz:" ::msgcat::mcset es "WARNING: %s\n" "AVISO: %s\n" ::msgcat::mcset es "Waiting for activating privacy list" "Esperando para activar la lista de privacidad" ::msgcat::mcset es "Waiting for authentication results" "Esperando los resultados de la autenticación" ::msgcat::mcset es "Waiting for handshake results" "Esperando los resultados del handshake" ::msgcat::mcset es "Waiting for roster" "Esperando la lista de contactos" ::msgcat::mcset es "Warning display options." "Opciones de mostrar advertencias." ::msgcat::mcset es "Warning" "Advertencia" ::msgcat::mcset es "Warning:" "Aviso:" ::msgcat::mcset es "Web Site" "Sitio web" ::msgcat::mcset es "Web Site:" "Sitio web:" ::msgcat::mcset es "What action does the close button." "Acción realizada por el botón de Cerrar." ::msgcat::mcset es "When set, all changes to the ignore rules are applied only until Tkabber is closed\; they are not saved and thus will be not restored at the next run." "Cuando se activa, todos los cambios en las reglas de ignorados se aplican solo hasta que se cierre Tkabber\; no se guardan y por tanto no se restaurarán cuando inicies Tkabber de nuevo." ::msgcat::mcset es "Whois" "¿Quién es?" ::msgcat::mcset es "Work:" "Trabajo:" ::msgcat::mcset es "XML Not Well-Formed" "XML No está Bien Formado" ::msgcat::mcset es "XMPP stream options when connecting to server." "Opciones de la conexión XMPP cuando se conecta al servidor." ::msgcat::mcset es "Year:" "Año:" ::msgcat::mcset es "You are unsubscribed from %s" "Te has desubscrito de %s" ::msgcat::mcset es "You're using root directory %s for storing Tkabber logs!\n\nI refuse to convert logs database." "Estas usando el directorio raíz %s para guardas los ficheros históricos de Tkabber!\n\nNo se van a convertir esos ficheros." ::msgcat::mcset es "Your new Tkabber config directory is now:\n%s\nYou can delete the old one:\n%s" "Tu nuevo directorio de configuración de Tkabber es:\n%s\nPuedes borrar el directorio viejo:\n%s" ::msgcat::mcset es "Zip:" "Código Postal:" ::msgcat::mcset es "\nAlternative venue: %s" "\nLugar alternativo: %s" ::msgcat::mcset es "\nReason is: %s" "\nLa razón es: %s" ::msgcat::mcset es "\nReason: %s" "\nRazón: %s" ::msgcat::mcset es "\nRoom is empty at %s" "\nLa sala %s está vacía" ::msgcat::mcset es "\nRoom participants at %s:" "\nParticipantes a las %s:" ::msgcat::mcset es "\n\tActivity: %s" "\n\tActividad: %s" ::msgcat::mcset es "\n\tAffiliation: %s" "\n\tAfiliación: %s" ::msgcat::mcset es "\n\tCan't browse: %s" "\n\tNo se puede navegar: %s" ::msgcat::mcset es "\n\tClient: %s" "\n\tCliente: %s" ::msgcat::mcset es "\n\tJID: %s" "\n\tJID: %s" ::msgcat::mcset es "\n\tLocation: %s : %s" "\n\tLocalización: %s : %s" ::msgcat::mcset es "\n\tMood: %s" "\n\tEstado de ánimo: %s" ::msgcat::mcset es "\n\tName: %s" "\n\tNombre: %s" ::msgcat::mcset es "\n\tOS: %s" "\n\tSO: %s" ::msgcat::mcset es "\n\tPresence is signed:" "\n\tLa presencia está firmada:" ::msgcat::mcset es "\n\tTune: %s - %s" "\n\tCanción: %s - %s" ::msgcat::mcset es "\n\tUser activity subscription: %s" "\n\tSubscripción a la actividad de usuario: %s" ::msgcat::mcset es "\n\tUser location subscription: %s" "\n\tSubscripción a la localización del usuario: %s" ::msgcat::mcset es "\n\tUser mood subscription: %s" "\n\tSubscripción al estado de ánimo de usuario: %s" ::msgcat::mcset es "\n\tUser tune subscription: %s" "\n\tSubscripción a la canción de usuario: %s" ::msgcat::mcset es "admin" "admin" ::msgcat::mcset es "afraid" "asustado" ::msgcat::mcset es "amazed" "sorprendido" ::msgcat::mcset es "and" "y" ::msgcat::mcset es "angry" "enfadado" ::msgcat::mcset es "annoyed" "molesto" ::msgcat::mcset es "anxious" "ansioso" ::msgcat::mcset es "aroused" "despertado" ::msgcat::mcset es "as %s/%s" "como %s/%s" ::msgcat::mcset es "ashamed" "avergonzado" ::msgcat::mcset es "at the spa" "en el balneario" ::msgcat::mcset es "auto-away" "auto-ausencia" ::msgcat::mcset es "avatars" "avatares" ::msgcat::mcset es "balloon help" "ayuda contextual" ::msgcat::mcset es "bored" "aburrido" ::msgcat::mcset es "brave" "valiente" ::msgcat::mcset es "browsing" "explorando" ::msgcat::mcset es "brushing teeth" "lavándose los dientes" ::msgcat::mcset es "buying groceries" "comprando comida" ::msgcat::mcset es "bwidget workarounds" "arreglos de bwidget" ::msgcat::mcset es "calm" "calmado" ::msgcat::mcset es "change message type to" "cambiar el tipo del mensaje a" ::msgcat::mcset es "cleaning" "limpiando" ::msgcat::mcset es "coding" "programando" ::msgcat::mcset es "cold" "frío" ::msgcat::mcset es "commuting" "viaje diario" ::msgcat::mcset es "configuration" "configuración" ::msgcat::mcset es "confused" "confundido" ::msgcat::mcset es "connections" "conexiones" ::msgcat::mcset es "contented" "contento" ::msgcat::mcset es "continue processing rules" "seguir procesando reglas" ::msgcat::mcset es "cooking" "cocinando" ::msgcat::mcset es "cranky" "quisquilloso" ::msgcat::mcset es "cryptographics" "criptografía" ::msgcat::mcset es "curious" "curioso" ::msgcat::mcset es "customization" "personalización" ::msgcat::mcset es "cycling" "en bicicleta" ::msgcat::mcset es "day off" "día libre" ::msgcat::mcset es "day" "día" ::msgcat::mcset es "days" "días" ::msgcat::mcset es "depressed" "deprimido" ::msgcat::mcset es "disappointed" "decepcionado" ::msgcat::mcset es "disgusted" "disgustado" ::msgcat::mcset es "distracted" "distraído" ::msgcat::mcset es "doesn't want to be disturbed" "no quiere ser molestado" ::msgcat::mcset es "doing chores" "haciendo faenas" ::msgcat::mcset es "doing maintenance" "haciendo mantenimiento" ::msgcat::mcset es "doing the dishes" "lavando los platos" ::msgcat::mcset es "doing the laundry" "haciendo la colada" ::msgcat::mcset es "drinking" "bebiendo" ::msgcat::mcset es "driving" "conduciendo" ::msgcat::mcset es "eating" "comiendo" ::msgcat::mcset es "embarrassed" "embarazoso" ::msgcat::mcset es "emoticons" "emoticonos" ::msgcat::mcset es "excited" "excitado" ::msgcat::mcset es "exercising" "haciendo ejercicio" ::msgcat::mcset es "extension management" "gestión de extensiones" ::msgcat::mcset es "file transfer" "transferencia de ficheros" ::msgcat::mcset es "flirtatious" "flirteo" ::msgcat::mcset es "forward message to" "reenviar el mensaje a" ::msgcat::mcset es "frustrated" "frustrado" ::msgcat::mcset es "gaming" "jugando" ::msgcat::mcset es "gardening" "haciendo jardinería" ::msgcat::mcset es "general plugins" "plugins generales" ::msgcat::mcset es "getting a haircut" "en la peluquería" ::msgcat::mcset es "going out" "saliendo" ::msgcat::mcset es "grooming" "acicalándose" ::msgcat::mcset es "grumpy" "irritable" ::msgcat::mcset es "guilty" "culpable" ::msgcat::mcset es "hanging out" "demorándose" ::msgcat::mcset es "happy" "feliz" ::msgcat::mcset es "having a beer" "tomando una cerveza" ::msgcat::mcset es "having a snack" "tomando un aperitivo" ::msgcat::mcset es "having appointment" "en una cita" ::msgcat::mcset es "having breakfast" "tomando el almuerzo" ::msgcat::mcset es "having coffee" "tomando un café" ::msgcat::mcset es "having dinner" "cenando" ::msgcat::mcset es "having lunch" "comiendo" ::msgcat::mcset es "having tea" "tomando un té" ::msgcat::mcset es "hiking" "de excursión" ::msgcat::mcset es "hot" "caliente" ::msgcat::mcset es "hour" "hora" ::msgcat::mcset es "hours" "horas" ::msgcat::mcset es "humbled" "humilde" ::msgcat::mcset es "humiliated" "humillado" ::msgcat::mcset es "hungry" "hambriento" ::msgcat::mcset es "hurt" "dolido" ::msgcat::mcset es "impressed" "impresionado" ::msgcat::mcset es "in a car" "en un coche" ::msgcat::mcset es "in a meeting" "en una reunión" ::msgcat::mcset es "in real life" "en la vida real" ::msgcat::mcset es "in_awe" "admirador" ::msgcat::mcset es "in_love" "enamorado" ::msgcat::mcset es "inactive" "inactivo" ::msgcat::mcset es "indignant" "indigno" ::msgcat::mcset es "interested" "interesado" ::msgcat::mcset es "intoxicated" "intoxicado" ::msgcat::mcset es "invalid userstatus value " "valor de estado de usuario inválido " ::msgcat::mcset es "invincible" "invencible" ::msgcat::mcset es "is available" "está disponible" ::msgcat::mcset es "is away" "esta ausente" ::msgcat::mcset es "is extended away" "está muy ausente" ::msgcat::mcset es "is free to chat" "está disponible para charlar" ::msgcat::mcset es "is invisible" "está invisible" ::msgcat::mcset es "is now" "está ahora" ::msgcat::mcset es "is unavailable" "está desconectado" ::msgcat::mcset es "jabber chat/muc" "salas de charla" ::msgcat::mcset es "jabber iq" "Jabber iq" ::msgcat::mcset es "jabber messages" "mensajes" ::msgcat::mcset es "jabber presence" "presencia Jabber" ::msgcat::mcset es "jabber registration" "registro Jabber" ::msgcat::mcset es "jabber roster" "lista de contactos" ::msgcat::mcset es "jabber xml" "Jabber XML" ::msgcat::mcset es "jealous" "celoso" ::msgcat::mcset es "jogging" "haciendo jogging" ::msgcat::mcset es "kde" ::msgcat::mcset es "last %s%s: %s" "último %s%s: %s" ::msgcat::mcset es "last %s%s:" "último %s%s:" ::msgcat::mcset es "lonely" "solitario" ::msgcat::mcset es "macintosh plugins" "plugins de macintosh" ::msgcat::mcset es "mean" "ruin" ::msgcat::mcset es "member" "miembro" ::msgcat::mcset es "message filters" "filtros de mensajes" ::msgcat::mcset es "minute" "minuto" ::msgcat::mcset es "minutes" "minutos" ::msgcat::mcset es "moderator" "moderador" ::msgcat::mcset es "moody" "malhumorado" ::msgcat::mcset es "my status is" "mi estado es" ::msgcat::mcset es "negotiation" "negociación" ::msgcat::mcset es "nervous" "nervioso" ::msgcat::mcset es "neutral" "neutral" ::msgcat::mcset es "none" "nada" ::msgcat::mcset es "offended" "ofendido" ::msgcat::mcset es "on a bus" "en un autobús" ::msgcat::mcset es "on a plane" "en un avión" ::msgcat::mcset es "on a train" "en un tren" ::msgcat::mcset es "on a trip" "en un viaje" ::msgcat::mcset es "on the phone" "al teléfono" ::msgcat::mcset es "on vacation" "de vacaciones" ::msgcat::mcset es "on video phone" "en el videoteléfono" ::msgcat::mcset es "outcast" "bloqueado" ::msgcat::mcset es "owner" "dueño" ::msgcat::mcset es "participant" "participante" ::msgcat::mcset es "partying" "en una fiesta" ::msgcat::mcset es "pixmaps management" "manejo de pixmaps" ::msgcat::mcset es "playful" "juguetón" ::msgcat::mcset es "playing sports" "practicando un deporte" ::msgcat::mcset es "plugin management" "gestión de plugins" ::msgcat::mcset es "presence" "presencia" ::msgcat::mcset es "privacy rules" "reglas de privacidad" ::msgcat::mcset es "proud" "orgulloso" ::msgcat::mcset es "reading" "leyendo" ::msgcat::mcset es "rehearsing" "ensayando" ::msgcat::mcset es "relaxing" "relajándose" ::msgcat::mcset es "relieved" "aliviado" ::msgcat::mcset es "remorseful" "arrepentido" ::msgcat::mcset es "reply with" "responder con" ::msgcat::mcset es "restless" "inquieto" ::msgcat::mcset es "roster plugins" "plugins de lista de contactos" ::msgcat::mcset es "running an errand" "haciendo un recado" ::msgcat::mcset es "running" "corriendo" ::msgcat::mcset es "sad" "triste" ::msgcat::mcset es "sarcastic" "sarcástico" ::msgcat::mcset es "scheduled holiday" "vacaciones planificadas" ::msgcat::mcset es "search plugins" "plugins de búsqueda" ::msgcat::mcset es "searching" "buscando" ::msgcat::mcset es "second" "segundo" ::msgcat::mcset es "seconds" "segundos" ::msgcat::mcset es "serious" "serio" ::msgcat::mcset es "service discovery" "descubrimiento de servicios" ::msgcat::mcset es "shaving" "afeitándose" ::msgcat::mcset es "shocked" "consternado" ::msgcat::mcset es "shopping" "de compras" ::msgcat::mcset es "shy" "tímido" ::msgcat::mcset es "sick" "enfermo" ::msgcat::mcset es "skiing" "esquiando" ::msgcat::mcset es "sleeping" "durmiendo" ::msgcat::mcset es "sleepy" "adormilado" ::msgcat::mcset es "socializing" "socializando" ::msgcat::mcset es "sound" "sonido" ::msgcat::mcset es "store this message offline" "guardar este mensaje fuera de linea" ::msgcat::mcset es "stressed" "estresado" ::msgcat::mcset es "studying" "estudiando" ::msgcat::mcset es "sunbathing" "bronceándose" ::msgcat::mcset es "surprised" "sorprendido" ::msgcat::mcset es "swimming" "nadando" ::msgcat::mcset es "taking a bath" "bañándose" ::msgcat::mcset es "taking a shower" "duchándose" ::msgcat::mcset es "talking" "hablando" ::msgcat::mcset es "the body is" "el cuerpo del mensaje es" ::msgcat::mcset es "the message is from" "el mensaje es de" ::msgcat::mcset es "the message is sent to" "el mensaje se envía a" ::msgcat::mcset es "the message type is" "el tipo del mensaje es" ::msgcat::mcset es "the option is set and saved." "opción modificada y guardada." ::msgcat::mcset es "the option is set to its default value." "opción en su valor por defecto." ::msgcat::mcset es "the option is set, but not saved." "opción modificada pero no guardada." ::msgcat::mcset es "the option is taken from config file." "opción leída del fichero de configuración." ::msgcat::mcset es "the subject is" "el asunto es" ::msgcat::mcset es "thirsty" "sediento" ::msgcat::mcset es "time %s%s: %s" "tiempo %s%s: %s" ::msgcat::mcset es "time %s%s:" "tiempo %s%s:" ::msgcat::mcset es "traveling" "viajando" ::msgcat::mcset es "unix plugins" "plugins de unix" ::msgcat::mcset es "unknown" "desconocido" ::msgcat::mcset es "user interface" "interfaz de usuario" ::msgcat::mcset es "utilities" "herramientas" ::msgcat::mcset es "vCard display options in chat windows." "Opciones de visualización de vCard en la ventana de charla." ::msgcat::mcset es "value is changed, but the option is not set." "valor modificado, pero opción no modificada." ::msgcat::mcset es "vcard %s%s: %s" "vCard %s%s: %s" ::msgcat::mcset es "vcard %s%s:" "vCard %s%s:" ::msgcat::mcset es "version %s%s: %s" "versión %s%s: %s" ::msgcat::mcset es "version %s%s:" "versión %s%s:" ::msgcat::mcset es "visitor" "visitante" ::msgcat::mcset es "walking the dog" "paseando al perro" ::msgcat::mcset es "walking" "andando" ::msgcat::mcset es "watching a movie" "viendo una película" ::msgcat::mcset es "watching tv" "viendo la TV" ::msgcat::mcset es "whois %s: %s" "Quien es %s: %s" ::msgcat::mcset es "whois %s: no info" "Quien es %s: información no disponible" ::msgcat::mcset es "windows plugins" "plugins de ventanas" ::msgcat::mcset es "wmaker" ::msgcat::mcset es "working out" "trabajando duro" ::msgcat::mcset es "working" "trabajando" ::msgcat::mcset es "worried" "preocupado" ::msgcat::mcset es "writing" "escribiendo" tkabber-0.11.1/msgs/eu.msg0000644000175000017500000010052711014357121014614 0ustar sergeisergei# $Id: eu.msg 1433 2008-05-19 20:08:49Z sergei $ # basque messages file # Author: Euskalerria.org / jalgitalki@euskalerria.org # http://www.euskalerria.org/jalgitalki JID: jalgitalki@jalgitalki.euskalerria.org # Please notify me of errors or incoherencies # avatars.tcl ::msgcat::mcset eu "No avatar to store" "ez dago gertaerarik gordetzeko dena" # browser.tcl ::msgcat::mcset eu "JBrowser" "Jabber Esploratzailea" ::msgcat::mcset eu "JID:" "JID:" ::msgcat::mcset eu "Browse" "Esploratu" ::msgcat::mcset eu "%s: %s/%s, Description: %s, Version: %s\nNumber of children: %s" "%s: %s/%s, Deskripzioa: %s, aldaera: %s\n2. mailako taldeak: %s" # chats.tcl ::msgcat::mcset eu ">>> Unable to decipher data: %s <<<" ">>> Ezin izan da daturik ulertu: %s <<<" ::msgcat::mcset eu "Error %s: %s" "Akatsa %s: %s" ::msgcat::mcset eu "Chat with %s" "Norekin mintzatu %s" ::msgcat::mcset eu "Toggle encryption" "Enkriptaketa hasi/amaitu" ::msgcat::mcset eu "To:" "Norentzat:" ::msgcat::mcset eu "Subject:" "Gaia:" ::msgcat::mcset eu "Error %s" "Akatsa %s" ::msgcat::mcset eu "Disconnected" "Ezezaguna" ::msgcat::mcset eu "Invite %s to conferences" "%s Gonbidatu taldean mintzatzeko" ::msgcat::mcset eu "Invite users..." "Erabiltzaileak gonbidatu..." ::msgcat::mcset eu "Invite" "Gonbidatu" ::msgcat::mcset eu "Please join %s" "Mesedez, hemen sartu: %s" ::msgcat::mcset eu "Invite users to %s" "Erabiltzaileak gonbidatu %s (e)ra" ::msgcat::mcset eu "No conferences in progress..." "Orain ez dago talde-mintzalderik..." ::msgcat::mcset eu "Send custom presence" "Bertan zaudela adierazi (pertsonalizatuta)" # custom.tcl ::msgcat::mcset eu "Customization of the One True Jabber Client." "Jabberren egiazko bezeroaren konfigurazioa." ::msgcat::mcset eu "Open" "Ireki" ::msgcat::mcset eu "Parent group:" "Talde nagusia:" ::msgcat::mcset eu "Parent groups:" "Talde nagusiak:" ::msgcat::mcset eu "State" "Egoera" ::msgcat::mcset eu "you have edited the value, but you have not set the option." "Balioa editatu egin duzu baina ez duzu aukerarik egin." ::msgcat::mcset eu "this option is unchanged from its standard setting." "aukera honi ez zaio bere definizio estandarra aldatu." ::msgcat::mcset eu "you have set this option, but not saved it for future sessions." "aukera aktibatu duzu, baina ez duzu gorde hurrengoetarako." ::msgcat::mcset eu "this option has been set and saved." "aukera hau definitu eta gorde egin da." ::msgcat::mcset eu "Set for Current Session" "Jardun honetarako zehaztu" ::msgcat::mcset eu "Set for Future Sessions" "Zehaztu hurrengo jardunetarako" ::msgcat::mcset eu "Reset to Current" "Oraingo baliora erabili" ::msgcat::mcset eu "Reset to Saved" "Gordetako balioa erabili" ::msgcat::mcset eu "Reset to Default" "Programaren balioa erabili" # datagathering.tcl # disco.tcl ::msgcat::mcset eu "Jabber Discovery" "Jabber Aurkikuntza" ::msgcat::mcset eu "Node:" "Nodoa:" ::msgcat::mcset eu "Error getting info: %s" "Akatsa informazioa biltzean: %s" ::msgcat::mcset eu "Error getting items: %s" "Akatsa datuak eskuratzen: %s" ::msgcat::mcset eu "Error negotiate: %s" "Akatsa negoziatzen: %s" # emoticons.tcl # filetransfer.tcl ::msgcat::mcset eu "Send file to %s" "Artxiboa nori bidali: %s" ::msgcat::mcset eu "File to Send:" "Bidaltzeko artxiboa:" ::msgcat::mcset eu "Browse..." "Esploratu..." ::msgcat::mcset eu "Description:" "Azalpena:" ::msgcat::mcset eu "IP address:" "IP helbidea:" ::msgcat::mcset eu "File not found or not regular file: %s" "Aurkitu gabego edo ohikoa ez den atxiboa" ::msgcat::mcset eu "Receive file from %s" "Artxiboa norengandik jaso: %s" ::msgcat::mcset eu "Save as:" "Nola gorde:" ::msgcat::mcset eu "Receive" "Jaso" ::msgcat::mcset eu "Request failed: %s" "Eskaera okerra: %s" ::msgcat::mcset eu "Transfering..." "Eskualdatzen..." ::msgcat::mcset eu "Size:" "Neurria:" ::msgcat::mcset eu "Connection closed" "Konexioa etenda" # filters.tcl ::msgcat::mcset eu "I'm not online" "Ez nago konekatuta" ::msgcat::mcset eu "the message is from" "Norena den mezua:" ::msgcat::mcset eu "the message is sent to" "norentzat den mezua:" ::msgcat::mcset eu "the subject is" "zein den gaia:" ::msgcat::mcset eu "the body is" "zein den mezuaren muina" ::msgcat::mcset eu "my status is" "nire egoera da..." ::msgcat::mcset eu "the message type is" "zein den mezuaren tankera" ::msgcat::mcset eu "change message type to" "mezuaren tankera aldatu" ::msgcat::mcset eu "forward message to" "mezua nori berbidali..." ::msgcat::mcset eu "reply with" "erantzun" ::msgcat::mcset eu "store this message offline" "mezu hau lerrotik at gorde" ::msgcat::mcset eu "continue processing rules" "jarrai arauak lantzen" ::msgcat::mcset eu "Filters" "Iragazkiak" ::msgcat::mcset eu "Add" "Gehitu" ::msgcat::mcset eu "Edit" "Editatu" ::msgcat::mcset eu "Remove" "Ezabatu" ::msgcat::mcset eu "Move up" "gora eraman" ::msgcat::mcset eu "Move down" "Behera eraman" ::msgcat::mcset eu "Edit rule" "Araua editatu" ::msgcat::mcset eu "Rule Name:" "Arauaren izena:" ::msgcat::mcset eu "Empty rule name" "Arauaren izena hutsik" ::msgcat::mcset eu "Rule name already exists" "Arauaren izena erabilita dago" ::msgcat::mcset eu "Condition" "baldintza" ::msgcat::mcset eu "Action" "Ekintza" # gpgme.tcl ::msgcat::mcset eu "Encrypt traffic" "Datuak enkriptatu" ::msgcat::mcset eu "Change security preferences for %s" "Seguritate baldintzak aldatu honentzat %s" ::msgcat::mcset eu "Select Key for Signing Traffic" "Datu-trukaketa izenpetzeko, giltza aukeratu" ::msgcat::mcset eu "Select" "Aukeratu" ::msgcat::mcset eu "Please enter passphrase" "Sar, mesedez, esaldi-giltza" ::msgcat::mcset eu "Please try again" "Saiatu berriz, mesedez" ::msgcat::mcset eu "Key ID" "Giltzaren IDa" ::msgcat::mcset eu "User ID" "Erabiltzailearen IDa" ::msgcat::mcset eu "Passphrase:" "Esaldi-giltza:" ::msgcat::mcset eu "Error in signature verification software: %s." "Akatsa izenpearen egiaztatzeko programan: %s." ::msgcat::mcset eu "%s purportedly signed by %s can't be verified.\n\n%s." "%s izenpetuta baina ezin da egiaztatu.\n\n%s." ::msgcat::mcset eu "Unable to sign presence information: %s.\n\nPresence will be sent, but signing traffic is now disabled." "Ezin da egote-informazioa izenpetu: %s.\n\nAgerpena adieraziko da, baina datu-trukaketaren izenpea desaktibatuta dago." ::msgcat::mcset eu "Unable to sign message body: %s.\n\nSigning traffic is now disabled.\n\nSend it WITHOUT a signature?" "Ezin da mezuaren muina izenpetu: %s.\n\nIzenpetu gabe bidali?" ::msgcat::mcset eu "Data purported sent by %s can't be deciphered.\n\n%s." "%s (e)k bidalitako datuak ezin dira ulertu.\n\n%s." ::msgcat::mcset eu "Unable to encipher data for %s: %s.\n\nEncrypting traffic to this user is now disabled.\n\nSend it as PLAINTEXT?" "Ezin da daturik enkritatu %s(r)entzat: %s.\n\nErabiltzaile honentzat, datuen enkriptazioa desaktibatuta dago hemendik aurrera.\n\nDATU GARBIAK bidali?" ::msgcat::mcset eu "" "" # iface.tcl ::msgcat::mcset eu "Options for main interface." "Interfaze nagusiaren aukerak." ::msgcat::mcset eu "Raise new tab." "Hegal berria sortu." ::msgcat::mcset eu "Colors for tab alert levels." "Hegalen alerta-mailentzako koloreak." ::msgcat::mcset eu "Presence" "bertan naiz" ::msgcat::mcset eu "Online" "Konektatuta" ::msgcat::mcset eu "Free to chat" "Mintzatzeko gertu" ::msgcat::mcset eu "Away" "Ez nago" ::msgcat::mcset eu "Extended Away" "Zeharo at" ::msgcat::mcset eu "Do not disturb" "Ez deitu" ::msgcat::mcset eu "Invisible" "Ikustezin" ::msgcat::mcset eu "Log in..." "Hasi jarduna..." ::msgcat::mcset eu "Log out" "Jarduna itxi" ::msgcat::mcset eu "Log out with reason..." "Jarduna itxi honegatik..." ::msgcat::mcset eu "Customize" "Konfiguratu" ::msgcat::mcset eu "Profile on" "Profila" ::msgcat::mcset eu "Profile report" "Profilaren datuak" ::msgcat::mcset eu "Quit" "Irten" ::msgcat::mcset eu "Services" "Zerbitzuak" ::msgcat::mcset eu "Send message..." "Mezua bidali..." ::msgcat::mcset eu "Roster" "Roster" ::msgcat::mcset eu "Add user..." "Erabiltzailea gehitu..." ::msgcat::mcset eu "Add conference..." "Mintza-taldea gehitu..." ::msgcat::mcset eu "Add group by regexp on JIDs..." "Taldea sortu regexp bidez JID gainean..." ::msgcat::mcset eu "Show online users only" "Konektatutako erabiltzaileak erakuts, ez beste" ::msgcat::mcset eu "Use aliases" "Gaitzizenak erabili" ::msgcat::mcset eu "Export roster..." "Zerrenda eraman..." ::msgcat::mcset eu "Import roster..." "Zerrenda ekarri..." ::msgcat::mcset eu "Periodically browse roster conferences" "Zerrendan diren mintza-taldeak aldian behin ikuskatu" ::msgcat::mcset eu "Browser" "Esploratzailea" ::msgcat::mcset eu "Discovery" "Aurkikuntza" ::msgcat::mcset eu "Join group..." "Mintza-taldean sartu..." ::msgcat::mcset eu "Chats" "Mintzaldiak" ::msgcat::mcset eu "Create room..." "Mintza-gela sortu" ::msgcat::mcset eu "Generate event messages" "Gertaera-mezuak sortu" ::msgcat::mcset eu "Stop autoscroll" "Ez mugitu goitik behera automatikoki" ::msgcat::mcset eu "Sound" "Hotsa" ::msgcat::mcset eu "Mute" "Ixilik" ::msgcat::mcset eu "Filters..." "Iragazkiak..." ::msgcat::mcset eu "Privacy rules..." "Pribatutasun arauak..." ::msgcat::mcset eu "Message archive" "Mezuen biltegia" ::msgcat::mcset eu "Change password..." "Pasahitza aldatu..." ::msgcat::mcset eu "Show user info..." "Erabiltzaile informazioa erakutsi..." ::msgcat::mcset eu "Edit my info..." "Aldatu nitaz dagoen informazioa..." ::msgcat::mcset eu "Avatar" "Gertaera" ::msgcat::mcset eu "Announce" "Iragarri" ::msgcat::mcset eu "Allow downloading" "Utzi deskargatzen" ::msgcat::mcset eu "Send to server" "Zerbitzariari bidali" ::msgcat::mcset eu "Jidlink" ::msgcat::mcset eu "Admin tools" "Administrazio-tresnak" ::msgcat::mcset eu "Open raw XML window" "XML gordinaren leihoa ireki" ::msgcat::mcset eu "Send broadcast message..." "Difusio-mezua bidali..." ::msgcat::mcset eu "Send message of the day..." "Egun honetako mezua bidali..." ::msgcat::mcset eu "Update message of the day..." "Egun honetako mezua eguneratu..." ::msgcat::mcset eu "Delete message of the day" "Egun honetako mezua ezabatu" ::msgcat::mcset eu "Help" "Laguntza" ::msgcat::mcset eu "Quick help" "Laguntza bizkorra" ::msgcat::mcset eu "Quick Help" "Laguntza bizkorra" ::msgcat::mcset eu "Main window:" "Leiho nagusia:" ::msgcat::mcset eu "Tabs:" "Hegalak:" ::msgcat::mcset eu "Chats:" "Mintzaldiak:" ::msgcat::mcset eu "Close tab" "Hegala itxi" ::msgcat::mcset eu "Previous/Next tab" "Aurreko/hurrengo hegala" ::msgcat::mcset eu "Hide/Show roster" "Zerrenda erakutsi/ezkutatu" ::msgcat::mcset eu "Complete nickname" "Gaitzizena osatu" ::msgcat::mcset eu "Previous/Next history message" "Aurreko/hurrengo mezua" ::msgcat::mcset eu "Show emoticons" "Marrazkiak erakutsi" ::msgcat::mcset eu "Undo" "Desegin" ::msgcat::mcset eu "Redo" "Berregin" ::msgcat::mcset eu "Scroll chat window up/down" "Mintza-leihoa gora/behera mugitu" ::msgcat::mcset eu "Correct word" "Hitza zuzendu" ::msgcat::mcset eu "About" "Programaz" ::msgcat::mcset eu "Authors:" "Egileak:" ::msgcat::mcset eu "Alexey Shchepin" "Alexey Shchepin" ::msgcat::mcset eu "Marshall T. Rose" "Marshall T. Rose" ::msgcat::mcset eu "Sergei Golovan" "Sergei Golovan" ::msgcat::mcset eu "Michail Litvak" "Michail Litvak" ::msgcat::mcset eu "Add new user..." "Erabiltzaile berria gehitu..." ::msgcat::mcset eu "Jabber Browser" "Jabber esploratzailea" #::msgcat::mcset eu "Join group..." "Mintza-taldean sartu..." ::msgcat::mcset eu "Toggle showing offline users" "Konektatu gabeko erabiltzaileen zerrenda aktibatu/desaktibatu" ::msgcat::mcset eu "Toggle signing" "Izenpea aktibatu/desaktibatu" ::msgcat::mcset eu "Toggle encryption (when possible)" "Enkriptazioa aktibatu/desaktibatu (ahal denetan)" ::msgcat::mcset eu "Cancel" "Deuseztatu" ::msgcat::mcset eu "Close" "Itxi" ::msgcat::mcset eu "Close other tabs" "Itxi beste hegalak" ::msgcat::mcset eu "Close all tabs" "Itxi hegal guztiak" ::msgcat::mcset eu "Send" "Bidali" # itemedit.tcl ::msgcat::mcset eu "Edit properties for %s" "Ezaugarriak editatu %s" ::msgcat::mcset eu "Edit nickname for %s" "Honen gaitzizena aldatu %s" ::msgcat::mcset eu "Nickname:" "Gaitzizena:" ::msgcat::mcset eu "Edit groups for %s" "Taldeak editatu %s" ::msgcat::mcset eu "Available groups" "Aukeran dauden taldeak" ::msgcat::mcset eu "Group:" "Taldea:" ::msgcat::mcset eu "Current groups" "Oraingo taldeak" ::msgcat::mcset eu "Add ->" "Gehitu ->" ::msgcat::mcset eu "<- Remove" "<- Ezabatu" # jidlink.tcl ::msgcat::mcset eu "Opening Jidlink connection" "Jidlink konexioa irekitzen" ::msgcat::mcset eu "Jidlink connection closed" "Jidlink konexioa itxita" # joingrdialog.tcl ::msgcat::mcset eu "Join group" "Mintza-taldean sartu" ::msgcat::mcset eu "Nick:" "Gaitzizena:" ::msgcat::mcset eu "Group:" "Taldea:" ::msgcat::mcset eu "Server:" "Zerbitzaria:" ::msgcat::mcset eu "use v2 protocol" "v2 protokoloa erabili" ::msgcat::mcset eu "Password (v2 only):" "Pasahitza (v2 bakarrik)" ::msgcat::mcset eu "Join" "Sartu" ::msgcat::mcset eu "Add group" "Mintza-taldea gehitu" ::msgcat::mcset eu "Get conference info failed: %s" "Mintza-taldeaz informazio-eskaerak huts egin du: %s" ::msgcat::mcset eu "Join failed: %s" "Huts egindako sarrera: %s" ::msgcat::mcset eu "Create Room" "Gela sortu" ::msgcat::mcset eu "Address:" "Helbidea:" ::msgcat::mcset eu "Nickname:" "Gaitzizena:" ::msgcat::mcset eu "Password:" "Pasahitza:" ::msgcat::mcset eu "Name: " "Izena:" ::msgcat::mcset eu "Description:" "Azalpena:" ::msgcat::mcset eu "Create" "Sortu" # login.tcl ::msgcat::mcset eu "Login options." "Jardun-hasieraren aukerak." ::msgcat::mcset eu "User name." "Erabiltzailea." ::msgcat::mcset eu "Password." "Pasahitza." ::msgcat::mcset eu "Resource." "Baliabidea." ::msgcat::mcset eu "Server name." "Zerbitzaria." ::msgcat::mcset eu "Server port." "Portua." ::msgcat::mcset eu "Priority." "Lehentasuna." ::msgcat::mcset eu "Use SSL to connect to server." "Konexioan SSL erabili" ::msgcat::mcset eu "SSL port." "SSL portua." ::msgcat::mcset eu "Use HTTP proxy to connect." "Konexioan HTTP proxya erabili." ::msgcat::mcset eu "HTTP proxy address." "HTTP proxyaren helbidea." ::msgcat::mcset eu "HTTP proxy port." "HTTP proxyaren portua." ::msgcat::mcset eu "HTTP proxy username." "HTTP proxyaren erabiltzailea." ::msgcat::mcset eu "HTTP proxy password." "HTTP proxyaren pasahitza." ::msgcat::mcset eu "Use explicitly-specified server address." "Zehazki adierazitako zerbitzariaren helbidea erabili." ::msgcat::mcset eu "Server name or IP-address." "Zerbitzariaren izena ala IP helbidea." ::msgcat::mcset eu "Login" "jarduna hasi" ::msgcat::mcset eu "Username:" "Erabiltzailea:" ::msgcat::mcset eu "Password:" "Pasahitza:" ::msgcat::mcset eu "Server:" "Zerbitzaria:" ::msgcat::mcset eu "Resource:" "Baliabidea:" ::msgcat::mcset eu "Port:" "Portua:" ::msgcat::mcset eu "Use hashed password" "Pasahitzaren laburpena erabili" ::msgcat::mcset eu "Connect via alternate server" "Ordezko zerbitzariaren bidez konektatu" ::msgcat::mcset eu "Use SSL" "SSL erabili" ::msgcat::mcset eu "SSL Port:" "SSL portua:" ::msgcat::mcset eu "Use Proxy" "Proxya erabili" ::msgcat::mcset eu "Proxy Server:" "Proxy zerbitzaria:" ::msgcat::mcset eu "Proxy Port:" "Proxyaren portua:" ::msgcat::mcset eu "Proxy Login:" "Proxyaren erabiltzailea:" ::msgcat::mcset eu "Proxy Password:" "Proxyaren pasahitza:" ::msgcat::mcset eu "Profiles" "Soslaiak" ::msgcat::mcset eu "Profile" "Soslaia" ::msgcat::mcset eu "Authentication failed: %s\nCreate new account?" "Egiaztapenak huts egin du: %s\nKontu berria sortu?" ::msgcat::mcset eu "Registration failed: %s" "Errejistroak huts egin du: %s" ::msgcat::mcset eu "Change password" "Pasahitza aldatu" ::msgcat::mcset eu "Old password:" "Pasahitz zaharra:" ::msgcat::mcset eu "New password:" "Pasahitz berria:" ::msgcat::mcset eu "Repeat new password:" "Idatzi berriz pasahitz berria:" ::msgcat::mcset eu "Old password is incorrect" "Pasahitz zaharra okerra da" ::msgcat::mcset eu "New passwords do not match" "Pasahitz berriak ez dira berdinak" ::msgcat::mcset eu "Password is changed" "Pasahitza aldatu egin da" ::msgcat::mcset eu "Password change failed: %s" "Pasahitz aldaketak huts egin du: %s" ::msgcat::mcset eu "Logout with reason" "Jarduna itxi zio honekin" ::msgcat::mcset eu "Reason:" "Zergatia:" ::msgcat::mcset eu "Priority:" "Lehentasuna:" # messages.tcl ::msgcat::mcset eu "Message from %s" "Honen mezua %s" ::msgcat::mcset eu "Message from" "Noren mezua" ::msgcat::mcset eu "Extras from %s" "Honen gehigarriak %s" ::msgcat::mcset eu "Extras from" "Noren gehigarriak" ::msgcat::mcset eu "Reply" "Erantzun" ::msgcat::mcset eu "Attached user:" "Atxikitako erabiltzailea:" ::msgcat::mcset eu "Attached file:" "Atxikitako artxiboa:" ::msgcat::mcset eu "Invited to:" "Nori gonbidatu:" ::msgcat::mcset eu "Message body" "Mezuaren muina" ::msgcat::mcset eu "Send message to %s" "Nori bidali mezua %s" ::msgcat::mcset eu "Send message" "Mezua bidali" ::msgcat::mcset eu "This message is encrypted." "Mezu hau enkriptatuta dago." ::msgcat::mcset eu "Subscribe request from %s" "Honen harpidetza eskaera %s" ::msgcat::mcset eu "Subscribe request from" "Honen harpidetza eskaera" ::msgcat::mcset eu "Subscribe" "Harpidetu" ::msgcat::mcset eu "Unsubscribe" "Harpidetza eten" ::msgcat::mcset eu "Send subscription" "Harpidetza bidali" ::msgcat::mcset eu "Send subscription to %s" "Nori bidali harpidetza %s" ::msgcat::mcset eu "Send subscription to " "Nori bidali harpidetza " ::msgcat::mcset eu "Headlines" "Izenburuak" ::msgcat::mcset eu "Toggle seen" "-ikusita- aktibatu/deskaktibatu" ::msgcat::mcset eu "Sort" "Sailkatu" # muc.tcl #::msgcat::mcset eu "Whois" "" #::msgcat::mcset eu "Kick" "" #::msgcat::mcset eu "Ban" "" #::msgcat::mcset eu "Grant Voice" "" #::msgcat::mcset eu "Revoke Voice" "" #::msgcat::mcset eu "Grant Membership" "" #::msgcat::mcset eu "Revoke Membership" "" #::msgcat::mcset eu "Grant Moderator Privilege" "" #::msgcat::mcset eu "Revoke Moderator Privilege" "" #::msgcat::mcset eu "MUC" "" #::msgcat::mcset eu "Configure" "" #::msgcat::mcset eu "Edit admin list" "" #::msgcat::mcset eu "Edit moderator list" "" #::msgcat::mcset eu "Edit ban list" "" #::msgcat::mcset eu "Edit member list" "" #::msgcat::mcset eu "Edit voice list" "" #::msgcat::mcset eu "Destroy" "" # presence.tcl ::msgcat::mcset eu "Not logged in" "Konektatu gabe" #::msgcat::mcset eu "Online" "Konektatuta" #::msgcat::mcset eu "Free to chat" "Mintzatzeko gertu" #::msgcat::mcset eu "Away" "Ez nago" #::msgcat::mcset eu "Extended Away" "Zeharo at" #::msgcat::mcset eu "Do not disturb" "Ez deitu" #::msgcat::mcset eu "Invisible" "Ikustezin" ::msgcat::mcset eu "Offline" "Konektatu gabe" ::msgcat::mcset eu "invalid userstatus value " "erabiltzailearen egoera balioa okerra " # privacy.tcl ::msgcat::mcset eu "Requesting privacy rules: %s" "Pribatutasun arauak eskatzen: %s" ::msgcat::mcset eu "Zebra lists" "Zebra zerrendak" ::msgcat::mcset eu "Add list" "Zerrenda gehitu" ::msgcat::mcset eu "No active" "Geldirik" ::msgcat::mcset eu "Type:" "Mota:" ::msgcat::mcset eu "Subscription:" "Harpidetza:" ::msgcat::mcset eu "Zebra list: %s" "Zebra zerrenda: %s" ::msgcat::mcset eu "Active" "Abian" ::msgcat::mcset eu "Remove list" "Zerrenda ezabatu" ::msgcat::mcset eu "Add item" "Datua gehitu" # register.tcl ::msgcat::mcset eu "Register in %s" "%s(ea)n izena eman" ::msgcat::mcset eu "Unsubscribed from %s" "%s(e)tik baja emanda " ::msgcat::mcset eu "We unsubscribed from %s" "%s(ea)n baja eman dugu" # roster.tcl ::msgcat::mcset eu "Undefined" "Zehaztu gabe" ::msgcat::mcset eu "is now" "Oraintxe dago" #::msgcat::mcset eu "Show online & offline users" "konektatu & konektatu gabeko erabiltzaileak erakutsi" #::msgcat::mcset eu "Show online users only" "Konektatuakoak erakutsi, ez beste" ::msgcat::mcset eu "Are you sure to remove %s from roster?" "¿%s zure zerrendatik ezabatzeko ziur zaude??" ::msgcat::mcset eu "Add roster group by JID regexp" "Zerrendan taldea gehitu regexp bidez JID gainean" ::msgcat::mcset eu "New group name:" "Talde berriaren izena:" ::msgcat::mcset eu "JID regexp:" "JID regexp:" ::msgcat::mcset eu "Start chat" "Mintzaldia hasi" #::msgcat::mcset eu "Send message..." "Mezua bidali..." ::msgcat::mcset eu "Invite to conference..." "Mintza-taldera gonbidatu..." ::msgcat::mcset eu "Resubscribe" "Harpidetu berriz" ::msgcat::mcset eu "Send users..." "Erabiltzaileak bidali..." ::msgcat::mcset eu "Send file..." "Artxiboa bidali..." ::msgcat::mcset eu "Send file via Jidlink..." "Artxiboa bidali Jidlink bidez..." ::msgcat::mcset eu "Show info" "Informazioa erakutsi" ::msgcat::mcset eu "Show history" "Historiala erakutsi" ::msgcat::mcset eu "Edit item..." "Datua editatu..." ::msgcat::mcset eu "Edit security..." "Seguritatea editatu..." ::msgcat::mcset eu "Remove..." "Ezabatu..." ::msgcat::mcset eu "Join..." "Mintza-taldean sartu..." ::msgcat::mcset eu "Log in" "Jarduna hasi" ::msgcat::mcset eu "Log out" "Jarduna amaitu" ::msgcat::mcset eu "Send contacts to" "Nori bidali kontaktuak" ::msgcat::mcset eu "Send" "Bidali" ::msgcat::mcset eu "No users in roster..." "Zerrendan ez dago erabiltzailerik..." ::msgcat::mcset eu "Contact Information" "Harremanetarako informazioa" ::msgcat::mcset eu "Raw XML input" "XML gordinaren sarrera" ::msgcat::mcset eu "Rename..." "Berrizendatu..." ::msgcat::mcset eu "Resubscribe to all users in group..." "Harpidetu berriz erabiltzaile guztiak taldean..." # search.tcl ::msgcat::mcset eu "#" "#" ::msgcat::mcset eu "Search in" "Non bilatu" ::msgcat::mcset eu "Search again" "Bilatu berriz" ::msgcat::mcset eu "OK" "Ondo" ::msgcat::mcset eu "Try again" "Saiatu berriz" ::msgcat::mcset eu "An error is occurred when searching in %s\n\n%s" "Akats bat gertatu da hemen bilatzean: %s\n\n%s" # splash.tcl ::msgcat::mcset eu "auto-away" "auto-ezegotea" ::msgcat::mcset eu "avatars" "gertaerak" ::msgcat::mcset eu "balloon help" "testuingu laguntza" ::msgcat::mcset eu "browsing" "nabigazioa" ::msgcat::mcset eu "configuration" "konfigurazioa" ::msgcat::mcset eu "connections" "konexioak" ::msgcat::mcset eu "cryptographics" "kriptografia" ::msgcat::mcset eu "emoticons" "marrazkiak" ::msgcat::mcset eu "extension management" "luzapenen kudeaketa" ::msgcat::mcset eu "file transfer" "artxiboen igorpena" ::msgcat::mcset eu "jabber chat" "Jabber solasgunea" ::msgcat::mcset eu "jabber groupchats" "Jabber mintza-taldeak" ::msgcat::mcset eu "jabber iq" "jabber iq" ::msgcat::mcset eu "jabber presence" "Jabber presentzia" ::msgcat::mcset eu "jabber registration" "Jabber errejistroa" ::msgcat::mcset eu "jabber xml" ::msgcat::mcset eu "kde" ::msgcat::mcset eu "message filters" "mezuen iragazkiak" ::msgcat::mcset eu "message/headline" "mezua/mezuburua" ::msgcat::mcset eu "plugin management" "plugin-en kudeaketa" ::msgcat::mcset eu "presence" "egotea" ::msgcat::mcset eu "rosters" "zerrendak" ::msgcat::mcset eu "searching" "bilatzen" ::msgcat::mcset eu "text undo" "Testua ezabatu" ::msgcat::mcset eu "user interface" "erabiltzaile interfazea" ::msgcat::mcset eu "utilities" "tresnak" ::msgcat::mcset eu "wmaker" # sound.tcl ::msgcat::mcset eu "Sound options." "Hots aukerak." ::msgcat::mcset eu "Mute sound notifying." "Hots jakinarazpenak ixilik." ::msgcat::mcset eu "External program, which is to be executed to play sound. If empty, Snack library is required to play sound." "Hotsa entzuteko abiatuko den kanpoko programa. Hutsik uzten bada, Snack liburutegia behar izango da entzuteko." ::msgcat::mcset eu "Sound theme. If it starts with \"/\" or \"~\" then it is considered as theme directory. Otherwise theme is loaded from \"sounds\" directory of Tkabber tree." "Hots gaia. \"/\" edo \"~\" batez hasten bada, gai direktoriotzat joko da. Bestela, gaia \"sounds\" direktorioan sartuko da Tkabber direktorioaren zuhaitzean." ::msgcat::mcset eu "Time interval before playing next sound (in milliseconds)." "Hotsen arteko denbora tartea (milisegundutan)." # userinfo.tcl ::msgcat::mcset eu "Show user info" "Erabiltzaile-informazioa erakutsi" ::msgcat::mcset eu "Show" "Erakutsi" ::msgcat::mcset eu "%s info" "%s(r)en informazioa" ::msgcat::mcset eu "Personal" "Pertsonala" ::msgcat::mcset eu "Name" "Izena" ::msgcat::mcset eu "Full Name:" "Izen osoa:" ::msgcat::mcset eu "Family Name:" "Deitura:" ::msgcat::mcset eu "Name:" "Izena:" ::msgcat::mcset eu "Middle Name:" "2. izena:" ::msgcat::mcset eu "Prefix:" "Aurrizkia:" ::msgcat::mcset eu "Suffix:" "Atzizkia:" ::msgcat::mcset eu "Nickname:" "Gaitzizena:" ::msgcat::mcset eu "Information" "Informazioa" ::msgcat::mcset eu "E-mail:" "E-posta" ::msgcat::mcset eu "Web Site:" "Web gunea:" ::msgcat::mcset eu "JID:" ::msgcat::mcset eu "UID:" ::msgcat::mcset eu "Phones" "Telefonoak" ::msgcat::mcset eu "Telephone numbers" "Telefono zenbakiak" ::msgcat::mcset eu "Home:" "Etxekoa:" ::msgcat::mcset eu "Work:" "Lanekoa:" ::msgcat::mcset eu "Voice:" "Ahotsa:" ::msgcat::mcset eu "Fax:" "Faxa:" ::msgcat::mcset eu "Pager:" "Bilatu:" ::msgcat::mcset eu "Message Recorder:" "Erantzungailua:" ::msgcat::mcset eu "Cell:" "Sakelekoa:" ::msgcat::mcset eu "Video:" "Bideoa:" ::msgcat::mcset eu "BBS:" ::msgcat::mcset eu "Modem:" "Modema:" ::msgcat::mcset eu "ISDN:" "RDSI:" ::msgcat::mcset eu "PCS:" ::msgcat::mcset eu "Preferred:" "Lehenetsia:" ::msgcat::mcset eu "Location" "Tokia" ::msgcat::mcset eu "Address" "Helbidea" ::msgcat::mcset eu "Address:" "Helbidea:" ::msgcat::mcset eu "Address 2:" "2. helbidea:" ::msgcat::mcset eu "City:" "Herria:" ::msgcat::mcset eu "State:" "Lurraldea:" ::msgcat::mcset eu "Postal Code:" "Posta kodea:" ::msgcat::mcset eu "Country:" "Estatua:" ::msgcat::mcset eu "Geographical position" "Kokapen geografikoa" ::msgcat::mcset eu "Latitude:" "Latitudea:" ::msgcat::mcset eu "Longitude:" "Longitudea:" ::msgcat::mcset eu "Organization" "Erakundea" ::msgcat::mcset eu "Details" "Ñabardurak" # Space at the end of the next word is to distinguish it from another "Name:" ::msgcat::mcset eu "Name: " "izena:" ::msgcat::mcset eu "Unit:" "Unitatea:" # Space at the end of the next word is to distinguish it from another "Personal" ::msgcat::mcset eu "Personal " "Pertsonala" ::msgcat::mcset eu "Title:" "Ardura:" ::msgcat::mcset eu "Role:" "Zeregina:" # Space at the end of the next word is to distinguish it from another "About" ::msgcat::mcset eu "About " "Programaz" ::msgcat::mcset eu "Birthday" "Jaiotze eguna" ::msgcat::mcset eu "Birthday:" "Jaiotze eguna:" ::msgcat::mcset eu "Year:" "Urtea:" ::msgcat::mcset eu "Month:" "Hila:" ::msgcat::mcset eu "Day:" "Eguna:" ::msgcat::mcset eu "Photo" "Argazkia" ::msgcat::mcset eu "URL:" "URLa:" ::msgcat::mcset eu "URL" "URLa" ::msgcat::mcset eu "Image" "Irudia" ::msgcat::mcset eu "None" "Batere ez" ::msgcat::mcset eu "Load Image" "Irudia kargatu" ::msgcat::mcset eu "Avatar" "gartaera" ::msgcat::mcset eu "Client Info" "Bezero-informazioa" ::msgcat::mcset eu "Client" "Bezeroa" ::msgcat::mcset eu "Client:" "Bezeroa:" ::msgcat::mcset eu "Version:" "Bertsioa:" ::msgcat::mcset eu "Last Activity or Uptime" "Azken jarduna edo ibiltze-denbora" ::msgcat::mcset eu "Interval:" "Tartea:" ::msgcat::mcset eu "Description:" "Azalpena:" ::msgcat::mcset eu "Computer" "Konputagailua" ::msgcat::mcset eu "OS:" "SO:" ::msgcat::mcset eu "Time:" "Ordua:" ::msgcat::mcset eu "Time Zone:" "Ordu-gunea:" ::msgcat::mcset eu "UTC:" ::msgcat::mcset eu "Presence" "Presentzia" ::msgcat::mcset eu "Presence id signed" "Presentzia IDa izenpetuta" ::msgcat::mcset eu " by " " nork " # utils.tcl ::msgcat::mcset eu "day" "eguna" ::msgcat::mcset eu "days" "egunak" ::msgcat::mcset eu "hour" "ordua" ::msgcat::mcset eu "hours" "ordu" ::msgcat::mcset eu "minute" "minutu" ::msgcat::mcset eu "minutes" "minutu" ::msgcat::mcset eu "second" "segundo" ::msgcat::mcset eu "seconds" "segundo" # plugins/chat/clear.tcl ::msgcat::mcset eu "Clear chat window" "Solasgunearen leihoa garbitu" # plugins/jidlink/dtcp.tcl ::msgcat::mcset eu "Opening DTCP active connection" "DTCP konexio aktiboa irekitzen" ::msgcat::mcset eu "Opening DTCP passive connection" "DTCP konexio pasiboa irekitzen" # plugins/jidlink/ibb.tcl ::msgcat::mcset eu "Opening IBB connection" "IBB konexioa irekitzen" # plugins/clientinfo.tcl ::msgcat::mcset eu "\n\tClient: %s" "\n\tBezeroa: %s" ::msgcat::mcset eu "\n\tOS: %s" "\n\tSO: %s" # plugins/general/autoaway.tcl # "Automatically away due to idle" goes to textstatus (probably no needs to translate) ::msgcat::mcset eu "Automatically away due to idle" # rest should be translated ::msgcat::mcset eu "Returning from auto-away" "Auto-esegotetik itzultzen" ::msgcat::mcset eu "Moving to extended away" "Zeharo at egoerara igarotzen" ::msgcat::mcset eu "Starting auto-away" "Auto-ezegote egoerara igarotzen" ::msgcat::mcset eu "Idle for %s" "Jarduerarik gabe %s " ::msgcat::mcset eu "Options for module that automatically marks you as away after idle threshold." "Denbora jakin bat geldirik egon eta gero, 'ez nago' egoeran jartzen zaituen moduloaren aukerak." ::msgcat::mcset eu "Idle threshold in milliseconds after that Tkabber marks you as away." "'ez nago' egoeran automatikoki ipin zaitzan Tkabber behar duen denbora tartea." ::msgcat::mcset eu "Idle threshold in milliseconds after that Tkabber marks you as extended away." "'Zeharo at' egoeran automatikoki ipin zaitzan Tkabber behar duen denbora tartea." ::msgcat::mcset eu "Text status, which is set when Tkabber is moving in away state." "Tkabber-rek 'ez nago' egoeran ipintzen zaituenean, ezarriko den testu-egoera." ::msgcat::mcset eu "Tkabber will set priority to 0 when moving in extended away state." "Tkabber-rek 0 lehentasunean ipiniko du 'zeharo at' egoerara igarotakoan." # plugins/general/conferenceinfo.tcl ::msgcat::mcset eu "Options for Conference Info module, that allows you to see list of participants in roster popup, regardless of whether you are currently joined with the conference." "Mintza-taldeez informazio moduloaren aukerak. Honek partaidek erakusten ditu zerrendaren leihoan, bertan parte hartzen zauden ala ez." ::msgcat::mcset eu "Use this module" "Modulo hau erabili" ::msgcat::mcset eu "Interval between requests of participants list" "Partaide zerrenden eskaeren arteko denbora tartea" ::msgcat::mcset eu "Interval after error reply on request of participants list" "Partaide zerrenda eskatu eta gero, akatsik dela jakin eta geroko denbora tartea" ::msgcat::mcset eu "\n\tCan't browse: %s" "\n\tEzin da nabigatu: %s" ::msgcat::mcset eu "\nRoom participants at %s:" "\nPartaideak %setan:" ::msgcat::mcset eu "\nRoom is empty at %s" "\n %s gela hutsik dago" # plugins/general/message_archive.tcl ::msgcat::mcset eu "Messages" "Mezuak" ::msgcat::mcset eu "Received/Sent" "Bidalitakoak/Jasotakoak" ::msgcat::mcset eu "Dir" "Dir" ::msgcat::mcset eu "From/To" "Norengandik/Norentzat" ::msgcat::mcset eu "From:" "Norenagandik:" ::msgcat::mcset eu "To:" "Norentzat:" ::msgcat::mcset eu "Subject" "Gaia" # plugins/general/rawxml.tcl ::msgcat::mcset eu "Options for Raw XML Input module, which allows you to monitor incoming/outgoing traffic from connection to server and send custom XML stanzas." "XML gordinarn sarrerako moduloaren aukerak. Honek, konexio honetan zerbitzaritik sartu eta irteten diren datuak monitorizatzea eta XML bidaltzea ahalbidetzen du" ::msgcat::mcset eu "Pretty print incoming and outgoing XML stanzas." "XML parrafoentzat XML txukuna erakutsi." ::msgcat::mcset eu "Indentation for pretty-printed XML subtags." "XML markak eskumara eraman bertsio txukunean." ::msgcat::mcset eu "Raw XML" "XML gordina" ::msgcat::mcset eu "Pretty print XML" "XML txukuna erakutsi" # plugins/unix/dockingtray.tcl ::msgcat::mcset eu "Hide Main Window" "Ezkutatu leiho nagusia" ::msgcat::mcset eu "Show Main Window" "Erakutsi leiho nagusia" # plugins/unix/ispell.tcl ::msgcat::mcset eu "- nothing -" "- ezer ez -" ::msgcat::mcset eu "Spell check options." "Zuzenketa ortografikoaren aukerak." ::msgcat::mcset eu "Path to the ispell executable." "ispell exekutagarriarntzako bidea." ::msgcat::mcset eu "Check spell after every entered symbol." "Ikur bakoitzaren ondoren, ortografia zuzendu." # unix/wmdock.tcl ::msgcat::mcset eu "%s msgs" "%s mezu" ::msgcat::mcset eu "%s is %s" "%s %s dago" # error messages ::msgcat::mcset eu "Redirect" "berbideraketa" ::msgcat::mcset eu "Bad Request" "Eskaera okerra" ::msgcat::mcset eu "Unauthorized" "Baimenik gabe" ::msgcat::mcset eu "Payment Required" "Ordaina behar da" ::msgcat::mcset eu "Forbidden" "Debekatuta" ::msgcat::mcset eu "Not Found" "Ez da aurkitu" ::msgcat::mcset eu "Not Allowed" "Baimenik gabe" ::msgcat::mcset eu "Not Acceptable" "Ez da onargarria" ::msgcat::mcset eu "Registration Required" "Errejistratzea beharrezkoa da" ::msgcat::mcset eu "Request Timeout" "Eskaeraren itxaron tartea agortuta" ::msgcat::mcset eu "Username Not Available" "Erabiltzaile izen hori beste batek hartu du" ::msgcat::mcset eu "Conflict" "Gatazka" ::msgcat::mcset eu "Internal Server Error" "Zerbitzariaren barneko akatsa" ::msgcat::mcset eu "Not Implemented" "Ez garatuta" ::msgcat::mcset eu "Remote Server Error" "Urrutiko zerbitzariaren akatsa" ::msgcat::mcset eu "Service Unavailable" "Zerbitzu hau ez dago eskura" ::msgcat::mcset eu "Remote Server Timeout" "Urrutiko zerbitzariaren itxaron tartea agortuta" tkabber-0.11.1/msgs/ro.msg0000644000175000017500000010042311014357121014616 0ustar sergeisergei# Romanian messages file # 25-07-2003 # Author: Adrian Rapa (e-mail & JID: adrian@dtedu.net) # avatars.tcl ::msgcat::mcset ro "No avatar to store" "Nu există nici un avatar de reÅ£inut." # browser.tcl ::msgcat::mcset ro "JBrowser" "JBrowser" ::msgcat::mcset ro "JID:" "JID:" ::msgcat::mcset ro "Browse" "Răsfoire" ::msgcat::mcset ro "%s: %s/%s, Description: %s, Version: %s\nNumber of children: %s" "%s: %s/%s, Descriere: %s, Versiune: %s\nNumărul de copii: %s" # chats.tcl ::msgcat::mcset ro ">>> Unable to decipher data: %s <<<" ">>> Nu am putut descifra datele: %s <<<" ::msgcat::mcset ro "Error %s: %s" "Eroare %s: %s" ::msgcat::mcset ro "Chat with %s" "DiscuÅ£ie cu %s" ::msgcat::mcset ro "Toggle encryption" "Comută criptarea" ::msgcat::mcset ro "To:" "Către:" ::msgcat::mcset ro "Subject:" "Subiect:" ::msgcat::mcset ro "Error %s" "Eroare° %s" ::msgcat::mcset ro "Disconnected" "Deconectat" ::msgcat::mcset ro "Invite %s to conferences" "Invită %s în conferinţă" ::msgcat::mcset ro "Invite users..." "Invită utilizatori..." ::msgcat::mcset ro "Invite" "Invită" ::msgcat::mcset ro "Please join %s" "Intră în %s" ::msgcat::mcset ro "Invite users to %s" "Invită utilizatori în %s" ::msgcat::mcset ro "No conferences in progress..." "Nu există nici o conferinţă în desfăşurare..." # datagathering.tcl # emoticons.tcl # filetransfer.tcl ::msgcat::mcset ro "Send file to %s" "Trimite fiÅŸierul lui %s" ::msgcat::mcset ro "File to Send:" "FiÅŸier de trimis:" ::msgcat::mcset ro "Browse..." "Răsfoire..." ::msgcat::mcset ro "Description:" "Descriere:" ::msgcat::mcset ro "IP address:" "Adresă IP:" ::msgcat::mcset ro "File not found or not regular file: %s" "FiÅŸierul nu a fost găsit sau nu este un fiÅŸier obiÅŸnuit: %s" ::msgcat::mcset ro "Receive file from %s" "Primesc fiÅŸier de la: %s" ::msgcat::mcset ro "Save as:" "Salvare ca:" ::msgcat::mcset ro "Receive" "Primesc" ::msgcat::mcset ro "Request failed: %s" "Cererea a eÅŸuat: %s" ::msgcat::mcset ro "Transfering..." "Transfer..." ::msgcat::mcset ro "Size:" "Dimensiune:" ::msgcat::mcset ro "Connection closed" "Conexiunea a fost închisă" # filters.tcl ::msgcat::mcset ro "I'm not online" "Nu sunt conectat" ::msgcat::mcset ro "the message is from" "mesajul este de la" ::msgcat::mcset ro "the message is sent to" "mesajul este trimis către" ::msgcat::mcset ro "the subject is" "subiectul este" ::msgcat::mcset ro "the body is" "corpul este" ::msgcat::mcset ro "my status is" "starea mea este" ::msgcat::mcset ro "the message type is" "tipul mesajului este" ::msgcat::mcset ro "change message type to" "schimbă tipul mesajului in" ::msgcat::mcset ro "forward message to" "înaintează mesajul către" ::msgcat::mcset ro "reply with" "răspunde cu" ::msgcat::mcset ro "store this message offline" "salvează acest mesaj" ::msgcat::mcset ro "continue processing rules" "continuă prelucrarea regulilor" ::msgcat::mcset ro "Filters" "Filtre" ::msgcat::mcset ro "Add" "Adaugă" ::msgcat::mcset ro "Edit" "Modifică" ::msgcat::mcset ro "Remove" "Åžterge" ::msgcat::mcset ro "Move up" "Mută mai sus" ::msgcat::mcset ro "Move down" "Mută mai jos" ::msgcat::mcset ro "Edit rule" "Modifică regulă" ::msgcat::mcset ro "Rule Name:" "Nume regulă" ::msgcat::mcset ro "Empty rule name" "Åžterge numele regulei" ::msgcat::mcset ro "Rule name already exists" "O regulă cu acelasi nume există deja" ::msgcat::mcset ro "Condition" "CondiÅ£ie" ::msgcat::mcset ro "Action" "AcÅ£iune" # gpgme.tcl ::msgcat::mcset ro "Encrypt traffic" "Criptează traficul" ::msgcat::mcset ro "Change security preferences for %s" "Schimbă setările de securitate pentru %s" ::msgcat::mcset ro "Select Key for Signing Traffic" "Selectează cheia pentru traficul semnat" ::msgcat::mcset ro "Select" "Selectează" ::msgcat::mcset ro "Please enter passphrase" "IntroduceÅ£i parola" ::msgcat::mcset ro "Please try again" "ÃŽncercaÅ£i din nou" ::msgcat::mcset ro "Key ID" "Identificatorul cheii" ::msgcat::mcset ro "User ID" "Identificatorul utilizatorului" ::msgcat::mcset ro "Passphrase:" "Parola:" ::msgcat::mcset ro "Error in signature verification software: %s." "Eroare in semnătura programului de verificare: %s." ::msgcat::mcset ro "%s purportedly signed by %s can't be verified.\n\n%s." "%s pretins a fi semnat de %s, nu poate fi verificat.\n\n%s." ::msgcat::mcset ro "Unable to sign presence information: %s.\n\nPresence will be sent, but signing traffic is now disabled." "Nu am putu semna informaÅ£iile de prezenţă pentru: %s.\n\nPrezenÅŸa va fi trimisă, dar semnarea traficului este acum dezactivată." ::msgcat::mcset ro "Unable to sign message body: %s.\n\nSigning traffic is now disabled.\n\nSend it WITHOUT a signature?" "Nu am putu semna corbul mesajului: %s.\n\n Traficul semnat este acum dezactivat.\n\n ÃŽl trimit FÄ‚RÄ‚ semnătură?" ::msgcat::mcset ro "Data purported sent by %s can't be deciphered.\n\n%s." "Datele pretinse a fi trimise de %s, nu pot fi descifrate.\n\n%s." ::msgcat::mcset ro "Unable to encipher data for %s: %s.\n\nEncrypting traffic to this user is now disabled.\n\nSend it as PLAINTEXT?" "Nu am putu cifra datele pentru %s: %s.\n\n Traficul codat până la acest utilizator este dezactivat.\n\nÃŽl trimit în TEXT CLAR?" ::msgcat::mcset ro "" "" # iface.tcl ::msgcat::mcset ro "Presence" "PrezenÅ£a" ::msgcat::mcset ro "Online" "Conectat" ::msgcat::mcset ro "Free to chat" "Liber la discuÅ£ii" ::msgcat::mcset ro "Away" "Plecat" ::msgcat::mcset ro "Extended Away" "Plecat mai mult" ::msgcat::mcset ro "Do not disturb" "Nu deranjaÅ£i" ::msgcat::mcset ro "Invisible" "Invizibil" ::msgcat::mcset ro "Log in..." "Autentificare..." ::msgcat::mcset ro "Log out" "Deconectare" ::msgcat::mcset ro "Log out with reason..." "Deconectare cu motiv..." ::msgcat::mcset ro "Customize" "Particularizare" ::msgcat::mcset ro "Profile on" "Pornire depanare" ::msgcat::mcset ro "Profile report" "Salvare raport depanare" ::msgcat::mcset ro "Quit" "IeÅŸire" ::msgcat::mcset ro "Services" "Servicii" ::msgcat::mcset ro "Send message..." "Trimite mesaj..." ::msgcat::mcset ro "Roster" "Listă" ::msgcat::mcset ro "Add user..." "Adăugare utilizator..." ::msgcat::mcset ro "Add conference..." "Adăugare conferinţă..." ::msgcat::mcset ro "Add group by regexp on JIDs..." "Adăugare grup după expresii regulate din JID-uri..." ::msgcat::mcset ro "Export roster..." "Exportă listă..." ::msgcat::mcset ro "Import roster..." "Importă listă..." ::msgcat::mcset ro "Periodically browse roster conferences" "RăsfoieÅŸte periodic lista de conferinÅ£e" ::msgcat::mcset ro "Browser" "Navigator" ::msgcat::mcset ro "Discovery" "Descoperire" ::msgcat::mcset ro "Join group..." "Alăturare grup..." ::msgcat::mcset ro "Toggle showing offline users" "Arată doar utilizatorii conectati sau pe toÅ£i" ::msgcat::mcset ro "Chats" "DiscuÅ£ii" ::msgcat::mcset ro "Create room..." "Crează cameră..." ::msgcat::mcset ro "Generate event messages" "Generează evenimetele mesajelor" ::msgcat::mcset ro "Stop autoscroll" "Fără derulare automată" ::msgcat::mcset ro "Smart autoscroll" "Autoderulare inteligentă" ::msgcat::mcset ro "Emphasize" "EvidenÅ£iere" ::msgcat::mcset ro "Sound" "Sunet" ::msgcat::mcset ro "Mute" "Fără sunet" ::msgcat::mcset ro "Filters..." "Filtre..." ::msgcat::mcset ro "Privacy rules..." "Reguli de intimitate..." ::msgcat::mcset ro "Change password..." "Schimbare parolă..." ::msgcat::mcset ro "Message archive" "Arhiva de mesaje" ::msgcat::mcset ro "Show user info..." "Arată informaÅ£ii utilizator..." ::msgcat::mcset ro "Edit my info..." "Modifică informaÅ£iile mele..." ::msgcat::mcset ro "Avatar" "Avatar" ::msgcat::mcset ro "Announce" "Anunţă" ::msgcat::mcset ro "Allow downloading" "Permite descărcare" ::msgcat::mcset ro "Send to server" "Trimite la server" ::msgcat::mcset ro "Jidlink" ::msgcat::mcset ro "Admin tools" "Instrumente de administrare" ::msgcat::mcset ro "Open raw XML window" "Deschide fereastra pentru XML brut" ::msgcat::mcset ro "Open statistics monitor" "Arată statisticile" ::msgcat::mcset ro "Send broadcast message..." "Trimite mesaj..." ::msgcat::mcset ro "Send message of the day..." "Trimite mesajul zilei..." ::msgcat::mcset ro "Update message of the day..." "Actualizeaza mesajul zilei..." ::msgcat::mcset ro "Delete message of the day" "Åžterge mesajul zilei" ::msgcat::mcset ro "Help" "Ajutor" ::msgcat::mcset ro "Quick help" "Ajutor rapid" ::msgcat::mcset ro "Quick Help" "Ajutor rapid" ::msgcat::mcset ro "Main window:" "Fereastra principală:" ::msgcat::mcset ro "Tabs:" "Pagini:" ::msgcat::mcset ro "Chats:" "Dialoguri:" ::msgcat::mcset ro "Close tab" "ÃŽnchide pagina" ::msgcat::mcset ro "Previous/Next tab" "Pagina anterioară/următoare" ::msgcat::mcset ro "Hide/Show roster" "AfiÅŸează/Ascunde lista." ::msgcat::mcset ro "Move tab left/right" "Mută pagina în stânga/dreapta" ::msgcat::mcset ro "Switch to tab number 10,1-9" "Comută pe pagina numărul 10,1-9" ::msgcat::mcset ro "Complete nickname" "Pseudonim complet" ::msgcat::mcset ro "Previous/Next history message" "Antecedentul/Următorul mesaj din istoric" ::msgcat::mcset ro "Show emoticons" "Arată emoticons" ::msgcat::mcset ro "Undo" "Undo" ::msgcat::mcset ro "Redo" "Redo" ::msgcat::mcset ro "Scroll chat window up/down" "Deruleaza discutia in sus/jos" ::msgcat::mcset ro "Right mouse" "Click dreapta" ::msgcat::mcset ro "Correct word" "Corectare cuvant" ::msgcat::mcset ro "About" "Despre" ::msgcat::mcset ro "Authors:" "Autori:" ::msgcat::mcset ro "Alexey Shchepin" "Alexey Shchepin" ::msgcat::mcset ro "Marshall T. Rose" "Marshall T. Rose" ::msgcat::mcset ro "Sergei Golovan" "Sergei Golovan" ::msgcat::mcset ro "Michail Litvak" "Michail Litvak" ::msgcat::mcset ro "Add new user..." "Adaugă utilizator nou..." ::msgcat::mcset ro "Jabber Browser" "Navigator Jabber" ::msgcat::mcset ro "Show online & offline users" "Arată utilizatorii conectaÅ£i ÅŸi neconectaÅ£i" ::msgcat::mcset ro "Show online users only" "Arată doar utilizatorii conectaÅ£i" ::msgcat::mcset ro "Use aliases" "FoloseÅŸte pseudonime" ::msgcat::mcset ro "Toggle signing" "Comută semnarea" ::msgcat::mcset ro "Toggle encryption (when possible)" "Comută criptarea (când este posibil)" ::msgcat::mcset ro "Cancel" "Renunţă" ::msgcat::mcset ro "Close" "ÃŽnchide" ::msgcat::mcset ro "Close other tabs" "ÃŽnchide celelalte pagini" ::msgcat::mcset ro "Close all tabs" "ÃŽnchide toate paginile" ::msgcat::mcset ro "Send" "Trimite" # itemedit.tcl ::msgcat::mcset ro "Edit properties for %s" "Modifica proprietăţile pentruË› %s" ::msgcat::mcset ro "Edit nickname for %s" "Modifică pseudonimul pentru %s" ::msgcat::mcset ro "Nickname:" "Pseudonim:" ::msgcat::mcset ro "Edit groups for %s" "Modifcă grupuri pentru %s" ::msgcat::mcset ro "Available groups" "Grupuri disponibile" ::msgcat::mcset ro "Group:" "Grup:" ::msgcat::mcset ro "Current groups" "Grupuri curente" ::msgcat::mcset ro "Add ->" "Adaugă ->" ::msgcat::mcset ro "<- Remove" "<- Åžterge" # jidlink.tcl ::msgcat::mcset ro "Opening Jidlink connection" "Deschide conexiune Jidlink" ::msgcat::mcset ro "Jidlink connection closed" "Conexiunea Jidlink a fost închisă" # joingrdialog.tcl ::msgcat::mcset ro "Join group" "Alăturare grup" ::msgcat::mcset ro "Nick:" "Pseudonim:" ::msgcat::mcset ro "Group:" "Grup:" ::msgcat::mcset ro "Server:" "Server:" ::msgcat::mcset ro "use v2 protocol" "foloseÅŸte protocolul v2" ::msgcat::mcset ro "Password (v2 only):" "Parola (numai pentru v2)" ::msgcat::mcset ro "Join" "Alăturare" ::msgcat::mcset ro "Add group" "Adaugă grup" ::msgcat::mcset ro "Get conference info failed: %s" "ObÅ£inerea informaÅ£iilor despre conferinţă a eÅŸuat: %s" ::msgcat::mcset ro "Join failed: %s" "Alăturarea a eÅŸuat: %s" ::msgcat::mcset ro "Create Room" "Crează cameră" ::msgcat::mcset ro "Address:" "Adresă:" ::msgcat::mcset ro "Nickname:" "Pseudonim:" ::msgcat::mcset ro "Password:" "Parolă:" ::msgcat::mcset ro "Name: " "Nume:" ::msgcat::mcset ro "Description:" "Description:" ::msgcat::mcset ro "Create" "Creează" # login.tcl ::msgcat::mcset ro "Login" "Autentificare" ::msgcat::mcset ro "Username:" "Nume utilizator:" ::msgcat::mcset ro "Password:" "Parolă:" ::msgcat::mcset ro "Server:" "Server:" ::msgcat::mcset ro "Resource:" "Resursă:" ::msgcat::mcset ro "Port:" "Port:" ::msgcat::mcset ro "Use hashed password" "FoloseÅŸte parolă codată (hashed)" ::msgcat::mcset ro "Connect via alternate server" "Conectare prin alt server" ::msgcat::mcset ro "Use SSL" "FoloseÅŸte SSL" ::msgcat::mcset ro "SSL Port:" "Port SSL:" ::msgcat::mcset ro "Use Proxy" "FoloseÅŸte proxy" ::msgcat::mcset ro "Proxy Server:" "Server proxy:" ::msgcat::mcset ro "Proxy Port:" "Port proxy:" ::msgcat::mcset ro "Proxy Login:" "Autentificare proxy:" ::msgcat::mcset ro "Proxy Password:" "Parolă proxy:" ::msgcat::mcset ro "Profiles" "Profile" ::msgcat::mcset ro "Profile" "Profil" ::msgcat::mcset ro "Authentication failed: %s\nCreate new account?" "Autentificarea a eÅŸuat: %s\nCreaÅ£i un cont nou?" ::msgcat::mcset ro "Registration failed: %s" "ÃŽnregistrarea a eÅŸuat: %s" ::msgcat::mcset ro "Change password" "Schimbă parola" ::msgcat::mcset ro "Old password:" "Parola veche:" ::msgcat::mcset ro "New password:" "Parola nouă:" ::msgcat::mcset ro "Repeat new password:" "Repetă parola nouă:" ::msgcat::mcset ro "Old password is incorrect" "Parola veche este incorectă" ::msgcat::mcset ro "New passwords do not match" "Parolele noi nu se potrivesc" ::msgcat::mcset ro "Password is changed" "Parola este schimbatăË" ::msgcat::mcset ro "Password change failed: %s" "Schimbarea parolei a eÅŸuat: %s" ::msgcat::mcset ro "Logout with reason" "Deconectare cu motiv" ::msgcat::mcset ro "Reason:" "Motiv:" ::msgcat::mcset ro "Priority:" "Prioritate:" # messages.tcl ::msgcat::mcset ro "Message from %s" "Mesaj de la %s" ::msgcat::mcset ro "Message from" "Mesaj de la" ::msgcat::mcset ro "Extras from %s" "Extras de la %s" ::msgcat::mcset ro "Extras from" "Extras de la" ::msgcat::mcset ro "Reply" "Răspunde" ::msgcat::mcset ro "Attached user:" "Utilizator ataÅŸat:" ::msgcat::mcset ro "Attached file:" "FiÅŸier ataÅŸat:" ::msgcat::mcset ro "Invited to:" "Invitat la:" ::msgcat::mcset ro "Message body" "Corp Mesaj" ::msgcat::mcset ro "Send message to %s" "Trimite mesaj lui %s" ::msgcat::mcset ro "Send message" "Trimite mesaj" ::msgcat::mcset ro "This message is encrypted." "Acest mesaj e codat" ::msgcat::mcset ro "Subscribe request from %s" "Cerere de subscriere de la %s" ::msgcat::mcset ro "Subscribe request from" "Cerere de subscriere de la" ::msgcat::mcset ro "Subscribe" "Subscrie" ::msgcat::mcset ro "Unsubscribe" "Åžterge subscrierea" ::msgcat::mcset ro "Send subscription" "Trimite subscriere" ::msgcat::mcset ro "I would like to add you to my roster." "Doresc să te adaug în lista de prieteni" ::msgcat::mcset ro "Send subscription to %s" "Trimite subscriere lui %s" ::msgcat::mcset ro "Send subscription to " "Trimite subscriere lui" ::msgcat::mcset ro "Headlines" "Titluri" ::msgcat::mcset ro "Toggle seen" "Comută seen" ::msgcat::mcset ro "Sort" "Sortare" # muc.tcl ::msgcat::mcset ro "Whois" "Cine e" ::msgcat::mcset ro "Kick" "Dă afară" ::msgcat::mcset ro "Ban" "Interzice access" ::msgcat::mcset ro "Grant Voice" "Acordă voce" ::msgcat::mcset ro "Revoke Voice" "Retrage voce" ::msgcat::mcset ro "Grant Membership" "Acordă drept de membru" ::msgcat::mcset ro "Revoke Membership" "Retrage drept de membru" ::msgcat::mcset ro "Grant Moderator Privilege" "Acordă privilegiu de moderator" ::msgcat::mcset ro "Revoke Moderator Privilege" "Retrage privilegiu de moderator" ::msgcat::mcset ro "Grant Administrative Privilege" "Acordă privilegii administrative" ::msgcat::mcset ro "Revoke Administrative Privilege" "Retrage privilegii administrative" ::msgcat::mcset ro "MUC" "MUC" ::msgcat::mcset ro "Configure" "Configureaz" ::msgcat::mcset ro "Edit admin list" "Modifică lista de administratori" ::msgcat::mcset ro "Edit moderator list" "Modifică lista de moderatori" ::msgcat::mcset ro "Edit ban list" "Modifică lista de bauri" ::msgcat::mcset ro "Edit member list" "Modifică lista de membrii" ::msgcat::mcset ro "Edit voice list" "Modifică lista de voce" ::msgcat::mcset ro "Destroy" "Distruge" # presence.tcl ::msgcat::mcset ro "Not logged in" "Neautentificat" ::msgcat::mcset ro "Offline" "Neconectat" ::msgcat::mcset ro "invalid usersatatus value " "valoare invalidă s statutului utilizatorului" # register.tcl ::msgcat::mcset ro "Register in %s" "ÃŽnregistreazăte în %s" ::msgcat::mcset ro "Unsubscribed from %s" ::msgcat::mcset ro "We unsubscribed from %s" # roster.tcl ::msgcat::mcset ro "Undefined" "Nedefinit" ::msgcat::mcset ro "is now" "este acum" ::msgcat::mcset ro "Add roster group by JID regexp" "Adăugare grup după expressi regulate din JID-uri..." ::msgcat::mcset ro "New group name:" "Nume de grup nou:" ::msgcat::mcset ro "JID regexp:" "Expresie regulată din JID-uri" ::msgcat::mcset ro "Are you sure to remove %s from roster?" "EÅŸti sigur că doreÅŸti să îl ÅŸtergi pe %s din listă?" ::msgcat::mcset ro "Start chat" "PorneÅŸte discuÅ£ie" ::msgcat::mcset ro "Invite to conference..." "Invită în conferinţă..." ::msgcat::mcset ro "Resubscribe" "Subscrie din nou" ::msgcat::mcset ro "Send users..." "Trimite utilizatori..." ::msgcat::mcset ro "Send custom presence" "Trimite prezenţă personalizată" ::msgcat::mcset ro "Rename..." "Redenumire" ::msgcat::mcset ro "Rename roster group" "Redenumire grup din listă" ::msgcat::mcset ro "Resubscribe to all users in group..." "Resubscrie către toÅ£i utilizatorii din grup..." ::msgcat::mcset ro "Send file..." "Trimite fiÅŸier..." ::msgcat::mcset ro "Send file via Jidlink..." "Trimite fiÅŸier folosind Jidlink..." ::msgcat::mcset ro "Show info" "Arată informaÅ£ii" ::msgcat::mcset ro "Show history" "Arată istoric" ::msgcat::mcset ro "Edit item..." "Modifică element..." ::msgcat::mcset ro "Edit security..." "Modifică securitatea..." ::msgcat::mcset ro "Remove..." "Åžterge..." ::msgcat::mcset ro "Join..." "Alăturare..." ::msgcat::mcset ro "Log in" "Autentificare" ::msgcat::mcset ro "Log out" "Deconectare" ::msgcat::mcset ro "Send contacts to" "Trimite contactele către" ::msgcat::mcset ro "Send" "Trimite" ::msgcat::mcset ro "No users in roster..." "Nu există utilizatori în listă..." ::msgcat::mcset ro "Contact Information" "InformaÅ£ii de contact" ::msgcat::mcset ro "Raw XML input" "Introduce XML brut" # search.tcl ::msgcat::mcset ro "Search in" "Caută în" ::msgcat::mcset ro "Search again" "Caută din nou" ::msgcat::mcset ro "OK" "OK" # splash.tcl ::msgcat::mcset ro "auto-away" "retragere automată" ::msgcat::mcset ro "avatars" "avatars" ::msgcat::mcset ro "balloon help" "ajutor cu baloane" ::msgcat::mcset ro "browsing" "navigare" ::msgcat::mcset ro "configuration" "configuraÅ£ie" ::msgcat::mcset ro "connections" "conexiuni" ::msgcat::mcset ro "cryptographics" "criptografie" ::msgcat::mcset ro "emoticons" "emoticons" ::msgcat::mcset ro "extension management" "administrare extensii" ::msgcat::mcset ro "file transfer" "transfer fiÅŸiere" ::msgcat::mcset ro "jabber chat" "discuÅ£ii jabber" ::msgcat::mcset ro "jabber groupchats" "discuÅ£ii în group jabber" ::msgcat::mcset ro "jabber iq" "iq jabber" ::msgcat::mcset ro "jabber presence" "prezenţă jabber" ::msgcat::mcset ro "jabber registration" "înregistrare jabber" ::msgcat::mcset ro "jabber xml" "jabber xml" ::msgcat::mcset ro "kde" "kde" ::msgcat::mcset ro "message filters" "filtre mesaje" ::msgcat::mcset ro "message/headline" "mesaj/titlu" ::msgcat::mcset ro "plugin management" "administrare plugin-uri" ::msgcat::mcset ro "presence" "prezenÅ£a" ::msgcat::mcset ro "rosters" "liste" ::msgcat::mcset ro "searching" "căutare" #::msgcat::mcset ro "text undo" "" ::msgcat::mcset ro "user interface" "interfaţă utilizator" ::msgcat::mcset ro "utilities" "utilitare" ::msgcat::mcset ro "wmaker" "wmaker" # userinfo.tcl ::msgcat::mcset ro "Show user info" "Arată infotmaÅ£ii utilizator" ::msgcat::mcset ro "Show" "Arată" ::msgcat::mcset ro "%s info" "InformaÅ£ii %s" ::msgcat::mcset ro "Personal" "Personale" ::msgcat::mcset ro "Name" "Nume" ::msgcat::mcset ro "Full Name:" "Nume complet:" ::msgcat::mcset ro "Family Name:" "Nume de familie:" ::msgcat::mcset ro "Name:" "nume:" ::msgcat::mcset ro "Middle Name:" "IniÅ£iala tatălui:" ::msgcat::mcset ro "Prefix:" "Prefix:" ::msgcat::mcset ro "Suffix:" "Sufix:" ::msgcat::mcset ro "Nickname:" "Pseudonim:" ::msgcat::mcset ro "Information" "InformaÅ£ii" ::msgcat::mcset ro "E-mail:" "E-mail" ::msgcat::mcset ro "Web Site:" "Pagină web:" ::msgcat::mcset ro "JID:" ::msgcat::mcset ro "UID:" ::msgcat::mcset ro "Phones" "Telefoane" ::msgcat::mcset ro "Telephone numbers" "Numere telefon" ::msgcat::mcset ro "Home:" "Acasă:" ::msgcat::mcset ro "Work:" "Serviciu:" ::msgcat::mcset ro "Voice:" "Voce:" ::msgcat::mcset ro "Fax:" "Fax:" ::msgcat::mcset ro "Pager:" "Pager:" ::msgcat::mcset ro "Message Recorder:" "ÃŽnregistrator de mesaje:" ::msgcat::mcset ro "Cell:" "Mobil:" ::msgcat::mcset ro "Video:" "Video:" ::msgcat::mcset ro "BBS:" "BBS:" ::msgcat::mcset ro "Modem:" "Modem:" ::msgcat::mcset ro "ISDN:" "ISDN:" ::msgcat::mcset ro "PCS:" "PCS:" ::msgcat::mcset ro "Preferred:" "Preferat:" ::msgcat::mcset ro "Location" "LocaÅ£ie" ::msgcat::mcset ro "Address" "Adresă" ::msgcat::mcset ro "Address:" "Adresă:" ::msgcat::mcset ro "Address 2:" "Adresă 2:" ::msgcat::mcset ro "City:" "OraÅŸ:" ::msgcat::mcset ro "State:" "Stat/JudeÅ£:" ::msgcat::mcset ro "Postal Code:" "Cod PoÅŸtal:" ::msgcat::mcset ro "Country:" "Å¢ară:" ::msgcat::mcset ro "Geographical position" "PoziÅ£ie geografică" ::msgcat::mcset ro "Latitude:" "Latitudine:" ::msgcat::mcset ro "Longitude:" "Longitudine:" ::msgcat::mcset ro "Organization" "OrganizaÅ£ie" ::msgcat::mcset ro "Details" "Detalii" # Space at the end of the next word is to distinguish it from another "Name:" ::msgcat::mcset ro "Name: " "Nume:" ::msgcat::mcset ro "Unit:" "Unitate:" # Space at the end of the next word is to distinguish it from another "Personal" ::msgcat::mcset ro "Personal " "Personal" ::msgcat::mcset ro "Title:" "Titlu:" ::msgcat::mcset ro "Role:" "Rol:" # Space at the end of the next word is to distinguish it from another "About" ::msgcat::mcset ro "About " "Despre" ::msgcat::mcset ro "Birthday" "Zi de naÅŸtere" ::msgcat::mcset ro "Birthday:" "Zi de naÅŸtere:" ::msgcat::mcset ro "Photo" "Fotografie" ::msgcat::mcset ro "URL:" "URL:" ::msgcat::mcset ro "URL" "URL" ::msgcat::mcset ro "Image" "Imagine" ::msgcat::mcset ro "None" "Fără" ::msgcat::mcset ro "Load Image" "ÃŽncarcă imagine" ::msgcat::mcset ro "Avatar" "Avatar" ::msgcat::mcset ro "Client Info" "InformaÅ£ii client" ::msgcat::mcset ro "Client" "Client" ::msgcat::mcset ro "Client:" "Client:" ::msgcat::mcset ro "Version:" "Versiune:" ::msgcat::mcset ro "Last Activity or Uptime" "Ultima activitate" ::msgcat::mcset ro "Interval:" "Interval:" ::msgcat::mcset ro "Description:" "Descriere:" ::msgcat::mcset ro "Computer" "Computer" ::msgcat::mcset ro "OS:" "Sistem de operare:" ::msgcat::mcset ro "Time:" "Timp:" ::msgcat::mcset ro "Time Zone:" "Fus orar:" ::msgcat::mcset ro "UTC:" ::msgcat::mcset ro "Presence" "Prezenţă" ::msgcat::mcset ro "Presence id signed" "Identificator prezenţă semnat de" ::msgcat::mcset ro " by " " de " # plugins/jidlink/dtcp.tcl ::msgcat::mcset ro "Opening DTCP active connection" "Deschid legătura DTCP activă" ::msgcat::mcset ro "Opening DTCP passive connection" "Deschid legătura DTCP pasivă" # plugins/jidlink/ibb.tcl ::msgcat::mcset ro "Opening IBB connection" "Deschid legătură IBB" # plugins/clientinfo.tcl ::msgcat::mcset ro "\n\tClient: %s" "\n\tClient: %s" ::msgcat::mcset ro "\n\tOS: %s" "\n\tSistem operare: %s" # unix/autoaway.tcl # "Automatically away due to idle" goes to textstatus (probably no needs to translate) ::msgcat::mcset ro "Automatically away due to idle" "Plecat automat datorită inactivităţii" # rest should be translated ::msgcat::mcset ro "Returning from auto-away" "Revenire din auto-Plecat" ::msgcat::mcset ro "Moving to extended away" "Trecere în Plecat mai mult" ::msgcat::mcset ro "Starting auto-away" "Pornire auto-Plecat" ::msgcat::mcset ro "Idle for %s" "Inactiv pentru " # unix/dockingtray.tcl ::msgcat::mcset ro "Hide Main Window" "Ascunde fereastra principală" ::msgcat::mcset ro "Show Main Window" "Arată fereastra principală" # unix/ispell.tcl ::msgcat::mcset ro "- nothing -" "- nimic -" # unix/wmdock.tcl ::msgcat::mcset ro "%s msgs" "%s mdeaje." ::msgcat::mcset ro "%s is %s" "%s este %s" ::msgcat::mcset ro "Messages" "Mesaje" ::msgcat::mcset ro "Received/Sent" "Primite/Trimise" ::msgcat::mcset ro "From/To" "De la/Către" ::msgcat::mcset ro "Subject" "Subiect" ::msgcat::mcset ro "From:" "De la:" ::msgcat::mcset ro "Raw XML" "XML Brut" ::msgcat::mcset ro "Pretty print XML" "AfiÅŸare formatată a XML-ului" ::msgcat::mcset ro "Statistics" "Statistici" ::msgcat::mcset ro "Node" "Nod" ::msgcat::mcset ro "Value" "Valoare" ::msgcat::mcset ro "Units" "Unităţi" ::msgcat::mcset ro "Timer" "Timp" ::msgcat::mcset ro "State" "Stare" ::msgcat::mcset ro "this option has been set and saved." "această opÅ£iune a fost aplicată ÅŸi salvată." ::msgcat::mcset ro "this option is unchanged from its standard setting." "această opÅ£iune este neschimbată faţă de setările standard." ::msgcat::mcset ro "you have edited the value, but you have not set the option." "valoarea este modificată, dar nu este aplicată." ::msgcat::mcset ro "you have set this option, but not saved it for future sessions." "valoarea este modificată, dar nu este salvată pentru sesiunile viitoare." ::msgcat::mcset ro "Set for Current Session" "Aplică pentru sesiunea curentă." ::msgcat::mcset ro "Set for Future Sessions" "Aplică pentru sesiunile viitoare." ::msgcat::mcset ro "Reset to Current" "Restaurează valoarea curentă." ::msgcat::mcset ro "Reset to Saved" "Restaurează valoarea salvată." ::msgcat::mcset ro "Reset to Default" "Restaurează valoarea implicită." ::msgcat::mcset ro "Open" "Deschide" ::msgcat::mcset ro "Parent group:" "Grup părinte:" ::msgcat::mcset ro "Roster options." "OpÅ£iuni listă." ::msgcat::mcset ro "Enable nested roster groups." "Activează grupuri de listă amestecate." ::msgcat::mcset ro "Chat options." "OpÅ£iuni discuÅ£ii." ::msgcat::mcset ro "Enable chat window autoscroll only when last message is shown." "Activează auto-derularea ferestrei de discuÅ£ii numai când ultimul mesaj este afiÅŸat." ::msgcat::mcset ro "Stop chat window autoscroll." "OpreÅŸte auto-derularea ferestrei de discuÅ£ii." ::msgcat::mcset ro "Enable messages emphasize." "Activează evidenÅ£ierea a mesajelor" ::msgcat::mcset ro "Enable rendering of XHTML messages" "Activează randarea mesajelor XHTML" ::msgcat::mcset ro "Generate event messages in MUC compatible conference rooms." "Generează evenimente de mesaje în camerel de discuÅ£ii compatibile MUC" ::msgcat::mcset ro "Logging options." "OpÅ£iuni jurnal." ::msgcat::mcset ro "Directory to store logs." "Directorul unde este stocat jurnalul." ::msgcat::mcset ro "Store private chats logs." "Stocare jurnal al discuÅ£iilor particulare." ::msgcat::mcset ro "Store group chats logs." "Stocare jurnal al discuÅ£iilor în grup." ::msgcat::mcset ro "File Transfer options." "OpÅ£iuni transfer de fiÅŸiere." ::msgcat::mcset ro "Default directory for downloaded files." "Directorul implicit unde vor fi descărcate fiÅŸierele." ::msgcat::mcset ro "Sound options." "OpÅ£iuni sunet." ::msgcat::mcset ro "Mute sound notification.." "Nu folosi notificările sonore." ::msgcat::mcset ro "Use sound notification only when being online." "FoloseÅŸte notificările sonore numai când sunt Conectat" ::msgcat::mcset ro "External program, which is to be executed to play sound. If empty, Snack library is required to play sound." "Programul extern cu care se redau sunetele. Dacă este gol, librăria snack este necesară pentru readrea sunetelor." ::msgcat::mcset ro "Sound theme. If it starts with \"/\" or \"~\" then it is considered as theme directory. Otherwise theme is loaded from \"sounds\" directory of Tkabber tree." "Schema de sunet. Dacă începe cu \"/\" sau cu \"~\" atunci este considerat ca directorul cu teme. Altfel tema este încărcată din directorul \"sounds\" din radăcina tkabber-ului." ::msgcat::mcset ro "Time interval before playing next sound (in milliseconds)." "Intervalul de timp dintre redarea a două sunete consecutive (în milisecunde)." ::msgcat::mcset ro "Mute sound when displaying delayed groupchat messages." "Fără sunet la afiÅŸarea mesajelor de discuÅ£ii în grup venite cu întârziere." ::msgcat::mcset ro "Mute sound when displaying delayed personal chat messages." "Fără sunet la afiÅŸarea mesajelor personale venite cu întârziere." ::msgcat::mcset ro "Options for external play program" "OpÅ£iuni pentru programul extern." ::msgcat::mcset ro "Login options." "OpÅ£iuni autentificare." ::msgcat::mcset ro "User name." "Nume utilizator." ::msgcat::mcset ro "Password." "Parolă." ::msgcat::mcset ro "Resource." "Resursă." ::msgcat::mcset ro "Server name." "Nume server." ::msgcat::mcset ro "Server port." "Port server." ::msgcat::mcset ro "Priority." "Prioritate." ::msgcat::mcset ro "Use SSL to connect to server." "FoloseÅŸte SSL pentru conectarea la server." ::msgcat::mcset ro "SSL port." "Port SSL." ::msgcat::mcset ro "Use HTTP proxy to connect." "FoloseÅŸte proxy HTTP pentru conectare." ::msgcat::mcset ro "HTTP proxy address." "Adresă proxy HTTP." ::msgcat::mcset ro "HTTP proxy port." "Port proxy HTTP." ::msgcat::mcset ro "HTTP proxy username." "Nume utilizator proxy HTTP." ::msgcat::mcset ro "HTTP proxy password." "Parolă proxy HTTP." ::msgcat::mcset ro "Use explicitly-specified server address." "FoloseÅŸte adresa serverului specificată explicit." ::msgcat::mcset ro "Server name or IP-address." "Numele server-ului sau adresa IP." ::msgcat::mcset ro "Replace opened connections." "ÃŽnlocuieÅŸte conexiunile deschise." ::msgcat::mcset ro "Replace opened connections" "ÃŽnlocuieÅŸte conexiunile deschise" ::msgcat::mcset ro "Options for module that automatically marks you as away after idle threshold." "OpÅ£iuni pentru modulul care setează automat starea ca fiind Plecat după ce a expirat timpul setat." ::msgcat::mcset ro "Idle threshold in milliseconds after that Tkabber marks you as away." "Timpul în milisecunde după care Tkabber vă trece în starea de \"Plecat\"." ::msgcat::mcset ro "Idle threshold in milliseconds after that Tkabber marks you as extended away." "Timpul în milisecunde după care Tkabber vă trece în starea de \"Plecat mai mult\"." ::msgcat::mcset ro "Text status, which is set when Tkabber is moving in away state." "Mesajul pe care tkabber îl va pune când intră in starea \"Plecat\"." ::msgcat::mcset ro "Tkabber will set priority to 0 when moving in extended away state." "Tkabber va aplica prioritatea 0 după trecerea în starea \"Plecat mai mult\"." ::msgcat::mcset ro "Options for Conference Info module, that allows you to see list of participants in roster popup, regardless of whether you are currently joined with the conference." "OpÅ£iuni pentru modulul de InformaÅ£ii despre ConferinÅ£e, care vă permite să vedeÅ£i lista de participanÅ£i într-un tooltip în lista de prieteni, indiferent dacă sunteÅ£i sau nu alăturat conferinÅ£ei." ::msgcat::mcset ro "Use this module" "FoloseÅŸte acest modul." ::msgcat::mcset ro "Interval between requests of participants list" "Intervalul dintre cererea listei participanÅ£ilor." ::msgcat::mcset ro "Interval after error reply on request of participants list" "Intervalul după care survine eroare în cererea listei participanÅ£ilor." ::msgcat::mcset ro "Options for Raw XML Input module, which allows you to monitor incoming/outgoing traffic from connection to server and send custom XML stanzas." "OpÅ£iuni pentru modulul de Introdus XML Brut, care vă permite să monitorizaÅ£i trafic de intrare/ieÅŸire de la server ÅŸi să trimiteÅ£i fragmente de XML personalizate." ::msgcat::mcset ro "Pretty print incoming and outgoing XML stanzas." "Tipărirea formatată a părÅ£ilor de XML de intrare ÅŸi de ieÅŸire." ::msgcat::mcset ro "Indentation for pretty-printed XML subtags." "Alinierea subtag-urilor XML formatate." ::msgcat::mcset ro "Options for main interface." "OpÅ£iuni pentru interfaÅ£a principală." ::msgcat::mcset ro "Raise new tab." "AfiÅŸează pagini noi." ::msgcat::mcset ro "Show number of unread messages in tab titles." "AfiÅŸează numărul de mesaje necitite în titlul tab-urilor." ::msgcat::mcset ro "Colors for tab alert levels." "Culorile pentru nivelul activităţii pe pagină." ::msgcat::mcset ro "%s SSL Certificate Info" "InformaÅ£ii certificat SSL pentru %s" ::msgcat::mcset ro "Issuer:" "Emitent:" ::msgcat::mcset ro "Begin date:" "Data de începere:" ::msgcat::mcset ro "Expiry date:" "Data de expirare:" ::msgcat::mcset ro "Serial number:" "Număr serial:" ::msgcat::mcset ro "Cipher:" "Algoritm:" # Local Variables: # mode: tcl # End: tkabber-0.11.1/msgs/it.msg0000644000175000017500000023013011062233737014622 0ustar sergeisergei# filters.tcl ::msgcat::mcset it "Blocking communication options." "Opzioni del blocaggio dei messagi" ::msgcat::mcset it "Edit message filters" "Modifica filtro dei messagi" ::msgcat::mcset it "Enable jabberd 1.4 mod_filter support (obsolete)." "Attiva supporto di jabberd 1.4 mod_filter (obsoleto)" ::msgcat::mcset it "Requesting filter rules: %s" "Regole del filtro richiesti: %s" # jabberlib-tclxml/jlibcomponent.tcl ::msgcat::mcset it "Handshake failed" "Stretta di mano non riuscita" ::msgcat::mcset it "Handshake successful" "Stretta di mano riuscita" ::msgcat::mcset it "Waiting for handshake results" "Attesa dei resultati della stretta di mano" # plugins/chat/chatstate.tcl ::msgcat::mcset it "%s has activated chat window" "%s ha attivato la finestra della conversazione" ::msgcat::mcset it "%s has gone chat window" "%s ha chiuso la finestra della conversazione" ::msgcat::mcset it "%s has inactivated chat window" "%s ha disattivato la finestra della conversazione" ::msgcat::mcset it "%s is composing a reply" "%s sta scrivendo la risposta" ::msgcat::mcset it "%s is paused a reply" "% si è fermato scrivendo la risposta" ::msgcat::mcset it "Chat message window state plugin options." "Opzioni delle notifiche dello stato di conversazione" ::msgcat::mcset it "Chat window is active" "Finestra di conversazione è attiva" ::msgcat::mcset it "Chat window is gone" "La finestra di conversazione è stata chiusa" ::msgcat::mcset it "Chat window is inactive" "La finestra di conversazione non è attiva" ::msgcat::mcset it "Composing a reply" "Sta scrivendo la risposta" ::msgcat::mcset it "Enable sending chat state notifications." "Attivare invio delle notifiche dello stato di chat" ::msgcat::mcset it "Paused a reply" "Si e fermato scrivendo la risposta" # jabberlib-tclxml/jabberlib.tcl ::msgcat::mcset it "Got roster" "Contatti ricevuti" ::msgcat::mcset it "Timeout" "Timeout" ::msgcat::mcset it "Waiting for roster" "Attesa dei contatti" # plugins/richtext/stylecodes.tcl ::msgcat::mcset it "Emphasize stylecoded messages using different fonts." "Evidenziare messagi stilizzati usando altro tipo di caratteri" ::msgcat::mcset it "Handling of \"stylecodes\". Stylecodes are (groups of) special formatting symbols used to emphasize parts of the text by setting them with boldface, italics or underlined styles, or as combinations of these." \ "Elaborazione di \"stylecodes\". Stylecodes sono caratteri speciali che servono per evidenziare il testo con grasetto, corsivo o sottolineato e le loro combinazioni." # chats.tcl ::msgcat::mcset it "%s has changed nick to %s." "%s ora è conosciuto come %s" ::msgcat::mcset it "/me has set the subject to: %s" "/me ha cambiato l'argomento а: %s" ::msgcat::mcset it "Chat" "Conversare" ::msgcat::mcset it "Chat " "Conversazione" ::msgcat::mcset it "Chat options." "Opzioni di conversazione." ::msgcat::mcset it "Connection:" "Conessioni:" ::msgcat::mcset it "Default message type (if not specified explicitly)." "Tipo di messagio predefinito (se non è specificato)" ::msgcat::mcset it "Display description of user status in chat windows." "Visualizzare descrizione dello status del utente nella finestra di conversazione" ::msgcat::mcset it "Enable chat window autoscroll only when last message is shown." "Abilitare auto-scorrimento nella finestra di conversazione solo quando ultimo messagio e visualizzato" ::msgcat::mcset it "Generate chat messages when chat peer changes his/her status and/or status message" "Generare messagio di conversazione quando partecipante cambia suo status o messagio di status" ::msgcat::mcset it "List of users for chat." "Lista degli utenti per conversazione" ::msgcat::mcset it "Moderators" "Moderatori" ::msgcat::mcset it "No conferences for %s in progress..." "Nessuna conferenza per %s in progresso..." ::msgcat::mcset it "No users in %s roster..." "Nessun utente nei contatti di %s" ::msgcat::mcset it "Normal" "Normale" ::msgcat::mcset it "Open chat" "Aprire la finestra di conversazione" ::msgcat::mcset it "Open new conversation" "Aprire una nuova finestra di conversazione" ::msgcat::mcset it "Opens a new chat window for the new nick of the room occupant" "Aprire una nuova finestra di conversazione per ogni nick dell abitante della conferenza" ::msgcat::mcset it "Participants" "Partecipanti" ::msgcat::mcset it "Stop chat window autoscroll." "Fermare auto-scorrimento" ::msgcat::mcset it "Subject is set to: %s" "Argomento è: %s" ::msgcat::mcset it "Users" "Utenti" ::msgcat::mcset it "Visitors" "Ospiti" # custom.tcl ::msgcat::mcset it "Customization of the One True Jabber Client." "Personalizzare One True Jabber Client" ::msgcat::mcset it "Customize" "Personalizzare" ::msgcat::mcset it "Open" "Aprire" ::msgcat::mcset it "Parent group" "Categoria di livello superiore" ::msgcat::mcset it "Parent groups" "Categorie di livello superiore" ::msgcat::mcset it "Reset to current value" "Resettare a valore corrente" ::msgcat::mcset it "Reset to default value" "Resettare a valore predefenito" ::msgcat::mcset it "Reset to saved value" "Resettare a valore salvato" ::msgcat::mcset it "Reset to value from config file" "Resettare a valore da file di configurazione" ::msgcat::mcset it "Set for current and future sessions" "Stabilire per sessione corrente e quelle future" ::msgcat::mcset it "Set for current session only" "Stabilire solo per sessione corrente" ::msgcat::mcset it "State" "Stato" ::msgcat::mcset it "the option is set and saved." "la opzione è stabilita e salvata." ::msgcat::mcset it "the option is set to its default value." "la opzione e stabilita con il valore predefenito." ::msgcat::mcset it "the option is set, but not saved." "la opzione e stabilita, ma non salvata." ::msgcat::mcset it "the option is taken from config file." "la opzione ripresa dal file di configurazione." ::msgcat::mcset it "value is changed, but the option is not set." "valore è cambiato, ma la opzione non è stabilita." # plugins/windows/taskbar.tcl ::msgcat::mcset it "Enable windows tray icon." "Attivare tray icon" # plugins/general/message_archive.tcl ::msgcat::mcset it "#" "#" ::msgcat::mcset it "Dir" "Direzione" ::msgcat::mcset it "From/To" "Da/A" ::msgcat::mcset it "From:" "Da:" ::msgcat::mcset it "Messages" "Messagi" ::msgcat::mcset it "Received/Sent" "Ricevuto/Spedito" ::msgcat::mcset it "Subject" "Argomento" ::msgcat::mcset it "To:" "A:" # plugins/si/socks5.tcl ::msgcat::mcset it "Cannot connect to proxy" "Conessione a proxy non riuscita" ::msgcat::mcset it "Cannot negotiate proxy connection" "Impossibile negoziare con conessione proxy" ::msgcat::mcset it "Illegal result" "Risultato illecito" ::msgcat::mcset it "List of proxy servers for SOCKS5 bytestreams (all available servers will be tried for mediated connection)." "Lista di proxy servers per SOCKS5 flusso (tutti server disponibili saranno provati per conessione mediata)" ::msgcat::mcset it "Opening SOCKS5 listening socket" "Apertura SOCKS5 socket ricevente" ::msgcat::mcset it "Use mediated SOCKS5 connection if proxy is available." "Usare conessione SOCKS5 mediata se proxy non è disponibile." # ifacetk/systray.tcl ::msgcat::mcset it "Available" "Disponibile" ::msgcat::mcset it "Display status tooltip when main window is minimized to systray." "Visualizza finestra di status quando finestra principale e minimizzata a systray." ::msgcat::mcset it "Systray icon blinks when there are unread messages." "Systray icon lampeggia quando ci sono messagi non letti." ::msgcat::mcset it "Systray icon options." "Opzioni di icon systray" ::msgcat::mcset it "Tkabber Systray" "Tkabber Systray" # ifaceck/iroster.tcl ::msgcat::mcset it "Add group by regexp on JIDs..." "Aggiungere categoria usando regexp su JIDs..." ::msgcat::mcset it "Add roster group by JID regexp" "Aggiungere categoria di contatti usando JID regexp" ::msgcat::mcset it "Are you sure to remove group '%s' from roster?" "Sei sicuro di eliminare categoria '%s' dalla lista dei contatti?" ::msgcat::mcset it "Extended away" "Away estenso" ::msgcat::mcset it "JID regexp:" "JID regexp:" ::msgcat::mcset it "New group name:" "Nuovo nome della categoria:" ::msgcat::mcset it "Remove group..." "Elimina categoria..." ::msgcat::mcset it "Remove item..." "Elimina oggetto..." ::msgcat::mcset it "Rename group..." "Rinomina categoria..." ::msgcat::mcset it "Rename roster group" "Rinomina categoria di contatti" ::msgcat::mcset it "Resubscribe to all users in group..." "Reabonarsi a tutti gli utenti nella categoria..." ::msgcat::mcset it "Roster options." "Opzioni della lista dei contatti." ::msgcat::mcset it "Send custom presence" "Inviare presenza personalizzata" ::msgcat::mcset it "Unavailable" "Non disponibile" # plugins/chat/events.tcl ::msgcat::mcset it "Chat message events plugin options." ::msgcat::mcset it "Enable sending chat message events." ::msgcat::mcset it "Message delivered" "Messaggio consegnato con sucesso" ::msgcat::mcset it "Message delivered to %s" "Messaggio consegnato a %s" ::msgcat::mcset it "Message displayed" "Messaggio visualizzato" ::msgcat::mcset it "Message displayed to %s" "Message visualizzato da %s" ::msgcat::mcset it "Message stored on %s's server" "Messaggio salvato salvato sul %s's server" ::msgcat::mcset it "Message stored on the server" "Messaggio salvato sul server" # plugins/filetransfer/http.tcl ::msgcat::mcset it "Can't receive file: %s" "Impossibile ricevere file: %s" ::msgcat::mcset it "Force advertising this hostname (or IP address) for outgoing HTTP file transfers." "Avvertimento forzato di questo hostname (o indirizzo IP) di HTTP trasferimenti in uscita" ::msgcat::mcset it "HTTP options." "Opzioni HTTP" ::msgcat::mcset it "Port for outgoing HTTP file transfers (0 for assigned automatically). This is useful when sending files from behind a NAT with a forwarded port." \ "Port di uscita per HTTP trasfermenti (0 per assegnato automaticamente). Questo è molto utile quando file sono inviati dietro il NAT con forwarded port." # privacy.tcl ::msgcat::mcset it "Activate lists at startup" "Attivare la lista all avvio" ::msgcat::mcset it "Activate visible/invisible/ignore/conference lists before sending initial presence." "Attivare le liste visibile/invisibile/ignore/conference prima di inviare presenza iniziale." ::msgcat::mcset it "Activating privacy list failed: %s\n\nTry to reconnect. If problem persists, you may want to disable privacy list activation at start" "Inizializzazione della privacy lista non riuscita: %s\n\nProva a reconetterti. Se problema non si risolve prova a disabilitare attivazione della lista privacy all invio" ::msgcat::mcset it "Active" "Attivo" ::msgcat::mcset it "Add JID" "Aggiungere JID " ::msgcat::mcset it "Add item" "Aggiungere sogetto" ::msgcat::mcset it "Add list" "Aggiungere lista" ::msgcat::mcset it "Blocking communication (XMPP privacy lists) options." "Opzioni del blocco delle communicazioni (la privacy lista di XMPP)." ::msgcat::mcset it "Changing accept messages from roster only: %s" "Cambiare acettazione dei messaggi solo dagli utenti in lista: %s" ::msgcat::mcset it "Creating default privacy list" "Creazione della lista privacy predefenita" ::msgcat::mcset it "Creating default privacy list failed: %s\n\nTry to reconnect. If problem persists, you may want to disable privacy list activation at start" "Creazione della privacy lista non riuscita: %s\n\nProva a reconetterti. Se problema non si risolve prova a disabilitare attivazione della lista privacy all invio" ::msgcat::mcset it "Default" "Predefinito " ::msgcat::mcset it "Down" "Giu" ::msgcat::mcset it "Edit conference list" "Modificare la lista delle conferenze" ::msgcat::mcset it "Edit ignore list" "Modificare la lista degli ignorati" ::msgcat::mcset it "Edit invisible list" "Modificare la lista degli invisibili" ::msgcat::mcset it "Edit list" "Modificare la lista" ::msgcat::mcset it "Edit privacy list" "Modificare la lista privacy" ::msgcat::mcset it "Edit visible list" "Modificare la lista dei visibili" ::msgcat::mcset it "IQ" "IQ" ::msgcat::mcset it "Ignore list" "La lista degli ignorati" ::msgcat::mcset it "Invisible list" "La lista degli invisibili" ::msgcat::mcset it "List name" "Nome della lista" ::msgcat::mcset it "Message" "Messaggio" ::msgcat::mcset it "No active list" "Nessuna lista attiva" ::msgcat::mcset it "No default list" "Nessuna lista predefinita" ::msgcat::mcset it "Presence-in" "Presenza-in" ::msgcat::mcset it "Presence-out" "Presenza-out" ::msgcat::mcset it "Privacy list is activated" "La lista privacy è attivata" ::msgcat::mcset it "Privacy list is not activated" "La lista privacy non è attivata" ::msgcat::mcset it "Privacy list is not created" "La lista privacy non creata" ::msgcat::mcset it "Privacy lists" "Liste privacy" ::msgcat::mcset it "Privacy lists are not implemented" "Liste privacy non implementati" ::msgcat::mcset it "Privacy lists are unavailable" "Liste privacy non disponibili" ::msgcat::mcset it "Privacy lists error" "Errore delle liste privacy" ::msgcat::mcset it "Privacy rules" "Privacy regole" ::msgcat::mcset it "Remove from list" "Rimuovi dalla lista" ::msgcat::mcset it "Remove list" "Rimuovi la lista" ::msgcat::mcset it "Requesting conference list: %s" "Richiesta della lista di conferenze : %s" ::msgcat::mcset it "Requesting ignore list: %s" "Richiesta della lista degli ignorati: %s" ::msgcat::mcset it "Requesting invisible list: %s" "Richiesta della degli invisibili: %s" ::msgcat::mcset it "Requesting privacy list: %s" "Richiesta della lista privacy: %s" ::msgcat::mcset it "Requesting privacy rules: %s" "Richiesta delle privacy regole: %s" ::msgcat::mcset it "Requesting visible list: %s" "Richiesta della lista dei visibili: %s" ::msgcat::mcset it "Sending conference list: %s" "Invio della lista delle conferenze: %s" ::msgcat::mcset it "Sending ignore list: %s" "Invio della lista degli ignorati: %s" ::msgcat::mcset it "Sending invisible list: %s" "Invio della lista degli invisibile: %s" ::msgcat::mcset it "Sending visible list: %s" "Invio della lista degli visibili: %s" ::msgcat::mcset it "Type" "Tipo" ::msgcat::mcset it "Up" "Su" ::msgcat::mcset it "Value" "Valore" ::msgcat::mcset it "Visible list" "Lista dei visibili" ::msgcat::mcset it "Waiting for activating privacy list" "Attesa dell'attivazione della lista privacy" # plugins/general/copy_jid.tcl ::msgcat::mcset it "Copy JID to clipboard" "Copiare JID" # gpgme.tcl ::msgcat::mcset it "Display warning dialogs when signature verification fails." "Visualizzare un avvertimento quando controllo della signatura e fallito." ::msgcat::mcset it "Encrypt traffic (when possible)" "Criptare traffic (quando possibile)" ::msgcat::mcset it "Encryption" "Criptamento" ::msgcat::mcset it "Error in signature processing" "Errore nell elaborazione di signatura" ::msgcat::mcset it "Fetch GPG key" "Prelieva GPG key" ::msgcat::mcset it "GPG-encrypt outgoing messages where possible." "Cripta con GPG messaggi in uscita quando possibile." ::msgcat::mcset it "GPG-sign outgoing messages and presence updates." "Segna con GPG messagi in uscita e aggiornamenti della presenza." ::msgcat::mcset it "GPG options (signing and encryption)." "Opzioni di GPG (signatura e criptamento)" ::msgcat::mcset it "Invalid signature" "Signatura non valida" ::msgcat::mcset it "Malformed signature block" "Signatura malformata" ::msgcat::mcset it "Multiple signatures having different authenticity" "Signature differenti hanno una autenticita diversa" ::msgcat::mcset it "No information available" "Nessun informazione disponibile" ::msgcat::mcset it "Presence information" "Informazione della presenza" ::msgcat::mcset it "Presence is signed" "Presenza segnata" ::msgcat::mcset it "Select Key for Signing %s Traffic" "Seleziona la chiave per segnare %s Traffic" ::msgcat::mcset it "Sign traffic" "Segna traffic" ::msgcat::mcset it "Signature not processed due to missing key" "Signatura non verificata perche la chiave non c'e" ::msgcat::mcset it "The signature is good but has expired" "Signatura è buona ma è scaduta" ::msgcat::mcset it "The signature is good but the key has expired" "Signatura è buona ma la chiave è scaduta" ::msgcat::mcset it "Use specified key ID for signing and decrypting messages." "Usare ID della chiave specifico per segnare e decriptare messaggi." ::msgcat::mcset it "Use the same passphrase for signing and decrypting messages." "Usare la stessa frase identificativa per segnare e decriptare i messaggi." ::msgcat::mcset it "View" "Visualizza" ::msgcat::mcset it "\n\tPresence is signed:" "\n\tPresenza segnata" # pubsub.tcl ::msgcat::mcset it "Affiliation" "Affiliazione" ::msgcat::mcset it "Edit entities affiliations: %s" "Modifica le entita di affiliazione: %s" ::msgcat::mcset it "Jabber ID" "Jabber ID" ::msgcat::mcset it "Outcast" "Esiliato" ::msgcat::mcset it "Owner" "Fondatore" ::msgcat::mcset it "Pending" "Incompiuto" ::msgcat::mcset it "Publisher" "Editore" ::msgcat::mcset it "SubID" "SubID" ::msgcat::mcset it "Subscribed" "Abonato" ::msgcat::mcset it "Subscription" "Abonamento" ::msgcat::mcset it "Unconfigured" "Non configurato" # joingrdialog.tcl ::msgcat::mcset it "Join group dialog data (groups)." "I dati del dialogo per conettersi al gruppo (gruppi)." ::msgcat::mcset it "Join group dialog data (nicks)." "I dati del dialogo per conettersi al gruppo (nomi)." ::msgcat::mcset it "Join group dialog data (servers)." "I dati del dialogo per conettersi al gruppo (i server)." # jabberlib-tclxml/jlibsasl.tcl ::msgcat::mcset it "Aborted" "Abortito" ::msgcat::mcset it "Authentication Error" "Errore di autenticazione" ::msgcat::mcset it "Authentication failed" "Autenticazione fallita" ::msgcat::mcset it "Authentication successful" "Autenticazione riuscita" ::msgcat::mcset it "Incorrect encoding" "Codifica non coretta" ::msgcat::mcset it "Invalid authzid" "Authzid invalido" ::msgcat::mcset it "Invalid mechanism" "Mechanismo invalido" ::msgcat::mcset it "Mechanism too weak" "Mechanismo troppo debole" ::msgcat::mcset it "Not Authorized" "Non autorizzato" ::msgcat::mcset it "SASL auth error: %s" "Errore di autenticazione di SASL: %s" ::msgcat::mcset it "Server haven't provided SASL authentication feature" "Server non ha fornito autenticazione via SASL" ::msgcat::mcset it "Temporary auth failure" "Errore di autenticazione temporaneo" ::msgcat::mcset it "no mechanism available" "nessun mechanismo disponibile" # jabberlib-tclxml/jlibcompress.tcl ::msgcat::mcset it "Compression negotiation failed" "Negoziazione di compressione fallita" ::msgcat::mcset it "Compression negotiation successful" "Negoziazione di compressione riuscita" ::msgcat::mcset it "Compression setup failed" "Compressione non riuscita" ::msgcat::mcset it "Server haven't provided compress feature" "Server non ha fornito la funzione di compressione" ::msgcat::mcset it "Server haven't provided supported compress method" "Server non ha fornito il metodo di compressione supportato" ::msgcat::mcset it "Unsupported compression method" "Metodo di compressione non supportato" # jidlink.tcl ::msgcat::mcset it "Enable Jidlink transport %s." "Attivare Jidlink trasporto %s." # plugins/general/stats.tcl ::msgcat::mcset it "JID" "JID" ::msgcat::mcset it "Name " "Nome " ::msgcat::mcset it "Node" "Nodo " ::msgcat::mcset it "Open statistics monitor" "Aprire monitor delle statistiche" ::msgcat::mcset it "Request" "Richiesta" ::msgcat::mcset it "Service statistics" "Statistiche del servizio" ::msgcat::mcset it "Set" "Porre" ::msgcat::mcset it "Statistics" "Statistiche" ::msgcat::mcset it "Statistics monitor" "Monitor delle statistiche" ::msgcat::mcset it "Timer" "Cronometro" ::msgcat::mcset it "Units" "Le unita" # ifaceck/iface.tcl ::msgcat::mcset it "Move tab left/right" "Muovere tab sinistra/destra" ::msgcat::mcset it "Raise new tab." "Tirare su la nuova tab" ::msgcat::mcset it "Right mouse button" "Pulsante destro di mouse" ::msgcat::mcset it "Switch to tab number 1-9,10" "Cambiare a numero di tab 1-9,10" # search.tcl ::msgcat::mcset it "An error occurred when searching in %s\n\n%s" "Un errore accaduto durante la ricerca in %s\n\n%s" ::msgcat::mcset it "Search" "Cerca" ::msgcat::mcset it "Search in %s" "Cerca in %s" ::msgcat::mcset it "Search in %s: No matching items found" "Ricerca in %s: Nessuna voce trovata" ::msgcat::mcset it "Search: %s" "Cerca: %s" ::msgcat::mcset it "Try again" "Ritenta" # roster.tcl ::msgcat::mcset it "Active Chats" "Conversazioni attive" ::msgcat::mcset it "My Resources" "Le mie risorse" # plugins/general/ispell.tcl ::msgcat::mcset it "Check spell after every entered symbol." "Controlla spell dopo ogni simbolo inserito." ::msgcat::mcset it "Could not start ispell server. Check your ispell path and dictionary name. Ispell is disabled now" "Non è possibile avviare ispell server. Controlla via per ispell e il nome dell dizionario. Ispell è disabilitato ora adesso" ::msgcat::mcset it "Enable spellchecker in text input windows." "Attivare spellchecker nella finestra di inserimento del testo." ::msgcat::mcset it "Ispell dictionary encoding. If it is empty, system encoding is used." "La codifica del dizionario ispell. Se vuota, la codifica di sistema verra usata." ::msgcat::mcset it "Path to the ispell executable." "Via al eseguibile di ispell" ::msgcat::mcset it "Plugins options." "Opzioni di plugin" ::msgcat::mcset it "Spell check options." "Opzioni dell controllo di spell" # iface.tcl ::msgcat::mcset it "Begin date" "Data dell inizio" ::msgcat::mcset it "Cipher" "Metodo di codifica" ::msgcat::mcset it "Disabled\n" "Disabilitato\n" ::msgcat::mcset it "Enabled\n" "Abilitato\n" ::msgcat::mcset it "Expiry date" "Data di scadenza" ::msgcat::mcset it "Issuer" "Emmitente" ::msgcat::mcset it "Serial number" "Numero seriale" # ifacetk/ilogin.tcl ::msgcat::mcset it "Account" "Account" ::msgcat::mcset it "Allow plaintext authentication mechanisms" "Permettere mechanismi di autenticazione plaintext" ::msgcat::mcset it "Authentication" "Autenticazione" ::msgcat::mcset it "Compression" "Compressione" ::msgcat::mcset it "Connect via HTTP polling" "Connetersi usando HTTP" ::msgcat::mcset it "Connection" "Conessione" ::msgcat::mcset it "Encryption (STARTTLS)" "Crittazione (STARTTLS)" ::msgcat::mcset it "Encryption (legacy SSL)" "Crittazione (vechio SSL)" ::msgcat::mcset it "Explicitly specify host and port to connect" "Specificare host e port per conessione" ::msgcat::mcset it "HTTP Poll" "HTTP conessione" ::msgcat::mcset it "Host:" "Host:" ::msgcat::mcset it "Logout" "Uscire" ::msgcat::mcset it "Plaintext" "Plaintext" ::msgcat::mcset it "Proxy" "Proxy" ::msgcat::mcset it "Replace opened connections" "Rimpiazzare le conessione gia aperte" ::msgcat::mcset it "SSL" "SSL" ::msgcat::mcset it "SSL & Compression" "SSL & Compressione" ::msgcat::mcset it "SSL Certificate:" "SSL Certificato:" ::msgcat::mcset it "URL to poll:" "URL per conessione:" ::msgcat::mcset it "Use SASL authentication" "Usa autenticazione SASL" ::msgcat::mcset it "Use client security keys" "Usa le chiavi di sicurezza del cliente" # plugins/general/xcommands.tcl ::msgcat::mcset it "Commands" "Commandi" ::msgcat::mcset it "Error completing command: %s" "Errore nel completare la commanda: %s" ::msgcat::mcset it "Error executing command: %s" "Errore nel esecuzione del commanda: %s" ::msgcat::mcset it "Error:" "Errore:" ::msgcat::mcset it "Execute command" "Eseguire il commando" ::msgcat::mcset it "Finish" "Fine" ::msgcat::mcset it "Info:" "Info:" ::msgcat::mcset it "Next" "Avanti" ::msgcat::mcset it "Prev" "Indietro" ::msgcat::mcset it "Submit" "Invia" ::msgcat::mcset it "Warning:" "Avviso:" # plugins/chat/logger.tcl ::msgcat::mcset it "All" "Tutto" ::msgcat::mcset it "April" "Aprile" ::msgcat::mcset it "August" "Agosto" ::msgcat::mcset it "Chats history is converted.\nBackup of the old history is stored in %s" "La storia delle conversazione e convertita.\nBackup della vechia storia e salvato in %s" ::msgcat::mcset it "Conversion is finished" "Conversione è finita" ::msgcat::mcset it "Converting Log Files" "File di log di conversione" ::msgcat::mcset it "December" "Dicembre" ::msgcat::mcset it "Directory to store logs." "La cartella per salvare i log." ::msgcat::mcset it "Export to XHTML" "Esporta a XHTML" ::msgcat::mcset it "February" "Febbraio" ::msgcat::mcset it "File %s cannot be opened: %s. History for %s (%s) is NOT converted\n" "Impossibile aprire file %s : %s. Storia per %s (%s) non convertita\n" ::msgcat::mcset it "File %s cannot be opened: %s. History for %s is NOT converted\n" "Impossibile aprire file %s : %s. Storia per %s non convertita\n" ::msgcat::mcset it "File %s is corrupt. History for %s (%s) is NOT converted\n" "File %s è corrotto. Storia per %s (%s) non convertita\n" ::msgcat::mcset it "File %s is corrupt. History for %s is NOT converted\n" "File %s è corrotto. Storia per %s non convertita\n" ::msgcat::mcset it "History for %s" "Storia per %s" ::msgcat::mcset it "January" "Gennaio" ::msgcat::mcset it "July" "Luglio" ::msgcat::mcset it "June" "Giugno" ::msgcat::mcset it "Logging options." "Opzioni del registrazione dei conversazioni" ::msgcat::mcset it "March" "Marzo" ::msgcat::mcset it "May" "Maggio" ::msgcat::mcset it "November" "Novembre" ::msgcat::mcset it "October" "Ottobre" ::msgcat::mcset it "Please, be patient while chats history is being converted to new format" "Per favore, aspettate un attimo finche la storia dei conversazioni non è convertita al formato nuovo" ::msgcat::mcset it "Select month:" "Seleziona mese:" ::msgcat::mcset it "September" "Settembre" ::msgcat::mcset it "Store group chats logs." "Salva la storia di conversazione del gruppo" ::msgcat::mcset it "Store private chats logs." "Salva la storia di conversazione private" ::msgcat::mcset it "You're using root directory %s for storing Tkabber logs!\n\nI refuse to convert logs database." "Sta usando la cartella di root %s per salvare la storia dei messagi!\n\nIo mi rifiuto di convertire la database delle conversazioni." # plugins/general/clientinfo.tcl ::msgcat::mcset it "\n\tName: %s" "\n\tNome: %s" # plugins/general/subscribe_gateway.tcl ::msgcat::mcset it "Add user to roster..." "Aggiungi utente alla lista dei contatti" ::msgcat::mcset it "Convert" "Convertire" ::msgcat::mcset it "Convert screenname" "Convertire il nome" ::msgcat::mcset it "Enter screenname of contact you want to add" "Inserire il nome del contatto che vuoi aggiungere" ::msgcat::mcset it "Error while converting screenname: %s." "Errore nel convertire nome: %s" ::msgcat::mcset it "I would like to add you to my roster." "Mi piacerebbe di aggiungere te alla mia lista dei contatti" ::msgcat::mcset it "Screenname conversion" "Conversione dei nomi" ::msgcat::mcset it "Screenname:" "Nome:" ::msgcat::mcset it "Screenname: %s\n\nConverted JID: %s" "Nome: %s\n\nJID Convertito: %s" ::msgcat::mcset it "Send subscription at %s" "Invia la sottoscirizione a %s" ::msgcat::mcset it "Send subscription to: " "Invia la sottoscrizione a: %s" # pixmaps.tcl ::msgcat::mcset it "Tkabber icon theme. To make new theme visible for Tkabber put it to some subdirectory of %s." "La tema delle icone di Tkabber. Per fare visibile la nuova tema per Tkabber metterla nella cartella qualuncue dentro %s" # iq.tcl ::msgcat::mcset it "%s request from %s" "%s richiesta da %s" ::msgcat::mcset it "Info/Query options." "Opzioni di Info/Domande." ::msgcat::mcset it "Show IQ requests in the status line." "Mostra rechieste di IQ nella linea di status." ::msgcat::mcset it "Strip leading \"http://jabber.org/protocol/\" from IQ namespaces in the status line." "Strappa \"http://jabber.org.protocol/\" dagli namespace nella linea di status." # plugins/chat/histool.tcl ::msgcat::mcset it "Chats History" "La storia di conversazioni" ::msgcat::mcset it "Chats history" "La storia di conversazioni" ::msgcat::mcset it "Client message" "Messagio di cliente" ::msgcat::mcset it "Full-text search" "Ricerca a testo completo" ::msgcat::mcset it "JID list" "Lista JID" ::msgcat::mcset it "Logs" "Logs" ::msgcat::mcset it "Server message" "Messagi di server" ::msgcat::mcset it "Service Discovery" "Ricerca dei Servizi" ::msgcat::mcset it "Unsupported log dir format" "Formato del log dir non supportato" ::msgcat::mcset it "WARNING: %s\n" "ATTENZIONE: %s\n" # plugins/unix/systray.tcl ::msgcat::mcset it "Enable freedesktop systray icon." "Abilitare icona di systray libera dal desktop." # ifaceck/widgets.tcl ::msgcat::mcset it "Error" "Errore" ::msgcat::mcset it "Question" "Domanda" ::msgcat::mcset it "Warning" "Attenzione" # plugins/richtext/emoticons.tcl ::msgcat::mcset it "Handle ROTFL/LOL smileys -- those like :))) -- by \"consuming\" all that parens and rendering the whole word with appropriate icon." "Interpretare ROTFL/LOL sorrisi -- come questo :))) -- \"togliendo\" tutte le parentesi e sostituendoli con icona appropriata." ::msgcat::mcset it "Handling of \"emoticons\". Emoticons (also known as \"smileys\") are small pictures resembling a human face used to represent user's emotion. They are typed in as special mnemonics like :) or can be inserted using menu." "Interpretazione degli \"emoticons\". Emoticons (conosciuti anche come \"smiles\") sono piccoli icone che rappresentano una emozione sulla faccia umana. Possono essere inseriti digitando :) (o qualcosa del genere) o inseriti tramite menu." ::msgcat::mcset it "Show images for emoticons." "Mostra immagini per emoticons." ::msgcat::mcset it "Tkabber emoticons theme. To make new theme visible for Tkabber put it to some subdirectory of %s." "La tema dei emoticons per Tkabber. Per far visibile la tema bisogna metterla nella qualche cartella di %s." ::msgcat::mcset it "Use only whole words for emoticons." "Usare soltanto parole complete per emoticons." # plugins/roster/annotations.tcl ::msgcat::mcset it "Created: %s" "Creato %s" ::msgcat::mcset it "Edit item notes..." "Modificare le note dei articoli..." ::msgcat::mcset it "Edit roster notes for %s" "Modificare le note dell roster per %s" ::msgcat::mcset it "Modified: %s" "Modificato: %s" ::msgcat::mcset it "Notes" "Note" ::msgcat::mcset it "Roster Notes" "Note del roster" ::msgcat::mcset it "Store" "Deposito" ::msgcat::mcset it "Storing roster notes failed: %s" "Immagazinamento delle note di roster non riuscito: %s" # plugins/chat/bookmark_highlighted.tcl ::msgcat::mcset it "Next highlighted" "Prossimo sottolineato" ::msgcat::mcset it "Prev highlighted" "Precedente sottolineato" # plugins/chat/complete_last_nick.tcl ::msgcat::mcset it "Number of groupchat messages to expire nick completion according to the last personally addressed message." # login.tcl ::msgcat::mcset it ". Proceed?\n\n" ". Proseguire?\n\n" ::msgcat::mcset it "Allow plaintext authentication mechanisms (when password is transmitted unencrypted)." "Consentire i mechanismi di autenticazione di testo semplice (quando password trasmesso non è criptato)" ::msgcat::mcset it "Authentication failed: %s" "Autenticazione non riuscita: %s" ::msgcat::mcset it "Display SSL warnings." "Visualizza avvisi di SSL" ::msgcat::mcset it "Failed to connect: %s" "Conessione non riuscita: %s" ::msgcat::mcset it "HTTP proxy address." "Indirizzo HTTP proxy." ::msgcat::mcset it "HTTP proxy password." "HTTP proxy password." ::msgcat::mcset it "HTTP proxy port." "Porta di HTTP proxy." ::msgcat::mcset it "HTTP proxy username." "Nome utente di HTTP proxy." ::msgcat::mcset it "Keep trying" "Continua a tentare" ::msgcat::mcset it "List of logout reasons." "Lista dei messagi di uscita." ::msgcat::mcset it "Login options." "Opzioni di login." ::msgcat::mcset it "Maximum poll interval." "Intervallo massimo tra le richieste HTTP." ::msgcat::mcset it "Minimum poll interval." "Intervallo minimo tra le richieste HTTP." ::msgcat::mcset it "Number of HTTP poll client security keys to send before creating new key sequence." "Quantita delle chiavi della sicurezza, dopo trasmissione dei quali si genera la nuova sequenza." ::msgcat::mcset it "Password." "Password." ::msgcat::mcset it "Priority." "Priorita." ::msgcat::mcset it "Replace opened connections." "Rimpiazza le conessione aperte." ::msgcat::mcset it "Resource." "Risorsa." ::msgcat::mcset it "Retry to connect forever." "Continua a reconettersi di continuo." ::msgcat::mcset it "SSL certificate file (optional)." "File con certificato SSL (opzionale)." ::msgcat::mcset it "SSL certification authority file or directory (optional)." "File o cartella della certificazione SSL (opzionale)." ::msgcat::mcset it "SSL private key file (optional)." "File con la chiave privata SSL (opzionale)." ::msgcat::mcset it "Server name or IP-address." "Nome del server o indirizzo IP." ::msgcat::mcset it "Server name." "Nome del server." ::msgcat::mcset it "Server port." "La porta del server." ::msgcat::mcset it "Timeout for waiting for HTTP poll responses (if set to zero, Tkabber will wait forever)." "Tempo di scadenza delle risposte HTTP (se a zero, Tkabber aspettera per sempre)." ::msgcat::mcset it "URL to connect to." "URL da reconettersi." ::msgcat::mcset it "Use HTTP poll client security keys (recommended)." "Usare le chiavi di sicurezza (raccomandato)." ::msgcat::mcset it "Use HTTP poll connection method." "Usare metodo di conessione HTTP." ::msgcat::mcset it "Use HTTP proxy to connect." "Usare HTTP proxy per conettersi." ::msgcat::mcset it "Use SASL authentication." "Usare autenticazione SASL." ::msgcat::mcset it "Use explicitly-specified server address and port." "Usare nome del server e port specificato." ::msgcat::mcset it "User name." "Nome utente." ::msgcat::mcset it "User-Agent string." "Stringa User-Agent." ::msgcat::mcset it "Warning display options." "Opzioni dei avvisi." ::msgcat::mcset it "XMPP stream options when connecting to server." "Opzioni del flusso XMPP durante la conessione al server." # plugins/chat/draw_timestamp.tcl ::msgcat::mcset it "Format of timestamp in delayed chat messages delayed for more than 24 hours." "Formato del tempo nella finestra dei messagi che sono stati mandati piu di 24 ore fa." # plugins/general/session.tcl ::msgcat::mcset it "Load state on Tkabber start." "Caricare stato quando Tkabber parte." ::msgcat::mcset it "Load state on start" "Caricare stato all avvio" ::msgcat::mcset it "Save state" "Salva stato" ::msgcat::mcset it "Save state on Tkabber exit." "Salva stato alla uscita di Tkabber." ::msgcat::mcset it "Save state on exit" "Salva stato all'uscita" ::msgcat::mcset it "Tkabber save state options." "Opzioni dello stato di Tkabber." # plugins/filetransfer/jidlink.tcl ::msgcat::mcset it "Jidlink connection failed" "Jidlink conessione non riuscita" ::msgcat::mcset it "Jidlink options." "Opzioni Jidlink." ::msgcat::mcset it "Jidlink transfer failed" "Trasferimento Jidlink non riuscito" ::msgcat::mcset it "Receiving file failed: %s" "Ricevimento del file non riuscito: %s" ::msgcat::mcset it "Transferring..." "Trasferimento..." # splash.tcl ::msgcat::mcset it "%s plugin" "%s plugin" ::msgcat::mcset it "Save To Log" "Salvare log" ::msgcat::mcset it "bwidget workarounds" ::msgcat::mcset it "customization" "personalizzazione" ::msgcat::mcset it "general plugins" "Plugin communi" ::msgcat::mcset it "jabber chat/muc" "Jabber chat/muc" ::msgcat::mcset it "jabber messages" "messagi jabber" ::msgcat::mcset it "jabber roster" "jabber roster" ::msgcat::mcset it "macintosh plugins" "plugin per macintosh" ::msgcat::mcset it "negotiation" "negoziazione" ::msgcat::mcset it "pixmaps management" "gestione di pixmaps" ::msgcat::mcset it "privacy rules" "regole della privacy" ::msgcat::mcset it "roster plugins" "i plugin del roster" ::msgcat::mcset it "search plugins" "plugin per ricerca" ::msgcat::mcset it "service discovery" "ricerca dei servizi" ::msgcat::mcset it "sound" "suono" ::msgcat::mcset it "unix plugins" ::msgcat::mcset it "windows plugins" # datagathering.tcl ::msgcat::mcset it "Configure service" "Configurazione" ::msgcat::mcset it "Data form" "Forma da riempire" ::msgcat::mcset it "Date:" "Data:" ::msgcat::mcset it "Email:" "Email:" ::msgcat::mcset it "Error requesting data: %s" "Errore nel richiedere data: %s" ::msgcat::mcset it "First Name:" "Nome:" ::msgcat::mcset it "Instructions" "Istruzioni:" ::msgcat::mcset it "Key:" "Chiave:" ::msgcat::mcset it "Last Name:" "Cognome:" ::msgcat::mcset it "Misc:" "Misc:" ::msgcat::mcset it "Phone:" "Telefono:" ::msgcat::mcset it "Text:" "Testo:" ::msgcat::mcset it "Zip:" "Cap:" # plugins/richtext/highlight.tcl ::msgcat::mcset it "Enable highlighting plugin." "Attivare plugin di evidenziazione." ::msgcat::mcset it "Groupchat message highlighting plugin options." "Opzioni di evidenziazione nel chat di gruppo." ::msgcat::mcset it "Highlight current nickname in messages." "Evidenziare nickname attuale nei messaggi." ::msgcat::mcset it "Highlight only whole words in messages." "Evidenziare solo parole complete nei messaggi." ::msgcat::mcset it "Substrings to highlight in messages." "Sottostringhe da evidenziare nei messaggi." # plugins/unix/dockingtray.tcl ::msgcat::mcset it "Enable KDE tray icon." "Attivare icona di tray KDE." # plugins/search/search.tcl ::msgcat::mcset it "Match case while searching in chat, log or disco windows." "Usare ricerca sensibile al registro dei caratteri nel chat, log o scoperta dei servizi." ::msgcat::mcset it "Search in Tkabber windows options." "Cercare nelle opzioni di finestre del Tkabber" ::msgcat::mcset it "Specifies search mode while searching in chat, log or disco windows. \"substring\" searches exact substring, \"glob\" uses glob style matching, \"regexp\" allows to match regular expression." "Specificare la modalita di ricerca per chat, log o scoperta dei servizi. \"substring\" cerca esattamente sottostringa, \"glob\" usa ricerca globale, \"regexp\" permette di fare ricerca usando espressioni regolari. " # register.tcl ::msgcat::mcset it "Register" "Registra" ::msgcat::mcset it "Registration is successful!" "Registrazione riuscita!" ::msgcat::mcset it "Registration: %s" "Registrazione: %s" ::msgcat::mcset it "Unregister" "Cancella registrazione" # plugins/chat/info_commands.tcl ::msgcat::mcset it "Address 2" "Indirizzo 2" ::msgcat::mcset it "City" "Citta" ::msgcat::mcset it "Country" "Paese" ::msgcat::mcset it "Display %s in chat window when using /vcard command." "Visualizzare %s nella finestra di chat quando si usa commando /vcard." ::msgcat::mcset it "E-mail" "E-mail" ::msgcat::mcset it "Family Name" "Cognome" ::msgcat::mcset it "Full Name" "Nome" ::msgcat::mcset it "Latitude" "Latitudine" ::msgcat::mcset it "Longitude" "Longitudine" ::msgcat::mcset it "Middle Name" "Secondo nome" ::msgcat::mcset it "Nickname" "Sopranome" ::msgcat::mcset it "Organization Name" "Nome del organizzazione" ::msgcat::mcset it "Organization Unit" "Unita del organizzazione" ::msgcat::mcset it "Phone BBS" "Numero BBS" ::msgcat::mcset it "Phone Cell" "Numero di cellulare" ::msgcat::mcset it "Phone Fax" "Numero di Fax" ::msgcat::mcset it "Phone Home" "Numero di telefono di casa" ::msgcat::mcset it "Phone ISDN" "Numero di ISDN" ::msgcat::mcset it "Phone Message Recorder" "Numero di segreteria telefonica" ::msgcat::mcset it "Phone Modem" "Telefono Modem" ::msgcat::mcset it "Phone PCS" "Telefono PCS" ::msgcat::mcset it "Phone Pager" "Numero di pager" ::msgcat::mcset it "Phone Preferred" "Telefono preferito" ::msgcat::mcset it "Phone Video" "Telefono video " ::msgcat::mcset it "Phone Voice" "Telefono voce" ::msgcat::mcset it "Phone Work" "Telefono di lavoro" ::msgcat::mcset it "Postal Code" "Codice postale" ::msgcat::mcset it "Prefix" "Prefisso" ::msgcat::mcset it "Role" "Impiego" ::msgcat::mcset it "State " "Stato " ::msgcat::mcset it "Suffix" "Suffisso" ::msgcat::mcset it "Title" "Titolo" ::msgcat::mcset it "UID" "UID" ::msgcat::mcset it "Web Site" "Sito Web" ::msgcat::mcset it "last %s%s:" "ultimo %s%s:" ::msgcat::mcset it "last %s%s: %s" "ultimo %s%s: %s" ::msgcat::mcset it "time %s%s:" "tempo %s%s" ::msgcat::mcset it "time %s%s: %s" "tempo %s%s: %s" ::msgcat::mcset it "vCard display options in chat windows." "opzioni di visualizzazione di vCard nella finestra del chat." ::msgcat::mcset it "vcard %s%s:" "vcard %s%s:" ::msgcat::mcset it "vcard %s%s: %s" "vcard %s%s: %s" ::msgcat::mcset it "version %s%s:" "versione %s%s:" ::msgcat::mcset it "version %s%s: %s" "versione %s%s: %s" # plugins/general/sound.tcl ::msgcat::mcset it "External program, which is to be executed to play sound. If empty, Snack library is used (if available) to play sound." ::msgcat::mcset it "Mute sound" "Muto" ::msgcat::mcset it "Mute sound if Tkabber window is focused." "Disattivare suono quando finestra di Tkabber e in fuoco" ::msgcat::mcset it "Mute sound notification." "Disattivare il suono delle notifiche." ::msgcat::mcset it "Mute sound when displaying delayed groupchat messages." "Disattivare il suono quando messagi di groupchat differiti vengono visualizzate." ::msgcat::mcset it "Mute sound when displaying delayed personal chat messages." "Disattivare il suono quando messagi personali differiti vengono visualizzate." ::msgcat::mcset it "Notify only when available" "Notificare solo quando disponibile" ::msgcat::mcset it "Options for external play program" "Opzioni per i programmi esterni di suono" ::msgcat::mcset it "Sound options." "Opzioni di suono" ::msgcat::mcset it "Sound to play when available presence is received." "Suono da riprodurre quando stato disponibile e ricevuto." ::msgcat::mcset it "Sound to play when connected to Jabber server." "Suono da riprodurre quando conessione a Jabber server e riuscita." ::msgcat::mcset it "Sound to play when groupchat message from me is received." "Suono da riprodurre quando messaggio nel groupchat da me è ricevuto." ::msgcat::mcset it "Sound to play when groupchat message is received." "Suono da riprodurre quando messaggio di groupchat è ricevuto." ::msgcat::mcset it "Sound to play when groupchat server message is received." "Suono da riprodurre quando messaggio di server è ricevuto." ::msgcat::mcset it "Sound to play when highlighted (usually addressed personally) groupchat message is received." "Suono da riprodurre quando messaggio di groupchat evidenziato è ricevuto." ::msgcat::mcset it "Sound to play when personal chat message is received." "Suono da riprodurre quando messaggio personale è ricevuto." ::msgcat::mcset it "Sound to play when sending personal chat message." "Suono da riprodurre quando messaggio personale è spedito." ::msgcat::mcset it "Sound to play when unavailable presence is received." "Suono da riprodurre quando lo stato non disponibile è ricevuto." ::msgcat::mcset it "Time interval before playing next sound (in milliseconds)." "Intervallo di tempo tra riproduzione dei suoni (millisecondi)." ::msgcat::mcset it "Use sound notification only when being available." "Usare notifica del suono quando lo stato è disponibile." # ifaceck/ilogin.tcl ::msgcat::mcset it "SASL" "SASL" ::msgcat::mcset it "SASL Certificate:" "SASL Certificato: " ::msgcat::mcset it "SASL Port:" "SASL Porta:" ::msgcat::mcset it "Server Port:" "Server porta:" # plugins/chat/log_on_open.tcl ::msgcat::mcset it "Maximum interval length in hours for which log messages should be shown in newly opened chat window (if set to negative then the interval is unlimited)." "Intervallo massimo di tempo per quanto i messaggi di log devono essere visualizzati nelle nuove finestre (se il valore è negativo, allora intervallo è illimitato)." ::msgcat::mcset it "Maximum number of log messages to show in newly opened chat window (if set to negative then the number is unlimited)." "Numero massimo dei messaggi salvati da visualizzare nella nuova finestra del chat (se il valore è negativo allora il numero è illimitato)." # plugins/chat/clear.tcl ::msgcat::mcset it "Clear chat window" "Pulire la finestra del chat" # plugins/roster/cache_categories.tcl ::msgcat::mcset it "Cached service categories and types (from disco#info)." "Categorie e tipi dei servizi memorizzati (da disco#info)." # jabberlib-tclxml/stanzaerror.tcl ::msgcat::mcset it "Bad Request" "Richiesta non valida" ::msgcat::mcset it "Conflict" "Conflitto" ::msgcat::mcset it "Feature Not Implemented" "Funzione non realizzata" ::msgcat::mcset it "Forbidden" "Proibito" ::msgcat::mcset it "Gone" "Andato" ::msgcat::mcset it "Internal Server Error" "Errore all interno del server" ::msgcat::mcset it "Item Not Found" "Ogetto non trovato" ::msgcat::mcset it "JID Malformed" "JID Malformato" ::msgcat::mcset it "Not Acceptable" "Non Acettabile" ::msgcat::mcset it "Not Allowed" "Non permesso" ::msgcat::mcset it "Payment Required" "Pagamento richiesto" ::msgcat::mcset it "Recipient Unavailable" "Recipiente non disponibile" ::msgcat::mcset it "Redirect" "Reindirizzamento" ::msgcat::mcset it "Registration Required" "Registrazione richiesta" ::msgcat::mcset it "Remote Server Not Found" "Server non trovato" ::msgcat::mcset it "Remote Server Timeout" "Tempo scaduto" ::msgcat::mcset it "Request Error" "Errore di richiesta" ::msgcat::mcset it "Resource Constraint" "Risorsa costretta" ::msgcat::mcset it "Service Unavailable" "Servizio non disponibile" ::msgcat::mcset it "Subscription Required" "Sottoscirizione richiesta" ::msgcat::mcset it "Temporary Error" "Errore temporaneo" ::msgcat::mcset it "Undefined Condition" "Condizione indefinita" ::msgcat::mcset it "Unexpected Request" "Richiesta inaspettata" ::msgcat::mcset it "Unrecoverable Error" "Errore non risarcibile" # plugins/chat/abbrev.tcl ::msgcat::mcset it "Abbreviations:" "Abbreviature:" ::msgcat::mcset it "Added abbreviation:\n%s: %s" "Abbreviature aggiunte:\n%s: %s" ::msgcat::mcset it "Deleted abbreviation: %s" "Abbreviature cancellate: %s" ::msgcat::mcset it "No such abbreviation: %s" "Nessuna abbreviazione: %s" ::msgcat::mcset it "Purged all abbreviations" "Tutte le abbreviature sono cancellate" ::msgcat::mcset it "Usage: /abbrev WHAT FOR" "Uso: /abbrev COSA PER" ::msgcat::mcset it "Usage: /unabbrev WHAT" "Uso: /unnabrev COSA" # richtext.tcl ::msgcat::mcset it "Settings of rich text facility which is used to render chat messages and logs." "Impostazioni della sistema che si usa per visualizzare i messaggi del chat e log." # plugins/roster/conferenceinfo.tcl ::msgcat::mcset it "Interval (in minutes) after error reply on request of participants list." "Intervallo (in minuti) dopo risposta con errore a richiesta della lista dei participanti." ::msgcat::mcset it "Interval (in minutes) between requests of participants list." "Inervallo (in minuti) tra le richieste della lista dei participanti." ::msgcat::mcset it "Options for Conference Info module, that allows you to see list of participants in roster popup, regardless of whether you are currently joined with the conference." "Opzioni per modulo Conference Info, che permette di vedere la lista dei participanti nella pop up di rosyer, indipendentemente dalla sua presenza nella conferenza." ::msgcat::mcset it "Use this module" "Usa questo modulo" ::msgcat::mcset it "\nRoom is empty at %s" "\nStanza è vuota a %s" ::msgcat::mcset it "\nRoom participants at %s:" "\nParticipanti della stanza a %s:" ::msgcat::mcset it "\n\tCan't browse: %s" "\n\tNon è possibile visualizzare: %s" # plugins/general/headlines.tcl ::msgcat::mcset it "%s Headlines" "%s Intestazioni" ::msgcat::mcset it "" "" ::msgcat::mcset it "Cache headlines on exit and restore on start." "Memorizzare intestazioni prima di uscire e ripristinare all'avvio." ::msgcat::mcset it "Copy URL to clipboard" "Copiare URL" ::msgcat::mcset it "Copy headline to clipboard" "Copiare intestazione" ::msgcat::mcset it "Delete" "Cancella" ::msgcat::mcset it "Delete all" "Cancella tutto" ::msgcat::mcset it "Delete seen" "Cancella gia visti" ::msgcat::mcset it "Display headlines in single/multiple windows." "Visualizza intestazioni nelle finestre singole/multiple." ::msgcat::mcset it "Do not display headline descriptions as tree nodes." "Non visualizzare descrizioni degli intestazioni come nodi dell albero." ::msgcat::mcset it "Format of timestamp in headline tree view. Set to empty string if you don't want to see timestamps." "Formato delle marcature orarie nell albero con intestazioni. Mettere un valore nullo per non visualizzare narcature orarie." ::msgcat::mcset it "Forward headline" "Inoltrare intestazione" ::msgcat::mcset it "Forward to %s" "Inoltra a %s" ::msgcat::mcset it "Forward..." "Inoltra..." ::msgcat::mcset it "List of JIDs to whom headlines have been sent." "Lista degli JID a chi sono stati mandati intestazioni." ::msgcat::mcset it "Mark all seen" "Segnare tutto come visto" ::msgcat::mcset it "Mark all unseen" "Segnare tutto come non visto" ::msgcat::mcset it "One window per bare JID" "Una finestra per JID corto (senza risorsa)" ::msgcat::mcset it "One window per full JID" "Una finestra per JID intero" ::msgcat::mcset it "Read on..." "Leggere ancora..." ::msgcat::mcset it "Show balloons with headline messages over tree nodes." "Mostrare le mongolfiere con messagi dei intestazioni al di sopra di nodi del albero." ::msgcat::mcset it "Single window" "Finestra singola" ::msgcat::mcset it "Sort by date" "Ordinare a secondo di data" # si.tcl ::msgcat::mcset it "Enable SI transport %s." "Attivare SI trasporto %s." ::msgcat::mcset it "Opening SI connection" "Aprire conessione SI" ::msgcat::mcset it "SI connection closed" "Conessione SI chiusa" ::msgcat::mcset it "Stream method negotiation failed" "Impossibile negoziare con metodo di flusso" # plugins/chat/draw_xhtml_message.tcl ::msgcat::mcset it "Enable rendering of XHTML messages." "Abilitare la visualizzazione dei messagi con XHTML" # plugins/general/rawxml.tcl ::msgcat::mcset it "Available presence" "Presenza disponibile" ::msgcat::mcset it "Chat message" "Messagio di chat" ::msgcat::mcset it "Clear" "Pulire" ::msgcat::mcset it "Create node" "Creare nodo" ::msgcat::mcset it "Generic IQ" "IQ Generico" ::msgcat::mcset it "Get items" "Prendere elementi" ::msgcat::mcset it "Headline message" "Messaggio con intestazione" ::msgcat::mcset it "Indentation for pretty-printed XML subtags." "La misura dell'alinea per bell-stampati XML sottotags" ::msgcat::mcset it "Normal message" "Messaggio normale" ::msgcat::mcset it "Open raw XML window" "Aprire finestra per XML puro" ::msgcat::mcset it "Options for Raw XML Input module, which allows you to monitor incoming/outgoing traffic from connection to server and send custom XML stanzas." "Opzioni per modulo di Input di XML puro, che permette du monitorare traffic in entrata/uscita da conessione al server, e spedire XML stanze personalizzate" ::msgcat::mcset it "Pretty print XML" "Formattazione del XML" ::msgcat::mcset it "Pretty print incoming and outgoing XML stanzas." "Formattazione delle XML stanze in entrata/uscita" ::msgcat::mcset it "Pub/sub" "Pub/sotto" ::msgcat::mcset it "Publish node" "Publicare nodo" ::msgcat::mcset it "Raw XML" "Puro XML" ::msgcat::mcset it "Retract node" "Ritrarre nodo" ::msgcat::mcset it "Subscribe to a node" "Sottoscriversi al nodo" ::msgcat::mcset it "Templates" "Modello" ::msgcat::mcset it "Unavailable presence" "Presenza non disponibile" ::msgcat::mcset it "Unsubscribe from a node" "Disdire dal nodo" # plugins/filetransfer/si.tcl ::msgcat::mcset it "Receive error: Stream ID is in use" "Errore di ricevimento: ID del flusso e gia in uso" ::msgcat::mcset it "Stream initiation options." "Opzioni dell iniziazione di flusso" ::msgcat::mcset it "Transfer failed: %s" "Trasferimento non riuscito: %s" # plugins/iq/time.tcl ::msgcat::mcset it "Reply to current time (jabber:iq:time) requests." "Rispondere alle richieste del tempo corrente (jabber:iq:time)." # plugins/roster/conferences.tcl ::msgcat::mcset it "Add Conference to Roster" "Aggiungere Conferenza al Roster" ::msgcat::mcset it "Add conference to roster..." "Aggiungere conferenze al roster..." ::msgcat::mcset it "Automatically join conference upon connect" "Automaticamente unirsi alla conferenza dopo la conessione" ::msgcat::mcset it "Conference:" "Conferenza:" ::msgcat::mcset it "Conferences" "Conferenze" ::msgcat::mcset it "Roster group:" "Gruppa di roster:" ::msgcat::mcset it "Storing conferences failed: %s" "Impossibile salvare le conferenze: %s" # plugins/unix/tktray.tcl ::msgcat::mcset it "Enable freedesktop system tray icon." "Abilitare freedesktop system tray icon." # filetransfer.tcl ::msgcat::mcset it "Can't open file \"%s\": %s" "Impossibile aprire file \"%s\": %s" ::msgcat::mcset it "Default directory for downloaded files." "Cartella predefinita per file scaricati." ::msgcat::mcset it "Default protocol for sending files." "Protocollo predefinito per spedire file." ::msgcat::mcset it "File Transfer options." "Opzioni del trasferimento dei file." ::msgcat::mcset it "File path:" "Percorso per file:" ::msgcat::mcset it "Protocol:" "Protocollo:" ::msgcat::mcset it "unknown" "sconosciuto" # plugins/roster/rosterx.tcl ::msgcat::mcset it "Send contacts to %s" "Spedire contatti a %s" # plugins/chat/nick_colors.tcl ::msgcat::mcset it "Color message bodies in chat windows." "Messaggi colorati nelle finestre di chat." ::msgcat::mcset it "Edit %s color" "Modificare %s colore" ::msgcat::mcset it "Edit chat user colors" "Modificare colore degli utenti" ::msgcat::mcset it "Edit nick color..." "Modificare colore del nick..." ::msgcat::mcset it "Edit nick colors..." "Modificare i colori del nick..." ::msgcat::mcset it "Use colored messages" "Usa messaggi colorati" ::msgcat::mcset it "Use colored nicks" "Usa nick colorati" ::msgcat::mcset it "Use colored nicks in chat windows." "Usa nick colorati nelle finestre di chat" ::msgcat::mcset it "Use colored nicks in groupchat rosters." "Usa nick colorati nelle roster di groupchat." ::msgcat::mcset it "Use colored roster nicks" "Usa nick colorati nel roster" # plugins/chat/muc_ignore.tcl ::msgcat::mcset it "Edit MUC ignore rules" "Modificare le MUC regole di ignoro" ::msgcat::mcset it "Error loading MUC ignore rules, purged." "Errore nel caricamento delle MUC regole di ignoro, purgato." ::msgcat::mcset it "Ignore" "Ignorare" ::msgcat::mcset it "Ignore chat messages" "Ignorare messaggi del chat" ::msgcat::mcset it "Ignore groupchat messages" "Ignorare messagi del groupchat" ::msgcat::mcset it "Ignoring groupchat and chat messages from selected occupants of multi-user conference rooms." "Ignorare dei messagi del chat e groupchat dai occupanti selezionati dalle stanze con piu utenti." ::msgcat::mcset it "MUC Ignore" "MUC Ignoro" ::msgcat::mcset it "MUC Ignore Rules" "Regole del ignoro MUC" ::msgcat::mcset it "When set, all changes to the ignore rules are applied only until Tkabber is closed\; they are not saved and thus will be not restored at the next run." "Quando impostato, tutte le modifiche alle regole del ignoro saranno applicate solo quando Tkabber e chiuso\; non sono salvati e non saranno ripristinati all prossimo avvio." # plugins/iq/ping.tcl ::msgcat::mcset it "Ping server using urn:xmpp:ping requests." "Ping server usando urn:xmpp:ping richieste." ::msgcat::mcset it "Reconnect to server if it does not reply (with result or with error) to ping (urn:xmpp:ping) request in specified time interval (in seconds)." "Reconettersi al server se non risponde (con risultato o con errore) alla richiesta del ping (urn:xmpp:ping) nel intervallo specifico del tempo (in secondi)." ::msgcat::mcset it "Reply to ping (urn:xmpp:ping) requests." "Rispondi alle richieste ping (urn:xmpp:ping)." # plugins/general/autoaway.tcl ::msgcat::mcset it "Idle threshold in minutes after that Tkabber marks you as away." "Tempo di idle dopo il quale Tkabber cambia status da attuale ad assente." ::msgcat::mcset it "Idle threshold in minutes after that Tkabber marks you as extended away." "Tempo di idle dopo il quale Tkabber cambia status da attuale ad assente esteso." ::msgcat::mcset it "Options for module that automatically marks you as away after idle threshold." "Opzioni per il modulo che automaticamente cambia status dopo tempo determinato di idle." ::msgcat::mcset it "Set priority to 0 when moving to extended away state." "Mettere priorita a 0 quando si attiva status assente esteso." ::msgcat::mcset it "Text status, which is set when Tkabber is moving to away state." "Testo di status, che si imposta quando Tkabber attiva status assente." # plugins/general/offline.tcl ::msgcat::mcset it "Fetch all messages" "Prelevare tutti i messaggi" ::msgcat::mcset it "Fetch message" "Prelevare il messaggio" ::msgcat::mcset it "Fetch unseen messages" "Prelevare messaggi non letti" ::msgcat::mcset it "Offline Messages" "Messaggi offline" ::msgcat::mcset it "Purge all messages" "Pulire tutti i messaggi" ::msgcat::mcset it "Purge message" "Pulire messaggio" ::msgcat::mcset it "Purge seen messages" "Pulire messaggi letti" ::msgcat::mcset it "Retrieve offline messages using POP3-like protocol." "Prelevare messaggi offline usando POP3-like protocollo." ::msgcat::mcset it "Sort by from" "Ordinare per mittente" ::msgcat::mcset it "Sort by node" "Ordinare per nodo" ::msgcat::mcset it "Sort by type" "Ordinare per tipo" # plugins/chat/popupmenu.tcl ::msgcat::mcset it "Clear bookmarks" "Pulire preferiti" ::msgcat::mcset it "Copy selection to clipboard" "Copiare selezionato a clipboard" ::msgcat::mcset it "Google selection" "Selezione Google" ::msgcat::mcset it "Next bookmark" "Prossimo preferito" ::msgcat::mcset it "Prev bookmark" "Precedente preferito" ::msgcat::mcset it "Set bookmark" "Imposta preferito" # disco.tcl ::msgcat::mcset it "Clear window" "Pulire finestra" ::msgcat::mcset it "Delete current node and subnodes" "Eliminare nodo attuale e tutti sottonodi" ::msgcat::mcset it "Delete subnodes" "Eliminare sottonodi" ::msgcat::mcset it "Discover service" "Esplora servizio" ::msgcat::mcset it "Discovery" "Esplorazione" ::msgcat::mcset it "Error getting info: %s" "Errore nel prelievo dell info: %s" ::msgcat::mcset it "Error getting items: %s" "Errore nel prelievo degli elementi: %s" ::msgcat::mcset it "Error negotiate: %s" "Errore del negoziazione: %s" ::msgcat::mcset it "List of discovered JID nodes." "Lista degli nodi JID scoperti." ::msgcat::mcset it "List of discovered JIDs." "Lista degli JID scoperti." ::msgcat::mcset it "Node:" "Nodo:" ::msgcat::mcset it "Sort items by JID/node" "Ordina elementi per JID/nodo" ::msgcat::mcset it "Sort items by name" "Ordina elementi per nome" # plugins/general/remote.tcl ::msgcat::mcset it "Accept connections from my own JID." "Acetta conessioni dal mio JID." ::msgcat::mcset it "Accept connections from the listed JIDs." "Acetta conessioni da JID nella lista." ::msgcat::mcset it "All unread messages were forwarded to %s." "Tutti messaggi non letti sono inoltrati a %s." ::msgcat::mcset it "Enable remote control." "Attivare controllo remoto." ::msgcat::mcset it "Remote control options." "Opzioni del controllo remoto." ::msgcat::mcset it "Show my own resources in the roster." "Mostra le mie risorse nel roster." ::msgcat::mcset it "This message was forwarded to %s" "Questo messaggio è stato inoltrato a %s" # userinfo.tcl ::msgcat::mcset it "All files" "Tutti file" ::msgcat::mcset it "Day:" "Giorno:" ::msgcat::mcset it "GIF images" "Immagini GIF" ::msgcat::mcset it "JPEG images" "Immagini JPEG" ::msgcat::mcset it "Last activity" "Ultima attivita" ::msgcat::mcset it "List of users for userinfo." "Lista degli utenti per userinfo" ::msgcat::mcset it "Loading photo failed: %s." "Caricamento del foto non riuscito: %s" ::msgcat::mcset it "Month:" "Mese:" ::msgcat::mcset it "PNG images" "Immagini PNG" ::msgcat::mcset it "Service info" "Info del servizio" ::msgcat::mcset it "Show user or service info" "Mostra info del utente o del servizio" ::msgcat::mcset it "Time" "Tempo" ::msgcat::mcset it "Uptime" "Tempo on-line " ::msgcat::mcset it "User info" "Info del utente" ::msgcat::mcset it "Version" "Versione" ::msgcat::mcset it "Year:" "Anno:" # plugins/si/iqibb.tcl ::msgcat::mcset it "Opening IQ-IBB connection" "Apertura del conessione IQ-IBB" # jabberlib-tclxml/streamerror.tcl ::msgcat::mcset it "Bad Format" "Formato non valido" ::msgcat::mcset it "Bad Namespace Prefix" "Prefisso del namespace non valido" ::msgcat::mcset it "Connection Timeout" "Tempo di conessione scaduto" ::msgcat::mcset it "Host Gone" "Host è andato" ::msgcat::mcset it "Host Unknown" "Host sconosciuto" ::msgcat::mcset it "Improper Addressing" "Indirizzamento inadatto" ::msgcat::mcset it "Invalid From" "Mettente non valido" ::msgcat::mcset it "Invalid ID" "ID non valido" ::msgcat::mcset it "Invalid Namespace" "Namespace non valido" ::msgcat::mcset it "Invalid XML" "XML non valido" ::msgcat::mcset it "Policy Violation" "Violazione della policy" ::msgcat::mcset it "Remote Connection Failed" "Conessione remota non riuscita" ::msgcat::mcset it "Restricted XML" "XML ristretto" ::msgcat::mcset it "See Other Host" "Vedere altro host" ::msgcat::mcset it "Stream Error%s%s" "Errore del flusso%s%s" ::msgcat::mcset it "System Shutdown" "Chiusura del sistema" ::msgcat::mcset it "Unsupported Encoding" "Codifica non supportata" ::msgcat::mcset it "Unsupported Stanza Type" "Tipo di stanza non supportato" ::msgcat::mcset it "Unsupported Version" "Versione non supportata" ::msgcat::mcset it "XML Not Well-Formed" "XML Malformato" # browser.tcl ::msgcat::mcset it "Browse error: %s" "Errore nel navigare: %s" ::msgcat::mcset it "List of browsed JIDs." "Lista degli JID sfogliati." ::msgcat::mcset it "Number of children:" "Numero dei bambini:" ::msgcat::mcset it "Sort items by JID" "Ordinare elementi per JID" # plugins/general/xaddress.tcl ::msgcat::mcset it "Blind carbon copy" "Copia invisibile" ::msgcat::mcset it "Carbon copy" "Copia" ::msgcat::mcset it "Extended addressing fields:" "Campi estesi di indirizzi" ::msgcat::mcset it "Forwarded by:" "Inoltrato da:" ::msgcat::mcset it "No reply" "Nessuna risposta" ::msgcat::mcset it "Original from" "Originale da" ::msgcat::mcset it "Original to" "Originale a" ::msgcat::mcset it "Reply to" "Rispondere" ::msgcat::mcset it "Reply to room" "Rispondere alla stanza" ::msgcat::mcset it "This message was forwarded by %s\n" "Questo messaggio è stato inoltrato da %s\n" ::msgcat::mcset it "This message was sent by %s\n" "Questo messaggio è stato spedito da %s\n" ::msgcat::mcset it "To" "A" # default.tcl ::msgcat::mcset it "Command to be run when you click a URL in a message. '%s' will be replaced with this URL (e.g. \"galeon -n %s\")." "Commando da eseguire quando URL nel messaggio è stato cliccato. '%s' sara rimpiazzato con questo URL ( \"galeon -n %s\")." ::msgcat::mcset it "Error displaying %s in browser\n\n%s" "Errore nel visualizzare %s nel browser\n\n%s" ::msgcat::mcset it "Please define environment variable BROWSER" "Per favore, definire variabile BROWSER" # ifacetk/iface.tcl ::msgcat::mcset it "%s SSL Certificate Info" "%s Info del SSL certificato" ::msgcat::mcset it "&Help" "&Aiuto" ::msgcat::mcset it "&Services" "&Servizi" ::msgcat::mcset it "Accept messages from roster users only" "Accetta i messaggi solo dai contatti nel roster" ::msgcat::mcset it "Activate search panel" "Attivare panello di ricerca" ::msgcat::mcset it "Bottom" "Basso" ::msgcat::mcset it "Change priority..." "Cambia priorita..." ::msgcat::mcset it "Close Tkabber" "Chiudi Tkabber" ::msgcat::mcset it "Common:" "Comune:" ::msgcat::mcset it "Complete nickname or command" "Nome o commando completo" ::msgcat::mcset it "Delay between getting focus and updating window or tab title in milliseconds." "Intervallo tra focus e aggiornamento dell titolo di una finestra o di una tab in millisecondi." ::msgcat::mcset it "Do nothing" "Non fare niente" ::msgcat::mcset it "Edit conference list " "Modificare la lista delle conferenze " ::msgcat::mcset it "Edit ignore list " "Modificare la lista di ignore" ::msgcat::mcset it "Edit invisible list " "Modificare la lista degli invisibili " ::msgcat::mcset it "Emphasize" "Evidenziare" ::msgcat::mcset it "Font to use in roster, chat windows etc." "Caratteri da usare nel roster, finestra del chat etc." ::msgcat::mcset it "Generate enter/exit messages" "Generare messaggi di entrata/uscita" ::msgcat::mcset it "Iconize" "Iconizzare" ::msgcat::mcset it "Left" "Sinistra" ::msgcat::mcset it "Manually edit rules" "Regole modificate manualmente" ::msgcat::mcset it "Maximum width of tab buttons in tabbed mode." "Larghezza massima dei tasti di tab nel tabbed mode" ::msgcat::mcset it "Message archive" "Archivio dei messaggi" ::msgcat::mcset it "Middle mouse button" "Tasto medio del mouse" ::msgcat::mcset it "Minimize" "Minimizzare" ::msgcat::mcset it "Minimize to systray (if systray icon is enabled, otherwise do nothing)" "Minimizzare a systray (se icona di systray è disabilitata, altrimenti non fare nulla)" ::msgcat::mcset it "Minimum width of tab buttons in tabbed mode." "Larghezza minima dei tasti di tab nel tabbed mode." ::msgcat::mcset it "Open chat..." "Aprire chat..." ::msgcat::mcset it "Options for main interface." "Opzioni per interfaccia principale." ::msgcat::mcset it "Plugins" "Plugins" ::msgcat::mcset it "Presence bar" "Sbarra di presenza" ::msgcat::mcset it "Right" "Destra" ::msgcat::mcset it "SSL Info" "SSL Info" ::msgcat::mcset it "Show Toolbar." "Mostra Toolbar." ::msgcat::mcset it "Show menu tearoffs when possible." "Mostra menu lacerato quando è possibile." ::msgcat::mcset it "Show number of unread messages in tab titles." "Mostra numero dei messaggi non letti nei titoli di tab." ::msgcat::mcset it "Show own resources" "Mostra proprie risorse" ::msgcat::mcset it "Show palette of emoticons" "Mostra insieme di colori degli emoticons" ::msgcat::mcset it "Show presence bar." "Mostra sbarra di presenza." ::msgcat::mcset it "Show status bar." "Mostra sbarra di status." ::msgcat::mcset it "Show user or service info..." "Mostra utente o info del servizio..." ::msgcat::mcset it "Side where to place tabs in tabbed mode." "Da quale parte mettere i tab nel tabbed mode." ::msgcat::mcset it "Smart autoscroll" "Autoscroll intelligente" ::msgcat::mcset it "Status bar" "Sbarra di status" ::msgcat::mcset it "Stored main window state (normal or zoomed)" "Stato salvato della finestra principale (normale o zummato)" ::msgcat::mcset it "Toggle showing offline users" "Non visualizzare utenti non conessi" ::msgcat::mcset it "Toolbar" "Toolbar" ::msgcat::mcset it "Top" "Cima" ::msgcat::mcset it "Use Tabbed Interface (you need to restart)." "Usare interfaccia con i tab (riavvio di Tkabber necessario)." ::msgcat::mcset it "What action does the close button." "Che cosa fa tasto di chiusura." # plugins/windows/console.tcl ::msgcat::mcset it "Show console" "Mostra console" # messages.tcl ::msgcat::mcset it "Approve subscription" "Approva sottoscrizione" ::msgcat::mcset it "Attached URL:" "URL allegato:" ::msgcat::mcset it "Decline subscription" "Rifiutare sottoscrizione" ::msgcat::mcset it "Extras from:" "Extras da:" ::msgcat::mcset it "From: " "Da: " ::msgcat::mcset it "Grant subscription" "Concedere sottoscrizione" ::msgcat::mcset it "Group: " "Gruppo: " ::msgcat::mcset it "List of message destination JIDs." "Lista degli JID ai quali è destinato il messaggio." ::msgcat::mcset it "Message and Headline options." "Opzioni di messaggi e di headline" ::msgcat::mcset it "Message from:" "Messaggio da:" ::msgcat::mcset it "Quote" "Citazione" ::msgcat::mcset it "Received by:" "Ricevuto da:" ::msgcat::mcset it "Reply subject:" "Sogetto di risposta: " ::msgcat::mcset it "Request subscription" "Richiesta di sottoscrizione" ::msgcat::mcset it "Send message to group" "Invia messaggio al gruppo " ::msgcat::mcset it "Send message to group %s" "Invia messaggio al gruppo %s" ::msgcat::mcset it "Send request to: " "Invia richiesta a: " ::msgcat::mcset it "Send subscription request" "Invia richiesta di sottoscrizione" ::msgcat::mcset it "Send subscription request to %s" "Invia richiesta di sosttoscrizione a %s" ::msgcat::mcset it "Subject: " "Sogetto: " ::msgcat::mcset it "Subscription request from %s" "Richiesta di sottoscrizione da %s" ::msgcat::mcset it "Subscription request from:" "Richiesta di sottoscrizione da:" ::msgcat::mcset it "To: " "A:" ::msgcat::mcset it "You are unsubscribed from %s" "La sottoscrizione da %s non esiste piu" # plugins/roster/fetch_nicknames.tcl ::msgcat::mcset it "Fetch nickname" "Prelevare i nomi" ::msgcat::mcset it "Fetch user nicknames" "Prelevare i nomi degli utenti" # jabberlib-tclxml/jlibtls.tcl ::msgcat::mcset it "STARTTLS failed" "STARTTL fallito" ::msgcat::mcset it "STARTTLS successful" "STARTTLS riuscito" ::msgcat::mcset it "Server haven't provided STARTTLS feature" "Server non ha fornito funzione di STARTTLS" # plugins/search/spanel.tcl ::msgcat::mcset it "Search down" "Cerca in su" ::msgcat::mcset it "Search up" "Cerca in giu" # muc.tcl ::msgcat::mcset it " by %s" " da %s" ::msgcat::mcset it "%s has been banned" "a %s adesso è vietato di entrare" ::msgcat::mcset it "%s has been kicked" "%s è stato espulso dalla conferenza" ::msgcat::mcset it "%s has been kicked because of membership loss" "%s è stato espulso a causa di perdita di membership" ::msgcat::mcset it "%s has been kicked because room became members-only" "%s è stato espulso perche conferenza è diventata members-only" ::msgcat::mcset it "%s has entered" "%s è entrato" ::msgcat::mcset it "%s has left" "%s è uscito" ::msgcat::mcset it "%s invites you to conference room %s" "%s ti invita a conferenza %s" ::msgcat::mcset it "%s is now known as %s" "%s ora è conosciuto come %s" ::msgcat::mcset it "Accept default config" "Accettare config predefinito" ::msgcat::mcset it "Cancelling configure form" "Cancellare modulo di configurazione" ::msgcat::mcset it "Conference room %s will be destroyed permanently.\n\nProceed?" "Conferenza è stata definitivamente cancellata.\n\nProseguire?" ::msgcat::mcset it "Configure form: %s" "Modulo di configurazione: %s" ::msgcat::mcset it "Configure room" "Configura conferenza" ::msgcat::mcset it "Destroy room" "Elimina conferenza" ::msgcat::mcset it "Edit owner list" "Modifica la lista dei proprietari" ::msgcat::mcset it "Generate groupchat messages when occupant changes his/her status and/or status message" "Genera messaggi di groupchat quando occupante cambia suo messaggio di status" ::msgcat::mcset it "Generate status messages when occupants enter/exit MUC compatible conference rooms." "Genera messaggio di status quando occupante entra/esce nelle conferenze compatibile con MUC." ::msgcat::mcset it "Grant Admin Privileges" "Concedere privilegi di Admin" ::msgcat::mcset it "Grant Moderator Privileges" "Concedere privilegi di Moderator" ::msgcat::mcset it "Grant Owner Privileges" "Concedere privilegi del Proprietario" ::msgcat::mcset it "Join conference" "Unirsi alla conferenza" ::msgcat::mcset it "Join groupchat" "Unirsi a groupchat" ::msgcat::mcset it "Maximum number of characters in the history in MUC compatible conference rooms." "Numero massimo dei caratteri nella storia delle conferenze compatibili con MUC." ::msgcat::mcset it "Maximum number of stanzas in the history in MUC compatible conference rooms." "Numero massi delle stanze nella storia delle conferenze compatibili con MUC." ::msgcat::mcset it "Nick" "Sopranome" ::msgcat::mcset it "Propose to configure newly created MUC room. If set to false then the default room configuration is automatically accepted." "Proporre di configurare stanze MUC appena creati. Se impostato a falso allora configurazione predefinita sara accettata." ::msgcat::mcset it "Reason" "Raggione" ::msgcat::mcset it "Report the list of current MUC rooms on disco#items query." "Riportare la lista delle stanze correnti sul disco#items domanda." ::msgcat::mcset it "Request only unseen (which aren't displayed in the chat window) messages in the history in MUC compatible conference rooms." "Richiesta solo messaggi non letti (quelli che non sono stati visualizzati nella finestra del chat) nella storia dell conferenze compatibili con MUC." ::msgcat::mcset it "Revoke Admin Privileges" "Anullare privilegi di Admin" ::msgcat::mcset it "Revoke Moderator Privileges" "Anullare privilegi di Moderator" ::msgcat::mcset it "Revoke Owner Privileges" "Anullare privilegi di Proprietario" ::msgcat::mcset it "Room %s is successfully created" "Conferenza %s creata con sucesso" ::msgcat::mcset it "Room is created" "Stanza creata" ::msgcat::mcset it "Room is destroyed" "Stanza eliminata" ::msgcat::mcset it "Sending %s %s list" "Invio %s %s della lista" ::msgcat::mcset it "Sending configure form" "Invio dell modulo di configurazione" ::msgcat::mcset it "User already %s" "Utente gia %s" ::msgcat::mcset it "\nAlternative venue: %s" "\nLuogo alternativo: %s" ::msgcat::mcset it "\nReason is: %s" "\nRaggione è: %s" ::msgcat::mcset it "\nReason: %s" "\nRaggione: %s" ::msgcat::mcset it "\n\tAffiliation: %s" "\n\tAffiliazione: %s" ::msgcat::mcset it "\n\tJID: %s" "\n\tJID: %s" ::msgcat::mcset it "and" "e" ::msgcat::mcset it "whois %s: %s" "whois %s: %s" ::msgcat::mcset it "whois %s: no info" "whois %s: no info" # configdir.tcl ::msgcat::mcset it "Attention" "Attenzione" ::msgcat::mcset it "Please, be patient while Tkabber configuration directory is being transferred to the new location" "Per favore siate pazienti mentre cartella di configurazione non sara trasferita a una nuova locazione" ::msgcat::mcset it "Tkabber configuration directory transfer failed with:\n%s\n Tkabber will use the old directory:\n%s" "Trasferimento della cartella di configurazione fallita con\n%s\n Tkabber usera cartella vecchia:\n%s" ::msgcat::mcset it "Your new Tkabber config directory is now:\n%s\nYou can delete the old one:\n%s" "La sua nuova cartella di configurazione adesso è:\n%s\nPuo eliminare la vecchia:\n%s" # presence.tcl ::msgcat::mcset it "Change Presence Priority" "Cambia priorita della presenza" ::msgcat::mcset it "Stored user priority." "Priorita dell utente salvata" ::msgcat::mcset it "Stored user status." "Status dell utente salvato" ::msgcat::mcset it "Stored user text status." "Text status dell utente salvato" ::msgcat::mcset it "doesn't want to be disturbed" "non vuole essere disturbato" ::msgcat::mcset it "is available" "disponibile" ::msgcat::mcset it "is away" "è away" ::msgcat::mcset it "is extended " "è away distante" ::msgcat::mcset it "is free to chat" "è libero di parlare" ::msgcat::mcset it "is invisible" "è invisibile" ::msgcat::mcset it "is unavailable" "non è disponibile" # plugins/general/tkcon.tcl ::msgcat::mcset it "Show TkCon console" "Mostra TkCon console" # ifacetk/iroster.tcl ::msgcat::mcset it "Add chats group in roster." "Aggiungere gruppi del chat nel roster." ::msgcat::mcset it "Are you sure to remove all users in group '%s' from roster? \n(Users which are in another groups too, will not be removed from the roster.)" "Sei sicuro di eliminare tutti utenti nell gruppo '%s' dal roster? \n(Utenti, che sono anche in altri gruppi, non saranno eliminati dal roster.)" ::msgcat::mcset it "Are you sure to remove group '%s' from roster? \n(Users which are in this group only, will be in undefined group.)" "Sicuro di voler eliminare il gruppo '%s' dal roster? \n(Utenti, che sono solo in questo gruppo, saranno in un gruppo non definito.)" ::msgcat::mcset it "Ask:" "Domandare:" ::msgcat::mcset it "Default nested roster group delimiter." "Divisore predefinito di gruppi messi un dentro l'altro." ::msgcat::mcset it "Enable nested roster groups." "Attivare gruppi messi un dentro l'altro nel roster." ::msgcat::mcset it "Remove all users in group..." "Elimina tutti utenti nel gruppo..." ::msgcat::mcset it "Remove from roster..." "Elimina dal roster..." ::msgcat::mcset it "Roster item may be dropped not only over group name but also over any item in group." "Ogetto di roster puo essere rilasciato non solo sopra nome del gruppo ma anche sopra ogni elemento in gruppo." ::msgcat::mcset it "Roster of %s" "Roster di %s" ::msgcat::mcset it "Send message to all users in group..." "Inviare messaggio a tutti utenti nel gruppo..." ::msgcat::mcset it "Show detailed info on conference room members in roster item tooltips." "Mostra info di utenti in una conferenza dettagliata nel roster tooltip." ::msgcat::mcset it "Show native icons for contacts, connected to transports/services in roster." "Mostra icone native per contatti, conessi a transporti/servizi nel roster." ::msgcat::mcset it "Show native icons for transports/services in roster." "Mostra icone native per transporti/servizi in roster." ::msgcat::mcset it "Show offline users" "Visualizza utenti offline" ::msgcat::mcset it "Show only online users in roster." "Visualizza solo utenti online" ::msgcat::mcset it "Show subscription type in roster item tooltips." "Visualizza tipo di sottoscrizione dentro un roster tooltip." ::msgcat::mcset it "Stored collapsed roster groups." "Memorizzati gruppi del roster crollati." ::msgcat::mcset it "Stored show offline roster groups." "Info memorizzata di visualizzazione dei gruppi offline nel roster." ::msgcat::mcset it "Subscription:" "Sottoscrizione:" ::msgcat::mcset it "Use aliases to show multiple users in one roster item." "Usare aliases per visualizzare piu utenti in un ogetto di roster." # plugins/iq/last.tcl ::msgcat::mcset it "Reply to idle time (jabber:iq:last) requests." "Rispondere alle richieste del tempo di idle (jabber:iq:last)." # jabberlib-tclxml/jlibauth.tcl ::msgcat::mcset it "Server doesn't support hashed password authentication" "Server non supporta autenticazione con hashed password" ::msgcat::mcset it "Server doesn't support plain or digest authentication" "Server non supporta autenticazione plain o digest" ::msgcat::mcset it "Server haven't provided non-SASL authentication feature" "Server non fornisce funzione di non-SASL autenticazione" ::msgcat::mcset it "Waiting for authentication results" "Aspettiamo resultati di autenticazione" # plugins/iq/version.tcl ::msgcat::mcset it "Reply to version (jabber:iq:version) requests." "Rispondere alle richieste di versione (jabber:iq:version)." tkabber-0.11.1/msgs/ru.rc0000644000175000017500000000311210516465506014454 0ustar sergeisergei! ------------------------------------------------------------------------------ ! ru.rc ! Definition of russian resources for BWidget ! ------------------------------------------------------------------------------ ! --- symbolic names of buttons ------------------------------------------------ *abortName: Прервать *retryName: Повторить *ignoreName: Игнорировать *okName: Продолжить *cancelName: Отменить *yesName: Да *noName: Ðет ! --- symbolic names of label of SelectFont dialog ---------------------------- *boldName: Полужирный *italicName: КурÑивный *underlineName: Подчеркнутый *overstrikeName: Перечеркнутый *fontName: Шрифт *sizeName: Размер *styleName: Вид ! --- symbolic names of label of PasswdDlg dialog ----------------------------- *loginName: Ð˜Ð¼Ñ *passwordName: Пароль ! --- resource for SelectFont dialog ------------------------------------------ *SelectFont.title: Выбор шрифта *SelectFont.sampletext: Sample text, пример текÑта ! --- resource for MessageDlg dialog ------------------------------------------ *MessageDlg.noneTitle: Сообщение *MessageDlg.infoTitle: Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ *MessageDlg.questionTitle: Ð’Ð¾Ð¿Ñ€Ð¾Ñ *MessageDlg.warningTitle: Внимание! *MessageDlg.errorTitle: Ошибка ! --- resource for PasswdDlg dialog ------------------------------------------- *PasswdDlg.title: Ввод имени и Ð¿Ð°Ñ€Ð¾Ð»Ñ tkabber-0.11.1/msgs/de.msg0000644000175000017500000051502311067146413014604 0ustar sergeisergei # German messages file # Roger Sondermann 26.09.2008 # .../chats.tcl ::msgcat::mcset de "%s has changed nick to %s." "%s hat seinen Nicknamen geändert in %s" ::msgcat::mcset de "/me has set the subject to: %s" "/me hat den Betreff gesetzt zu: %s" ::msgcat::mcset de "Chat" "Chat" ::msgcat::mcset de "Chat " "Chat" ::msgcat::mcset de "Chat options." "Optionen für Chats." ::msgcat::mcset de "Chat with %s" "Mit %s chatten" ::msgcat::mcset de "Default message type (if not specified explicitly)." "Voreingestellter Nachrichten-Typ (wenn nicht explizit angegeben)." ::msgcat::mcset de "Display description of user status in chat windows." "Beschreibung des Kontakt-Status in Chat-Fenstern anzeigen." ::msgcat::mcset de "Enable chat window autoscroll only when last message is shown." "Automatisches Scrollen erst aktivieren, nachdem die letzte Nachricht angezeigt worden ist." ::msgcat::mcset de "Error %s" "Fehler %s" ::msgcat::mcset de "Generate chat messages when chat peer changes his/her status and/or status message" "Chat-Nachrichten erstellen, wenn der Chat-Partner seinen Status und/oder die Status-Nachricht ändert." ::msgcat::mcset de "Invite" "Einladen" ::msgcat::mcset de "Invite %s to conferences" "%s zu Konferenzen einladen" ::msgcat::mcset de "Invite to conference..." "Zu Konferenz einladen..." ::msgcat::mcset de "Invite users to %s" "Kontakte einladen nach %s" ::msgcat::mcset de "Invite users..." "Kontakte einladen..." ::msgcat::mcset de "List of users for chat." "Kontakt-Liste für Chat." ::msgcat::mcset de "Moderators" "Moderatoren" ::msgcat::mcset de "No conferences for %s in progress..." "Keine Konferenzen für %s im Gang." ::msgcat::mcset de "No users in %s roster..." "Keine Kontakte in %s Roster." ::msgcat::mcset de "Normal" "Normal" ::msgcat::mcset de "Open chat" "Chat öffnen" ::msgcat::mcset de "Open new conversation" "Neue Konversation öffnen" ::msgcat::mcset de "Opens a new chat window for the new nick of the room occupant" "Öffnet ein neues Chat-Fenster für den neuen Nicknamen des Konferenz-Teilnehmers" ::msgcat::mcset de "Participants" "Teilnehmer" ::msgcat::mcset de "Please join %s" "Bitte %s beitreten" ::msgcat::mcset de "Start chat" "Chat starten" ::msgcat::mcset de "Stop chat window autoscroll." "Automatisches Scrollen von Chat-Fenstern abstellen." ::msgcat::mcset de "Subject is set to: %s" "Betreff ist gesetzt zu: %s" ::msgcat::mcset de "Subject:" "Betreff:" ::msgcat::mcset de "Users" "Benutzer" ::msgcat::mcset de "Visitors" "Besucher" # .../configdir.tcl ::msgcat::mcset de "Attention" "Achtung" ::msgcat::mcset de "Please, be patient while Tkabber configuration directory is being transferred to the new location" "Bitte haben Sie Geduld, während der Tkabber Konfigurations-Ordner an die neue Stelle übertragen wird." ::msgcat::mcset de "Tkabber configuration directory transfer failed with:\n%s\n Tkabber will use the old directory:\n%s" "Die Übertragung des Tkabber Konfigurations-Ordners ist misslungen:\n%s\n Tkabber wird den bisherigen Ordner benutzen:\n%s" ::msgcat::mcset de "Your new Tkabber config directory is now:\n%s\nYou can delete the old one:\n%s" "Der neue Tkabber Konfigurations-Ordner ist:\n%s\nDer bisherige kann gelöscht werden:\n%s" # .../custom.tcl ::msgcat::mcset de "Customization of the One True Jabber Client." "Einstellungen für den einzig wahren Jabber-Client." ::msgcat::mcset de "Open" "Öffnen" ::msgcat::mcset de "Parent group" "Übergeordnete Gruppe" ::msgcat::mcset de "Parent groups" "Übergeordnete Gruppen" ::msgcat::mcset de "Reset to current value" "Zurücksetzen auf derzeitigen Wert" ::msgcat::mcset de "Reset to default value" "Zurücksetzen auf voreingestellten Wert" ::msgcat::mcset de "Reset to saved value" "Zurücksetzen auf gespeicherten Wert" ::msgcat::mcset de "Reset to value from config file" "Zurücksetzen auf Wert aus Konfigurations-Datei" ::msgcat::mcset de "Set for current and future sessions" "Setzen für derzeitige und zukünftige Sitzungen" ::msgcat::mcset de "Set for current session only" "Setzen nur für derzeitige Sitzung" ::msgcat::mcset de "the option is set and saved." "die Option ist gesetzt und gespeichert." ::msgcat::mcset de "the option is set to its default value." "die Option ist auf ihren voreingestellten Wert gesetzt." ::msgcat::mcset de "the option is set, but not saved." "die Option ist gesetzt, aber nicht gespeichert." ::msgcat::mcset de "the option is taken from config file." "die Option ist aus der Konfigurations-Datei übernommen worden." ::msgcat::mcset de "value is changed, but the option is not set." "Wert wurde geändert, aber die Option ist nicht gesetzt." # .../datagathering.tcl ::msgcat::mcset de "Address:" "Adresse:" ::msgcat::mcset de "City:" "Stadt:" ::msgcat::mcset de "Configure service" "Dienst konfigurieren" ::msgcat::mcset de "Data form" "Daten-Formular" ::msgcat::mcset de "Date:" "Datum:" ::msgcat::mcset de "Error requesting data: %s" "Fehler bei Daten-Anforderung: %s" ::msgcat::mcset de "First Name:" "Vorname:" ::msgcat::mcset de "Full Name:" "Vollst. Name:" ::msgcat::mcset de "Instructions" "Anweisungen" ::msgcat::mcset de "Key:" "Schlüssel:" ::msgcat::mcset de "Last Name:" "Nachname:" ::msgcat::mcset de "Misc:" "Verschiedenes:" ::msgcat::mcset de "Phone:" "Telefon:" ::msgcat::mcset de "State:" "Bundesland:" ::msgcat::mcset de "Text:" "Text:" ::msgcat::mcset de "Username:" "Benutzer-Name:" ::msgcat::mcset de "Zip:" "PLZ:" # .../default.tcl ::msgcat::mcset de "Command to be run when you click a URL in a message. '%s' will be replaced with this URL (e.g. \"galeon -n %s\")." "Auszuführendes Kommando, wenn in einer Nachricht eine URL angeklickt wird. '%s' wird ersetzt durch die URL. Beispiel: ...\\firefox.exe %s" ::msgcat::mcset de "Error displaying %s in browser\n\n%s" "Fehler bei der Anzeige von %s im Browser\n\n%s" ::msgcat::mcset de "Please define environment variable BROWSER" "Bitte die Umgebungsvariable BROWSER setzen" # .../disco.tcl ::msgcat::mcset de "%s: %s/%s, Description: %s, Version: %s\nNumber of children: %s" "%s: %s/%s, Beschreibung: %s, Version: %s\nAnzahl Einträge: %s" ::msgcat::mcset de "Browse" "Durchsuchen" ::msgcat::mcset de "Clear window" "Fenster leeren" ::msgcat::mcset de "Delete current node and subnodes" "Aktuellen Knoten und Sub-Knoten löschen" ::msgcat::mcset de "Delete subnodes" "Sub-Knoten löschen" ::msgcat::mcset de "Discovery" "Service-Discovery" ::msgcat::mcset de "Error getting info: %s" "Fehler beim Erhalten der Informationen: %s" ::msgcat::mcset de "Error getting items: %s" "Fehler beim Erhalten der Einträge: %s" ::msgcat::mcset de "Error negotiate: %s" "Fehler bei der Verhandlung: %s" ::msgcat::mcset de "JID:" "JID:" ::msgcat::mcset de "List of discovered JID nodes." "Liste der entdeckten JID-Knoten." ::msgcat::mcset de "List of discovered JIDs." "Liste der entdeckten JIDs." ::msgcat::mcset de "Node:" "Knoten:" ::msgcat::mcset de "Service Discovery" "Service-Discovery" ::msgcat::mcset de "Sort items by JID/node" "Nach JID/Knoten sortieren" ::msgcat::mcset de "Sort items by name" "Nach Namen sortieren" ::msgcat::mcset de "Version:" "Version:" # .../filetransfer.tcl ::msgcat::mcset de "Can't open file \"%s\": %s" "Kann Datei nicht öffnen \"%s\": %s" ::msgcat::mcset de "Default directory for downloaded files." "Voreingestellter Ordner für heruntergeladene Dateien." ::msgcat::mcset de "Default protocol for sending files." "Voreingestelltes Protokoll für das Senden von Dateien." ::msgcat::mcset de "File Transfer options." "Optionen für die Datei-Übertragung." ::msgcat::mcset de "File path:" "Datei-Pfad:" ::msgcat::mcset de "Protocol:" "Protokoll:" ::msgcat::mcset de "Send file to %s" "Datei an %s senden" ::msgcat::mcset de "Send file..." "Datei senden..." ::msgcat::mcset de "unknown" "unbekannt" # .../filters.tcl ::msgcat::mcset de "Action" "Aktion" ::msgcat::mcset de "Blocking communication options." "Optionen für das Blockieren der Kommunikation." ::msgcat::mcset de "Condition" "Bedingung" ::msgcat::mcset de "Edit" "Ändern" ::msgcat::mcset de "Edit message filters" "Nachrichten-Filter ändern" ::msgcat::mcset de "Edit rule" "Regel ändern" ::msgcat::mcset de "Empty rule name" "Leerer Regel-Name" ::msgcat::mcset de "Enable jabberd 1.4 mod_filter support (obsolete)." "'jabberd 1.4 mod_filter'-Unterstützung aktivieren (veraltet)." ::msgcat::mcset de "Filters" "Filter" ::msgcat::mcset de "I'm not online" "Ich bin nicht 'Online'" ::msgcat::mcset de "Move down" "Nach unten" ::msgcat::mcset de "Move up" "Nach oben" ::msgcat::mcset de "Requesting filter rules: %s" "Fordere Filter-Regeln an: %s" ::msgcat::mcset de "Rule Name:" "Regel-Name" ::msgcat::mcset de "Rule name already exists" "Regel-Name existiert bereits" ::msgcat::mcset de "change message type to" "ändere Nachrichten-Typ zu" ::msgcat::mcset de "continue processing rules" "Regel-Verarbeitung fortsetzen" ::msgcat::mcset de "forward message to" "Nachricht weiterleiten an" ::msgcat::mcset de "my status is" "mein Status ist" ::msgcat::mcset de "reply with" "antworte mit" ::msgcat::mcset de "store this message offline" "speichere diese Nachricht Offline" ::msgcat::mcset de "the body is" "der Nachrichten-Text ist" ::msgcat::mcset de "the message is from" "die Nachricht ist von" ::msgcat::mcset de "the message is sent to" "die Nachricht ist gesendet an" ::msgcat::mcset de "the message type is" "der Nachrichten-Typ ist" ::msgcat::mcset de "the subject is" "der Betreff ist" # .../gpgme.tcl ::msgcat::mcset de " by " " durch " ::msgcat::mcset de "%s purportedly signed by %s can't be verified.\n\n%s." "%s, (möglicherweise) von %s signiert, kann nicht verifiziert werden.\n\n%s." ::msgcat::mcset de ">>> Unable to decipher data: %s <<<" ">>> Keine Daten-Verschlüsselung möglich: %s <<<" ::msgcat::mcset de "Change security preferences for %s" "Sicherheits-Einstellungen für %s ändern" ::msgcat::mcset de "Data purported sent by %s can't be deciphered.\n\n%s." "Die Daten, die (möglicherweise) von %s gesendet wurden, können nicht entschlüsselt werden.\n\n%s." ::msgcat::mcset de "Display warning dialogs when signature verification fails." "Warnung anzeigen, wenn Signatur-Verifizierung misslingt." ::msgcat::mcset de "Edit security..." "Sicherheitseinstellungen ändern..." ::msgcat::mcset de "Encrypt traffic" "Datenverkehr verschlüsseln" ::msgcat::mcset de "Encrypt traffic (when possible)" "Datenverkehr verschlüsseln (wenn möglich)" ::msgcat::mcset de "Encryption" "Verschlüsselung" ::msgcat::mcset de "Error in signature processing" "Fehler bei der Signatur-Verarbeitung" ::msgcat::mcset de "Error in signature verification software: %s." "Fehler in der Signatur-Verarbeitungs-Software: %s" ::msgcat::mcset de "Fetch GPG key" "GPG-Schlüssel abrufen" ::msgcat::mcset de "GPG-encrypt outgoing messages where possible." "Ausgehende Nachrichten GPG-verschlüsseln wo möglich." ::msgcat::mcset de "GPG-sign outgoing messages and presence updates." "Ausgehende Nachrichten und Präsenz-Aktualisierungen GPG-signieren." ::msgcat::mcset de "GPG options (signing and encryption)." "GPG-Optionen (verschlüsseln und signieren)." ::msgcat::mcset de "Invalid signature" "Ungültige Signatur" ::msgcat::mcset de "Key ID" "Schlüssel-ID" ::msgcat::mcset de "Malformed signature block" "Missgebildeter Signatur-Block" ::msgcat::mcset de "Message body" "Nachrichten-Text" ::msgcat::mcset de "Multiple signatures having different authenticity" "Mehrere Signaturen haben unterschiedliche Glaubwürdigkeiten" ::msgcat::mcset de "No information available" "Keine Informationen verfügbar" ::msgcat::mcset de "Passphrase:" "Passphrase:" ::msgcat::mcset de "Please enter passphrase" "Bitte die Passphrase eingeben" ::msgcat::mcset de "Please try again" "Bitte nochmals versuchen" ::msgcat::mcset de "Presence information" "Präsenz-Information" ::msgcat::mcset de "Presence is signed" "Präsenz ist signiert" ::msgcat::mcset de "Reason:" "Grund:" ::msgcat::mcset de "Select" "Auswählen" ::msgcat::mcset de "Select Key for Signing %s Traffic" "Schlüssel für die Signatur von %s Datenverkehr auswählen" ::msgcat::mcset de "Sign traffic" "Datenverkehr signieren" ::msgcat::mcset de "Signature not processed due to missing key" "Signatur nicht verarbeitet wegen fehlendem Schlüssel" ::msgcat::mcset de "The signature is good but has expired" "Die Signatur ist gut, aber verfallen" ::msgcat::mcset de "The signature is good but the key has expired" "Die Signatur ist gut, aber der Schlüssel ist verfallen" ::msgcat::mcset de "Toggle encryption" "Verschlüsselung umschalten" ::msgcat::mcset de "Toggle encryption (when possible)" "Verschlüsselung umschalten (wenn möglich)" ::msgcat::mcset de "Toggle signing" "Signierung umschalten" ::msgcat::mcset de "Unable to encipher data for %s: %s.\n\nEncrypting traffic to this user is now disabled.\n\nSend it as PLAINTEXT?" "Es ist nicht möglich, Daten für %s zu verschlüsseln: %s.\n\nDatenverkehr-Verschlüsselung zu diesem Kontakt ist jetzt deaktiviert.\n\nAls KLARTEXT versenden?" ::msgcat::mcset de "Unable to sign message body: %s.\n\nSigning traffic is now disabled.\n\nSend it WITHOUT a signature?" "Es ist nicht möglich, den Nachrichten-Text zu signieren: %s.\n\nDatenverkehr-Signierung ist jetzt deaktiviert.\n\nOHNE Signature versenden?" ::msgcat::mcset de "Unable to sign presence information: %s.\n\nPresence will be sent, but signing traffic is now disabled." "Es ist nicht möglich, die Präsenz-Information zu signieren: %s.\n\nDie Präsenz wird gesendet, aber Datenverkehr-Signierung ist jetzt deaktiviert." ::msgcat::mcset de "Use specified key ID for signing and decrypting messages." "Angegebene Schlüssel-ID für das Verschlüsseln und Signieren von Nachrichten benutzen." ::msgcat::mcset de "Use the same passphrase for signing and decrypting messages." "Dieselbe Passphrase zum Verschlüsseln und Signieren von Nachrichten benutzen." ::msgcat::mcset de "User ID" "Kontakt-ID" ::msgcat::mcset de "\n\tPresence is signed:" "\n\tPräsenz ist signiert:" # .../iface.tcl ::msgcat::mcset de "Begin date" "Erstell-Datum\t" ::msgcat::mcset de "Cipher" "Verschlüsselung\t" ::msgcat::mcset de "Disabled\n" "Deaktiviert\n" ::msgcat::mcset de "Enabled\n" "Aktiviert\n" ::msgcat::mcset de "Expiry date" "Verfalls-Datum\t" ::msgcat::mcset de "Invisible" "Unsichtbar" ::msgcat::mcset de "Issuer" "Aussteller" ::msgcat::mcset de "Not logged in" "Nicht angemeldet" ::msgcat::mcset de "Serial number" "Serien-Nummer\t" ::msgcat::mcset de "Session key bits" "'Session Key'-Bits\t" ::msgcat::mcset de "SHA1 hash" "SHA1-Prüfsumme\t" ::msgcat::mcset de "Subject" "Betreff\t\t" # .../iq.tcl ::msgcat::mcset de "%s request from %s" "%s-Anfrage von %s" ::msgcat::mcset de "Info/Query options." "Optionen für Informationen/Anfragen." ::msgcat::mcset de "Show IQ requests in the status line." "IQ-Anfragen in der Status-Leiste anzeigen." ::msgcat::mcset de "Strip leading \"http://jabber.org/protocol/\" from IQ namespaces in the status line." "Führendes \"http://jabber.org/protocol/\" von IQ-Namensräumen in der Status-Leiste entfernen." # .../itemedit.tcl ::msgcat::mcset de "<- Remove" "<- Entfernen" ::msgcat::mcset de "Add ->" "Hinzufügen ->" ::msgcat::mcset de "Available groups" "Verfügbare Gruppen" ::msgcat::mcset de "Current groups" "Derzeitige Gruppen" ::msgcat::mcset de "Edit groups for %s" "Gruppen ändern für %s" ::msgcat::mcset de "Edit item..." "Eintrag ändern..." ::msgcat::mcset de "Edit nickname for %s" "Nicknamen ändern für %s" ::msgcat::mcset de "Nickname:" "Nickname:" # .../joingrdialog.tcl ::msgcat::mcset de "Cancel" "Abbrechen" ::msgcat::mcset de "Connection:" "Verbindung:" # This "Group:"-translation is also used at the top of the "Customize"-Window! ::msgcat::mcset de "Group:" "Gruppe:" ::msgcat::mcset de "Join" "Beitreten" ::msgcat::mcset de "Join group" "Konferenz beitreten" ::msgcat::mcset de "Join group dialog data (groups)." "Dialog-Daten Konferenz-Beitritt (Konferenzen)." ::msgcat::mcset de "Join group dialog data (nicks)." "Dialog-Daten Konferenz-Beitritt (Nicknamen)." ::msgcat::mcset de "Join group dialog data (servers)." "Dialog-Daten Konferenz-Beitritt (Server)." ::msgcat::mcset de "Nick:" "Nickname:" ::msgcat::mcset de "Password:" "Kennwort:" ::msgcat::mcset de "Server:" "Server:" # .../login.tcl ::msgcat::mcset de ". Proceed?\n\n" ". Fortsetzen?\n\n" ::msgcat::mcset de "Address type not supported by SOCKS proxy" "Adressen-Typ wird vom SOCKS-Proxy nicht unterstützt" ::msgcat::mcset de "Allow plaintext authentication mechanisms (when password is transmitted unencrypted)." "Klartext-Authentifizierung erlauben (wenn Kennwort unverschlüsselt übermittelt wird)." ::msgcat::mcset de "Allow X-GOOGLE-TOKEN authentication mechanisms. It requires connection to Google via HTTPS." "X-GOOGLE-TOKEN Authentifizierungs-Mechanismus erlauben. Dies erfordert eine Verbindung zu Google via HTTPS." ::msgcat::mcset de "Authentication failed: %s" "Authentifizierung misslungen: %s" ::msgcat::mcset de "Authentication failed: %s\nCreate new account?" "Authentifizierung misslungen: %s\nNeues Konto einrichten?" ::msgcat::mcset de "Change password" "Kennwort ändern" ::msgcat::mcset de "Compression" "Komprimierung" ::msgcat::mcset de "Connection refused by destination host" "Verbindung wurde vom Ziel-Host verweigert" ::msgcat::mcset de "Display SSL warnings." "SSL-Warnungen anzeigen." ::msgcat::mcset de "Encryption (STARTTLS)" "Verschlüsselung (STARTTLS)" ::msgcat::mcset de "Encryption (legacy SSL)" "Verschlüsselung (Legacy SSL)" ::msgcat::mcset de "Failed to connect: %s" "Verbindung misslungen: %s" ::msgcat::mcset de "Host unreachable" "Host nicht erreichbar" ::msgcat::mcset de "HTTP proxy address." "HTTP-Proxy-Adresse." ::msgcat::mcset de "HTTP proxy password." "HTTP-Proxy-Kennwort." ::msgcat::mcset de "HTTP proxy port." "HTTP-Proxy-Port." ::msgcat::mcset de "HTTP proxy username." "HTTP-Proxy-Benutzer-Name." ::msgcat::mcset de "HTTPS" "HTTPS" ::msgcat::mcset de "Incorrect SOCKS version" "Inkorrekte SOCKS-Version" ::msgcat::mcset de "Keep trying" "Weiterhin versuchen" ::msgcat::mcset de "List of logout reasons." "Liste von Abmelde-Gründen." ::msgcat::mcset de "Login options." "Optionen für die Anmeldung." ::msgcat::mcset de "Logout with reason" "Abmelden mit Grund" ::msgcat::mcset de "Maximum poll interval." "Abfrage-Intervall (max.)." ::msgcat::mcset de "Minimum poll interval." "Abfrage-Intervall (min.)." ::msgcat::mcset de "Network failure" "Netzwerk-Fehler" ::msgcat::mcset de "Network unreachable" "Netzwerk nicht erreichbar" ::msgcat::mcset de "New password:" "Neues Kennwort:" ::msgcat::mcset de "New passwords do not match" "Das neue Kennwort passt nicht" ::msgcat::mcset de "Number of HTTP poll client security keys to send before creating new key sequence." "Anzahl der HTTP-Poll-Sicherheitsschlüssel, die gesendet werden, bevor eine neue Schlüssel-Sequenz erstellt wird." ::msgcat::mcset de "Old password is incorrect" "Altes Kennwort ist nicht korrekt" ::msgcat::mcset de "Old password:" "Altes Kennwort:" ::msgcat::mcset de "Password change failed: %s" "Kennwort-Änderung misslungen: %s" ::msgcat::mcset de "Password is changed" "Kennwort wurde geändert" ::msgcat::mcset de "Password." "Kennwort." ::msgcat::mcset de "Plaintext" "Klartext" ::msgcat::mcset de "Priority." "Priorität." ::msgcat::mcset de "Priority:" "Priorität:" ::msgcat::mcset de "Proxy authentication required" "Proxy-Authentifizierung erforderlich" ::msgcat::mcset de "Proxy type to connect." "Proxy-Typ der Verbindung." ::msgcat::mcset de "Registration failed: %s" "Registrierung misslungen: %s" ::msgcat::mcset de "Repeat new password:" "Neues Kennwort wiederholen:" ::msgcat::mcset de "Replace opened connections." "Offene Verbindungen ersetzen." ::msgcat::mcset de "Resource." "Ressource." ::msgcat::mcset de "Retry to connect forever." "Wiederholt versuchen, eine Verbindung herzustellen." ::msgcat::mcset de "SOCKS authentication failed" "SOCKS-Authentifizierung misslungen" ::msgcat::mcset de "SOCKS command not supported" "SOCKS-Kommando nicht unterstützt" ::msgcat::mcset de "SOCKS connection not allowed by ruleset" "SOCKS-Verbindung wurde vom Regelwerk nicht erlaubt" ::msgcat::mcset de "SOCKS request failed" "SOCKS-Anforderung misslungen" ::msgcat::mcset de "SOCKS server cannot identify username" "SOCKS-Server kann Benutzer-Namen nicht identifizieren" ::msgcat::mcset de "SOCKS server username identification failed" "SOCKS-Server Benutzer-Namen-Identifizierung misslungen" ::msgcat::mcset de "SOCKS4a" "SOCKS4a" ::msgcat::mcset de "SOCKS5" "SOCKS5" ::msgcat::mcset de "SSL certificate file (optional)." "SSL-Zertifikat-Datei (optional)." ::msgcat::mcset de "SSL certification authority file or directory (optional)." "Autorisierungs-Datei oder -Ordner für SSL-Zertifizierung (optional)." ::msgcat::mcset de "SSL private key file (optional)." "Private SSL-Schlüssel-Datei (optional)." ::msgcat::mcset de "Server name or IP-address." "Server-Name oder IP-Adresse." ::msgcat::mcset de "Server name." "Server-Name." ::msgcat::mcset de "Server port." "Server-Port." ::msgcat::mcset de "Timeout for waiting for HTTP poll responses (if set to zero, Tkabber will wait forever)." "Wartezeit-Beschränkung für HTTP-Poll-Antworten (unbegrenzt bei 0)." ::msgcat::mcset de "TTL expired" "TTL verfallen" ::msgcat::mcset de "Unknown address type" "Unbekannter Adressen-Typ" ::msgcat::mcset de "Unknown error" "Unbekannter Fehler" ::msgcat::mcset de "Unsupported SOCKS authentication method" "Nicht unterstützte SOCKS-Authentifizierungs-Methode" ::msgcat::mcset de "Unsupported SOCKS method" "Nicht unterstützte SOCKS-Methode" ::msgcat::mcset de "URL to connect to." "URL für die Verbindung." ::msgcat::mcset de "Use HTTP poll client security keys (recommended)." "HTTP-Poll-Sicherheitsschlüssel benutzen (empfohlen)." ::msgcat::mcset de "Use HTTP poll connection method." "HTTP-Polling als Verbindungs-Methode benutzen." ::msgcat::mcset de "Use SASL authentication." "SASL-Authentifizierung benutzen." ::msgcat::mcset de "Use explicitly-specified server address and port." "Explizit vorgegebene Server-Adresse und -Port benutzen." ::msgcat::mcset de "User name." "Benutzer-Name." ::msgcat::mcset de "User-Agent string." "HTTP-'User-Agent'-Zeichenfolge." ::msgcat::mcset de "Warning display options." "Optionen für die Anzeige von Warnungen." ::msgcat::mcset de "XMPP stream options when connecting to server." "XMPP-'Stream'-Option für das Verbinden mit dem Server." ::msgcat::mcset de "Certificate has expired" "Zertifikat ist verfallen" ::msgcat::mcset de "Self signed certificate" "'Self Signed'-Zertifikat" # .../messages.tcl ::msgcat::mcset de "Attached URL:" "Angehängte URL:" ::msgcat::mcset de "Approve subscription" "Autorisierung genehmigen" ::msgcat::mcset de "Decline subscription" "Autorisierung verweigern" ::msgcat::mcset de "Extras from %s" "Extras von %s" ::msgcat::mcset de "Extras from:" "Extras von:" ::msgcat::mcset de "From: " "Von:" ::msgcat::mcset de "Grant subscription" "Autorisierung zugestehen" ::msgcat::mcset de "Group: " "Gruppe:" ::msgcat::mcset de "List of message destination JIDs." "Liste der Nachrichten-Ziel-JIDs." ::msgcat::mcset de "Message and Headline options." "Optionen für Nachrichten und Kopfzeilen." ::msgcat::mcset de "Message from:" "Nachricht von:" ::msgcat::mcset de "Quote" "Zitieren" ::msgcat::mcset de "Received by:" "Empfangen von:" ::msgcat::mcset de "Request subscription" "Autorisierung anfragen" ::msgcat::mcset de "Reply" "Antworten" ::msgcat::mcset de "Reply subject:" "Antwort-Betreff:" ::msgcat::mcset de "Send message" "Nachricht senden" ::msgcat::mcset de "Send message to %s" "Nachricht an %s senden" ::msgcat::mcset de "Send message to group" "Nachricht an Gruppe senden" ::msgcat::mcset de "Send message to group %s" "Nachricht an Gruppe %s senden" ::msgcat::mcset de "Send request to: " "Anfrage senden an:" ::msgcat::mcset de "Send subscription request" "Autorisierungs-Anfrage senden" ::msgcat::mcset de "Send subscription request to %s" "Autorisierungs-Anfrage an %s senden" ::msgcat::mcset de "Subject: " "Betreff:" ::msgcat::mcset de "Subscription request from %s" "Autorisierungs-Anfrage von %s" ::msgcat::mcset de "Subscription request from:" "Autorisierungs-Anfrage von:" ::msgcat::mcset de "This message is encrypted." "Diese Nachricht ist verschlüsselt." ::msgcat::mcset de "To: " "An:" # .../muc.tcl ::msgcat::mcset de " by %s" " durch %s" ::msgcat::mcset de "%s has been assigned a new affiliation: %s" "%s ist eine neue Zugehörigkeit zugewiesen worden: %s" ::msgcat::mcset de "%s has been assigned a new role: %s" "%s ist eine neue Funktion zugewiesen worden: %s" ::msgcat::mcset de "%s has been assigned a new room position: %s/%s" "%s ist eine neue Position innerhalb der Konferenz zugewiesen worden: %s/%s" ::msgcat::mcset de "%s has been banned" "%s ist gebannt worden" ::msgcat::mcset de "%s has been kicked" "%s ist gekickt worden" ::msgcat::mcset de "%s has been kicked because of membership loss" "%s ist gekickt worden wegen Verlust der Mitgliedschaft" ::msgcat::mcset de "%s has been kicked because room became members-only" "%s ist gekickt worden weil Konferenz 'Nur-für-Mitglieder' wurde" ::msgcat::mcset de "%s has entered" "%s ist eingetreten" ::msgcat::mcset de "%s has left" "%s ist gegangen" ::msgcat::mcset de "%s invites you to conference room %s" "%s lädt ein zu Konferenz %s" ::msgcat::mcset de "%s is now known as %s" "%s ist jetzt bekannt als %s" ::msgcat::mcset de "A new room is created" "Ein neuer Konferenz-Raum ist erstellt worden" ::msgcat::mcset de "Accept default config" "Voreingestellte Konfiguration akzeptieren" ::msgcat::mcset de "Add new item" "Neuen Eintrag hinzufügen" ::msgcat::mcset de "admin" "Administrator" ::msgcat::mcset de "All items:" "Alle Einträge:" ::msgcat::mcset de "as %s/%s" "als %s/%s" ::msgcat::mcset de "Ban" "Bannen" ::msgcat::mcset de "Cancelling configure form" "Annulliere Konfigurations-Formular" ::msgcat::mcset de "Conference room %s will be destroyed permanently.\n\nProceed?" "Konferenz-Raum %s wird dauerhaft entfernt.\n\nFortsetzen?" ::msgcat::mcset de "Configure form: %s" "Konfigurations-Formular: %s" ::msgcat::mcset de "Configure room" "Konferenz-Raum konfigurieren" ::msgcat::mcset de "Destroy room" "Konferenz-Raum entfernen" ::msgcat::mcset de "Edit admin list" "Administratoren-Liste ändern" ::msgcat::mcset de "Edit ban list" "Bann-Liste ändern" ::msgcat::mcset de "Edit member list" "Mitglieder-Liste ändern" ::msgcat::mcset de "Edit moderator list" "Moderatoren-Liste ändern" ::msgcat::mcset de "Edit owner list" "Eigentümer-Liste ändern" ::msgcat::mcset de "Edit voice list" "Teilnehmer-Liste ändern" ::msgcat::mcset de "Generate groupchat messages when occupant changes his/her status and/or status message." "Konferenz-Nachrichten erstellen, wenn Konferenz-Teilnehmer ihren Status und/oder die Status-Nachricht ändern." ::msgcat::mcset de "Generate groupchat messages when occupant's room position (affiliation and/or role) changes." "Konferenz-Nachrichten erstellen, wenn sich die Position (Zugehörigkeit und/oder Funktion) von Teilnehmern innerhalb einer Konferenz ändert." ::msgcat::mcset de "Generate status messages when occupants enter/exit MUC compatible conference rooms." "Status-Nachrichten erstellen, wenn Teilnehmer MUC-kompatible Konferenz-Räume betreten oder verlassen." ::msgcat::mcset de "Grant Admin Privileges" "Administrator-Privilegien zugestehen" ::msgcat::mcset de "Grant Membership" "Mitgliedschaft zugestehen" ::msgcat::mcset de "Grant Moderator Privileges" "Moderatoren-Privilegien zugestehen" ::msgcat::mcset de "Grant Owner Privileges" "Eigentümer-Privilegien zugestehen" ::msgcat::mcset de "Grant Voice" "Teilnehmerschaft zugestehen" ::msgcat::mcset de "Invited to:" "Eingeladen zu:" ::msgcat::mcset de "Join conference" "Konferenz beitreten" ::msgcat::mcset de "Join groupchat" "Konferenz beitreten" ::msgcat::mcset de "Kick" "Kick" ::msgcat::mcset de "MUC" "MUC" ::msgcat::mcset de "Maximum number of characters in the history in MUC compatible conference rooms." "Maximale Buchstaben-Anzahl in der Historie MUC-kompatibler Konferenz-Räume." ::msgcat::mcset de "Maximum number of stanzas in the history in MUC compatible conference rooms." "Maximale 'Stanza'-Anzahl in der Historie MUC-kompatibler Konferenz-Räume." ::msgcat::mcset de "member" "Mitglied" ::msgcat::mcset de "moderator" "Moderator" ::msgcat::mcset de "Nick" "Nickname" ::msgcat::mcset de "none" "Kein" ::msgcat::mcset de "outcast" "Gebannt" ::msgcat::mcset de "owner" "Eigentümer" ::msgcat::mcset de "participant" "Teilnehmer" ::msgcat::mcset de "Propose to configure newly created MUC room. If set to false then the default room configuration is automatically accepted." "Vorschlagen, neu erstellte MUC-Konferenz-Räume zu konfigurieren. Wenn nicht, wird die voreingestellte Konfiguration automatisch übernommen." ::msgcat::mcset de "Reason" "Grund" ::msgcat::mcset de "Report the list of current MUC rooms on disco#items query." "Berichte die Liste derzeitiger MUC-Konferenz-Räume bei 'disco#items'-Anfragen." ::msgcat::mcset de "Request only unseen (which aren't displayed in the chat window) messages in the history in MUC compatible conference rooms." "Nur ungesehene (nicht im Chat-Fenster angezeigte) Nachrichten aus der Historie MUC-kompatibler Konferenz-Räume abfragen." ::msgcat::mcset de "Revoke Admin Privileges" "Administrator-Privilegien widerrufen" ::msgcat::mcset de "Revoke Membership" "Mitgliedschaft widerrufen" ::msgcat::mcset de "Revoke Moderator Privileges" "Moderatoren-Privilegien widerrufen" ::msgcat::mcset de "Revoke Owner Privileges" "Eigentümer-Privilegien widerrufen" ::msgcat::mcset de "Revoke Voice" "Teilnehmerschaft widerrufen" ::msgcat::mcset de "Role" "Funktion/Rolle" ::msgcat::mcset de "Room %s is successfully created" "Konferenz-Raum %s wurde erfolgreich erstellt" ::msgcat::mcset de "Room is created" "Konferenz-Raum wurde erstellt" ::msgcat::mcset de "Room is destroyed" "Konferenz-Raum wurde beseitigt" ::msgcat::mcset de "Sending %s %s list" "Sende %s %s Liste" ::msgcat::mcset de "Sending configure form" "Sende Konfigurations-Formular" ::msgcat::mcset de "User already %s" "Teilnehmer ist bereits %s" ::msgcat::mcset de "visitor" "Besucher" ::msgcat::mcset de "Whois" "Whois" ::msgcat::mcset de "\nAlternative venue: %s" "\nAlternativer Treffpunkt: %s" ::msgcat::mcset de "\nReason is: %s" "\nGrund ist: %s" ::msgcat::mcset de "\nReason: %s" "\nGrund: %s" ::msgcat::mcset de "\n\tAffiliation: %s" "\n\tZugehörigkeit: %s" ::msgcat::mcset de "\n\tJID: %s" "\n\tJID: %s" ::msgcat::mcset de "and" "und" ::msgcat::mcset de "whois %s: %s" "Whois %s: %s" ::msgcat::mcset de "whois %s: no info" "Whois %s: keine Informationen" # .../pep.tcl ::msgcat::mcset de "Personal eventing" "Persönliche Ereignisse" ::msgcat::mcset de "Personal eventing via pubsub plugins options." "Optionen für die 'Personal Eventing'-Plugins (XEP-0163)." # .../pixmaps.tcl ::msgcat::mcset de "Tkabber icon theme. To make new theme visible for Tkabber put it to some subdirectory of %s." "Tkabber Icon-Thema. Um es für Tkabber sichtbar zu machen, muß es in einem Unterordner von %s platziert werden." # .../presence.tcl ::msgcat::mcset de "Change Presence Priority" "Präsenz-Priorität ändern" ::msgcat::mcset de "Stored user priority." "Gespeicherte Kontakt-Priorität" ::msgcat::mcset de "Stored user status." "Gespeicherter Kontakt-Status" ::msgcat::mcset de "Stored user text status." "Gespeicherter Kontakt-Text-Status" ::msgcat::mcset de "Unsubscribed from %s" "Autorisierung zurückgezogen" ::msgcat::mcset de "You are unsubscribed from %s" "Die Autorisierung wurde von %s zurückgezogen" ::msgcat::mcset de "doesn't want to be disturbed" "wünscht nicht gestört zu werden" ::msgcat::mcset de "invalid userstatus value " "ungültiger Status-Wert" ::msgcat::mcset de "is available" "ist anwesend" ::msgcat::mcset de "is away" "ist abwesend" ::msgcat::mcset de "is extended away" "ist länger abwesend" ::msgcat::mcset de "is free to chat" "ist frei zum Chatten" ::msgcat::mcset de "is invisible" "ist unsichtbar" ::msgcat::mcset de "is unavailable" "ist nicht verfügbar" # .../privacy.tcl ::msgcat::mcset de "Activate visible/invisible/ignore/conference lists before sending initial presence." "Sichtbar-/Unsichtbar-/Ignorieren-/Konferenzen-Listen vor dem Senden der einleitenden Präsenz aktivieren." ::msgcat::mcset de "Activating privacy list failed: %s\n\nTry to reconnect. If problem persists, you may want to disable privacy list activation at start" "Aktivierung der Privatsphären-Listen misslungen: %s\n\nVersuchen Sie eine erneute Verbindung mit dem Server. Wenn das Problem bestehen bleibt, stellen Sie die Aktivierung der Privatsphären-Listen beim Start ab." ::msgcat::mcset de "Active" "Aktiv" ::msgcat::mcset de "Add JID" "JID hinzufügen" ::msgcat::mcset de "Add item" "Eintrag hinzufügen" ::msgcat::mcset de "Add list" "Liste hinzufügen" ::msgcat::mcset de "Blocking communication (XMPP privacy lists) options." "Optionen für das Blockieren der Kommunikation (Privatsphären-Listen)." ::msgcat::mcset de "Changing accept messages from roster only: %s" "Ändere 'Nur Nachrichten von Kontakten im Roster akzeptieren': %s" ::msgcat::mcset de "Creating default privacy list" "Erstelle voreingestellte Privatsphären-Listen" ::msgcat::mcset de "Creating default privacy list failed: %s\n\nTry to reconnect. If problem persists, you may want to disable privacy list activation at start" "Erstellung der voreingestellten Privatsphären-Listen misslungen: %s\n\nVersuchen Sie eine erneute Verbindung mit dem Server. Wenn das Problem bestehen bleibt, stellen Sie die Aktivierung der Privatsphären-Listen beim Start ab." ::msgcat::mcset de "Default" "Voreinstellung" ::msgcat::mcset de "Down" "Abwärts" ::msgcat::mcset de "Edit conference list" "Konferenzen-Liste ändern" ::msgcat::mcset de "Edit ignore list" "Ignorieren-Liste ändern" ::msgcat::mcset de "Edit invisible list" "Unsichtbar-Liste ändern" ::msgcat::mcset de "Edit list" "Liste ändern" ::msgcat::mcset de "Edit privacy list" "Privatsphären-Liste ändern" ::msgcat::mcset de "Edit visible list" "Sichtbar-Liste ändern" ::msgcat::mcset de "Ignore list" "Ignorieren-Liste" ::msgcat::mcset de "Invisible list" "Unsichtbar-Liste" ::msgcat::mcset de "Visible list" "Sichtbar-Liste" ::msgcat::mcset de "List name" "Listen-Name" ::msgcat::mcset de "No active list" "Keine aktive Liste" ::msgcat::mcset de "No default list" "Keine voreingestellte Liste" ::msgcat::mcset de "Presence-in" "Präsenz eingehend" ::msgcat::mcset de "Presence-out" "Präsenz ausgehend" ::msgcat::mcset de "Privacy list is activated" "Privatsphären-Liste ist aktiv" ::msgcat::mcset de "Privacy list is not activated" "Privatsphären-Liste ist nicht aktiv" ::msgcat::mcset de "Privacy list is not created" "Privatsphären-Liste ist nicht erstellt" ::msgcat::mcset de "Privacy lists" "Privatsphären-Listen" ::msgcat::mcset de "Privacy lists are not implemented" "Privatsphären-Listen sind nicht implementiert" ::msgcat::mcset de "Privacy lists are unavailable" "Privatsphären-Listen sind nicht verfügbar" ::msgcat::mcset de "Privacy lists error" "Privatsphären-Listen-Fehler" ::msgcat::mcset de "Remove from list" "Von Liste entfernen" ::msgcat::mcset de "Remove list" "Liste entfernen" ::msgcat::mcset de "Requesting conference list: %s" "Fordere Konferenzen-Liste an: %s" ::msgcat::mcset de "Requesting privacy list: %s" "Fordere Privatsphären-Liste an: %s" ::msgcat::mcset de "Requesting privacy rules: %s" "Fordere Privatsphären-Regeln an: %s" ::msgcat::mcset de "Requesting ignore list: %s" "Fordere Ignorieren-Liste an: %s" ::msgcat::mcset de "Requesting invisible list: %s" "Fordere Unsichtbar-Liste an: %s" ::msgcat::mcset de "Requesting visible list: %s" "Fordere Sichtbar-Liste an: %s" ::msgcat::mcset de "Sending conference list: %s" "Sende Konferenzen-Liste: %s" ::msgcat::mcset de "Sending ignore list: %s" "Sende Ignorieren-Liste: %s" ::msgcat::mcset de "Sending invisible list: %s" "Sende Unsichtbar-Liste: %s" ::msgcat::mcset de "Sending visible list: %s" "Sende Sichtbar-Liste: %s" ::msgcat::mcset de "Type" "Typ" ::msgcat::mcset de "Up" "Aufwärts" ::msgcat::mcset de "Waiting for activating privacy list" "Warte auf Aktivierung der Privatsphären-Listen . . ." # .../pubsub.tcl ::msgcat::mcset de "Affiliation" "Zugehörigkeit" ::msgcat::mcset de "Edit entities affiliations: %s" "Zugehörigkeit der 'Entities' ändern: %s" ::msgcat::mcset de "Jabber ID" "Jabber ID" ::msgcat::mcset de "None" "Kein" ::msgcat::mcset de "Outcast" "Bann" ::msgcat::mcset de "Owner" "Eigentümer" ::msgcat::mcset de "Pending" "Unerledigt" ::msgcat::mcset de "Publisher" "Herausgeber" ::msgcat::mcset de "SubID" "SubID" ::msgcat::mcset de "Subscribed" "Autorisiert" ::msgcat::mcset de "Subscription" "Autorisierung" ::msgcat::mcset de "Unconfigured" "Nicht konfiguriert" # .../register.tcl ::msgcat::mcset de "Register" "Registrieren" ::msgcat::mcset de "Register in %s" "Registrieren in %s" ::msgcat::mcset de "Registration is successful!" "Registrierung erfolgreich!" ::msgcat::mcset de "Registration: %s" "Registrierung: %s" ::msgcat::mcset de "Unregister" "Registrierung rückgängig machen" # .../richtext.tcl ::msgcat::mcset de "Settings of rich text facility which is used to render chat messages and logs." "Optionen für die 'Rich Text'-Fähigkeiten.\nDiese werden für die Darstellung von Chat-Nachrichten und Logs benutzt." # .../roster.tcl ::msgcat::mcset de "Active Chats" "Aktive Chats" ::msgcat::mcset de "All Files" "Alle Dateien" ::msgcat::mcset de "My Resources" "Meine Ressourcen" ::msgcat::mcset de "Roster Files" "Roster-Dateien" ::msgcat::mcset de "Undefined" "Undefiniert" # .../search.tcl ::msgcat::mcset de "#" "#" ::msgcat::mcset de "An error occurred when searching in %s\n\n%s" "Fehler bei der Suche in %s\n\n%s" ::msgcat::mcset de "Search" "Suchen" ::msgcat::mcset de "Search again" "Erneut suchen" ::msgcat::mcset de "Search in %s" "Suchen in %s" ::msgcat::mcset de "Search in %s: No matching items found" "Suchen in %s: Keine passenden Einträge gefunden" ::msgcat::mcset de "Search: %s" "Suchen: %s" ::msgcat::mcset de "Try again" "Erneut versuchen" # .../si.tcl ::msgcat::mcset de "Enable SI transport %s." "Aktiviere SI-Transport %s." ::msgcat::mcset de "File transfer aborted" "Datei-Übertragung abgebrochen" ::msgcat::mcset de "Opening SI connection" "Öffne SI-Verbindung" ::msgcat::mcset de "SI connection closed" "SI-Verbindung geschlossen" ::msgcat::mcset de "Stream method negotiation failed" "Verhandlung der Stream-Methode misslungen" # .../splash.tcl ::msgcat::mcset de "%s plugin" ::msgcat::mcset de "Save To Log" "In Log-Datei speichern" ::msgcat::mcset de "auto-away" ::msgcat::mcset de "avatars" ::msgcat::mcset de "balloon help" ::msgcat::mcset de "browsing" ::msgcat::mcset de "bwidget workarounds" ::msgcat::mcset de "configuration" ::msgcat::mcset de "connections" ::msgcat::mcset de "cryptographics" ::msgcat::mcset de "customization" ::msgcat::mcset de "emoticons" ::msgcat::mcset de "extension management" ::msgcat::mcset de "file transfer" ::msgcat::mcset de "general plugins" ::msgcat::mcset de "jabber chat/muc" ::msgcat::mcset de "jabber iq" ::msgcat::mcset de "jabber messages" ::msgcat::mcset de "jabber presence" ::msgcat::mcset de "jabber registration" ::msgcat::mcset de "jabber roster" ::msgcat::mcset de "jabber xml" ::msgcat::mcset de "kde" ::msgcat::mcset de "macintosh plugins" ::msgcat::mcset de "message filters" ::msgcat::mcset de "negotiation" ::msgcat::mcset de "pixmaps management" ::msgcat::mcset de "plugin management" ::msgcat::mcset de "presence" ::msgcat::mcset de "privacy rules" ::msgcat::mcset de "roster plugins" ::msgcat::mcset de "search plugins" ::msgcat::mcset de "searching" ::msgcat::mcset de "service discovery" ::msgcat::mcset de "sound" ::msgcat::mcset de "unix plugins" ::msgcat::mcset de "user interface" ::msgcat::mcset de "utilities" ::msgcat::mcset de "windows plugins" ::msgcat::mcset de "wmaker" # .../userinfo.tcl ::msgcat::mcset de "%s info" "Informationen über %s" ::msgcat::mcset de "About " "Über" ::msgcat::mcset de "Address" "Adresse" ::msgcat::mcset de "Address 2:" "Adresse 2:" ::msgcat::mcset de "All files" "Alle Dateien" ::msgcat::mcset de "BBS:" "BBS:" ::msgcat::mcset de "Birthday" "Geburtstag" ::msgcat::mcset de "Birthday:" "Geburtstag:" ::msgcat::mcset de "Cell:" "Handy:" ::msgcat::mcset de "Client" "Client" ::msgcat::mcset de "Client:" "Client:" ::msgcat::mcset de "Country:" "Land:" ::msgcat::mcset de "Day:" "Tag:" ::msgcat::mcset de "Details" "Details" ::msgcat::mcset de "E-mail:" "E-Mail:" ::msgcat::mcset de "Family Name:" "Familienname:" ::msgcat::mcset de "Fax:" "Fax:" ::msgcat::mcset de "GIF images" "GIF-Bilder" ::msgcat::mcset de "Geographical position" "Geographische Position" ::msgcat::mcset de "Home:" "Privat:" ::msgcat::mcset de "ISDN:" "ISDN:" ::msgcat::mcset de "Image" "Bild" ::msgcat::mcset de "Information" "Information" ::msgcat::mcset de "Interval:" "Zeit-Intervall:" ::msgcat::mcset de "JPEG images" "JPEG-Bilder" ::msgcat::mcset de "Last Activity or Uptime" "Letzte Aktivität oder Betriebszeit" ::msgcat::mcset de "Last activity" "Letzte Aktivität" ::msgcat::mcset de "Latitude:" "Breitengrad:" ::msgcat::mcset de "List of users for userinfo." "Liste von Kontakten für Kontakt-Informationen." ::msgcat::mcset de "Load Image" "Bild laden" ::msgcat::mcset de "Loading photo failed: %s." "Laden des Bildes misslungen: %s" ::msgcat::mcset de "Location" "Wohnort" ::msgcat::mcset de "Longitude:" "Längengrad:" ::msgcat::mcset de "Message Recorder:" "Anrufbeantworter:" ::msgcat::mcset de "Middle Name:" "2. Vorname:" ::msgcat::mcset de "Modem:" "Modem:" ::msgcat::mcset de "Month:" "Monat:" ::msgcat::mcset de "Name" "Name" ::msgcat::mcset de "OS:" "Betriebssystem:" ::msgcat::mcset de "Organization" "Unternehmen" ::msgcat::mcset de "PCS:" "PCS:" ::msgcat::mcset de "PNG images" "PNG-Bilder" ::msgcat::mcset de "Pager:" "Pager:" ::msgcat::mcset de "Personal" "Persönlich" ::msgcat::mcset de "Personal " "Personell" ::msgcat::mcset de "Phones" "Telefon" ::msgcat::mcset de "Photo" "Photo" ::msgcat::mcset de "Postal Code:" "PLZ:" ::msgcat::mcset de "Preferred:" "Bevorzugt:" ::msgcat::mcset de "Prefix:" "Präfix:" ::msgcat::mcset de "Role:" "Funktion:" ::msgcat::mcset de "Service info" "Dienst-Information" ::msgcat::mcset de "Show" "Anzeigen" ::msgcat::mcset de "Show info" "Informationen anzeigen" ::msgcat::mcset de "Show user or service info" "Kontakt- oder Dienst-Informationen anzeigen" ::msgcat::mcset de "Suffix:" "Suffix:" ::msgcat::mcset de "Telephone numbers" "Telefon-Nummern" ::msgcat::mcset de "Time" "Zeit" ::msgcat::mcset de "Time Zone:" "Zeitzone:" ::msgcat::mcset de "Time:" "Zeit:" ::msgcat::mcset de "Title:" "Titel:" ::msgcat::mcset de "UID:" "UID:" ::msgcat::mcset de "URL" "URL" ::msgcat::mcset de "UTC:" "UTC:" ::msgcat::mcset de "Unit:" "Abteilung:" ::msgcat::mcset de "Update" "Aktualisieren" ::msgcat::mcset de "Uptime" "Betriebszeit" ::msgcat::mcset de "User info" "Kontakt-Informationen" ::msgcat::mcset de "Version" "Version" ::msgcat::mcset de "Video:" "Bild:" ::msgcat::mcset de "Voice:" "Sprache:" ::msgcat::mcset de "Web Site:" "Web-Seite:" ::msgcat::mcset de "Work:" "Beruflich:" ::msgcat::mcset de "Year:" "Jahr:" # .../utils.tcl ::msgcat::mcset de "OK" "OK" ::msgcat::mcset de "day" "Tag" ::msgcat::mcset de "days" "Tage" ::msgcat::mcset de "hour" "Stunde" ::msgcat::mcset de "hours" "Stunden" ::msgcat::mcset de "minute" "Minute" ::msgcat::mcset de "minutes" "Minuten" ::msgcat::mcset de "second" "Sekunde" ::msgcat::mcset de "seconds" "Sekunden" # .../ifaceck/widgets.tcl ::msgcat::mcset de "Question" "Frage" # .../ifaceck/iface.tcl ::msgcat::mcset de "Complete nickname" "Nicknamen vervollständigen" # .../ifaceck/ilogin.tcl ::msgcat::mcset de "Connect via alternate server" "Mittels alternativem Server verbinden" ::msgcat::mcset de "SASL" "SASL" ::msgcat::mcset de "SASL Certificate:" "SASL-Zertifikat:" ::msgcat::mcset de "SASL Port:" "SASL-Port:" ::msgcat::mcset de "SSL Port:" "SSL-Port:" ::msgcat::mcset de "Server Port:" "Server-Port:" ::msgcat::mcset de "Use Proxy" "Proxy benutzen" ::msgcat::mcset de "Use SSL" "SSL benutzen" ::msgcat::mcset de "Use hashed password" "'Hashed' Kennwort benutzen" # .../ifaceck/iroster.tcl ::msgcat::mcset de "Add conference..." "Konferenz hinzufügen..." ::msgcat::mcset de "Add user..." "Kontakt hinzufügen..." ::msgcat::mcset de "Are you sure to remove group '%s' from roster?" "Soll die Gruppe '%s' wirklich vom Roster entfernt werden?" ::msgcat::mcset de "is now" "ist jetzt" ::msgcat::mcset de "Remove item..." "Eintrag entfernen..." ::msgcat::mcset de "Resubscribe" "Autorisierung wiederholen" ::msgcat::mcset de "Send contacts to" "Kontakte senden an" ::msgcat::mcset de "Use aliases" "Aliase benutzen" # .../ifacetk/iface.tcl ::msgcat::mcset de "Alexey Shchepin" ::msgcat::mcset de "Konstantin Khomoutov" ::msgcat::mcset de "Marshall T. Rose" ::msgcat::mcset de "Michail Litvak" ::msgcat::mcset de "Sergei Golovan" ::msgcat::mcset de "%s SSL Certificate Info" "%s SSL-Zertifikat-Information" ::msgcat::mcset de "&Help" "&Hilfe" ::msgcat::mcset de "&Services" "&Dienste" ::msgcat::mcset de "About" "Über Tkabber" ::msgcat::mcset de "Accept messages from roster users only" "Nur Nachrichten von Kontakten im Roster akzeptieren" ::msgcat::mcset de "Activate lists at startup" "Listen beim Start aktivieren" ::msgcat::mcset de "Activate search panel" "Such-Leiste aktivieren" ::msgcat::mcset de "Add group by regexp on JIDs..." "Gruppe mit RegEx auf JIDs hinzufügen..." ::msgcat::mcset de "Add new user..." "Kontakt zu Roster hinzufügen..." ::msgcat::mcset de "Add user to roster..." "Kontakt zu Roster hinzufügen..." ::msgcat::mcset de "Admin tools" "Administrator-Werkzeuge" ::msgcat::mcset de "Authors:" "Autoren:" ::msgcat::mcset de "Available" "Anwesend" ::msgcat::mcset de "Away" "Abwesend" ::msgcat::mcset de "Bottom" "Unten" ::msgcat::mcset de "Change password..." "Kennwort ändern..." ::msgcat::mcset de "Change priority..." "Priorität andern..." ::msgcat::mcset de "Chats" "Chats" ::msgcat::mcset de "Chats:" "Chats:" ::msgcat::mcset de "Clear history" "Historie entfernen" ::msgcat::mcset de "Close Tkabber" "Tkabber beenden" ::msgcat::mcset de "Close all tabs" "Alle Tabs schließen" ::msgcat::mcset de "Close other tabs" "Andere Tabs schließen" ::msgcat::mcset de "Close tab" "Tab schließen" ::msgcat::mcset de "Common:" "Allgemein:" ::msgcat::mcset de "Complete nickname or command" "Nicknamen oder Kommando vervollständigen" ::msgcat::mcset de "Correct word" "Wort korrigieren" ::msgcat::mcset de "Customize" "Einstellungen" ::msgcat::mcset de "Delay between getting focus and updating window or tab title in milliseconds." "Verzögerung zwischen Erhalten des Fokus und Aktualisierung des Fenster- oder Tab-Titels (in Millisekunden)." ::msgcat::mcset de "Delete message of the day" "Nachricht des Tages löschen" ::msgcat::mcset de "Disconnected" "Nicht verbunden" ::msgcat::mcset de "Do not disturb" "Bitte nicht stören" ::msgcat::mcset de "Do nothing" "Nichts machen" ::msgcat::mcset de "Edit conference list " "Konferenzen-Liste ändern..." ::msgcat::mcset de "Edit ignore list " "Ignorieren-Liste ändern..." ::msgcat::mcset de "Edit invisible list " "Unsichtbar-Liste ändern..." ::msgcat::mcset de "Edit my info..." "Eigene Informationen ändern..." ::msgcat::mcset de "Emphasize" "Hervorheben" ::msgcat::mcset de "Export roster..." "Roster exportieren" ::msgcat::mcset de "Extended away" "Länger abwesend" ::msgcat::mcset de "Font to use in chat windows." "Schriftart/-größe für Chat-Fenster." ::msgcat::mcset de "Font to use in roster windows." "Schriftart/-größe für Roster-Fenster." ::msgcat::mcset de "Free to chat" "Frei zum Chatten" ::msgcat::mcset de "Generate enter/exit messages" "Betreten-/Verlassen-Nachrichten erstellen" ::msgcat::mcset de "Hide main window" "Haupt-Fenster verbergen" ::msgcat::mcset de "Hide/Show roster" "Roster verbergen/anzeigen" ::msgcat::mcset de "History of availability status messages" "Historie der Verfügbarkeits-Status-Nachrichten" ::msgcat::mcset de "Iconize" "Ikonifizieren" ::msgcat::mcset de "Import roster..." "Roster importieren" ::msgcat::mcset de "Join group..." "Konferenz beitreten..." ::msgcat::mcset de "Left" "Links" ::msgcat::mcset de "Left mouse button" "Linker Maus-Button" ::msgcat::mcset de "Log in" "Anmelden" ::msgcat::mcset de "Log in..." "Anmelden..." ::msgcat::mcset de "Log out" "Abmelden" ::msgcat::mcset de "Log out with reason..." "Abmelden mit Grund..." ::msgcat::mcset de "Main window:" "Haupt-Fenster:" ::msgcat::mcset de "Manually edit rules" "Listen von Hand ändern..." ::msgcat::mcset de "Maximum number of status messages to keep. If the history size reaches this threshold, the oldest message will be deleted automatically when a new one is recorded." "Maximale Anzahl der zwischenzuspeichernden Status-Nachrichten. Wenn die Historie ihren Schwellenwert erreicht hat, wird die älteste Nachricht automatisch gelöscht, sobald eine neue Nachricht hinzugefügt wird." ::msgcat::mcset de "Maximum width of tab buttons in tabbed mode." "Maximale Breite der Tabs bei Verwendung der Tab-Oberfläche." ::msgcat::mcset de "Message archive" "Nachrichten-Archiv" ::msgcat::mcset de "Middle mouse button" "Mittlerer Maus-Button" ::msgcat::mcset de "Minimize" "Minimieren" ::msgcat::mcset de "Minimize to systray (if systray icon is enabled, otherwise do nothing)" "In den SysTray minimieren (bei aktiviertem SysTray-Icon)" ::msgcat::mcset de "Minimum width of tab buttons in tabbed mode." "Minimale Breite der Tabs bei Verwendung der Tab-Oberfläche." ::msgcat::mcset de "Move tab left/right" "Tab nach rechts/links verschieben" ::msgcat::mcset de "Open chat..." "Chat öffnen..." ::msgcat::mcset de "Options for main interface." "Optionen für die Haupt-Oberfläche." ::msgcat::mcset de "Plugins" "Plugins" ::msgcat::mcset de "Popup menu" "Popup-Menü" ::msgcat::mcset de "Presence" "Präsenz" ::msgcat::mcset de "Presence bar" "Präsenz-Leiste" ::msgcat::mcset de "Previous/Next history message" "Vorherige/Nächste Nachricht aus Historie" ::msgcat::mcset de "Previous/Next tab" "Vorheriger/Nächster Tab" ::msgcat::mcset de "Privacy rules" "Privatsphären-Regeln" ::msgcat::mcset de "Profile on" "'Profiling' aktivieren" ::msgcat::mcset de "Profile report" "'Profiling'-Bericht" ::msgcat::mcset de "Quick Help" "Schnell-Hilfe" ::msgcat::mcset de "Quick help" "Schnell-Hilfe" ::msgcat::mcset de "Quit" "Beenden" ::msgcat::mcset de "Raise new tab." "Neuen Tab in den Vordergrund holen." ::msgcat::mcset de "Redo" "Wiederholen" ::msgcat::mcset de "Right" "Rechts" ::msgcat::mcset de "Right mouse button" "Rechter Maus-Button" ::msgcat::mcset de "Roster" "Roster" ::msgcat::mcset de "SSL Info" "SSL-Information" ::msgcat::mcset de "Scroll chat window up/down" "Chat-Fenster auf-/abwärts scrollen" ::msgcat::mcset de "Send broadcast message..." "Rundruf-Nachricht senden..." ::msgcat::mcset de "Send message of the day..." "Nachricht des Tages senden..." ::msgcat::mcset de "Send message..." "Nachricht senden..." ::msgcat::mcset de "Show Toolbar." "Werkzeug-Leiste anzeigen." ::msgcat::mcset de "Show emoticons" "Emoticons anzeigen" ::msgcat::mcset de "Show main window" "Haupt-Fenster anzeigen" ::msgcat::mcset de "Show menu tearoffs when possible." "Abreißbare Menüs anzeigen (wenn möglich)." ::msgcat::mcset de "Show number of unread messages in tab titles." "Anzahl ungelesener Nachrichten in Tab-Titeln anzeigen." ::msgcat::mcset de "Show online users only" "Nur 'Online'-Kontakte anzeigen" ::msgcat::mcset de "Show only the number of personal unread messages in window title." "Nur die Anzahl ungelesener persönlicher Nachrichten im Fenster-Titel anzeigen." ::msgcat::mcset de "Show own resources" "Eigene Ressourcen anzeigen" ::msgcat::mcset de "Show palette of emoticons" "Palette der Emoticons anzeigen" ::msgcat::mcset de "Show presence bar." "Präsenz-Leiste anzeigen." ::msgcat::mcset de "Show status bar." "Status-Leiste anzeigen." ::msgcat::mcset de "Show user or service info..." "Kontakt- oder Dienst-Informationen anzeigen..." ::msgcat::mcset de "Side where to place tabs in tabbed mode." "Fenster-Seite, an der die Tabs angeordnet werden sollen." ::msgcat::mcset de "Smart autoscroll" "Intelligentes automatisches Scrollen" ::msgcat::mcset de "Status bar" "Status-Leiste" ::msgcat::mcset de "Stop autoscroll" "Automatisches Scrollen abstellen" ::msgcat::mcset de "Stored main window state (normal or zoomed)" "Speichere Haupt-Fenster Status (Normal oder Zoomed)" ::msgcat::mcset de "Switch to tab number 1-9,10" "Wechsel zu Tab Nummer 1-9, 10" ::msgcat::mcset de "Systray:" "SysTray:" ::msgcat::mcset de "Tabs:" "Tabs:" ::msgcat::mcset de "Toggle showing offline users" "'Offline'-Kontakte anzeigen" ::msgcat::mcset de "Toolbar" "Werkzeug-Leiste" ::msgcat::mcset de "Top" "Oben" ::msgcat::mcset de "Undo" "Rückgängig" ::msgcat::mcset de "Update message of the day..." "Nachricht des Tages aktualisieren..." ::msgcat::mcset de "Use roster filter" "Roster-Filter anzeigen" ::msgcat::mcset de "Use Tabbed Interface (you need to restart)." "Tab-Oberfläche benutzen (Neustart erforderlich)." ::msgcat::mcset de "View" "Ansicht" ::msgcat::mcset de "What action does the close button." "Verhalten des Schließen-Buttons." # .../ifacetk/ilogin.tcl ::msgcat::mcset de "Account" "Konto" ::msgcat::mcset de "Allow plaintext authentication mechanisms" "Klartext-Authentifizierung erlauben" ::msgcat::mcset de "Allow X-GOOGLE-TOKEN SASL mechanism" "X-GOOGLE-TOKEN SASL-Mechanismus erlauben" ::msgcat::mcset de "Authentication" "Authentifizierung" ::msgcat::mcset de "Connect via HTTP polling" "Mittels HTTP-Polling verbinden" ::msgcat::mcset de "Connection" "Verbindung" ::msgcat::mcset de "Explicitly specify host and port to connect" "Host und Port der Verbindung explizit vorgeben" ::msgcat::mcset de "HTTP Poll" "HTTP-Polling" ::msgcat::mcset de "Host:" "Host:" ::msgcat::mcset de "Login" "Anmelden" ::msgcat::mcset de "Logout" "Abmelden" ::msgcat::mcset de "Port:" "Port:" ::msgcat::mcset de "Profile" "Profil" ::msgcat::mcset de "Profiles" "Profile" ::msgcat::mcset de "Proxy" "HTTP-Proxy" ::msgcat::mcset de "Proxy password:" "Proxy-Kennwort:" ::msgcat::mcset de "Proxy port:" "Proxy-Port:" ::msgcat::mcset de "Proxy server:" "Proxy-Server:" ::msgcat::mcset de "Proxy type:" "Proxy-Typ:" ::msgcat::mcset de "Proxy username:" "Proxy-Benutzer-Name:" ::msgcat::mcset de "Replace opened connections" "Offene Verbindungen ersetzen" ::msgcat::mcset de "Resource:" "Ressource:" ::msgcat::mcset de "SSL" "SSL" ::msgcat::mcset de "SSL & Compression" "SSL & Komprimierung" ::msgcat::mcset de "SSL certificate:" "SSL-Zertifikat:" ::msgcat::mcset de "URL to poll:" "URL für die Verbindung:" ::msgcat::mcset de "Use SASL authentication" "SASL-Authentifizierung benutzen" ::msgcat::mcset de "Use client security keys" "Sicherheitsschlüssel benutzen" # .../ifacetk/iroster.tcl ::msgcat::mcset de "Add chats group in roster." "'Chats'-Gruppe zu Roster hinzufügen." ::msgcat::mcset de "Add roster group by JID regexp" "Gruppe mit RegEx auf JIDs hinzufügen" ::msgcat::mcset de "Are you sure to remove %s from roster?" "Soll %s wirklich vom Roster entfernt werden?" ::msgcat::mcset de "Are you sure to remove all users in group '%s' from roster? \n(Users which are in another groups too, will not be removed from the roster.)" "Sollen wirklich alle Kontakte der Gruppe '%s' vom Roster entfernt werden?\n(Kontakte, die gleichzeitig in einer anderen Gruppe sind, werden nicht entfernt.)" ::msgcat::mcset de "Are you sure to remove group '%s' from roster? \n(Users which are in this group only, will be in undefined group.)" "Soll die Gruppe '%s' wirklich vom Roster entfernt werden?\n(Kontakte, die nur in dieser Gruppe sind, werden in die Gruppe 'Undefiniert' verschoben.)" ::msgcat::mcset de "Ask:" "Frage:" ::msgcat::mcset de "Default nested roster group delimiter." "Voreingestelltes Trennzeichen für verschachtelte Roster-Gruppen." ::msgcat::mcset de "Enable nested roster groups." "Verschachtelte Roster-Gruppen aktivieren." ::msgcat::mcset de "If set then open chat window/tab when user doubleclicks roster item. Otherwise open normal message window." "Bei Doppel-Klick auf Roster-Eintrag Chat-Fenster bzw. -Tab anstelle des normalen Nachrichten-Fensters öffnen." ::msgcat::mcset de "JID regexp:" "Regulärer Ausdruck:" ::msgcat::mcset de "Match contact JIDs in addition to nicknames in roster filter." "Im Roster-Filter zusätzlich zu den Nicknamen auch eine Übereinstimmung mit den Kontakt-JIDs überprüfen." ::msgcat::mcset de "New group name:" "Neuer Gruppen-Name:" ::msgcat::mcset de "Remove all users in group..." "Alle Kontakte der Gruppe entfernen..." ::msgcat::mcset de "Remove from roster..." "Vom Roster entfernen..." ::msgcat::mcset de "Remove group..." "Gruppe entfernen..." ::msgcat::mcset de "Rename group..." "Gruppe umbenennen..." ::msgcat::mcset de "Rename roster group" "Roster-Gruppe umbenennen" ::msgcat::mcset de "Resubscribe to all users in group..." "Autorisierung bei allen Kontakten der Gruppe wiederholen" ::msgcat::mcset de "Roster filter." "Roster-Filter." ::msgcat::mcset de "Roster item may be dropped not only over group name but also over any item in group." "Erlauben, daß Roster-Einträge nicht nur über Gruppen-Namen, sondern über jedem Eintrag in einer Gruppe fallen gelassen werden können." ::msgcat::mcset de "Roster of %s" "Roster von %s" ::msgcat::mcset de "Roster options." "Optionen für den Roster." ::msgcat::mcset de "Send custom presence" "Spezielle Präsenz senden" ::msgcat::mcset de "Send message to all users in group..." "Nachricht an alle Kontakte der Gruppe senden..." ::msgcat::mcset de "Show detailed info on conference room members in roster item tooltips." "Detaillierte Informationen über Konferenz-Teilnehmer im Eintrags-Tooltip anzeigen." ::msgcat::mcset de "Show my own resources in the roster." "Eigene Ressourcen in Roster anzeigen." ::msgcat::mcset de "Show native icons for contacts, connected to transports/services in roster." "Systemeigene Icons für Kontakte, die mit Transporten/Diensten verbunden sind, in Roster anzeigen." ::msgcat::mcset de "Show native icons for transports/services in roster." "Systemeigene Icons für Transporte/Dienste in Roster anzeigen." ::msgcat::mcset de "Show offline users" "'Offline'-Kontakte anzeigen" ::msgcat::mcset de "Show only online users in roster." "Nur 'Online'-Kontakte in Roster anzeigen." ::msgcat::mcset de "Show subscription type in roster item tooltips." "Autorisierungs-Status in Eintrags-Tooltip anzeigen." ::msgcat::mcset de "Stored collapsed roster groups." "Zusammengeklappte Roster-Gruppen gespeichert." ::msgcat::mcset de "Stored show offline roster groups." "'Offline anzeigen'-Roster-Gruppen gespeichert." ::msgcat::mcset de "Subscription:" "Autorisierung:" ::msgcat::mcset de "Unavailable" "Nicht verfügbar" ::msgcat::mcset de "Use aliases to show multiple users in one roster item." "Aliase benutzen, um mehrere Kontakte in einem Roster-Eintrag anzuzeigen." ::msgcat::mcset de "Use roster filter." "Roster-Filter anzeigen." # .../ifacetk/systray.tcl ::msgcat::mcset de "Display status tooltip when main window is minimized to systray." "Status-Tooltip anzeigen, wenn das Haupt-Fenster in den SysTray minimiert ist." ::msgcat::mcset de "Hide main window" "Haupt-Fenster verbergen" ::msgcat::mcset de "Show main window" "Haupt-Fenster anzeigen" ::msgcat::mcset de "Systray icon blinks when there are unread messages." "SysTray-Icon blinkt bei ungelesenen Nachrichten." ::msgcat::mcset de "Systray icon options." "Optionen für das SysTray-Icon." ::msgcat::mcset de "Tkabber Systray" "Tkabber SysTray" # .../jabberlib/jabberlib.tcl ::msgcat::mcset de "Got roster" "Roster erhalten" ::msgcat::mcset de "Timeout" "Wartezeit-Überschreitung" ::msgcat::mcset de "Waiting for roster" "Warte auf Roster . . ." # .../jabberlib/jlibauth.tcl ::msgcat::mcset de "Authentication failed" "Authentifizierung misslungen" ::msgcat::mcset de "Authentication successful" "Authentifizierung erfolgreich" ::msgcat::mcset de "Server doesn't support hashed password authentication" "Der Server unterstützt keine 'Hashed'-Kennwort-Authentifizierung." ::msgcat::mcset de "Server doesn't support plain or digest authentication" "Der Server unterstützt keine 'Plain'- or 'Digest'-Kennwort-Authentifizierung." ::msgcat::mcset de "Server haven't provided non-SASL authentication feature" "Der Server stellt keine Nicht-SASL-Authentifizierungs-Möglichkeit bereit." ::msgcat::mcset de "Waiting for authentication results" "Warte auf Authentifizierungs-Ergebnis . . ." # .../jabberlib/jlibcomponent.tcl ::msgcat::mcset de "Handshake failed" "'Handshake' misslungen" ::msgcat::mcset de "Handshake successful" "'Handshake' erfolgreich" ::msgcat::mcset de "Waiting for handshake results" "Warte auf 'Handshake'-Ergebnisse . . ." # .../jabberlib/jlibcompress.tcl ::msgcat::mcset de "Compression negotiation failed" "Komprimierungs-Verhandlung misslungen" ::msgcat::mcset de "Compression negotiation successful" "Komprimierungs-Verhandlung erfolgreich" ::msgcat::mcset de "Compression setup failed" "Komprimierungs-Einrichtung fehlgeschlagen" ::msgcat::mcset de "Server haven't provided compress feature" "Der Server stellt keine Komprimierungs-Möglichkeit bereit." ::msgcat::mcset de "Server haven't provided supported compress method" "Der Server stellt keine unterstützte Komprimierungs-Methode bereit." ::msgcat::mcset de "Unsupported compression method" "Nicht unterstützte Komprimierungs-Methode." # .../jabberlib/jlibsasl.tcl ::msgcat::mcset de "Aborted" "Abgebrochen" ::msgcat::mcset de "Authentication Error" "Authentifizierungs-Fehler" ::msgcat::mcset de "Incorrect encoding" "Fehlerhafte Kodierung" ::msgcat::mcset de "Invalid authzid" "Ungültiges 'authzid'" ::msgcat::mcset de "Invalid mechanism" "Ungültiger Mechanismus" ::msgcat::mcset de "Mechanism too weak" "Mechanismus zu weich" ::msgcat::mcset de "Not Authorized" "Nicht autorisiert" ::msgcat::mcset de "SASL auth error:\n%s" "SASL-Authentifizierungs-Fehler:\n%s" ::msgcat::mcset de "Server haven't provided SASL authentication feature" "Der Server stellt keine SASL-Authentifizierungs-Möglichkeit bereit." ::msgcat::mcset de "Server provided mechanism %s. It is forbidden" "Der Server stellt den Mechanismus %s bereit. Dieser ist unzulässig." ::msgcat::mcset de "Server provided mechanisms %s. They are forbidden" "Der Server stellt die Mechanismen %s bereit. Diese sind unzulässig." ::msgcat::mcset de "Server provided no SASL mechanisms" "Der Server stellt keinen SASL-Mechanismus bereit." ::msgcat::mcset de "Temporary auth failure" "Temporärer Authentifizierungs-Fehler" # .../jabberlib/jlibtls.tcl ::msgcat::mcset de "STARTTLS failed" "STARTTLS misslungen" ::msgcat::mcset de "STARTTLS successful" "STARTTLS erfolgreich" ::msgcat::mcset de "Server haven't provided STARTTLS feature" "Der Server stellt keine STARTTLS-Möglichkeit bereit." # .../jabberlib/stanzaerror.tcl ::msgcat::mcset de "Access Error" "Zugriffs-Fehler" ::msgcat::mcset de "Address Error" "Adressierungs-Fehler" ::msgcat::mcset de "Application Error" "Anwendungs-Fehler" ::msgcat::mcset de "Bad Request" "Ungültige Abfrage" ::msgcat::mcset de "Conflict" "Konflikt" ::msgcat::mcset de "Feature Not Implemented" "Möglichkeit nicht implementiert" ::msgcat::mcset de "Forbidden" "Unzulässig" ::msgcat::mcset de "Format Error" "Format-Fehler" ::msgcat::mcset de "Gone" "Verlassen" ::msgcat::mcset de "Internal Server Error" "Interner Server-Fehler" ::msgcat::mcset de "Item Not Found" "Eintrag nicht gefunden" ::msgcat::mcset de "JID Malformed" "Missgebildete JID" ::msgcat::mcset de "Not Acceptable" "Nicht akzeptierbar" ::msgcat::mcset de "Not Allowed" "Nicht erlaubt" ::msgcat::mcset de "Not Found" "Nicht gefunden" ::msgcat::mcset de "Not Implemented" "Nicht implementiert" ::msgcat::mcset de "Payment Required" "Zahlung erforderlich" ::msgcat::mcset de "Recipient Error" "Empfänger-Fehler" ::msgcat::mcset de "Recipient Unavailable" "Empfänger nicht verfügbar" ::msgcat::mcset de "Redirect" "Umleitung" ::msgcat::mcset de "Registration Required" "Registrierung erforderlich" ::msgcat::mcset de "Remote Server Error" "'Remote Server'-Fehler" ::msgcat::mcset de "Remote Server Not Found" "'Remote Server' nicht gefunden" ::msgcat::mcset de "Remote Server Timeout" "Wartezeit-Überschreitung des 'Remote Servers'" ::msgcat::mcset de "Request Error" "Abfrage-Fehler" ::msgcat::mcset de "Request Timeout" "Wartezeit-Überschreitung bei Abfrage" ::msgcat::mcset de "Resource Constraint" "Ressourcen-Beschränkung" ::msgcat::mcset de "Server Error" "Server-Fehler" ::msgcat::mcset de "Service Unavailable" "Dienst nicht verfügbar" ::msgcat::mcset de "Subscription Required" "Anmeldung erforderlich" ::msgcat::mcset de "Temporary Error" "Temporärer Fehler" ::msgcat::mcset de "Unauthorized" "Nicht autorisiert" ::msgcat::mcset de "Undefined Condition" "Nicht definierte Bedingung" ::msgcat::mcset de "Unexpected Request" "Unerwartete Abfrage" ::msgcat::mcset de "Unrecoverable Error" "Nicht zu behebender Fehler" ::msgcat::mcset de "Username Not Available" "Benutzer-Name nicht verfügbar" ::msgcat::mcset de "Warning" "Warnung" # .../jabberlib/streamerror.tcl ::msgcat::mcset de "Bad Format" "Ungültiges Format" ::msgcat::mcset de "Bad Namespace Prefix" "Ungültiger Namensraum-Präfix" ::msgcat::mcset de "Connection Timeout" "Verbindungs-Wartezeit-Überschreitung" ::msgcat::mcset de "Host Gone" "Host verloren" ::msgcat::mcset de "Host Unknown" "Host unbekannt" ::msgcat::mcset de "Improper Addressing" "Falsche Adressierung" ::msgcat::mcset de "Invalid From" "Ungültiges Von" ::msgcat::mcset de "Invalid ID" "Ungültige ID" ::msgcat::mcset de "Invalid Namespace" "Ungültiger Namensraum" ::msgcat::mcset de "Invalid XML" "Ungültiges XML" ::msgcat::mcset de "Policy Violation" "Richtlinien-Verletzung" ::msgcat::mcset de "Remote Connection Failed" "Fernverbindung misslungen" ::msgcat::mcset de "Restricted XML" "Eingeschränktes XML" ::msgcat::mcset de "See Other Host" "Anderen Host ansehen" ::msgcat::mcset de "Stream Error%s%s" "'Stream'-Fehler%s%s" ::msgcat::mcset de "System Shutdown" "Systemende" ::msgcat::mcset de "Unsupported Encoding" "Nicht unterstützte Kodierung" ::msgcat::mcset de "Unsupported Stanza Type" "Nicht unterstützter 'Stanza'-Typ" ::msgcat::mcset de "Unsupported Version" "Nicht unterstützte Version" ::msgcat::mcset de "XML Not Well-Formed" "XML missgebildet" # .../plugins/chat/abbrev.tcl ::msgcat::mcset de "Abbreviations:" "Abkürzungen:" ::msgcat::mcset de "Added abbreviation:\n%s: %s" "Abkürzung hinzugefügt:\n%s: %s" ::msgcat::mcset de "Deleted abbreviation: %s" "Abkürzung gelöscht: %s" ::msgcat::mcset de "No such abbreviation: %s" "Abkürzung nicht vorhanden: %s" ::msgcat::mcset de "Purged all abbreviations" "Alle Abkürzungen gelöscht" ::msgcat::mcset de "Usage: /abbrev WHAT FOR" "Benutzung: /abbrev Beispiel: /abbrev tk Tkabber" ::msgcat::mcset de "Usage: /unabbrev WHAT" "Benutzung: /unabbrev " # .../plugins/chat/bookmark_highlighted.tcl ::msgcat::mcset de "Next highlighted" "Nächste Markierte" ::msgcat::mcset de "Prev highlighted" "Vorherige Markierte" # .../plugins/chat/chatstate.tcl ::msgcat::mcset de "%s has activated chat window" "%s hat das Chat-Fenster aktiviert" ::msgcat::mcset de "%s has gone chat window" "%s hat das Chat-Fenster geschlossen" ::msgcat::mcset de "%s has inactivated chat window" "%s hat das Chat-Fenster deaktiviert" ::msgcat::mcset de "%s is composing a reply" "%s erstellt eine Antwort" ::msgcat::mcset de "%s is paused a reply" "%s pausiert eine Antwort" ::msgcat::mcset de "Chat message window state plugin options." "Optionen für das Chat-Nachrichten Status-Plugin." ::msgcat::mcset de "Chat window is active" "Chat-Fenster ist aktiv" ::msgcat::mcset de "Chat window is gone" "Chat-Fenster ist geschlossen" ::msgcat::mcset de "Chat window is inactive" "Chat-Fenster ist nicht aktiv" ::msgcat::mcset de "Composing a reply" "Erstellt eine Antwort" ::msgcat::mcset de "Enable sending chat state notifications." "Das Senden von Chat-Status-Benachrichtigungen aktivieren." ::msgcat::mcset de "Paused a reply" "Pausiert eine Antwort" # .../plugins/chat/clear.tcl ::msgcat::mcset de "Clear chat window" "Chat-Fenster leeren" # .../plugins/chat/complete_last_nick.tcl ::msgcat::mcset de "Number of groupchat messages to expire nick completion according to the last personally addressed message." "Anzahl der Konferenz-Nachrichten, nach denen die Nicknamen-Vervollständigung verfällt (unter Berücksichtigung der letzten persönlich adressierten Nachricht)." # .../plugins/chat/draw_timestamp.tcl ::msgcat::mcset de "Format of timestamp in chat message. Refer to Tcl documentation of 'clock' command for description of format.\n\nExamples:\n \[%R\] - \[20:37\]\n \[%T\] - \[20:37:12\]\n \[%a %b %d %H:%M:%S %Z %Y\] - \[Thu Jan 01 03:00:00 MSK 1970\]" "Format des Zeitstempels in Chat-Nachrichten (für Details bitte die Dokumentation des Tcl-'clock'-Kommandos lesen).\n\nBeispiele:\n \[%R\]\t\[15:15\]\n \[%T\]\t\[15:15:27\]\n \[%a %d. %b %Y %H:%M:%S %Z\] \[Son 11. Jun 2000 15:15:27 W. Europe Standard Time\]" ::msgcat::mcset de "Format of timestamp in delayed chat messages delayed for more than 24 hours." "Format des Zeitstempels für Chat-Nachrichten, die älter als 24 Stunden sind." # .../plugins/chat/draw_xhtml_message.tcl ::msgcat::mcset de "Enable rendering of XHTML messages." "Darstellung von XHTML-Nachrichten aktivieren." # .../plugins/chat/events.tcl ::msgcat::mcset de "Chat message events plugin options." "Optionen für das Chat-Nachrichten Ereignis-Plugin." ::msgcat::mcset de "Enable sending chat message events." "Das Senden von Chat-Nachrichten-Ereignissen aktivieren." ::msgcat::mcset de "Message delivered" "Nachricht abgeliefert" ::msgcat::mcset de "Message delivered to %s" "Nachricht bei %s abgeliefert" ::msgcat::mcset de "Message displayed" "Nachricht angezeigt" ::msgcat::mcset de "Message displayed to %s" "Nachricht bei %s angezeigt" ::msgcat::mcset de "Message stored on the server" "Nachricht auf dem Server gespeichert" ::msgcat::mcset de "Message stored on %s's server" "Nachricht für %s auf dem Server gespeichert" # .../plugins/chat/histool.tcl ::msgcat::mcset de "Chats History" "Chat-Historie" ::msgcat::mcset de "Chats history" "Chat-Historie" ::msgcat::mcset de "Client message" "Client-Nachricht" ::msgcat::mcset de "Full-text search" "Volltext-Suche" ::msgcat::mcset de "JID list" "JID-Liste" ::msgcat::mcset de "Logs" "Logs" ::msgcat::mcset de "Server message" "Server-Nachricht" ::msgcat::mcset de "Unsupported log dir format" "Nicht unterstütztes Log-Ordner Format" ::msgcat::mcset de "WARNING: %s\n" "WARNUNG: %s\n" # .../plugins/chat/info_commands.tcl ::msgcat::mcset de "Address 2" "Adresse 2" ::msgcat::mcset de "City" "Stadt" ::msgcat::mcset de "Country" "Land" ::msgcat::mcset de "Display %s in chat window when using /vcard command." "Zeige '%s' in Chat-Fenster an, wenn /vcard-Kommando benutzt wird." ::msgcat::mcset de "E-mail" "E-Mail" ::msgcat::mcset de "Family Name" "Familienname" ::msgcat::mcset de "Full Name" "Vollst. Name" ::msgcat::mcset de "Latitude" "Breitengrad" ::msgcat::mcset de "Longitude" "Längengrad" ::msgcat::mcset de "Middle Name" "2. Vorname" ::msgcat::mcset de "Nickname" "Nickname" ::msgcat::mcset de "Organization Name" "Unternehmen Name" ::msgcat::mcset de "Organization Unit" "Unternehmen Abteilung" ::msgcat::mcset de "Phone BBS" "Telefon BBS" ::msgcat::mcset de "Phone Cell" "Telefon Handy" ::msgcat::mcset de "Phone Fax" "Telefon Fax" ::msgcat::mcset de "Phone Home" "Telefon Privat" ::msgcat::mcset de "Phone ISDN" "Telefon ISDN" ::msgcat::mcset de "Phone Message Recorder" "Telefon Anrufbeantworter" ::msgcat::mcset de "Phone Modem" "Telefon Modem" ::msgcat::mcset de "Phone PCS" "Telefon PCS" ::msgcat::mcset de "Phone Pager" "Telefon Pager" ::msgcat::mcset de "Phone Preferred" "Telefon Bevorzugt" ::msgcat::mcset de "Phone Video" "Telefon Bild" ::msgcat::mcset de "Phone Voice" "Telefon Sprache" ::msgcat::mcset de "Phone Work" "Telefon Beruflich" ::msgcat::mcset de "Postal Code" "PLZ" ::msgcat::mcset de "Prefix" "Präfix" ::msgcat::mcset de "State " "Bundesland" ::msgcat::mcset de "Suffix" "Suffix" ::msgcat::mcset de "Title" "Title" ::msgcat::mcset de "UID" "UID" ::msgcat::mcset de "Web Site" "Web-Seite" ::msgcat::mcset de "last %s%s:" "letzte %s%s:" ::msgcat::mcset de "last %s%s: %s" "letzte %s%s: %s" ::msgcat::mcset de "time %s%s:" "Zeit %s%s:" ::msgcat::mcset de "time %s%s: %s" "Zeit %s%s: %s" ::msgcat::mcset de "vCard display options in chat windows." "Optionen für die Anzeige von Visitenkarten in Chat-Fenstern." ::msgcat::mcset de "vcard %s%s:" "Visitenkarte %s%s:" ::msgcat::mcset de "vcard %s%s: %s" "Visitenkarte %s%s: %s" ::msgcat::mcset de "version %s%s:" "Version %s%s:" ::msgcat::mcset de "version %s%s: %s" "Version %s%s: %s" # .../plugins/chat/log_on_open.tcl ::msgcat::mcset de "Maximum interval length in hours for which log messages should be shown in newly opened chat window (if set to negative then the interval is unlimited)." "Maximale Anzahl von Stunden, für die Log-Nachrichten in neu geöffneten Chat-Fenstern angezeigt werden sollen (unbegrenzt bei negativem Wert)." ::msgcat::mcset de "Maximum number of log messages to show in newly opened chat window (if set to negative then the number is unlimited)." "Maximale Anzahl von Log-Nachrichten, die in neu geöffneten Chat-Fenstern angezeigt werden sollen (unbegrenzt bei negativem Wert)." # .../plugins/chat/logger.tcl ::msgcat::mcset de "All" "Alle" ::msgcat::mcset de "April" "April" ::msgcat::mcset de "August" "August" ::msgcat::mcset de "Chats history is converted.\nBackup of the old history is stored in %s" "Die Chat-Historie ist konvertiert worden.\nEine Sicherung der alten Historie ist in %s." ::msgcat::mcset de "Close" "Schließen" ::msgcat::mcset de "Conversion is finished" "Konvertierung abgeschlossen" ::msgcat::mcset de "Converting Log Files" "Konvertiere Log-Dateien" ::msgcat::mcset de "December" "Dezember" ::msgcat::mcset de "Directory to store logs." "Ordner zum Speichern der Logs." ::msgcat::mcset de "Export to XHTML" "Als XHTML exportieren" ::msgcat::mcset de "February" "Februar" ::msgcat::mcset de "File %s cannot be opened: %s. History for %s (%s) is NOT converted\n" "Die Datei %s kann nicht geöffnet werden: %s. Die Historie für %s (%s) wurde NICHT konvertiert\n" ::msgcat::mcset de "File %s cannot be opened: %s. History for %s is NOT converted\n" "Die Datei %s kann nicht geöffnet werden: %s. Die Historie für %s wurde NICHT konvertiert\n" ::msgcat::mcset de "File %s is corrupt. History for %s (%s) is NOT converted\n" "Die Datei %s ist beschädigt. Die Historie für %s (%s) wurde NICHT konvertiert\n" ::msgcat::mcset de "File %s is corrupt. History for %s is NOT converted\n" "Die Datei %s ist beschädigt. Die Historie für %s wurde NICHT konvertiert\n" ::msgcat::mcset de "History for %s" "Historie für %s" ::msgcat::mcset de "January" "Januar" ::msgcat::mcset de "July" "Juli" ::msgcat::mcset de "June" "Juni" ::msgcat::mcset de "Logging options." "Optionen für Logs" ::msgcat::mcset de "March" "März" ::msgcat::mcset de "May" "Mai" ::msgcat::mcset de "November" "November" ::msgcat::mcset de "October" "Oktober" ::msgcat::mcset de "Please, be patient while chats history is being converted to new format" "Bitte haben Sie Geduld, während die Chat-Historie in ein neues Format konvertiert wird." ::msgcat::mcset de "Select month:" "Monat auswählen:" ::msgcat::mcset de "September" "September" ::msgcat::mcset de "Show history" "Historie anzeigen" ::msgcat::mcset de "Store group chats logs." "Konferenz-Logs sichern." ::msgcat::mcset de "Store private chats logs." "Chat-Logs sichern." ::msgcat::mcset de "You're using root directory %s for storing Tkabber logs!\n\nI refuse to convert logs database." "Das Wurzelverzeichnis %s wird für die Speicherung der Tkabber-Logs benutzt!\n\nEs ist deswegen nicht möglich, die Log-Datenbank zu konvertieren." # .../plugins/chat/muc_ignore.tcl ::msgcat::mcset de "Edit MUC ignore rules" "MUC-Ignorieren-Regeln ändern" ::msgcat::mcset de "Error loading MUC ignore rules, purged." "Fehler beim Laden der MUC-Ignorieren-Regeln, bereinigt." ::msgcat::mcset de "Ignore" "Ignorieren" ::msgcat::mcset de "Ignore chat messages" "Ignoriere Chat-Nachrichten" ::msgcat::mcset de "Ignore groupchat messages" "Ignoriere Konferenz-Nachrichten" ::msgcat::mcset de "Ignoring groupchat and chat messages from selected occupants of multi-user conference rooms." "Optionen für das Ignorieren von Konferenz- und Chat-Nachrichten ausgewählter Teilnehmer." ::msgcat::mcset de "MUC Ignore" "MUC-Ignorieren" ::msgcat::mcset de "MUC Ignore Rules" "MUC-Ignorieren-Regeln" ::msgcat::mcset de "When set, all changes to the ignore rules are applied only until Tkabber is closed\; they are not saved and thus will be not restored at the next run." "Wenn gesetzt, werden alle Änderungen an den Ignorieren-Regeln nur übernommen, bis Tkabber geschlossen wird. Sie werden nicht gespeichert und deshalb beim nächsten Start auch nicht wieder hergestellt." # .../plugins/chat/nick_colors.tcl ::msgcat::mcset de "Color message bodies in chat windows." "Farbige Nachrichten in Chat-Fenstern benutzen." ::msgcat::mcset de "Edit %s color" "%s Farbe ändern" ::msgcat::mcset de "Edit chat user colors" "Chatteilnehmer-Farben ändern" ::msgcat::mcset de "Edit nick color..." "Nicknamen-Farbe ändern..." ::msgcat::mcset de "Edit nick colors..." "Nicknamen-Farben ändern..." ::msgcat::mcset de "Use colored messages" "Farbige Nachrichten benutzen" ::msgcat::mcset de "Use colored nicks" "Farbige Nicknamen benutzen" ::msgcat::mcset de "Use colored nicks in chat windows." "Farbige Nicknamen in Chat-Fenstern benutzen." ::msgcat::mcset de "Use colored nicks in groupchat rosters." "Farbige Nicknamen in Konferenz-Rostern benutzen." ::msgcat::mcset de "Use colored roster nicks" "Farbige Roster-Nicknamen benutzen" # .../plugins/chat/popupmenu.tcl ::msgcat::mcset de "Clear bookmarks" "Lesezeichen entfernen" ::msgcat::mcset de "Copy selection to clipboard" "In Zwischenablage kopieren" ::msgcat::mcset de "Google selection" "Auswahl mit Google suchen" ::msgcat::mcset de "Next bookmark" "Nächstes Lesezeichen" ::msgcat::mcset de "Prev bookmark" "Vorheriges Lesezeichen" ::msgcat::mcset de "Set bookmark" "Lesezeichen setzen" # .../plugins/filetransfer/http.tcl ::msgcat::mcset de "Browse..." "Durchsuchen..." ::msgcat::mcset de "Can't receive file: %s" "Kann Datei nicht empfangen: %s" ::msgcat::mcset de "Description:" "Beschreibung:" ::msgcat::mcset de "Force advertising this hostname (or IP address) for outgoing HTTP file transfers." "Erzwinge die Angabe dieses Host-Namens (oder IP-Adresse) für ausgehende HTTP-Datei-Übertragungen." ::msgcat::mcset de "HTTP options." "Optionen für HTTP." ::msgcat::mcset de "IP address:" "IP-Adresse:" ::msgcat::mcset de "Port for outgoing HTTP file transfers (0 for assigned automatically). This is useful when sending files from behind a NAT with a forwarded port." "Port für ausgehende HTTP-Datei-Übertragungen (0 für automatische Zuweisung). Nützlich beim Datei-Versand von hinter einem NAT-Router mit weitergeleitetem Port." ::msgcat::mcset de "Receive" "Empfangen" ::msgcat::mcset de "Receive file from %s" "Empfange Datei von %s" ::msgcat::mcset de "Request failed: %s" "Anfrage misslungen: %s" ::msgcat::mcset de "Save as:" "Speichern als:" ::msgcat::mcset de "URL:" "URL:" # .../plugins/filetransfer/si.tcl ::msgcat::mcset de "Name:" "Name:" ::msgcat::mcset de "Receive error: Stream ID is in use" "Fehler beim Empfang: 'Stream'-ID wird bereits benutzt" ::msgcat::mcset de "Size:" "Größe:" ::msgcat::mcset de "Stream initiation options." "Optionen für 'Stream'-Initialisierung" ::msgcat::mcset de "Transfer failed: %s" "Übertragung misslungen: %s" ::msgcat::mcset de "Transferring..." "Übertrage . . ." # .../plugins/general/autoaway.tcl ::msgcat::mcset de "Automatically away due to idle" "Automatisch Abwesend wegen Leerlauf" ::msgcat::mcset de "Idle for %s" "Leerlauf seit %s" ::msgcat::mcset de "Idle threshold in minutes after that Tkabber marks you as away." "Leerlauf-Zeit (in Minuten), nach der Tkabber 'Abwesend' anzeigt." ::msgcat::mcset de "Idle threshold in minutes after that Tkabber marks you as extended away." "Leerlauf-Zeit (in Minuten), nach der Tkabber 'Länger abwesend' anzeigt." ::msgcat::mcset de "Moving to extended away" "Wechseln zu 'Länger abwesend'" ::msgcat::mcset de "Options for module that automatically marks you as away after idle threshold." "Optionen für das 'Automatisch-Abwesend'-Modul." ::msgcat::mcset de "Returning from auto-away" "Beende 'Automatisch-Abwesend'" ::msgcat::mcset de "Set priority to 0 when moving to extended away state." "Setze Priorität auf 0 beim Wechsel zu 'Länger abwesend'." ::msgcat::mcset de "Starting auto-away" "Starte 'Automatisch-Abwesend'" ::msgcat::mcset de "Text status, which is set when Tkabber is moving to away state." "Status-Text, der angezeigt wird, wenn Tkabber zu 'Abwesend' wechselt." # .../plugins/general/avatars.tcl ::msgcat::mcset de "Allow downloading" "Herunterladen erlauben" ::msgcat::mcset de "Announce" "Bekanntmachen" ::msgcat::mcset de "Avatar" "Avatar" ::msgcat::mcset de "No avatar to store" "Kein Avatar zu speichern" ::msgcat::mcset de "Send to server" "An Server senden" # .../plugins/general/caps.tcl ::msgcat::mcset de "Enable announcing entity capabilities in every outgoing presence." "Das Bekanntmachen von 'Entity Capabilities' in jeder ausgehenden Präsenz aktivieren." ::msgcat::mcset de "Options for entity capabilities plugin." "Optionen für das 'Entity Capabilities'-Plugin (XEP-0115)." ::msgcat::mcset de "Use the specified function to hash supported features list." "Das ausgewählte Prüfsummenverfahren für das 'hashen' der unterstützten Eigenschaften benutzen." # .../plugins/general/clientinfo.tcl ::msgcat::mcset de "\n\tClient: %s" "\n\tClient: %s" ::msgcat::mcset de "\n\tName: %s" "\n\tName: %s" ::msgcat::mcset de "\n\tOS: %s" "\n\tBetriebssystem: %s" # .../plugins/general/copy_jid.tcl ::msgcat::mcset de "Copy JID to clipboard" "JID in Zwischenablage kopieren" ::msgcat::mcset de "Copy real JID to clipboard" "Tatsächliche JID in Zwischenablage kopieren" # .../plugins/general/headlines.tcl ::msgcat::mcset de "%s Headlines" "%s Kopfzeilen" ::msgcat::mcset de "" "" ::msgcat::mcset de "Cache headlines on exit and restore on start." "Kopfzeilen beim Beenden zwischenspeichern und beim Start wiederherstellen." ::msgcat::mcset de "Copy URL to clipboard" "URL in Zwischenablage kopieren" ::msgcat::mcset de "Copy headline to clipboard" "Kopfzeile in Zwischenablage kopieren" ::msgcat::mcset de "Delete" "Löschen" ::msgcat::mcset de "Delete all" "Alle löschen" ::msgcat::mcset de "Delete seen" "Gesehene löschen" ::msgcat::mcset de "Display headlines in single/multiple windows." "Kopfzeilen in einem/mehreren Fenstern anzeigen." ::msgcat::mcset de "Do not display headline descriptions as tree nodes." "Kopfzeilen-Beschreibungen nicht als Baum anzeigen." ::msgcat::mcset de "Format of timestamp in headline tree view. Set to empty string if you don't want to see timestamps." "Format des Zeitstempels in der Kopfzeilen-Baumansicht (frei lassen, wenn keine Zeitstempel angezeigt werden sollen)." ::msgcat::mcset de "Forward headline" "Kopfzeile weiterleiten" ::msgcat::mcset de "Forward to %s" "Weiterleiten zu %s" ::msgcat::mcset de "Forward..." "Weiterleiten..." ::msgcat::mcset de "From:" "Von:" ::msgcat::mcset de "Headlines" "Kopfzeilen" ::msgcat::mcset de "List of JIDs to whom headlines have been sent." "Liste der JIDs, an die Kopfzeilen gesendet wurden." ::msgcat::mcset de "Mark all seen" "Alle als gesehen markieren" ::msgcat::mcset de "Mark all unseen" "Alle als ungesehen markieren" ::msgcat::mcset de "One window per bare JID" "Ein Fenster je blanker JID" ::msgcat::mcset de "One window per full JID" "Ein Fenster je voller JID" ::msgcat::mcset de "Read on..." "Weiterlesen..." ::msgcat::mcset de "Show balloons with headline messages over tree nodes." "Tooltips mit Kopfzeilen-Nachrichten über Baum-Knoten anzeigen." ::msgcat::mcset de "Single window" "Einzelnes Fenster" ::msgcat::mcset de "Sort" "Sortieren" ::msgcat::mcset de "Sort by date" "Nach Datum sortieren" ::msgcat::mcset de "Toggle seen" "Gesehen-Markierung umkehren" # .../plugins/general/ispell.tcl ::msgcat::mcset de "- nothing -" "- nichts -" ::msgcat::mcset de "Check spell after every entered symbol." "Überprüfe Rechtschreibung nach jedem eingegebenen Symbol." ::msgcat::mcset de "Could not start ispell server. Check your ispell path and dictionary name. Ispell is disabled now" "Der Ispell-Server konnte nicht gestartet werden. Bitte Ispell-Pfad und Wörterbuch-Namen überprüfen. Ispell ist jetzt deaktiviert." ::msgcat::mcset de "Enable spellchecker in text input windows." "Rechtschreibprüfung in Text-Eingabe-Fenstern aktivieren." ::msgcat::mcset de "Ispell dictionary encoding. If it is empty, system encoding is used." "Ispell Wörterbuch-Kodierung. Wenn nicht angegeben, wird die System-Kodierung benutzt." ::msgcat::mcset de "Path to the ispell executable." "Pfad zum Ispell-Programm." ::msgcat::mcset de "Spell check options." "Optionen für die Rechtschreibprüfung." ::msgcat::mcset de "Ispell options. See ispell manual for details.\n\nExamples:\n -d russian\n -d german -T latin1\n -C -d english" "Ispell-Optionen (für Details bitte die Ispell-Dokumentation lesen).\n\nBeispiele:\n -d russian\n -d german -T latin1 bzw. -d deutsch -T latin1\n -C -d english" # .../plugins/general/message_archive.tcl ::msgcat::mcset de "Dir" "<->" ::msgcat::mcset de "From/To" "Von/An" ::msgcat::mcset de "Messages" "Nachrichten-Archiv" ::msgcat::mcset de "Received/Sent" "Empfangen/Gesendet" ::msgcat::mcset de "To:" "An:" # .../plugins/general/offline.tcl ::msgcat::mcset de "Fetch all messages" "Alle Nachrichten abrufen" ::msgcat::mcset de "Fetch message" "Nachricht abrufen" ::msgcat::mcset de "Fetch unseen messages" "Ungesehene Nachrichten abrufen" ::msgcat::mcset de "Offline Messages" "Offline-Nachrichten" ::msgcat::mcset de "Purge all messages" "Alle Nachrichten beseitigen" ::msgcat::mcset de "Purge message" "Nachricht beseitigen" ::msgcat::mcset de "Purge seen messages" "Gesehene Nachrichten beseitigen" ::msgcat::mcset de "Retrieve offline messages using POP3-like protocol." "Offline-Nachrichten mittels POP3-ähnlichem Protokoll empfangen." ::msgcat::mcset de "Sort by from" "Nach Von sortieren" ::msgcat::mcset de "Sort by node" "Nach Knoten sortieren" ::msgcat::mcset de "Sort by type" "Nach Typ sortieren" # .../plugins/general/rawxml.tcl ::msgcat::mcset de "Available presence" "'Anwesend'-Präsenz" ::msgcat::mcset de "Chat message" "Chat-Nachricht" ::msgcat::mcset de "Clear" "Leeren" ::msgcat::mcset de "Create node" "Knoten erstellen" ::msgcat::mcset de "Generic IQ" "Allgemeine IQ" ::msgcat::mcset de "Get items" "Einträge erhalten" ::msgcat::mcset de "Headline message" "Kopfzeilen-Nachricht" ::msgcat::mcset de "IQ" "IQ" ::msgcat::mcset de "Indentation for pretty-printed XML subtags." "Einzug für optimierte (Pretty Print) XML-'Subtags'." ::msgcat::mcset de "Message" "Nachricht" ::msgcat::mcset de "Normal message" "Normale Nachricht" ::msgcat::mcset de "Not connected" "Nicht verbunden" ::msgcat::mcset de "Open raw XML window" "Original-XML öffnen" ::msgcat::mcset de "Options for Raw XML Input module, which allows you to monitor incoming/outgoing traffic from connection to server and send custom XML stanzas." "Optionen für das Original-XML Modul.\nDieses erlaubt die Betrachtung ein- und ausgehenden Datenverkehrs zum Server und das Senden spezifischer XML-'Stanzas'." ::msgcat::mcset de "Plugins options." "Optionen für Plugins." ::msgcat::mcset de "Pretty print XML" "XML-Ausgabe optimieren (Pretty Print)" ::msgcat::mcset de "Pretty print incoming and outgoing XML stanzas." "Ausgabe ein- und ausgehender XML-'Stanzas' optimieren (Pretty Print)." ::msgcat::mcset de "Pub/sub" "Pub/Sub" ::msgcat::mcset de "Publish node" "Knoten veröffentlichen" ::msgcat::mcset de "Raw XML" "Original-XML" ::msgcat::mcset de "Retract node" "Knoten widerrufen" ::msgcat::mcset de "Subscribe to a node" "Bei einem Knoten anmelden" ::msgcat::mcset de "Templates" "Vorlagen" ::msgcat::mcset de "Unavailable presence" "'Nicht verfügbar'-Präsenz" ::msgcat::mcset de "Unsubscribe from a node" "Bei einem Knoten abmelden" # .../plugins/general/remote.tcl ::msgcat::mcset de "Accept connections from my own JID." "Verbindungen von der eigenen JID akzeptieren." ::msgcat::mcset de "Accept connections from the listed JIDs." "Verbindungen von den aufgelisteten JIDs akzeptieren." ::msgcat::mcset de "All unread messages were forwarded to %s." "Alle ungelesenen Nachrichten wurden weitergeleitet an %s" ::msgcat::mcset de "Enable remote control." "Fernsteuerung aktivieren." ::msgcat::mcset de "Remote control options." "Optionen für die Fernsteuerung (Remote Control)." ::msgcat::mcset de "This message was forwarded to %s" "Diese Nachricht wurde weitergeleitet an %s" # .../plugins/general/session.tcl ::msgcat::mcset de "Load state on Tkabber start." "Status beim Start von Tkabber wiederherstellen." ::msgcat::mcset de "Load state on start" "Status beim Start wiederherstellen" ::msgcat::mcset de "Save state" "Status speichern" ::msgcat::mcset de "Save state on Tkabber exit." "Status beim Beenden von Tkabber speichern." ::msgcat::mcset de "Save state on exit" "Status beim Beenden speichern" ::msgcat::mcset de "State" "Status" ::msgcat::mcset de "Tkabber save state options." "Optionen für die Status-Speicherung." # .../plugins/general/sound.tcl ::msgcat::mcset de "External program, which is to be executed to play sound. If empty, Snack library is used (if available) to play sound." "Externes Programm, welches für die Wiedergabe von Klängen ausgeführt werden soll. Wenn nicht angegeben, wird die 'Snack'-Bibliothek benutzt (wenn vorhanden)." ::msgcat::mcset de "Mute sound" "Klänge unterdrücken" ::msgcat::mcset de "Mute sound if Tkabber window is focused." "Klänge unterdrücken, wenn Tkabber das aktive Fenster ist (den Fokus hat)." ::msgcat::mcset de "Mute sound notification." "Klang-Benachrichtigung unterdrücken." ::msgcat::mcset de "Mute sound when displaying delayed groupchat messages." "Klänge bei der Anzeige verzögerter Konferenz-Nachrichten unterdrücken." ::msgcat::mcset de "Mute sound when displaying delayed personal chat messages." "Klänge bei der Anzeige verzögerter persönlicher Chat-Nachrichten unterdrücken." ::msgcat::mcset de "Notify only when available" "Benachrichtigung nur wenn anwesend" ::msgcat::mcset de "Options for external play program" "Optionen für das externe Wiedergabe-Programm." ::msgcat::mcset de "Sound" "Klänge" ::msgcat::mcset de "Sound options." "Optionen für Klänge." ::msgcat::mcset de "Sound to play when available presence is received." "Wiederzugebender Klang bei Empfang einer 'Anwesend'-Präsenz." ::msgcat::mcset de "Sound to play when connected to Jabber server." "Wiederzugebender Klang bei Verbindung mit dem Jabber-Server." ::msgcat::mcset de "Sound to play when disconnected from Jabber server." "Wiederzugebender Klang bei Trennung vom Jabber-Server." ::msgcat::mcset de "Sound to play when groupchat message from me is received." "Wiederzugebender Klang bei Empfang einer eigenen Konferenz-Nachricht." ::msgcat::mcset de "Sound to play when groupchat message is received." "Wiederzugebender Klang bei Empfang einer Konferenz-Nachricht." ::msgcat::mcset de "Sound to play when groupchat server message is received." "Wiederzugebender Klang bei Empfang einer Konferenz-Server-Nachricht." ::msgcat::mcset de "Sound to play when highlighted (usually addressed personally) groupchat message is received." "Wiederzugebender Klang bei Empfang einer markierten (üblicherweise persönlich adressierten) Konferenz-Nachricht." ::msgcat::mcset de "Sound to play when personal chat message is received." "Wiederzugebender Klang bei Empfang einer persönlichen Chat-Nachricht." ::msgcat::mcset de "Sound to play when sending personal chat message." "Wiederzugebender Klang bei Sendung einer persönlichen Chat-Nachricht." ::msgcat::mcset de "Sound to play when unavailable presence is received." "Wiederzugebender Klang bei Empfang einer 'Nicht verfügbar'-Präsenz." ::msgcat::mcset de "Time interval before playing next sound (in milliseconds)." "Zeitraum bevor ein weiterer Klang abgespielt wird (in Millisekunden)." ::msgcat::mcset de "Use sound notification only when being available." "Klang-Benachrichtigung nur benutzen, wenn anwesend." # .../plugins/general/stats.tcl ::msgcat::mcset de "JID" "JID" ::msgcat::mcset de "Name " "Name" ::msgcat::mcset de "Node" "Knoten" ::msgcat::mcset de "Open statistics monitor" "Dienst-Statistik öffnen" ::msgcat::mcset de "Remove" "Entfernen" ::msgcat::mcset de "Request" "Abfragen" ::msgcat::mcset de "Service statistics" "Dienst-Statistik" ::msgcat::mcset de "Set" "Setzen" ::msgcat::mcset de "Statistics" "Dienst-Statistik" ::msgcat::mcset de "Statistics monitor" "Dienst-Statistik" ::msgcat::mcset de "Timer" "Intervall" ::msgcat::mcset de "Units" "Einheit" ::msgcat::mcset de "Value" "Anzahl" # .../plugins/general/subscribe_gateway.tcl ::msgcat::mcset de "Convert" "Konvertieren" ::msgcat::mcset de "Convert screenname" "Bildschirm-Namen konvertieren" ::msgcat::mcset de "Enter screenname of contact you want to add" "Den Bildschirm-Namen des hinzuzufügenden Kontakts eingeben" ::msgcat::mcset de "Error while converting screenname: %s." "Fehler beim Konvertieren des Bildschirm-Namens: %s" ::msgcat::mcset de "I would like to add you to my roster." "Ich würde Dich/Sie gerne in meine Kontaktliste aufnehmen.\nI would like to add you to my roster." ::msgcat::mcset de "Screenname conversion" "Bildschirm-Namen-Konvertierung" ::msgcat::mcset de "Screenname:" "Bildschirm-Name:" ::msgcat::mcset de "Screenname: %s\n\nConverted JID: %s" "Bildschirm-Name: %s\n\nKonvertierte JID: %s" ::msgcat::mcset de "Send subscription at %s" "Anmeldung an %s senden" ::msgcat::mcset de "Send subscription to: " "Anmeldung senden an:" ::msgcat::mcset de "Subscribe" "Anmelden" # .../plugins/general/tkcon.tcl ::msgcat::mcset de "Help" "Hilfe" ::msgcat::mcset de "Show TkCon console" "TkCon-Konsole anzeigen" # .../plugins/general/xaddress.tcl ::msgcat::mcset de "Blind carbon copy" "Blind Carbon Copy" ::msgcat::mcset de "Carbon copy" "Carbon Copy" ::msgcat::mcset de "Extended addressing fields:" "Erweiterte Adressfelder:" ::msgcat::mcset de "Forwarded by:" "Weitergeleitet von:" ::msgcat::mcset de "No reply" "Keine Antwort" ::msgcat::mcset de "Original from" "Original von" ::msgcat::mcset de "Original to" "Original an" ::msgcat::mcset de "Reply to" "Antwort an" ::msgcat::mcset de "Reply to room" "Antwort an Konferenz" ::msgcat::mcset de "This message was forwarded by %s\n" "Diese Nachricht wurde weitergeleitet von %s\n" ::msgcat::mcset de "This message was sent by %s\n" "Diese Nachricht wurde gesendet von %s\n" ::msgcat::mcset de "To" "An" # .../plugins/general/xcommands.tcl ::msgcat::mcset de "Commands" "Kommandos" ::msgcat::mcset de "Error completing command: %s" "Fehler bei der Vervollständigung des Kommandos: %s" ::msgcat::mcset de "Error executing command: %s" "Fehler bei der Ausführung des Kommandos: %s" ::msgcat::mcset de "Error:" "Fehler:" ::msgcat::mcset de "Execute command" "Kommando ausführen" ::msgcat::mcset de "Finish" "Fertigstellen" ::msgcat::mcset de "Info:" "Information:" ::msgcat::mcset de "Next" "Nächstes" ::msgcat::mcset de "Prev" "Vorheriges" ::msgcat::mcset de "Submit" "Abschicken" ::msgcat::mcset de "Warning:" "Warnung:" # .../plugins/iq/last.tcl ::msgcat::mcset de "Reply to idle time (jabber:iq:last) requests." "Antworte auf Leerlauf-Zeit-Anfragen (jabber:iq:last)." # .../plugins/iq/ping.tcl ::msgcat::mcset de "Ping server using urn:xmpp:ping requests." "Server mittels 'urn:xmpp:ping'-Anfragen anpingen." ::msgcat::mcset de "Reconnect to server if it does not reply (with result or with error) to ping (urn:xmpp:ping) request in specified time interval (in seconds)." "Erneut mit dem Server verbinden, wenn dieser nicht im angegebenem Zeitraum (mit Ergebnis oder Fehler) auf Ping-Anfragen (urn:xmpp:ping) antwortet (in Sekunden)." ::msgcat::mcset de "Reply to ping (urn:xmpp:ping) requests." "Antworte auf Ping-Anfragen (urn:xmpp:ping)." # .../plugins/iq/time.tcl ::msgcat::mcset de "Reply to current time (jabber:iq:time) requests." "Antworte auf Aktuelle-Zeit-Anfragen (jabber:iq:time)." # .../plugins/iq/time2.tcl ::msgcat::mcset de "Reply to entity time (urn:xmpp:time) requests." "Antworte auf 'Entity'-Zeit-Anfragen (urn:xmpp:time)." # .../plugins/iq/version.tcl ::msgcat::mcset de "Include operating system info into a reply to version (jabber:iq:version) requests." "Betriebssystem-Informationen zu Antworten auf Versions-Anfragen (jabber:iq:version) hinzufügen." ::msgcat::mcset de "Reply to version (jabber:iq:version) requests." "Antworte auf Versions-Anfragen (jabber:iq:version)." # .../plugins/pep/user_activity.tcl ::msgcat::mcset de "%s's activity changed to %s" "Aktivität für %s geändert in %s" ::msgcat::mcset de "%s's activity is unset" "Aktivität für %s ist nicht gesetzt" ::msgcat::mcset de "Activity" "Aktivität" ::msgcat::mcset de "Activity:" "Aktivität:" ::msgcat::mcset de "Auto-subscribe to other's user activity" "Kontakt-Aktivität Anderer automatisch abonnieren" ::msgcat::mcset de "Auto-subscribe to other's user activity notifications." "Benachrichtigungen über die Kontakt-Aktivitäten Anderer automatisch abonnieren." ::msgcat::mcset de "Cannot publish empty activity" "Unausgefüllte Aktivität kann nicht veröffentlicht werden" ::msgcat::mcset de "Error" "Fehler" ::msgcat::mcset de "Publish user activity..." "Eigene Kontakt-Aktivität veröffentlichen..." ::msgcat::mcset de "Unpublish user activity" "Eigene Kontakt-Aktivität zurückziehen" ::msgcat::mcset de "Unpublish user activity..." "Eigene Kontakt-Aktivität zurückziehen..." ::msgcat::mcset de "Subactivity" "Neben-Aktivität" ::msgcat::mcset de "Subactivity:" "Neben-Aktivität:" ::msgcat::mcset de "User activity" "Kontakt-Aktivität" ::msgcat::mcset de "User activity publishing failed: %s" "Veröffentlichen der Kontakt-Aktivität misslungen: %s" ::msgcat::mcset de "User activity unpublishing failed: %s" "Zurückziehen der Kontakt-Aktivität misslungen: %s" ::msgcat::mcset de "\n\tActivity: %s" "\n\tAktivität: %s" ::msgcat::mcset de "\n\tUser activity subscription: %s" "\n\tAktivitäts-Anmeldung des Kontakts: %s" ::msgcat::mcset de "doing chores" "Haushalt" ::msgcat::mcset de "buying groceries" "Lebensmittel kaufen" ::msgcat::mcset de "cleaning" "Putzen" ::msgcat::mcset de "cooking" "Kochen" ::msgcat::mcset de "doing maintenance" "Wartungsarbeiten" ::msgcat::mcset de "doing the dishes" "Geschirr spülen" ::msgcat::mcset de "doing the laundry" "Wäsche waschen" ::msgcat::mcset de "gardening" "Gartenarbeit" ::msgcat::mcset de "running an errand" "Besorgungen machen" ::msgcat::mcset de "walking the dog" "Hund spazierenführen" ::msgcat::mcset de "drinking" "Trinken" ::msgcat::mcset de "having a beer" "Bier trinken" ::msgcat::mcset de "having coffee" "Kaffee trinken" ::msgcat::mcset de "having tea" "Tee trinken" ::msgcat::mcset de "eating" "Essen" ::msgcat::mcset de "having a snack" "Zwischenmahlzeit" ::msgcat::mcset de "having breakfast" "Frühstück" ::msgcat::mcset de "having dinner" "Abendessen" ::msgcat::mcset de "having lunch" "Mittagessen" ::msgcat::mcset de "exercising" "Trainieren" ::msgcat::mcset de "cycling" "radfahren" ::msgcat::mcset de "hiking" "wandern" ::msgcat::mcset de "jogging" "joggen" ::msgcat::mcset de "playing sports" "Sport" ::msgcat::mcset de "running" "laufen" ::msgcat::mcset de "skiing" "skifahren" ::msgcat::mcset de "swimming" "schwimmen" ::msgcat::mcset de "working out" "abarbeiten" ::msgcat::mcset de "grooming" "Pflegen" ::msgcat::mcset de "at the spa" "in Kur" ::msgcat::mcset de "brushing teeth" "zähneputzen" ::msgcat::mcset de "getting a haircut" "haarschneiden" ::msgcat::mcset de "shaving" "rasieren" ::msgcat::mcset de "taking a bath" "baden" ::msgcat::mcset de "taking a shower" "duschen" ::msgcat::mcset de "having appointment" "Termin" ::msgcat::mcset de "inactive" "Inaktiv" ::msgcat::mcset de "day off" "freier Tag" ::msgcat::mcset de "hanging out" "abhängen" ::msgcat::mcset de "on vacation" "in Urlaub" ::msgcat::mcset de "scheduled holiday" "geplanter Urlaub" ::msgcat::mcset de "sleeping" "schlafen" ::msgcat::mcset de "relaxing" "Ausspannen" ::msgcat::mcset de "gaming" "spielen" ::msgcat::mcset de "going out" "ausgehen" ::msgcat::mcset de "partying" "feiern" ::msgcat::mcset de "reading" "lesen" ::msgcat::mcset de "rehearsing" "proben" ::msgcat::mcset de "shopping" "einkaufen" ::msgcat::mcset de "socializing" "Gesellschaft" ::msgcat::mcset de "sunbathing" "sonnen" ::msgcat::mcset de "watching tv" "Fernseh gucken" ::msgcat::mcset de "watching a movie" "Kinofilm gucken" ::msgcat::mcset de "talking" "Reden" ::msgcat::mcset de "in real life" "im richtigen Leben" ::msgcat::mcset de "on the phone" "am Telefon" ::msgcat::mcset de "on video phone" "am Bild-Telefon" ::msgcat::mcset de "traveling" "Reisen" ::msgcat::mcset de "commuting" "pendeln" ::msgcat::mcset de "driving" "fahren" ::msgcat::mcset de "in a car" "im Auto" ::msgcat::mcset de "on a bus" "im Bus" ::msgcat::mcset de "on a plane" "im Flugzeug" ::msgcat::mcset de "on a train" "im Zug" ::msgcat::mcset de "on a trip" "auf Ausflug" ::msgcat::mcset de "walking" "gehen" ::msgcat::mcset de "working" "Arbeiten" ::msgcat::mcset de "coding" "programmieren" ::msgcat::mcset de "in a meeting" "in Besprechung" ::msgcat::mcset de "studying" "studieren" ::msgcat::mcset de "writing" "schreiben" # .../plugins/pep/user_location.tcl ::msgcat::mcset de "%s's location changed to %s : %s" "%ss Standort geändert in %s : %s" ::msgcat::mcset de "%s's location is unset" "%ss Standort ist nicht gesetzt" ::msgcat::mcset de "Auto-subscribe to other's user location" "Kontakt-Standort Anderer automatisch abonnieren" ::msgcat::mcset de "Auto-subscribe to other's user location notifications." "Benachrichtigungen über die Kontakt-Standorte Anderer automatisch abonnieren." ::msgcat::mcset de "Publish user location..." "Eigenen Kontakt-Standort veröffentlichen..." ::msgcat::mcset de "Unpublish user location" "Eigenen Kontakt-Standort zurückziehen" ::msgcat::mcset de "Unpublish user location..." "Eigenen Kontakt-Standort zurückziehen..." ::msgcat::mcset de "User location" "Kontakt-Standort" ::msgcat::mcset de "User location publishing failed: %s" "Veröffentlichen des Kontakt-Standorts misslungen: %s" ::msgcat::mcset de "User location unpublishing failed: %s" "Zurückziehen des Kontakt-Standorts misslungen: %s" ::msgcat::mcset de "\n\tLocation: %s : %s" "\n\tStandort: %s : %s" ::msgcat::mcset de "\n\tUser location subscription: %s" "\n\tStandort-Anmeldung des Kontakts: %s" ::msgcat::mcset de "Altitude:" "Höhenlage:" ::msgcat::mcset de "Area:" "Gegend:" ::msgcat::mcset de "Bearing:" "Peilung:" ::msgcat::mcset de "Building:" "Gebäude:" ::msgcat::mcset de "Floor:" "Ebene:" ::msgcat::mcset de "GPS datum:" "GPS-Datum:" ::msgcat::mcset de "Horizontal GPS error:" "Horizontaler GPS-Fehler:" ::msgcat::mcset de "Locality:" "Örtlichkeit:" ::msgcat::mcset de "Postal code:" "Postleitzahl:" ::msgcat::mcset de "Region:" "Region:" ::msgcat::mcset de "Room:" "Raum:" ::msgcat::mcset de "Speed:" "Geschwindigkeit:" ::msgcat::mcset de "Street:" "Straße:" ::msgcat::mcset de "Timestamp:" "Zeitstempel:" # .../plugins/pep/user_mood.tcl ::msgcat::mcset de "%s's mood changed to %s" "%ss Gemütslage geändert in %s" ::msgcat::mcset de "%s's mood is unset" "%ss Gemütslage ist nicht gesetzt" ::msgcat::mcset de "Auto-subscribe to other's user mood" "Kontakt-Gemütslage Anderer automatisch abonnieren" ::msgcat::mcset de "Auto-subscribe to other's user mood notifications." "Benachrichtigungen über die Kontakt-Gemütslagen Anderer automatisch abonnieren." ::msgcat::mcset de "Cannot publish empty mood" "Unausgefüllte Gemütslage kann nicht veröffentlicht werden" ::msgcat::mcset de "Mood" "Gemütslage" ::msgcat::mcset de "Mood:" "Gemütslage:" ::msgcat::mcset de "Publish" "Veröffentlichen" ::msgcat::mcset de "Unpublish" "Zurückziehen" ::msgcat::mcset de "Publish user mood..." "Eigene Kontakt-Gemütslage veröffentlichen..." ::msgcat::mcset de "Unpublish user mood" "Eigene Kontakt-Gemütslage zurückziehen" ::msgcat::mcset de "Unpublish user mood..." "Eigene Kontakt-Gemütslage zurückziehen..." ::msgcat::mcset de "Publishing is only possible while being online" "Veröffentlichung nur möglich wenn 'Online'" ::msgcat::mcset de "Unpublishing is only possible while being online" "Zurückziehen nur möglich wenn 'Online'" ::msgcat::mcset de "Unsubscribe" "Abmelden/Zurückziehen" ::msgcat::mcset de "Use connection:" "Benutze Verbindung:" ::msgcat::mcset de "User mood" "Kontakt-Gemütslage" ::msgcat::mcset de "User mood publishing failed: %s" "Veröffentlichen der Kontakt-Gemütslage misslungen: %s" ::msgcat::mcset de "User mood unpublishing failed: %s" "Zurückziehen der Kontakt-Gemütslage misslungen: %s" ::msgcat::mcset de "\n\tMood: %s" "\n\tGemütslage: %s" ::msgcat::mcset de "\n\tUser mood subscription: %s" "\n\tGemütslagen-Anmeldung des Kontakts: %s" ::msgcat::mcset de "afraid" "ängstlich" ::msgcat::mcset de "amazed" "erstaunt" ::msgcat::mcset de "angry" "zornig" ::msgcat::mcset de "annoyed" "verärgert" ::msgcat::mcset de "anxious" "verunsichert" ::msgcat::mcset de "aroused" "aufgerüttelt" ::msgcat::mcset de "ashamed" "verschämt" ::msgcat::mcset de "bored" "gelangweilt" ::msgcat::mcset de "brave" "mutig" ::msgcat::mcset de "calm" "ruhig" ::msgcat::mcset de "cold" "kalt" ::msgcat::mcset de "confused" "verwirrt" ::msgcat::mcset de "contented" "zufrieden" ::msgcat::mcset de "cranky" "schrullig" ::msgcat::mcset de "curious" "merkwürdig" ::msgcat::mcset de "depressed" "deprimiert" ::msgcat::mcset de "disappointed" "enttäuscht" ::msgcat::mcset de "disgusted" "angewidert" ::msgcat::mcset de "distracted" "abgelenkt" ::msgcat::mcset de "embarrassed" "geniert" ::msgcat::mcset de "excited" "aufgeregt" ::msgcat::mcset de "flirtatious" "kokett" ::msgcat::mcset de "frustrated" "frustriert" ::msgcat::mcset de "grumpy" "knurrig" ::msgcat::mcset de "guilty" "schuldig" ::msgcat::mcset de "happy" "glücklich" ::msgcat::mcset de "hot" "heiß" ::msgcat::mcset de "humbled" "gedemütigt" ::msgcat::mcset de "humiliated" "erniedrigt" ::msgcat::mcset de "hungry" "hungrig" ::msgcat::mcset de "hurt" "verletzt" ::msgcat::mcset de "impressed" "beeindruckt" ::msgcat::mcset de "in_awe" "scheu" ::msgcat::mcset de "in_love" "verliebt" ::msgcat::mcset de "indignant" "empört" ::msgcat::mcset de "interested" "interessiert" ::msgcat::mcset de "intoxicated" "berauscht" ::msgcat::mcset de "invincible" "unbesiegbar" ::msgcat::mcset de "jealous" "eifersüchtig" ::msgcat::mcset de "lonely" "einsam" ::msgcat::mcset de "mean" "kleinlich" ::msgcat::mcset de "moody" "launisch" ::msgcat::mcset de "nervous" "nervös" ::msgcat::mcset de "neutral" "neutral" ::msgcat::mcset de "offended" "beleidigt" ::msgcat::mcset de "playful" "verspielt" ::msgcat::mcset de "proud" "stolz" ::msgcat::mcset de "relieved" "erleichtert" ::msgcat::mcset de "remorseful" "reumütig" ::msgcat::mcset de "restless" "rastlos" ::msgcat::mcset de "sad" "traurig" ::msgcat::mcset de "sarcastic" "sarkastisch" ::msgcat::mcset de "serious" "ernsthaft" ::msgcat::mcset de "shocked" "schockiert" ::msgcat::mcset de "shy" "schüchtern" ::msgcat::mcset de "sick" "krank" ::msgcat::mcset de "sleepy" "schläfrig" ::msgcat::mcset de "stressed" "gestresst" ::msgcat::mcset de "surprised" "überrascht" ::msgcat::mcset de "thirsty" "durstig" ::msgcat::mcset de "worried" "besorgt" # .../plugins/pep/user_tune.tcl ::msgcat::mcset de "%s's tune changed to %s - %s" "%ss Musik geändert in %s - %s" ::msgcat::mcset de "%s's tune is unset" "%ss Musik ist nicht gesetzt" ::msgcat::mcset de "%s's tune has stopped playing" "%ss Musik wurde angehalten" ::msgcat::mcset de "Artist:" "Interpret:" ::msgcat::mcset de "Auto-subscribe to other's user tune" "Kontakt-Musik Anderer automatisch abonnieren" ::msgcat::mcset de "Auto-subscribe to other's user tune notifications." "Benachrichtigungen über die Kontakt-Musik Anderer automatisch abonnieren." ::msgcat::mcset de "Length:" "Länge:" ::msgcat::mcset de "Publish \"playback stopped\" instead" "Stattdessen \"Wiedergabe angehalten\" veröffentlichen" ::msgcat::mcset de "Publish user tune..." "Eigene Kontakt-Musik veröffentlichen..." ::msgcat::mcset de "Unpublish user tune" "Eigene Kontakt-Musik zurückziehen" ::msgcat::mcset de "Unpublish user tune..." "Eigene Kontakt-Musik zurückziehen..." ::msgcat::mcset de "Rating:" "Bewertung:" ::msgcat::mcset de "Source:" "Quelle:" ::msgcat::mcset de "Track:" "Index:" ::msgcat::mcset de "URI:" "URI:" ::msgcat::mcset de "User tune" "Kontakt-Musik" ::msgcat::mcset de "User tune publishing failed: %s" "Veröffentlichen der Kontakt-Musik misslungen: %s" ::msgcat::mcset de "User tune unpublishing failed: %s" "Zurückziehen der Kontakt-Musik misslungen: %s" ::msgcat::mcset de "\n\tTune: %s - %s" "\n\tMusik: %s - %s" ::msgcat::mcset de "\n\tUser tune subscription: %s" "\n\tMusik-Anmeldung des Kontakts: %s" # .../plugins/richtext/emoticons.tcl ::msgcat::mcset de "Handle ROTFL/LOL smileys -- those like :))) -- by \"consuming\" all that parens and rendering the whole word with appropriate icon." "ROTFL/LOL Smileys, wie z. B. :-))), derart behandeln, daß alle Paare entfernt werden und das Ganze mit dem zugehörigen Icon dargestellt wird." ::msgcat::mcset de "Handling of \"emoticons\". Emoticons (also known as \"smileys\") are small pictures resembling a human face used to represent user's emotion. They are typed in as special mnemonics like :) or can be inserted using menu." "Optionen für die Behandlung von Emoticons.\n'Emoticons' (auch als 'Smileys' bekannt) sind kleine, einem menschlichen Gesicht gleichende Bilder, die die Emotionen des Kontakts repräsentieren sollen. Sie werden mit einer speziellen Mnemonik wie z. B. :-) oder über ein Menü eingegeben." ::msgcat::mcset de "Show images for emoticons." "Bilder für Emoticons anzeigen." ::msgcat::mcset de "Tkabber emoticons theme. To make new theme visible for Tkabber put it to some subdirectory of %s." "Tkabber Emoticon-Thema. Um es für Tkabber sichtbar zu machen, muß es in einem Unterordner von %s platziert werden." ::msgcat::mcset de "Use only whole words for emoticons." "Nur ganze Wörter als Emoticons benutzen." # .../plugins/richtext/highlight.tcl ::msgcat::mcset de "Enable highlighting plugin." "Markierungs-Plugin aktivieren." ::msgcat::mcset de "Groupchat message highlighting plugin options." "Optionen für das Konferenz-Nachrichten Markierungs-Plugin." ::msgcat::mcset de "Highlight current nickname in messages." "Derzeitigen Nicknamen in Nachrichten markieren." ::msgcat::mcset de "Highlight only whole words in messages." "Nur ganze Wörter in Nachrichten markieren." ::msgcat::mcset de "Substrings to highlight in messages." "Teil-Zeichenfolgen, die in Nachrichten markiert werden sollen." # .../plugins/richtext/stylecodes.tcl ::msgcat::mcset de "Emphasize stylecoded messages using different fonts." "'Style'-kodierte Nachrichten durch die Benutzung unterschiedlicher Schriften hervorheben." ::msgcat::mcset de "Handling of \"stylecodes\". Stylecodes are (groups of) special formatting symbols used to emphasize parts of the text by setting them with boldface, italics or underlined styles, or as combinations of these." "Optionen für die Behandlung von Style-Kodierungen.\n'Style'-Kodierungen sind spezielle Formatierungs-Symbole, die dazu benutzt werden, Teile eines Textes durch Fett-, Schrägschrift, Unterstreichung, oder einer Kombination davon, hervorzuheben." ::msgcat::mcset de "Hide characters comprising stylecode markup." "Style-Kodierungs-Markups verbergen." # .../plugins/roster/annotations.tcl ::msgcat::mcset de "Created: %s" "Erstellt: %s" ::msgcat::mcset de "Edit item notes..." "Eintrags-Notizen ändern..." ::msgcat::mcset de "Edit roster notes for %s" "Roster-Notizen ändern für %s" ::msgcat::mcset de "Modified: %s" "Geändert: %s" ::msgcat::mcset de "Notes" "Notizen" ::msgcat::mcset de "Roster Notes" "Roster-Notizen" ::msgcat::mcset de "Store" "Sichern" ::msgcat::mcset de "Storing roster notes failed: %s" "Sichern der Roster-Notizen misslungen: %s" # .../plugins/roster/backup.tcl ::msgcat::mcset de "Error restoring roster contacts: %s" "Fehler bei der Wiederherstellung der Roster-Kontakte: %s" ::msgcat::mcset de "Roster restoration completed" "Roster-Wiederherstellung abgeschlossen" # .../plugins/roster/bkup_annotations.tcl ::msgcat::mcset de "Error restoring annotations: %s" "Fehler bei der Wiederherstellung der Roster-Notizen: %s" # .../plugins/roster/bkup_conferences.tcl ::msgcat::mcset de "Error restoring conference bookmarks: %s" "Fehler bei der Wiederherstellung der Konferenz-Lesezeichen: %s" # .../plugins/roster/cache_categories.tcl ::msgcat::mcset de "Cached service categories and types (from disco#info)." "Zwischengespeicherte Dienst-Kategorien und -Typen (von disco#info)." # .../plugins/roster/conferenceinfo.tcl ::msgcat::mcset de "Interval (in minutes) after error reply on request of participants list." "Wartezeit nach einer Fehler-Antwort auf Abfragen der Teilnehmer-Listen (in Minuten)." ::msgcat::mcset de "Interval (in minutes) between requests of participants list." "Zeitraum zwischen den Abfragen der Teilnehmer-Listen (in Minuten)." ::msgcat::mcset de "Options for Conference Info module, that allows you to see list of participants in roster popup, regardless of whether you are currently joined with the conference." "Optionen für das Konferenz-Informations Modul.\nDieses erlaubt, die Liste der Konferenz-Teilnehmer im zugehörigen Eintrags-Tooltip einzusehen, unabhängig davon, ob man der Konferenz derzeit beiwohnt oder nicht." ::msgcat::mcset de "Periodically browse roster conferences" "Konferenzen regelmäßig durchsuchen" ::msgcat::mcset de "Use this module" "Dieses Modul benutzen." ::msgcat::mcset de "\nRoom is empty at %s" "\nKonferenz-Raum ist leer um %s" ::msgcat::mcset de "\nRoom participants at %s:" "\nKonferenz-Teilnehmer um %s:" ::msgcat::mcset de "\n\tCan't browse: %s" "\n\tDurchsuchen misslungen: %s" # .../plugins/roster/conferences.tcl ::msgcat::mcset de "Add" "Hinzufügen" ::msgcat::mcset de "Add Conference to Roster" "Konferenz zu Roster hinzufügen" ::msgcat::mcset de "Add conference to roster..." "Konferenz zu Roster hinzufügen..." ::msgcat::mcset de "Automatically join conference upon connect" "Konferenz bei Verbindung automatisch beitreten" ::msgcat::mcset de "Conference:" "Konferenz:" ::msgcat::mcset de "Conferences" "Konferenzen" ::msgcat::mcset de "Edit properties for %s" "Eigenschaften ändern für %s" ::msgcat::mcset de "Join..." "Beitreten..." ::msgcat::mcset de "Name: " "Name:" ::msgcat::mcset de "Roster group:" "Roster-Gruppe:" ::msgcat::mcset de "Storing conferences failed: %s" "Sichern der Konferenzen misslungen: %s" # .../plugins/roster/fetch_nicknames.tcl ::msgcat::mcset de "Fetch nickname" "Nicknamen abrufen" ::msgcat::mcset de "Fetch user nicknames" "Kontakt-Nicknamen abrufen" ::msgcat::mcset de "Fetch nicknames of all users in group" "Nicknamen von allen Kontakten der Gruppe abrufen" # .../plugins/roster/rosterx.tcl ::msgcat::mcset de "Attached user:" "Angehängter Kontakt:" ::msgcat::mcset de "Contact Information" "Kontakt-Informationen" ::msgcat::mcset de "No users in roster..." "Keine Kontakte im Roster..." ::msgcat::mcset de "Send" "Senden" ::msgcat::mcset de "Send contacts to %s" "Kontakte an %s senden" ::msgcat::mcset de "Send users..." "Kontakte senden..." # .../plugins/search/rawxml.tcl ::msgcat::mcset de "Search down" "Abwärts suchen" ::msgcat::mcset de "Search up" "Aufwärts suchen" # .../plugins/search/search.tcl ::msgcat::mcset de "Match case while searching in chat, log or disco windows." "Groß-/Kleinschreibung bei der Suche in Chat-, Log- oder Discovery-Fenstern beachten." ::msgcat::mcset de "Search in Tkabber windows options." "Optionen für die Suche in Tkabber-Fenstern." ::msgcat::mcset de "Specifies search mode while searching in chat, log or disco windows. \"substring\" searches exact substring, \"glob\" uses glob style matching, \"regexp\" allows to match regular expression." "Gibt den Modus beim Suchen in Chat-, Log- oder Discovery-Fenstern vor. 'substring' sucht eine exakte Teil-Zeichenfolge, 'glob' benutzt 'global style pattern matching', 'regexp' erlaubt die Verwendung Regulärer Ausdrücke." # .../plugins/si/ibb.tcl ::msgcat::mcset de "Opening IBB connection" "Öffne IBB-Verbindung" # .../plugins/si/iqibb.tcl ::msgcat::mcset de "Opening IQ-IBB connection" "Öffne IQ-IBB Verbindung" # .../plugins/si/socks5.tcl ::msgcat::mcset de "Cannot connect to proxy" "Proxy-Verbindung misslungen" ::msgcat::mcset de "Cannot negotiate proxy connection" "Proxy-Verhandlung misslungen" ::msgcat::mcset de "Illegal result" "Unzulässiges Ergebnis" ::msgcat::mcset de "List of proxy servers for SOCKS5 bytestreams (all available servers will be tried for mediated connection)." "Liste von Proxy-Servern für SOCKS5-'bytestreams' (alle verfügbaren Server werden für vermittelte Verbindungen überprüft)." ::msgcat::mcset de "Opening SOCKS5 listening socket" "Öffne SOCKS5-'Listening-Socket'" ::msgcat::mcset de "Use mediated SOCKS5 connection if proxy is available." "Vermittelte SOCKS5-Verbindung benutzen, wenn Proxy verfügbar ist." # .../plugins/unix/dockingtray.tcl ::msgcat::mcset de "Enable KDE tray icon." "KDE Tray-Icon aktivivieren." # .../plugins/unix/systray.tcl ::msgcat::mcset de "Enable freedesktop systray icon." "freedesktop SysTray-Icon aktivivieren." # .../plugins/unix/tktray.tcl ::msgcat::mcset de "Enable freedesktop system tray icon." "freedesktop SysTray-Icon aktivivieren." # .../plugins/unix/wmdock.tcl ::msgcat::mcset de "%s is %s" "%s ist %s" ::msgcat::mcset de "%s msgs" "%s Nachrichten" ::msgcat::mcset de "Message from %s" "Nachricht von %s" # .../plugins/windows/console.tcl ::msgcat::mcset de "Show console" "Konsole anzeigen" # .../plugins/windows/taskbar.tcl ::msgcat::mcset de "Enable windows tray icon." "Windows SysTray-Icon aktivieren." tkabber-0.11.1/msgs/ru.msg0000644000175000017500000045242511073733523014651 0ustar sergeisergei# $Id: ru.msg 1507 2008-10-10 20:13:07Z sergei $ # # Russian messages file # Started by: Sergey Kalinin (aka BanZaj) # Maintained by: Sergei Golovan # #================================================================== ::msgcat::mcset ru "\n\tActivity: %s" "\n\tЗанÑтие: %s" ::msgcat::mcset ru "\n\tAffiliation: %s" "\n\tРанг: %s" ::msgcat::mcset ru "\n\tCan't browse: %s" "\n\tПроÑмотреть не удалоÑÑŒ: %s" ::msgcat::mcset ru "\n\tClient: %s" "\n\tКлиент: %s" ::msgcat::mcset ru "\n\tLocation: %s : %s" "\n\tМеÑтонахождение: %s : %s" ::msgcat::mcset ru "\n\tMood: %s" "\n\tСоÑтоÑние: %s" ::msgcat::mcset ru "\n\tName: %s" "\n\tИмÑ: %s" ::msgcat::mcset ru "\n\tOS: %s" "\n\tОС: %s" ::msgcat::mcset ru "\n\tPresence is signed:" "\n\tПриÑутÑтвие подпиÑано:" ::msgcat::mcset ru "\n\tTune: %s - %s" "\n\tМелодиÑ: %s - %s" ::msgcat::mcset ru "\n\tUser activity subscription: %s" "\n\tПодпиÑка на\ занÑтие пользователÑ: %s" ::msgcat::mcset ru "\n\tUser location subscription: %s" "\n\tПодпиÑка на\ меÑтонахождение пользователÑ: %s" ::msgcat::mcset ru "\n\tUser mood subscription: %s" "\n\tПодпиÑка на\ ÑоÑтоÑние пользователÑ: %s" ::msgcat::mcset ru "\n\tUser tune subscription: %s" "\n\tПодпиÑка на\ мелодию пользователÑ: %s" ::msgcat::mcset ru "\nAlternative venue: %s" "\nÐльтернативное меÑто Ñбора:\ %s" ::msgcat::mcset ru "\nReason is: %s" "\nРезон: %s" ::msgcat::mcset ru "\nReason: %s" "\nРезон: %s" ::msgcat::mcset ru "\nRoom is empty at %s" "\nКомната пуÑта на %s" ::msgcat::mcset ru "\nRoom participants at %s:" "\nУчаÑтники конференции на\ %s:" ::msgcat::mcset ru " by " " " ::msgcat::mcset ru " by %s" " (Ñто Ñделал(а) %s)" ::msgcat::mcset ru "#" "â„–" ::msgcat::mcset ru "%s has activated chat window" "%s активировал окно\ разговора" ::msgcat::mcset ru "%s has been assigned a new affiliation: %s" "%s приÑвоен\ ранг: %s" ::msgcat::mcset ru "%s has been assigned a new role: %s" "%s получил роль:\ %s" ::msgcat::mcset ru "%s has been assigned a new room position: %s/%s" "%s\ занимает положение: %s/%s" ::msgcat::mcset ru "%s has been banned" "%s запретили входить в комнату" ::msgcat::mcset ru "%s has been kicked" "%s выгнали из комнаты" ::msgcat::mcset ru "%s has been kicked because of membership loss" "%s\ выгнали из комнаты в результате потери членÑтва" ::msgcat::mcset ru "%s has been kicked because room became members-only" "%s\ выгнали из комнаты, потому что она Ñтала только Ð´Ð»Ñ Ñ‡Ð»ÐµÐ½Ð¾Ð²" ::msgcat::mcset ru "%s has changed nick to %s." "%s Ñменил пÑевдоним на %s." ::msgcat::mcset ru "%s has entered" "%s вошёл(а) в комнату" ::msgcat::mcset ru "%s has gone chat window" "%s закрыл окно разговора" ::msgcat::mcset ru "%s has inactivated chat window" "%s деактивировал окно\ разговора" ::msgcat::mcset ru "%s has left" "%s вышел(а) из комнаты" ::msgcat::mcset ru "%s Headlines" "%s новоÑти" ::msgcat::mcset ru "%s info" "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ %s" ::msgcat::mcset ru "%s invites you to conference room %s" "%s приглашает ВаÑ\ в конференцию %s" ::msgcat::mcset ru "%s is %s" "%s теперь %s" ::msgcat::mcset ru "%s is composing a reply" "%s пишет ответ" ::msgcat::mcset ru "%s is now known as %s" "%s изменил(а) Ð¸Ð¼Ñ Ð½Ð° %s" ::msgcat::mcset ru "%s is paused a reply" "%s оÑтановилÑÑ, Ð½Ð°Ð±Ð¸Ñ€Ð°Ñ Ð¾Ñ‚Ð²ÐµÑ‚" ::msgcat::mcset ru "%s msgs" "%s Ñообщ." ::msgcat::mcset ru "%s plugin" "раÑширение %s" ::msgcat::mcset ru "%s purportedly signed by %s can't be verified.\n\n%s."\ "То, что %s подпиÑано %s, невозможно проверить.\n\n%s." ::msgcat::mcset ru "%s request from %s" "Ð—Ð°Ð¿Ñ€Ð¾Ñ %s от %s" ::msgcat::mcset ru "%s SSL Certificate Info" "СвойÑтва Ñертификата SSL\ Ñервера %s" ::msgcat::mcset ru "%s's activity changed to %s" "Пользователь %s занÑÑ‚:\ \"%s\"" ::msgcat::mcset ru "%s's activity is unset" "Пользователь %s отозвал\ публикацию Ñвоего занÑтиÑ" ::msgcat::mcset ru "%s's location changed to %s : %s" "МеÑтонахождение %s\ изменилоÑÑŒ на %s : %s" ::msgcat::mcset ru "%s's location is unset" "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ меÑтонахождении %s\ удалена" ::msgcat::mcset ru "%s's mood changed to %s" "СоÑтоÑние %s изменилоÑÑŒ на %s" ::msgcat::mcset ru "%s's mood is unset" "Пользователь %s отозвал публикацию\ Ñвоего ÑоÑтоÑниÑ" ::msgcat::mcset ru "%s's tune changed to %s - %s" "ÐœÐµÐ»Ð¾Ð´Ð¸Ñ %s изменилаÑÑŒ на\ %s - %s" ::msgcat::mcset ru "%s's tune has stopped playing" "ÐœÐµÐ»Ð¾Ð´Ð¸Ñ %s оÑтановлена." ::msgcat::mcset ru "%s's tune is unset" "Пользователь %s отозвал публикацию\ Ñвоей мелодии" ::msgcat::mcset ru "%s: %s/%s, Description: %s, Version: %s\nNumber of\ children: %s" "%s: %s/%s, ОпиÑание: %s, ВерÑиÑ: %s\nЧиÑло ветвей: %s" ::msgcat::mcset ru "&Help" "&Помощь" ::msgcat::mcset ru "&Services" "&Службы" ::msgcat::mcset ru "- nothing -" "- нет вариантов -" ::msgcat::mcset ru ". Proceed?\n\n" ". Продолжить?\n\n" ::msgcat::mcset ru "/me has set the subject to: %s" "/me уÑтановил(а) тему в:\ %s" ::msgcat::mcset ru "<- Remove" "<- Удалить" ::msgcat::mcset ru "" "<нет>" ::msgcat::mcset ru ">>> Unable to decipher data: %s <<<" ">>> Ðе удалоÑÑŒ\ раÑшифровать данные: %s <<<" ::msgcat::mcset ru "A new room is created" "Создана Ð½Ð¾Ð²Ð°Ñ ÐºÐ¾Ð½Ñ„ÐµÑ€ÐµÐ½Ñ†Ð¸Ñ" ::msgcat::mcset ru "Abbreviations:" "СокращениÑ:" ::msgcat::mcset ru "Aborted" "Прервано" ::msgcat::mcset ru "About" "О программе" ::msgcat::mcset ru "About " "О Ñебе" ::msgcat::mcset ru "Accept connections from my own JID." "Принимать\ подключение Ñ Ð¼Ð¾ÐµÐ³Ð¾ ÑобÑтвенного JID." ::msgcat::mcset ru "Accept connections from the listed JIDs." "Принимать\ подключение Ñ Ð¿ÐµÑ€ÐµÑ‡Ð¸Ñленных JID'Ñ‹." ::msgcat::mcset ru "Accept default config" "ПринÑть конфигурацию по\ умолчанию" ::msgcat::mcset ru "Accept messages from roster users only" "Принимать\ ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ из контактов" ::msgcat::mcset ru "Access Error" "Ошибка доÑтупа" ::msgcat::mcset ru "Account" "Ð£Ñ‡Ñ‘Ñ‚Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ" ::msgcat::mcset ru "Action" "ДейÑтвие" ::msgcat::mcset ru "Activate lists at startup" "Ðктивировать ÑпиÑки при\ подключении" ::msgcat::mcset ru "Activate search panel" "Открыть панель поиÑка" ::msgcat::mcset ru "Activate visible/invisible/ignore/conference lists before\ sending initial presence." "Ðктивировать\ видимый/невидимый/игнорируемый ÑпиÑки (и ÑпиÑок конференций) перед\ тем, как объÑвлÑть о Ñвоём приÑутÑтвии в Ñети." ::msgcat::mcset ru "Activating privacy list failed: %s\n\nTry to reconnect.\ If problem persists, you may want to disable privacy list activation\ at start" "Ðе удалоÑÑŒ активировать ÑпиÑок приватноÑти:\ %s\n\nПопытайтеÑÑŒ подключитьÑÑ Ñнова. ЕÑли проблема оÑтаётÑÑ,\ возможно придётÑÑ Ð¾Ñ‚ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒ активацию ÑпиÑков приватноÑти при Ñтарте" ::msgcat::mcset ru "Active" "Ðктивный" ::msgcat::mcset ru "Active Chats" "Открытые разговоры" ::msgcat::mcset ru "Activity" "ЗанÑтие" ::msgcat::mcset ru "Activity:" "ЗанÑтие:" ::msgcat::mcset ru "Add" "Добавить" ::msgcat::mcset ru "Add ->" "Добавить ->" ::msgcat::mcset ru "Add chats group in roster." "ДобавлÑть в контакты группу\ открытых разговоров." ::msgcat::mcset ru "Add Conference to Roster" "Добавление конференции в\ контакты" ::msgcat::mcset ru "Add conference to roster..." "Добавить конференцию в\ контакты..." ::msgcat::mcset ru "Add conference..." "Добавить конференцию..." ::msgcat::mcset ru "Add group by regexp on JIDs..." "Добавить группу по\ регулÑрному выражению Ð´Ð»Ñ JID..." ::msgcat::mcset ru "Add item" "Добавить Ñлемент" ::msgcat::mcset ru "Add JID" "Добавить JID" ::msgcat::mcset ru "Add list" "Добавить ÑпиÑок" ::msgcat::mcset ru "Add new item" "Добавить новый Ñлемент" ::msgcat::mcset ru "Add new user..." "Добавить нового пользователÑ..." ::msgcat::mcset ru "Add roster group by JID regexp" "Добавить группу по\ регулÑрному выражению Ð´Ð»Ñ JID" ::msgcat::mcset ru "Add user to roster..." "Добавить Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð²\ контакты..." ::msgcat::mcset ru "Add user..." "Добавить пользователÑ..." ::msgcat::mcset ru "Added abbreviation:\n%s: %s" "Добавлено Ñокращение:\n%s:\ %s" ::msgcat::mcset ru "Address" "ÐдреÑ" ::msgcat::mcset ru "Address 2" "ÐÐ´Ñ€ÐµÑ 2" ::msgcat::mcset ru "Address 2:" "ÐÐ´Ñ€ÐµÑ 2:" ::msgcat::mcset ru "Address Error" "Ошибка адреÑа" ::msgcat::mcset ru "Address type not supported by SOCKS proxy" "Тип адреÑа не\ поддерживаетÑÑ SOCKS5 прокÑи" ::msgcat::mcset ru "Address:" "ÐдреÑ:" ::msgcat::mcset ru "admin" "админ" ::msgcat::mcset ru "Admin tools" "ИнÑтрументы админиÑтратора" ::msgcat::mcset ru "Affiliation" "Ранг" ::msgcat::mcset ru "afraid" "иÑпуганное" ::msgcat::mcset ru "Alexey Shchepin" "ÐлекÑей Щепин" ::msgcat::mcset ru "All" "Ð’Ñе" ::msgcat::mcset ru "All Files" "Ð’Ñе файлы" ::msgcat::mcset ru "All files" "Ð’Ñе файлы" ::msgcat::mcset ru "All items:" "Добавить Ñлементы:" ::msgcat::mcset ru "All unread messages were forwarded to %s." "Ð’Ñе\ непрочитанные ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð±Ñ‹Ð»Ð¸ переÑланы %s." ::msgcat::mcset ru "Allow downloading" "Разрешение загрузки" ::msgcat::mcset ru "Allow plaintext authentication mechanisms" "Разрешить\ механизмы аутентификации, иÑпользующие открытый текÑÑ‚" ::msgcat::mcset ru "Allow plaintext authentication mechanisms (when password\ is transmitted unencrypted)." "Разрешить механизмы аутентификации,\ иÑпользующие открытый текÑÑ‚ (при Ñтом пароль передаетÑÑ\ незашифрованным)." ::msgcat::mcset ru "Allow X-GOOGLE-TOKEN authentication mechanisms. It\ requires connection to Google via HTTPS." "Разрешить иÑпользование\ механизма аутентификации X-GOOGLE-TOKEN. Ð”Ð»Ñ Ñтого требуетÑÑ Ð¸Ð¼ÐµÑ‚ÑŒ\ возможноÑть ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ñ Google Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ HTTPS." ::msgcat::mcset ru "Allow X-GOOGLE-TOKEN SASL mechanism" "Разрешить механизм\ SASL X-GOOGLE-TOKEN" ::msgcat::mcset ru "Altitude:" "Ð’Ñ‹Ñота:" ::msgcat::mcset ru "amazed" "изумлённое" ::msgcat::mcset ru "An error occurred when searching in %s\n\n%s" "Возникла\ ошибка при поиÑке в %s\n\n%s" ::msgcat::mcset ru "and" "и" ::msgcat::mcset ru "angry" "раÑÑерженное" ::msgcat::mcset ru "Announce" "ОбъÑвление" ::msgcat::mcset ru "annoyed" "раздражённое" ::msgcat::mcset ru "anxious" "беÑпокойное" ::msgcat::mcset ru "Application Error" "Ошибка приложениÑ" ::msgcat::mcset ru "Approve subscription" "Утвердить подпиÑку" ::msgcat::mcset ru "April" "Ðпрель" ::msgcat::mcset ru "Are you sure to remove %s from roster?" "Ð’Ñ‹ дейÑтвительно\ хотите удалить %s из контактов?" ::msgcat::mcset ru "Are you sure to remove all users in group '%s' from\ roster? \n(Users which are in another groups too, will not be removed\ from the roster.)" "Ð’Ñ‹ дейÑтвительно хотите удалить вÑех, входÑщих в\ группу '%s', из контактов? \n(Контакты, которые еÑть не только в Ñтой\ группе, не удалÑÑŽÑ‚ÑÑ.)" ::msgcat::mcset ru "Are you sure to remove group '%s' from roster?" "Удалить\ группу '%s' из контактов?" ::msgcat::mcset ru "Are you sure to remove group '%s' from roster? \n(Users\ which are in this group only, will be in undefined group.)" "Ð’Ñ‹\ дейÑтвительно хотите удалить группу '%s' из контактов? \n(Контакты,\ которые еÑть только в Ñтой группе, окажутÑÑ Ð±ÐµÐ· группы.)" ::msgcat::mcset ru "Area:" "МеÑто:" ::msgcat::mcset ru "aroused" "возбуждённое" ::msgcat::mcset ru "Artist:" "ИÑполнитель:" ::msgcat::mcset ru "as %s/%s" "как %s/%s" ::msgcat::mcset ru "ashamed" "приÑтыжённое" ::msgcat::mcset ru "Ask:" "ЗапроÑ:" ::msgcat::mcset ru "at the spa" "Ñ Ð² Ñпа" ::msgcat::mcset ru "Attached URL:" "Приложенный URL:" ::msgcat::mcset ru "Attached user:" "Приложенный пользователь:" ::msgcat::mcset ru "Attention" "Внимание" ::msgcat::mcset ru "August" "ÐвгуÑÑ‚" ::msgcat::mcset ru "Authentication" "ÐутентификациÑ" ::msgcat::mcset ru "Authentication Error" "Ошибка аутентификации" ::msgcat::mcset ru "Authentication failed" "ÐутентифицироватьÑÑ Ð½Ðµ удалоÑÑŒ" ::msgcat::mcset ru "Authentication failed: %s" "ПодключитьÑÑ Ð½Ðµ удалоÑÑŒ: %s" ::msgcat::mcset ru "Authentication failed: %s\nCreate new account?"\ "ПодключитьÑÑ Ð½Ðµ удалоÑÑŒ: %s\nСоздать новую учетную запиÑÑŒ?" ::msgcat::mcset ru "Authentication successful" "ÐÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ ÑƒÑпешнаÑ" ::msgcat::mcset ru "Authors:" "Ðвторы:" ::msgcat::mcset ru "Auto-subscribe to other's user activity"\ "ÐвтоподпиÑыватьÑÑ Ð½Ð° занÑтие пользователей" ::msgcat::mcset ru "Auto-subscribe to other's user activity notifications."\ "ÐвтоматичеÑки подпиÑыватьÑÑ Ð½Ð° ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð¾ занÑтии пользователей." ::msgcat::mcset ru "Auto-subscribe to other's user location"\ "ÐвтоподпиÑыватьÑÑ Ð½Ð° меÑтонахождение пользователей" ::msgcat::mcset ru "Auto-subscribe to other's user location notifications."\ "ÐвтоматичеÑки подпиÑыватьÑÑ Ð½Ð° ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð¾ меÑтонахождении\ пользователей." ::msgcat::mcset ru "Auto-subscribe to other's user mood" "ÐвтоподпиÑыватьÑÑ\ на ÑоÑтоÑние пользователей" ::msgcat::mcset ru "Auto-subscribe to other's user mood notifications."\ "ÐвтоматичеÑки подпиÑыватьÑÑ Ð½Ð° ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð¾ ÑоÑтоÑнии\ пользователей." ::msgcat::mcset ru "Auto-subscribe to other's user tune" "ÐвтоподпиÑыватьÑÑ\ на мелодии пользователей" ::msgcat::mcset ru "Auto-subscribe to other's user tune notifications."\ "ÐвтоматичеÑки подпиÑыватьÑÑ Ð½Ð° ÑƒÐ²ÐµÐ´Ð¾Ð¼Ð»ÐµÐ½Ð¸Ñ Ð¾ мелодии пользователей." ::msgcat::mcset ru "Automatically away due to idle" "ÐвтоматичеÑки в\ ÑоÑтоÑнии \"отошёл\" по бездейÑтвию" ::msgcat::mcset ru "Automatically join conference upon connect"\ "ÐвтоматичеÑки приÑоединÑтьÑÑ Ðº конференции при подключении" ::msgcat::mcset ru "Available" "ДоÑтупен" ::msgcat::mcset ru "Available groups" "Группы" ::msgcat::mcset ru "Available presence" "ПриÑутÑтвие типа \"доÑтупен\"" ::msgcat::mcset ru "Avatar" "Ðватара" ::msgcat::mcset ru "avatars" "аватары" ::msgcat::mcset ru "Away" "Отошёл" ::msgcat::mcset ru "Bad Format" "Ðекорректный формат" ::msgcat::mcset ru "Bad Namespace Prefix" "Ðекорректный Ð¿Ñ€ÐµÑ„Ð¸ÐºÑ Ð¿Ñ€Ð¾ÑтранÑтва\ имен" ::msgcat::mcset ru "Bad Request" "Ðекорректный запроÑ" ::msgcat::mcset ru "balloon help" "вÑÐ¿Ð»Ñ‹Ð²Ð°ÑŽÑ‰Ð°Ñ Ð¿Ð¾Ð´Ñказка" ::msgcat::mcset ru "Ban" "Запретить входить в комнату" ::msgcat::mcset ru "Bearing:" "Ðаправление:" ::msgcat::mcset ru "Begin date" "Дата начала дейÑтвиÑ" ::msgcat::mcset ru "Birthday" "День рождениÑ" ::msgcat::mcset ru "Birthday:" "День рождениÑ:" ::msgcat::mcset ru "Blind carbon copy" "ÐÐµÐ²Ð¸Ð´Ð¸Ð¼Ð°Ñ ÐºÐ¾Ð¿Ð¸Ñ" ::msgcat::mcset ru "Blocking communication (XMPP privacy lists) options."\ "ÐаÑтройки блокировки Ñообщений (правил обеÑÐ¿ÐµÑ‡ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸Ð²Ð°Ñ‚Ð½Ð¾Ñти\ XMPP)." ::msgcat::mcset ru "Blocking communication options." "Параметры блокировки\ Ñообщений (правил обеÑÐ¿ÐµÑ‡ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸Ð²Ð°Ñ‚Ð½Ð¾Ñти)." ::msgcat::mcset ru "bored" "Ñкукотища!" ::msgcat::mcset ru "Bottom" "Снизу" ::msgcat::mcset ru "brave" "вÑÑ‘ нипочём" ::msgcat::mcset ru "Browse" "ПроÑмотреть" ::msgcat::mcset ru "Browse..." "Выбрать..." ::msgcat::mcset ru "browsing" "проÑмотр Ñлужб" ::msgcat::mcset ru "brushing teeth" "чищу зубы" ::msgcat::mcset ru "Building:" "Строение:" ::msgcat::mcset ru "buying groceries" "покупаю продукты" ::msgcat::mcset ru "Cache headlines on exit and restore on start." "СохранÑть\ новоÑти при выходе и воÑÑтанавливать при Ñтарте." ::msgcat::mcset ru "Cached service categories and types (from disco#info)."\ "Сохраненные категории и типы Ñлужб (из disco#info)" ::msgcat::mcset ru "calm" "Ñпокойное" ::msgcat::mcset ru "Can't open file \"%s\": %s" "Ðе удалоÑÑŒ открыть файл\ \"%s\": %s" ::msgcat::mcset ru "Can't receive file: %s" "Ðе удалоÑÑŒ получить файл: %s" ::msgcat::mcset ru "Cancel" "Отменить" ::msgcat::mcset ru "Cancelling configure form" "Отмена конфигурационной\ формы" ::msgcat::mcset ru "Cannot connect to proxy" "Ðе удалоÑÑŒ ÑоединитьÑÑ Ñ\ прокÑи" ::msgcat::mcset ru "Cannot negotiate proxy connection" "Ðе удалоÑÑŒ\ ÑоглаÑовать Ñоединение Ñ Ð¿Ñ€Ð¾ÐºÑи" ::msgcat::mcset ru "Cannot publish empty activity" "Ð’Ñ‹ должны выбрать\ занÑтие" ::msgcat::mcset ru "Cannot publish empty mood" "Ð’Ñ‹ должны выбрать ÑоÑтоÑние" ::msgcat::mcset ru "Carbon copy" "КопиÑ" ::msgcat::mcset ru "Cell:" "Мобильный:" ::msgcat::mcset ru "Certificate has expired" "Срок дейÑÑ‚Ð²Ð¸Ñ Ñертификата\ иÑтёк" ::msgcat::mcset ru "change message type to" "изменить тип ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð½Ð°" ::msgcat::mcset ru "Change password" "Смена паролÑ" ::msgcat::mcset ru "Change password..." "Сменить пароль..." ::msgcat::mcset ru "Change Presence Priority" "Изменить приоритет\ приÑутÑтвиÑ" ::msgcat::mcset ru "Change priority..." "Изменить приоритет..." ::msgcat::mcset ru "Change security preferences for %s" "Изменение параметров\ безопаÑноÑти Ð´Ð»Ñ %s" ::msgcat::mcset ru "Changing accept messages from roster only: %s" "Изменение\ приема Ñообщений только из роÑтера: %s" ::msgcat::mcset ru "Chat" "Разговаривать" ::msgcat::mcset ru "Chat " "Разговор" ::msgcat::mcset ru "Chat message" "Сообщение типа \"chat\"" ::msgcat::mcset ru "Chat message events plugin options." "ÐаÑтройки\ раÑширениÑ, отвечающего за уведомление об обработке Ñообщений в окне\ разговора." ::msgcat::mcset ru "Chat message window state plugin options." "ÐаÑтройки\ раÑширениÑ, отвечающего за уведомление о ÑоÑтоÑнии окна разговора." ::msgcat::mcset ru "Chat options." "Параметры разговора." ::msgcat::mcset ru "Chat window is active" "Окно разговора активно" ::msgcat::mcset ru "Chat window is gone" "Окно разговора закрыто" ::msgcat::mcset ru "Chat window is inactive" "Окно разговора неактивно" ::msgcat::mcset ru "Chat with %s" "Разговор Ñ %s" ::msgcat::mcset ru "Chats" "Конференции" ::msgcat::mcset ru "Chats History" "ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ñ€Ð°Ð·Ð³Ð¾Ð²Ð¾Ñ€Ð¾Ð²" ::msgcat::mcset ru "Chats history" "Разговоры" ::msgcat::mcset ru "Chats history is converted.\nBackup of the old history is\ stored in %s" "ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ñ€Ð°Ð·Ð³Ð¾Ð²Ð¾Ñ€Ð¾Ð² преобразована в новый\ формат.\nÐ ÐµÐ·ÐµÑ€Ð²Ð½Ð°Ñ ÐºÐ¾Ð¿Ð¸Ñ Ñохранена в %s" ::msgcat::mcset ru "Chats:" "Окна разговора:" ::msgcat::mcset ru "Check spell after every entered symbol." "ПроверÑть\ правопиÑание поÑле каждого введенного Ñимвола." ::msgcat::mcset ru "Cipher" "Метод шифрованиÑ" ::msgcat::mcset ru "City" "Город" ::msgcat::mcset ru "City:" "Город:" ::msgcat::mcset ru "cleaning" "убираюÑÑŒ" ::msgcat::mcset ru "Clear" "ОчиÑтить" ::msgcat::mcset ru "Clear bookmarks" "ОчиÑтить закладки" ::msgcat::mcset ru "Clear chat window" "ОчиÑтить окно разговора" ::msgcat::mcset ru "Clear history" "ОчиÑтить иÑторию" ::msgcat::mcset ru "Clear window" "ОчиÑтить окно" ::msgcat::mcset ru "Client" "Клиент" ::msgcat::mcset ru "Client message" "Сообщение клиента" ::msgcat::mcset ru "Client:" "Клиент:" ::msgcat::mcset ru "Close" "Закрыть" ::msgcat::mcset ru "Close all tabs" "Закрыть вÑе вкладки" ::msgcat::mcset ru "Close other tabs" "Закрыть оÑтальные вкладки" ::msgcat::mcset ru "Close tab" "Закрыть вкладку" ::msgcat::mcset ru "Close Tkabber" "Закрыть Tkabber" ::msgcat::mcset ru "coding" "программирую" ::msgcat::mcset ru "cold" "равнодушное" ::msgcat::mcset ru "Color message bodies in chat windows." "ИÑпользовать\ цветные ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð² окнах разговора." ::msgcat::mcset ru "Command to be run when you click a URL in a message. \ '%s' will be replaced with this URL (e.g. \"galeon -n %s\")."\ "Команда, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð±ÑƒÐ´ÐµÑ‚ выполнена при нажатии на URL в Ñообщении.\ ВмеÑто '%s' будет подÑтавлен URL (например, \"galeon -n %s\")." ::msgcat::mcset ru "Commands" "Команды" ::msgcat::mcset ru "Common:" "Общие:" ::msgcat::mcset ru "commuting" "трÑÑуÑÑŒ в общеÑтвенном транÑпорте" ::msgcat::mcset ru "Complete nickname" "Дополнить пÑевдоним" ::msgcat::mcset ru "Complete nickname or command" "Дополнить пÑевдоним или\ команду" ::msgcat::mcset ru "Composing a reply" "Пишет ответ" ::msgcat::mcset ru "Compression" "Сжатие" ::msgcat::mcset ru "Compression negotiation failed" "СоглаÑовать Ñжатие не\ удалоÑÑŒ" ::msgcat::mcset ru "Compression negotiation successful" "Сжатие ÑоглаÑовано\ уÑпешно" ::msgcat::mcset ru "Compression setup failed" "Сжать поток не удалоÑÑŒ" ::msgcat::mcset ru "Condition" "УÑловие" ::msgcat::mcset ru "Conference room %s will be destroyed\ permanently.\n\nProceed?" "ÐšÐ¾Ð½Ñ„ÐµÑ€ÐµÐ½Ñ†Ð¸Ñ %s будет\ удалена.\n\nПродолжить?" ::msgcat::mcset ru "Conference:" "КонференциÑ:" ::msgcat::mcset ru "Conferences" "Конференции" ::msgcat::mcset ru "configuration" "конфигурациÑ" ::msgcat::mcset ru "Configure form: %s" "ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð°Ñ Ñ„Ð¾Ñ€Ð¼Ð°: %s" ::msgcat::mcset ru "Configure room" "Конфигурировать комнату" ::msgcat::mcset ru "Configure service" "КонфигурациÑ" ::msgcat::mcset ru "Conflict" "Конфликт" ::msgcat::mcset ru "confused" "в замешательÑтве" ::msgcat::mcset ru "Connect via alternate server" "ПодключитьÑÑ Ñ‡ÐµÑ€ÐµÐ·\ альтернативный Ñервер" ::msgcat::mcset ru "Connect via HTTP polling" "ПодключитьÑÑ Ñ Ð¸Ñпользованием\ HTTP" ::msgcat::mcset ru "Connection" "Соединение" ::msgcat::mcset ru "Connection refused by destination host" "Удалённый хоÑÑ‚\ отказал в Ñоединении" ::msgcat::mcset ru "Connection Timeout" "Соединение разорвано по таймауту" ::msgcat::mcset ru "Connection:" "Соединение:" ::msgcat::mcset ru "connections" "подключение" ::msgcat::mcset ru "Contact Information" "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ контактах" ::msgcat::mcset ru "contented" "довольное" ::msgcat::mcset ru "continue processing rules" "продолжить применение правил" ::msgcat::mcset ru "Conversion is finished" "Преобразование закончено" ::msgcat::mcset ru "Convert" "Преобразовать" ::msgcat::mcset ru "Convert screenname" "Преобразовать Ñкранное имÑ" ::msgcat::mcset ru "Converting Log Files" "Преобразование файлов иÑтории" ::msgcat::mcset ru "cooking" "готовлю" ::msgcat::mcset ru "Copy headline to clipboard" "Скопировать новоÑть в буфер\ обмена" ::msgcat::mcset ru "Copy JID to clipboard" "Скопировать JID в буфер обмена" ::msgcat::mcset ru "Copy real JID to clipboard" "Скопировать реальный JID в буфер обмена" ::msgcat::mcset ru "Copy selection to clipboard" "Скопировать выделение в\ буфер обмена" ::msgcat::mcset ru "Copy URL to clipboard" "Скопировать URL в буфер обмена" ::msgcat::mcset ru "Correct word" "ИÑправить Ñлово" ::msgcat::mcset ru "Could not start ispell server. Check your ispell path and\ dictionary name. Ispell is disabled now" "Ðе удалоÑÑŒ запуÑтить Ñервер\ ispell. Проверьте путь к ispell и Ð¸Ð¼Ñ ÑловарÑ. Ð¡ÐµÐ¹Ñ‡Ð°Ñ ispell\ отключён" ::msgcat::mcset ru "Country" "Страна" ::msgcat::mcset ru "Country:" "Страна:" ::msgcat::mcset ru "cranky" "недовольное" ::msgcat::mcset ru "Create node" "Создать узел" ::msgcat::mcset ru "Created: %s" "Созданы: %s" ::msgcat::mcset ru "Creating default privacy list" "Создаём ÑпиÑок\ приватноÑти по умолчанию" ::msgcat::mcset ru "Creating default privacy list failed: %s\n\nTry to\ reconnect. If problem persists, you may want to disable privacy list\ activation at start" "Ðе удалоÑÑŒ Ñоздать ÑпиÑок приватноÑти по\ умолчанию: %s\n\nПопытайтеÑÑŒ подключитьÑÑ Ñнова. ЕÑли проблема\ оÑтаётÑÑ, возможно придётÑÑ Ð¾Ñ‚ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒ активацию ÑпиÑков приватноÑти\ при Ñтарте" ::msgcat::mcset ru "cryptographics" "криптографиÑ" ::msgcat::mcset ru "curious" "любознательное" ::msgcat::mcset ru "Current groups" "Текущие группы" ::msgcat::mcset ru "customization" "наÑтройки" ::msgcat::mcset ru "Customization of the One True Jabber Client." "ÐаÑтройка\ ИÑтинного клиента Jabber'а." ::msgcat::mcset ru "Customize" "ÐаÑтройки" ::msgcat::mcset ru "cycling" "катаюÑÑŒ на велоÑипеде" ::msgcat::mcset ru "Data form" "Форма Ð´Ð»Ñ Ð·Ð°Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ" ::msgcat::mcset ru "Data purported sent by %s can't be deciphered.\n\n%s."\ "Данные, предположительно приÑланные от %s, невозможно\ раÑшифровать.\n\n%s." ::msgcat::mcset ru "Date:" "Дата:" ::msgcat::mcset ru "day off" "у Ð¼ÐµÐ½Ñ Ð²Ñ‹Ñ…Ð¾Ð´Ð½Ð¾Ð¹" ::msgcat::mcset ru "Day:" "День:" ::msgcat::mcset ru "December" "Декабрь" ::msgcat::mcset ru "Decline subscription" "Отклонить подпиÑку" ::msgcat::mcset ru "Default" "По умолчанию" ::msgcat::mcset ru "Default directory for downloaded files." "Ð”Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Ð²\ которой по умолчанию ÑохранÑÑŽÑ‚ÑÑ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð½Ñ‹Ðµ файлы." ::msgcat::mcset ru "Default message type (if not specified explicitly)." "Тип\ Ñообщений по умолчанию (еÑли не указан Ñвно)" ::msgcat::mcset ru "Default nested roster group delimiter." "Разделитель\ вложенных групп по умолчанию." ::msgcat::mcset ru "Default protocol for sending files." "Протокол передачи\ файлов по умолчанию." ::msgcat::mcset ru "Delay between getting focus and updating window or tab\ title in milliseconds." "Задержка (в миллиÑекундах) между получением\ фокуÑа и обновлением заголовка окна или вкладки." ::msgcat::mcset ru "Delete" "Удалить" ::msgcat::mcset ru "Delete all" "Удалить вÑе" ::msgcat::mcset ru "Delete current node and subnodes" "Удалить узел и вÑех\ его потомков" ::msgcat::mcset ru "Delete message of the day" "Удалить Ñообщение днÑ" ::msgcat::mcset ru "Delete seen" "Удалить проÑмотренные" ::msgcat::mcset ru "Delete subnodes" "Удалить потомков узла" ::msgcat::mcset ru "Deleted abbreviation: %s" "Удалено Ñокращение: %s" ::msgcat::mcset ru "depressed" "подавленное" ::msgcat::mcset ru "Description:" "ОпиÑание:" ::msgcat::mcset ru "Destroy room" "Удалить комнату" ::msgcat::mcset ru "Details" "Детали" ::msgcat::mcset ru "Dir" "Куда" ::msgcat::mcset ru "Directory to store logs." "ДиректориÑ, в которой\ ÑохранÑÑŽÑ‚ÑÑ Ð¿Ñ€Ð¾Ñ‚Ð¾ÐºÐ¾Ð»Ñ‹." ::msgcat::mcset ru "Disabled\n" "Отключён\n" ::msgcat::mcset ru "disappointed" "разочарованное" ::msgcat::mcset ru "Disconnected" "Соединение разорвано" ::msgcat::mcset ru "Discovery" "Обзор" ::msgcat::mcset ru "disgusted" "чувÑтвую отвращение" ::msgcat::mcset ru "Display %s in chat window when using /vcard command."\ "Показывать параметр %s в окне разговора при иÑпользовании команды\ /vcard." ::msgcat::mcset ru "Display description of user status in chat windows."\ "Показывать детальное опиÑание ÑтатуÑа ÑобеÑедника в окне разговора." ::msgcat::mcset ru "Display headlines in single/multiple windows."\ "Показывать новоÑти в одном/неÑкольких окнах." ::msgcat::mcset ru "Display SSL warnings." "Показывать Ð¿Ñ€ÐµÐ´ÑƒÐ¿Ñ€ÐµÐ¶Ð´ÐµÐ½Ð¸Ñ SSL." ::msgcat::mcset ru "Display status tooltip when main window is minimized to\ systray." "Показывать вÑплывающее ÑтатуÑное окно, когда главное окно\ Ñвернуто в ÑиÑтемный лоток." ::msgcat::mcset ru "Display warning dialogs when signature verification\ fails." "Показывать Ð¿Ñ€ÐµÐ´ÑƒÐ¿Ñ€ÐµÐ¶Ð´ÐµÐ½Ð¸Ñ Ð² Ñлучае неудачи при проверке\ подпиÑи." ::msgcat::mcset ru "distracted" "раÑтерÑнное" ::msgcat::mcset ru "Do not display headline descriptions as tree nodes." "Ðе\ показывать опиÑание новоÑти в виде ветви дерева (только вÑплывающее\ окно)." ::msgcat::mcset ru "Do not disturb" "Ðе беÑпокоить" ::msgcat::mcset ru "Do nothing" "Ðе делать ничего" ::msgcat::mcset ru "doesn't want to be disturbed" "не хочет, чтобы его\ беÑпокоили" ::msgcat::mcset ru "doing chores" "занимаюÑÑŒ домашними делами" ::msgcat::mcset ru "doing maintenance" "Ñижу, Ð¿Ñ€Ð¸Ð¼ÑƒÑ Ð¿Ð¾Ñ‡Ð¸Ð½ÑÑŽ" ::msgcat::mcset ru "doing the dishes" "мою поÑуду" ::msgcat::mcset ru "doing the laundry" "Ñтираю бельё" ::msgcat::mcset ru "Down" "Вниз" ::msgcat::mcset ru "drinking" "пью" ::msgcat::mcset ru "driving" "веду машину" ::msgcat::mcset ru "eating" "ем" ::msgcat::mcset ru "Edit" "Изменить" ::msgcat::mcset ru "Edit %s color" "Изменение цвета Ð´Ð»Ñ %s" ::msgcat::mcset ru "Edit admin list" "Изменить ÑпиÑок админиÑтраторов" ::msgcat::mcset ru "Edit ban list" "Изменить чёрный ÑпиÑок" ::msgcat::mcset ru "Edit chat user colors" "Изменение цветов пÑевдонимов" ::msgcat::mcset ru "Edit conference list" "Изменение ÑпиÑка конференций" ::msgcat::mcset ru "Edit conference list " "Изменить ÑпиÑок конференций" ::msgcat::mcset ru "Edit groups for %s" "Изменение групп %s" ::msgcat::mcset ru "Edit ignore list" "Изменение игнорируемого ÑпиÑка" ::msgcat::mcset ru "Edit ignore list " "Изменить игнорируемый ÑпиÑок" ::msgcat::mcset ru "Edit invisible list" "Изменение невидимого ÑпиÑка" ::msgcat::mcset ru "Edit invisible list " "Изменить невидимый ÑпиÑок" ::msgcat::mcset ru "Edit item notes..." "Редактировать заметки..." ::msgcat::mcset ru "Edit item..." "Редактировать..." ::msgcat::mcset ru "Edit list" "Изменить ÑпиÑок" ::msgcat::mcset ru "Edit member list" "Изменить ÑпиÑок членов" ::msgcat::mcset ru "Edit message filters" "Изменить фильтры Ñообщений" ::msgcat::mcset ru "Edit moderator list" "Изменить ÑпиÑок модераторов" ::msgcat::mcset ru "Edit MUC ignore rules" "Редактировать правила\ Ð¸Ð³Ð½Ð¾Ñ€Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ MUC" ::msgcat::mcset ru "Edit my info..." "Редактировать личную информацию..." ::msgcat::mcset ru "Edit nick color..." "Изменение цвета пÑевдонима..." ::msgcat::mcset ru "Edit nick colors..." "Изменить цвета пÑевдонимов..." ::msgcat::mcset ru "Edit nickname for %s" "Изменение пÑевдонима %s" ::msgcat::mcset ru "Edit owner list" "Изменить ÑпиÑок владельцев" ::msgcat::mcset ru "Edit privacy list" "Изменить ÑпиÑок приватноÑти" ::msgcat::mcset ru "Edit properties for %s" "Изменение ÑвойÑтв %s" ::msgcat::mcset ru "Edit roster notes for %s" "Изменение заметок Ð´Ð»Ñ %s" ::msgcat::mcset ru "Edit rule" "Изменение правила" ::msgcat::mcset ru "Edit security..." "Редактировать параметры\ безопаÑноÑти..." ::msgcat::mcset ru "Edit visible list" "Изменение видимого ÑпиÑка" ::msgcat::mcset ru "Edit voice list" "Изменить ÑпиÑок учаÑтников" ::msgcat::mcset ru "embarrassed" "Ñмущённое" ::msgcat::mcset ru "emoticons" "Ñмоциконки" ::msgcat::mcset ru "Emphasize" "Выделение в ÑообщениÑÑ…" ::msgcat::mcset ru "Emphasize stylecoded messages using different fonts."\ "ВыделÑть ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ñо Ñтилевыми кодами, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ñ€Ð°Ð·Ð½Ñ‹Ðµ шрифты." ::msgcat::mcset ru "Empty rule name" "Ðазвание правила не должно быть пуÑтым" ::msgcat::mcset ru "Enable announcing entity capabilities in every outgoing\ presence." "Разрешить передачу информации о возможноÑÑ‚ÑÑ… программы\ вмеÑте Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸ÐµÐ¹ о приÑутÑтвии." ::msgcat::mcset ru "Enable chat window autoscroll only when last message is\ shown." "Включить автопрокрутку окна разговора только еÑли в окне\ видно поÑледнюю Ñтроку текÑта." ::msgcat::mcset ru "Enable freedesktop system tray icon." "Включить\ freedesktop system tray icon." ::msgcat::mcset ru "Enable freedesktop systray icon." "Включить freedesktop\ systray icon." ::msgcat::mcset ru "Enable highlighting plugin." "Включить модуль выделениÑ\ Ñлов." ::msgcat::mcset ru "Enable jabberd 1.4 mod_filter support (obsolete)."\ "Включить поддержку Ð¼Ð¾Ð´ÑƒÐ»Ñ mod_filter из jabberd 1.4 (уÑтаревшие)" ::msgcat::mcset ru "Enable KDE tray icon." "ИÑпользовать значок в ÑиÑтемном\ лотке KDE." ::msgcat::mcset ru "Enable nested roster groups." "Отображать вложенные\ группы в контактах." ::msgcat::mcset ru "Enable remote control." "Включить удалённое управление." ::msgcat::mcset ru "Enable rendering of XHTML messages." "Отображать\ ÑообщениÑ, форматированные Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ XHTML." ::msgcat::mcset ru "Enable sending chat message events." "Включить раÑÑылку\ уведомлений об обработке Ñообщений в окне разговора." ::msgcat::mcset ru "Enable sending chat state notifications." "Включить\ раÑÑылку уведомлений о ÑоÑтоÑнии окна разговора." ::msgcat::mcset ru "Enable SI transport %s." "Разрешить иÑпользование\ SI-транÑпорта %s" ::msgcat::mcset ru "Enable spellchecker in text input windows." "Разрешить\ проверку правопиÑÐ°Ð½Ð¸Ñ Ð² окнах ввода текÑта." ::msgcat::mcset ru "Enable windows tray icon." "ИÑпользовать значок в\ ÑиÑтемном лотке Windows" ::msgcat::mcset ru "Enabled\n" "Включён\n" ::msgcat::mcset ru "Encrypt traffic" "Шифровать ÑообщениÑ" ::msgcat::mcset ru "Encrypt traffic (when possible)" "Шифровать ÑообщениÑ\ (где возможно)" ::msgcat::mcset ru "Encryption" "Шифрование" ::msgcat::mcset ru "Encryption (legacy SSL)" "Шифрование (Ñтарый SSL)" ::msgcat::mcset ru "Encryption (STARTTLS)" "Шифрование (STARTTLS)" ::msgcat::mcset ru "Enter screenname of contact you want to add" "Введите\ Ñкранное Ð¸Ð¼Ñ Ð´Ð¾Ð±Ð°Ð²Ð»Ñемого контакта" ::msgcat::mcset ru "Error" "Ошибка" ::msgcat::mcset ru "Error %s" "Ошибка %s" ::msgcat::mcset ru "Error completing command: %s" "Ошибка при завершении\ команды: %s" ::msgcat::mcset ru "Error displaying %s in browser\n\n%s" "Ошибка при\ открытии %s в окне проÑмотра Ñлужб\n\n%s" ::msgcat::mcset ru "Error executing command: %s" "Ошибка при выполнении\ команды: %s" ::msgcat::mcset ru "Error getting info: %s" "Ошибка при получении информации:\ %s" ::msgcat::mcset ru "Error getting items: %s" "Ошибка при получении Ñлементов:\ %s" ::msgcat::mcset ru "Error in signature processing" "Ошибка при проверке\ подпиÑи" ::msgcat::mcset ru "Error in signature verification software: %s." "Ошибка в\ программе, проверÑющей цифровую подпиÑÑŒ: %s." ::msgcat::mcset ru "Error loading MUC ignore rules, purged." "Ошибка при\ загрузке правил Ð¸Ð³Ð½Ð¾Ñ€Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ MUC. Правила удалены." ::msgcat::mcset ru "Error negotiate: %s" "Ошибка при ÑоглаÑовании: %s" ::msgcat::mcset ru "Error requesting data: %s" "Ошибка запроÑа данных: %s" ::msgcat::mcset ru "Error restoring annotations: %s" "Ошибка воÑÑтановлениÑ\ заметок: %s" ::msgcat::mcset ru "Error restoring conference bookmarks: %s" "Ошибка\ воÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð·Ð°ÐºÐ»Ð°Ð´Ð¾Ðº на конференции: %s" ::msgcat::mcset ru "Error restoring roster contacts: %s" "Ошибка\ воÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ñодержимого ÑпиÑка контактов: %s" ::msgcat::mcset ru "Error while converting screenname: %s." "Ошибка при\ преобразовании Ñкранного имени: %s" ::msgcat::mcset ru "Error:" "Ошибка:" ::msgcat::mcset ru "excited" "взволнованное" ::msgcat::mcset ru "Execute command" "Выполнить команду" ::msgcat::mcset ru "exercising" "занимаюÑÑŒ Ñпортом" ::msgcat::mcset ru "Expiry date" "Дата иÑÑ‚ÐµÑ‡ÐµÐ½Ð¸Ñ Ð´ÐµÐ¹ÑтвиÑ" ::msgcat::mcset ru "Explicitly specify host and port to connect" "Явно\ указать Ð°Ð´Ñ€ÐµÑ Ð¸ порт Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ" ::msgcat::mcset ru "Export roster..." "ЭкÑпортировать контакты..." ::msgcat::mcset ru "Export to XHTML" "ЭкÑпорт в XHTML" ::msgcat::mcset ru "Extended addressing fields:" "ÐŸÐ¾Ð»Ñ Ñ€Ð°Ñширенной\ адреÑации:" ::msgcat::mcset ru "Extended away" "Отошёл давно" ::msgcat::mcset ru "extension management" "управление раÑширениÑми" ::msgcat::mcset ru "External program, which is to be executed to play sound.\ If empty, Snack library is used (if available) to play sound."\ "ВнешнÑÑ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¼Ð°, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÐµÐ¼Ð°Ñ Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð¸Ð³Ñ€Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð·Ð²ÑƒÐºÐ¾Ð². ЕÑли Ñтот\ параметр пуÑÑ‚, то иÑпользуетÑÑ (еÑли уÑтановлена) библиотека Snack." ::msgcat::mcset ru "Extras from %s" "Добавление от %s" ::msgcat::mcset ru "Extras from:" "Добавление от:" ::msgcat::mcset ru "Failed to connect: %s" "ПодключитьÑÑ Ð½Ðµ удалоÑÑŒ: %s" ::msgcat::mcset ru "Family Name" "ФамилиÑ" ::msgcat::mcset ru "Family Name:" "ФамилиÑ:" ::msgcat::mcset ru "Fax:" "ФакÑ:" ::msgcat::mcset ru "Feature Not Implemented" "Ðе реализовано" ::msgcat::mcset ru "February" "Февраль" ::msgcat::mcset ru "Fetch all messages" "Получить вÑе ÑообщениÑ" ::msgcat::mcset ru "Fetch GPG key" "Получить ключ GPG" ::msgcat::mcset ru "Fetch message" "Получить Ñообщение" ::msgcat::mcset ru "Fetch nickname" "Получить пÑевдоним" ::msgcat::mcset ru "Fetch nicknames of all users in group" "Получить\ пÑевдонимы вÑех контактов в группе" ::msgcat::mcset ru "Fetch unseen messages" "Получить неполученные ÑообщениÑ" ::msgcat::mcset ru "Fetch user nicknames" "Получить пÑевдонимы контактов" ::msgcat::mcset ru "File %s cannot be opened: %s. History for %s (%s) is NOT\ converted\n" "Файл %s открыть не удалоÑÑŒ: %s. ИÑÑ‚Ð¾Ñ€Ð¸Ñ %s (%s) ÐЕ\ Ñконвертирована\n" ::msgcat::mcset ru "File %s cannot be opened: %s. History for %s is NOT\ converted\n" "Файл %s открыть не удалоÑÑŒ: %s. ИÑÑ‚Ð¾Ñ€Ð¸Ñ %s ÐЕ\ Ñконвертирована\n" ::msgcat::mcset ru "File %s is corrupt. History for %s (%s) is NOT\ converted\n" "Файл %s иÑпорчен. ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ð´Ð»Ñ %s (%s) ÐЕ\ преобразована\n" ::msgcat::mcset ru "File %s is corrupt. History for %s is NOT converted\n"\ "Файл %s иÑпорчен. ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ð´Ð»Ñ %s ÐЕ преобразована\n" ::msgcat::mcset ru "File path:" "Путь к файлу:" ::msgcat::mcset ru "file transfer" "передача файлов" ::msgcat::mcset ru "File transfer aborted" "Передача файла прервана" ::msgcat::mcset ru "File Transfer options." "Параметры передачи файлов." ::msgcat::mcset ru "Filters" "Фильтры" ::msgcat::mcset ru "Finish" "Закончить" ::msgcat::mcset ru "First Name:" "ИмÑ:" ::msgcat::mcset ru "flirtatious" "кокетливое" ::msgcat::mcset ru "Floor:" "Этаж:" ::msgcat::mcset ru "Font to use in chat windows." "Шрифт Ð´Ð»Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð²\ окнах разговоров." ::msgcat::mcset ru "Font to use in roster windows." "Шрифт Ð´Ð»Ñ Ð¸ÑпользованиÑ\ в окнах ÑпиÑков контактов." ::msgcat::mcset ru "Forbidden" "Запрещено" ::msgcat::mcset ru "Force advertising this hostname (or IP address) for\ outgoing HTTP file transfers." "ОбъÑвлÑть указанное Ð¸Ð¼Ñ (или\ IP-адреÑ) Ð´Ð»Ñ Ð¸ÑходÑщей передачи файлов по HTTP." ::msgcat::mcset ru "Format Error" "Ошибка формата" ::msgcat::mcset ru "Format of timestamp in chat message. Refer to Tcl\ documentation of 'clock' command for description of\ format.\n\nExamples:\n \[%R\] - \[20:37\]\n \[%T\] - \[20:37:12\]\n \ \[%a %b %d %H:%M:%S %Z %Y\] - \[Thu Jan 01 03:00:00 MSK 1970\]"\ "Формат вывода даты/времени в ÑообщениÑÑ…. (Подробнее опиÑание формата\ можно узнать из документации к команде Tcl 'clock'.)\n\nПримеры:\n \ \[%R\] - \[20:37\]\n \[%T\] - \[20:37:12\]\n \[%a %b %d %H:%M:%S %Z\ %Y\] - \[Чтв Янв 01 03:00:00 MSK 1970\]" ::msgcat::mcset ru "Format of timestamp in delayed chat messages delayed for\ more than 24 hours." "Формат вывода даты/времени в ÑообщениÑÑ…,\ отправленных более Ñуток назад." ::msgcat::mcset ru "Format of timestamp in headline tree view. Set to empty\ string if you don't want to see timestamps." "Формат вывода\ даты/времени в окне новоÑтей. Ð”Ð»Ñ Ñ‚Ð¾Ð³Ð¾, чтобы не показывать\ дату/Ð²Ñ€ÐµÐ¼Ñ ÑовÑем, уÑтановите Ñту опцию в пуÑтую Ñтроку." ::msgcat::mcset ru "Forward headline" "ПереÑылка новоÑти" ::msgcat::mcset ru "forward message to" "переÑлать Ñообщение" ::msgcat::mcset ru "Forward to %s" "ПереÑлать %s" ::msgcat::mcset ru "Forward..." "ПереÑлать..." ::msgcat::mcset ru "Forwarded by:" "ПереÑлано:" ::msgcat::mcset ru "Free to chat" "Свободен Ð´Ð»Ñ Ñ€Ð°Ð·Ð³Ð¾Ð²Ð¾Ñ€Ð°" ::msgcat::mcset ru "From/To" "От кого/Кому" ::msgcat::mcset ru "From:" "От кого:" ::msgcat::mcset ru "From: " "От кого: " ::msgcat::mcset ru "frustrated" "раÑÑтроенное" ::msgcat::mcset ru "Full Name" "Полное имÑ" ::msgcat::mcset ru "Full Name:" "Полное имÑ:" ::msgcat::mcset ru "Full-text search" "ПолнотекÑтовый поиÑк" ::msgcat::mcset ru "gaming" "играю" ::msgcat::mcset ru "gardening" "работаю в Ñаду" ::msgcat::mcset ru "general plugins" "общие плагины" ::msgcat::mcset ru "Generate chat messages when chat peer changes his/her\ status and/or status message" "Генерировать ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¾ том, что\ ÑобеÑедник Ñменил Ñвоё приÑутÑтвие или ÑтатуÑное Ñообщение." ::msgcat::mcset ru "Generate enter/exit messages" "Генерирование Ñообщений о\ входе/выходе" ::msgcat::mcset ru "Generate groupchat messages when occupant changes his/her\ status and/or status message." "Генерировать ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¾ том, что\ учаÑтник конференции Ñменил Ñвоё приÑутÑтвие или ÑтатуÑное\ Ñообщение." ::msgcat::mcset ru "Generate groupchat messages when occupant's room position\ (affiliation and/or role) changes." "Генерировать ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¾ том,\ что положение, занимаемое учаÑтником конференции (его ранг и/или\ роль), изменилиÑÑŒ." ::msgcat::mcset ru "Generate status messages when occupants enter/exit MUC\ compatible conference rooms." "Генерировать ÑтатуÑные ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¾\ входе/выходе учаÑтников в MUC-конференциÑÑ…." ::msgcat::mcset ru "Generic IQ" "Общий IQ-запроÑ" ::msgcat::mcset ru "Geographical position" "ГеографичеÑкое раÑположение" ::msgcat::mcset ru "Get items" "Получить объекты" ::msgcat::mcset ru "getting a haircut" "подÑтригаюÑÑŒ" ::msgcat::mcset ru "GIF images" "Ð˜Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ GIF" ::msgcat::mcset ru "going out" "прогуливаюÑÑŒ" ::msgcat::mcset ru "Gone" "Объект Ñменил адреÑ" ::msgcat::mcset ru "Google selection" "ИÑкать выделенный текÑÑ‚ в Google" ::msgcat::mcset ru "Got roster" "Получены контакты" ::msgcat::mcset ru "GPG-encrypt outgoing messages where possible." "Шифровать\ иÑходÑщие ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ GPG, еÑли возможно." ::msgcat::mcset ru "GPG-sign outgoing messages and presence updates."\ "ПодпиÑывать иÑходÑщие ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¸ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸ÑутÑÑ‚Ð²Ð¸Ñ Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ\ GPG." ::msgcat::mcset ru "GPG options (signing and encryption)." "Параметры GPG\ (Ñ†Ð¸Ñ„Ñ€Ð¾Ð²Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ и шифрование)." ::msgcat::mcset ru "GPS datum:" "СиÑтема координат GPS:" ::msgcat::mcset ru "Grant Admin Privileges" "ПредоÑтавить права\ админиÑтратора" ::msgcat::mcset ru "Grant Membership" "ПредоÑтавить членÑтво" ::msgcat::mcset ru "Grant Moderator Privileges" "ПредоÑтавить права\ модератора" ::msgcat::mcset ru "Grant Owner Privileges" "ПредоÑтавить права владельца" ::msgcat::mcset ru "Grant subscription" "ПредоÑтавить подпиÑку" ::msgcat::mcset ru "Grant Voice" "ПредоÑтавить право говорить" ::msgcat::mcset ru "grooming" "привожу ÑÐµÐ±Ñ Ð² порÑдок" ::msgcat::mcset ru "Group:" "Группа:" ::msgcat::mcset ru "Group: " "Группа: " ::msgcat::mcset ru "Groupchat message highlighting plugin options."\ "ÐаÑтройки Ð¼Ð¾Ð´ÑƒÐ»Ñ Ð²Ñ‹Ð´ÐµÐ»ÐµÐ½Ð¸Ñ Ñлов в ÑообщениÑÑ… конференций." ::msgcat::mcset ru "grumpy" "ворчливое" ::msgcat::mcset ru "guilty" "виноватое" ::msgcat::mcset ru "Handle ROTFL/LOL smileys -- those like :))) -- by\ \"consuming\" all that parens and rendering the whole word with\ appropriate icon." "ЗаменÑть ROTFL/LOL обозначениÑ, которые выглÑдÑÑ‚\ как :))), ÑоответÑтвующей Ñмоциконконкой, убрав повторÑющиеÑÑ\ Ñкобки." ::msgcat::mcset ru "Handling of \"emoticons\". Emoticons (also known as\ \"smileys\") are small pictures resembling a human face used to\ represent user's emotion. They are typed in as special mnemonics like\ :) or can be inserted using menu." "Обработка Ñмоциконок. Эмоциконки\ (или улыбки) Ñто небольшие картинки, похожие на человечеÑкое лицо,\ иÑпользуемые Ð´Ð»Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ñмоций. Могут быть введены мнемоничеÑки,\ например как :), или вÑтавлены через меню." ::msgcat::mcset ru "Handling of \"stylecodes\". Stylecodes are (groups of)\ special formatting symbols used to emphasize parts of the text by\ setting them with boldface, italics or underlined styles, or as\ combinations of these." "Обработка Ñтилевых кодов. Стилевые коды -\ Ñто Ñпециальные Ñимволы Ð´Ð»Ñ Ð²Ñ‹Ð´ÐµÐ»ÐµÐ½Ð¸Ñ Ñ‡Ð°Ñтей текÑта полужирным,\ курÑивным или подчеркнутым начертанием и их комбинациÑми." ::msgcat::mcset ru "Handshake failed" "Рукопожатие не удалоÑÑŒ" ::msgcat::mcset ru "Handshake successful" "Рукопожатие уÑпешное" ::msgcat::mcset ru "hanging out" "туÑуюÑÑŒ где-то там" ::msgcat::mcset ru "happy" "ÑчаÑтливое" ::msgcat::mcset ru "having a beer" "пью пиво" ::msgcat::mcset ru "having a snack" "перекуÑываю" ::msgcat::mcset ru "having appointment" "у Ð¼ÐµÐ½Ñ Ð²Ñтреча" ::msgcat::mcset ru "having breakfast" "завтракаю" ::msgcat::mcset ru "having coffee" "пью кофе" ::msgcat::mcset ru "having dinner" "обедаю" ::msgcat::mcset ru "having lunch" "у Ð¼ÐµÐ½Ñ Ð»Ð°Ð½Ñ‡" ::msgcat::mcset ru "having tea" "пью чай" ::msgcat::mcset ru "Headline message" "Сообщение типа \"headline\"" ::msgcat::mcset ru "Headlines" "ÐовоÑти" ::msgcat::mcset ru "Help" "Помощь" ::msgcat::mcset ru "Hide characters comprising stylecode markup." "Скрывать\ Ñимволы, задающие разметку Ñтилевых кодов." ::msgcat::mcset ru "Hide main window" "Убрать главное окно" ::msgcat::mcset ru "Hide/Show roster" "Скрыть/показать контакты" ::msgcat::mcset ru "Highlight current nickname in messages." "ВыделÑть\ текущий пÑевдоним в ÑообщениÑÑ…." ::msgcat::mcset ru "Highlight only whole words in messages." "ВыделÑть только\ целые Ñлова." ::msgcat::mcset ru "hiking" "хожу пешком" ::msgcat::mcset ru "History for %s" "ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ñообщений %s" ::msgcat::mcset ru "Home:" "Домашний:" ::msgcat::mcset ru "Horizontal GPS error:" "Ð“Ð¾Ñ€Ð¸Ð·Ð¾Ð½Ñ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ° GPS:" ::msgcat::mcset ru "Host Gone" "ХоÑÑ‚ больше не обÑлуживаетÑÑ" ::msgcat::mcset ru "Host Unknown" "ÐеизвеÑтный хоÑÑ‚" ::msgcat::mcset ru "Host unreachable" "ХоÑÑ‚ недоÑтижим" ::msgcat::mcset ru "Host:" "ХоÑÑ‚:" ::msgcat::mcset ru "hot" "пылаю" ::msgcat::mcset ru "HTTP options." "Параметры HTTP-транÑпорта." ::msgcat::mcset ru "HTTP Poll" "HTTP-подключение" ::msgcat::mcset ru "HTTP proxy address." "ÐÐ´Ñ€ÐµÑ Ð¿Ñ€Ð¾ÐºÑи-Ñервера." ::msgcat::mcset ru "HTTP proxy password." "Пароль Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ðº\ прокÑи-Ñерверу." ::msgcat::mcset ru "HTTP proxy port." "Порт Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ðº\ прокÑи-Ñерверу." ::msgcat::mcset ru "HTTP proxy username." "Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ðº\ прокÑи-Ñерверу." ::msgcat::mcset ru "humbled" "Ñмиренное" ::msgcat::mcset ru "humiliated" "униженное" ::msgcat::mcset ru "hungry" "хочу еÑть" ::msgcat::mcset ru "hurt" "уÑзвлённое" ::msgcat::mcset ru "I would like to add you to my roster." "Мне бы хотелоÑÑŒ\ добавить Ð’Ð°Ñ Ð² ÑпиÑок контактов." ::msgcat::mcset ru "I'm not online" "Ñ Ð½Ðµ в Ñети" ::msgcat::mcset ru "Iconize" "Иконизировать" ::msgcat::mcset ru "Idle for %s" "Ð’Ñ€ÐµÐ¼Ñ Ð±ÐµÐ·Ð´ÐµÐ¹ÑтвиÑ: %s" ::msgcat::mcset ru "Idle threshold in minutes after that Tkabber marks you as\ away." "Период бездейÑÑ‚Ð²Ð¸Ñ Ð² минутах, по иÑтечении которого Ñледует\ уÑтановить ÑоÑтоÑние \"Отошёл\"." ::msgcat::mcset ru "Idle threshold in minutes after that Tkabber marks you as\ extended away." "Период бездейÑÑ‚Ð²Ð¸Ñ Ð² минутах, по иÑтечении которого\ Ñледует уÑтановить ÑоÑтоÑние \"Отошёл давно\"." ::msgcat::mcset ru "If set then open chat window/tab when user doubleclicks\ roster item. Otherwise open normal message window." "ЕÑли включено,\ двойной щелчок мышью на Ñлементе ÑпиÑка контактов открывает\ окно/вкладку разговора, в противном Ñлучае открываетÑÑ Ð¾ÐºÐ½Ð¾ длÑ\ отÑылки обычного ÑообщениÑ." ::msgcat::mcset ru "Ignore" "Игнорирование" ::msgcat::mcset ru "Ignore chat messages" "Игнорировать приватные ÑообщениÑ" ::msgcat::mcset ru "Ignore groupchat messages" "Игнорировать групповые\ ÑообщениÑ" ::msgcat::mcset ru "Ignore list" "Игнорируемый ÑпиÑок" ::msgcat::mcset ru "Ignoring groupchat and chat messages from selected\ occupants of multi-user conference rooms." "Игнорирование групповых и\ приватных Ñообщений от выбранных поÑетителей многопользовательÑкой\ конференции." ::msgcat::mcset ru "Illegal result" "Ðекорректный результат" ::msgcat::mcset ru "Image" "Изображение" ::msgcat::mcset ru "Import roster..." "Импортировать контакты..." ::msgcat::mcset ru "impressed" "под впечатлением" ::msgcat::mcset ru "Improper Addressing" "ÐÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð°Ñ Ð°Ð´Ñ€ÐµÑациÑ" ::msgcat::mcset ru "in a car" "еду в машине" ::msgcat::mcset ru "in a meeting" "у Ð¼ÐµÐ½Ñ Ñобрание" ::msgcat::mcset ru "in real life" "разговариваю в реале" ::msgcat::mcset ru "in_awe" "благоговейное" ::msgcat::mcset ru "in_love" "влюблённое" ::msgcat::mcset ru "inactive" "бездельничаю" ::msgcat::mcset ru "Include operating system info into a reply to version\ (jabber:iq:version) requests." "Включать информацию об операционной\ ÑиÑтеме в ответ на Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð²ÐµÑ€Ñии (jabber:iq:version)." ::msgcat::mcset ru "Incorrect encoding" "ÐÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð°Ñ ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²ÐºÐ°" ::msgcat::mcset ru "Incorrect SOCKS version" "ÐÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ SOCKS" ::msgcat::mcset ru "Indentation for pretty-printed XML subtags." "Величина\ отÑтупа при форматировании." ::msgcat::mcset ru "indignant" "возмущённое" ::msgcat::mcset ru "Info/Query options." "Параметры Info/Query." ::msgcat::mcset ru "Info:" "ИнформациÑ:" ::msgcat::mcset ru "Information" "ИнформациÑ" ::msgcat::mcset ru "Instructions" "ИнÑтрукциÑ" ::msgcat::mcset ru "interested" "заинтереÑованное" ::msgcat::mcset ru "Internal Server Error" "ВнутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ° Ñервера" ::msgcat::mcset ru "Interval (in minutes) after error reply on request of\ participants list." "Интервал (в минутах) поÑле ошибки в ответ на\ Ð·Ð°Ð¿Ñ€Ð¾Ñ ÑпиÑка учаÑтников." ::msgcat::mcset ru "Interval (in minutes) between requests of participants\ list." "Интервал (в минутах) между запроÑами ÑпиÑка учаÑтников." ::msgcat::mcset ru "Interval:" "Интервал:" ::msgcat::mcset ru "intoxicated" "одурманенное" ::msgcat::mcset ru "Invalid authzid" "ÐедопуÑтимый authzid" ::msgcat::mcset ru "Invalid From" "ÐедопуÑтимый From" ::msgcat::mcset ru "Invalid ID" "ÐедопуÑтимый ID" ::msgcat::mcset ru "Invalid mechanism" "ÐедопуÑтимый механизм" ::msgcat::mcset ru "Invalid Namespace" "ÐедопуÑтимое проÑтранÑтво имён" ::msgcat::mcset ru "Invalid signature" "ÐедопуÑÑ‚Ð¸Ð¼Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ" ::msgcat::mcset ru "invalid userstatus value " "недопуÑтимое значение ÑтатуÑа\ " ::msgcat::mcset ru "Invalid XML" "ÐедопуÑтимый XML" ::msgcat::mcset ru "invincible" "неукротимое" ::msgcat::mcset ru "Invisible" "Ðевидимый" ::msgcat::mcset ru "Invisible list" "Ðевидимый ÑпиÑок" ::msgcat::mcset ru "Invite" "ПриглаÑить" ::msgcat::mcset ru "Invite %s to conferences" "Приглашение %s в конференцию" ::msgcat::mcset ru "Invite to conference..." "ПриглаÑить в конференцию..." ::msgcat::mcset ru "Invite users to %s" "ПриглаÑить пользователей в %s" ::msgcat::mcset ru "Invite users..." "ПриглаÑить пользователей..." ::msgcat::mcset ru "Invited to:" "Приглашение:" ::msgcat::mcset ru "IP address:" "IP адреÑ:" ::msgcat::mcset ru "is available" "доÑтупен Ð´Ð»Ñ Ñ€Ð°Ð·Ð³Ð¾Ð²Ð¾Ñ€Ð°" ::msgcat::mcset ru "is away" "отошёл от компьютера" ::msgcat::mcset ru "is extended away" "давно отошёл от компьютера" ::msgcat::mcset ru "is free to chat" "Ñвободен Ð´Ð»Ñ Ñ€Ð°Ð·Ð³Ð¾Ð²Ð¾Ñ€Ð°" ::msgcat::mcset ru "is invisible" "невидим" ::msgcat::mcset ru "is now" "теперь" ::msgcat::mcset ru "is unavailable" "недоÑтупен Ð´Ð»Ñ Ñ€Ð°Ð·Ð³Ð¾Ð²Ð¾Ñ€Ð°" ::msgcat::mcset ru "Ispell dictionary encoding. If it is empty, system\ encoding is used." "Кодировка ÑÐ»Ð¾Ð²Ð°Ñ€Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸ правопиÑаниÑ. ЕÑли\ пуÑтаÑ, то иÑпользуетÑÑ ÑиÑÑ‚ÐµÐ¼Ð½Ð°Ñ ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²ÐºÐ°." ::msgcat::mcset ru "Ispell options. See ispell manual for\ details.\n\nExamples:\n -d russian\n -d german -T latin1\n -C -d\ english" "Параметры командной Ñтроки ispell. Подробнее Ñм. в\ руководÑтве Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ ispell.\n\nПримеры:\n -d russian\n -d\ german -T latin1\n -C -d english" ::msgcat::mcset ru "Issuer" "Издатель" ::msgcat::mcset ru "Item Not Found" "Объект не найден" ::msgcat::mcset ru "jabber chat/muc" "разговоры/конференции" ::msgcat::mcset ru "jabber iq" "информациÑ" ::msgcat::mcset ru "jabber messages" "ÑообщениÑ" ::msgcat::mcset ru "jabber presence" "приÑутÑтвие" ::msgcat::mcset ru "jabber registration" "региÑтрациÑ" ::msgcat::mcset ru "jabber roster" "контакты" ::msgcat::mcset ru "January" "Январь" ::msgcat::mcset ru "jealous" "ревнивое" ::msgcat::mcset ru "JID list" "СпиÑок ÑобеÑедников" ::msgcat::mcset ru "JID Malformed" "Ðеправильный JID" ::msgcat::mcset ru "JID regexp:" "РегулÑрное выражение Ð´Ð»Ñ JID:" ::msgcat::mcset ru "jogging" "бегаю труÑцой" ::msgcat::mcset ru "Join" "ПриÑоединитьÑÑ" ::msgcat::mcset ru "Join conference" "ПриÑоединитьÑÑ Ðº конференции" ::msgcat::mcset ru "Join group" "Подключение к конференции" ::msgcat::mcset ru "Join group dialog data (groups)." "Данные Ð´Ð»Ñ Ð´Ð¸Ð°Ð»Ð¾Ð³Ð°\ приÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ðº группе (группы)" ::msgcat::mcset ru "Join group dialog data (nicks)." "Данные Ð´Ð»Ñ Ð´Ð¸Ð°Ð»Ð¾Ð³Ð°\ приÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ðº группе (пÑевдонимы)" ::msgcat::mcset ru "Join group dialog data (servers)." "Данные Ð´Ð»Ñ Ð´Ð¸Ð°Ð»Ð¾Ð³Ð°\ приÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ðº группе (Ñерверы)" ::msgcat::mcset ru "Join group..." "ПриÑоединитьÑÑ Ðº группе..." ::msgcat::mcset ru "Join groupchat" "ПриÑоединитьÑÑ Ðº конференции" ::msgcat::mcset ru "Join..." "ПриÑоединитьÑÑ..." ::msgcat::mcset ru "JPEG images" "Ð˜Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ JPEG" ::msgcat::mcset ru "July" "Июль" ::msgcat::mcset ru "June" "Июнь" ::msgcat::mcset ru "Keep trying" "Продолжать попытки" ::msgcat::mcset ru "Key ID" "ID ключа" ::msgcat::mcset ru "Key:" "Ключ:" ::msgcat::mcset ru "Kick" "Выгнать" ::msgcat::mcset ru "Konstantin Khomoutov" "КонÑтантин Хомутов" ::msgcat::mcset ru "last %s%s:" "Ð²Ñ€ÐµÐ¼Ñ Ð±ÐµÐ·Ð´ÐµÐ¹ÑтвиÑ/работы %s%s:" ::msgcat::mcset ru "last %s%s: %s" "Ð²Ñ€ÐµÐ¼Ñ Ð±ÐµÐ·Ð´ÐµÐ¹ÑтвиÑ/работы %s%s: %s" ::msgcat::mcset ru "Last activity" "Ð’Ñ€ÐµÐ¼Ñ Ð±ÐµÐ·Ð´ÐµÐ¹ÑтвиÑ" ::msgcat::mcset ru "Last Activity or Uptime" "Ð’Ñ€ÐµÐ¼Ñ Ð±ÐµÐ·Ð´ÐµÐ¹ÑÑ‚Ð²Ð¸Ñ Ð¸Ð»Ð¸ времÑ\ работы" ::msgcat::mcset ru "Last Name:" "ФамилиÑ:" ::msgcat::mcset ru "Latitude" "Широта" ::msgcat::mcset ru "Latitude:" "Широта:" ::msgcat::mcset ru "Left" "Слева" ::msgcat::mcset ru "Left mouse button" "Ð›ÐµÐ²Ð°Ñ ÐºÐ½Ð¾Ð¿ÐºÐ° мыши" ::msgcat::mcset ru "Length:" "ПродолжительноÑть:" ::msgcat::mcset ru "List name" "Ðазвание ÑпиÑка" ::msgcat::mcset ru "List of discovered JID nodes." "СпиÑок проÑмотренных\ узлов JID." ::msgcat::mcset ru "List of discovered JIDs." "СпиÑок проÑмотренных JID." ::msgcat::mcset ru "List of JIDs to whom headlines have been sent." "СпиÑок\ JID, кому были поÑланы новоÑти." ::msgcat::mcset ru "List of logout reasons." "СпиÑок причин отключениÑ." ::msgcat::mcset ru "List of message destination JIDs." "СпиÑок JID, кому были\ поÑланы ÑообщениÑ." ::msgcat::mcset ru "List of proxy servers for SOCKS5 bytestreams (all\ available servers will be tried for mediated connection)." "СпиÑок\ прокÑи-Ñерверов Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ´Ð°Ñ‡Ð¸ потока SOCKS5 (попытка иÑпользовать в\ качеÑтве поÑредника будет предпринÑта Ð´Ð»Ñ Ð²Ñех доÑтупных Ñерверов)." ::msgcat::mcset ru "Load Image" "Загрузить изображение" ::msgcat::mcset ru "Load state on start" "Загружать ÑоÑтоÑние при Ñтарте" ::msgcat::mcset ru "Load state on Tkabber start." "Загружать ÑоÑтоÑние при\ Ñтарте Tkabber'а." ::msgcat::mcset ru "Loading photo failed: %s." "Ðе удалоÑÑŒ загрузить фото:\ %s." ::msgcat::mcset ru "Locality:" "ÐаÑелённый пункт:" ::msgcat::mcset ru "Location" "ÐдреÑ" ::msgcat::mcset ru "Log in" "ПодключитьÑÑ" ::msgcat::mcset ru "Log in..." "ПодключитьÑÑ..." ::msgcat::mcset ru "Log out" "ОтключитьÑÑ" ::msgcat::mcset ru "Log out with reason..." "ОтключитьÑÑ Ñ ÑƒÐºÐ°Ð·Ð°Ð½Ð¸ÐµÐ¼\ причины..." ::msgcat::mcset ru "Logging options." "Параметры протоколированиÑ." ::msgcat::mcset ru "Login" "Подключение" ::msgcat::mcset ru "Login options." "Параметры подключениÑ." ::msgcat::mcset ru "Logout" "Отключение" ::msgcat::mcset ru "Logout with reason" "Отключение Ñ ÑƒÐºÐ°Ð·Ð°Ð½Ð¸ÐµÐ¼ причины" ::msgcat::mcset ru "Logs" "Протоколы" ::msgcat::mcset ru "lonely" "одинокое" ::msgcat::mcset ru "Longitude" "Долгота" ::msgcat::mcset ru "Longitude:" "Долгота:" ::msgcat::mcset ru "macintosh plugins" "раÑÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð¼Ð°ÐºÐ¸Ð½Ñ‚Ð¾ÑˆÐ°" ::msgcat::mcset ru "Main window:" "Главное окно:" ::msgcat::mcset ru "Malformed signature block" "Ðеправильно Ñформирована\ подпиÑÑŒ" ::msgcat::mcset ru "Manually edit rules" "Изменить правила вручную" ::msgcat::mcset ru "March" "Март" ::msgcat::mcset ru "Mark all seen" "Пометить вÑе как проÑмотренные" ::msgcat::mcset ru "Mark all unseen" "Пометить вÑе как непроÑмотренные" ::msgcat::mcset ru "Marshall T. Rose" "Маршал Т. Роуз" ::msgcat::mcset ru "Match case while searching in chat, log or disco\ windows." "ИÑпользовать чувÑтвительный к региÑтру Ñимволов поиÑк в\ окнах разговора, протокола и обзора Ñлужб." ::msgcat::mcset ru "Match contact JIDs in addition to nicknames in roster\ filter." "Подбирать не только пÑевдоним, но и JID в фильтре\ контактов." ::msgcat::mcset ru "Maximum interval length in hours for which log messages\ should be shown in newly opened chat window (if set to negative then\ the interval is unlimited)." "МакÑимальный интервал (в чаÑах) длÑ\ которого запротоколированные ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð½Ð°Ð´Ð¾ показывать во вновь\ открываемом окне разговора (еÑли положить отрицательным, то\ неограниченный интервал)." ::msgcat::mcset ru "Maximum number of characters in the history in MUC\ compatible conference rooms." "МакÑимальное чиÑло Ñимволов в\ запрашиваемой иÑтории конференции, ÑовмеÑтимой Ñ MUC." ::msgcat::mcset ru "Maximum number of log messages to show in newly opened\ chat window (if set to negative then the number is unlimited)."\ "МакÑимальное чиÑло запротоколированных Ñообщений, которое надо\ показывать во вновь открываемом окне разговора (еÑли положить\ отрицательным, то неограниченное)." ::msgcat::mcset ru "Maximum number of stanzas in the history in MUC\ compatible conference rooms." "МакÑимальное чиÑло Ñообщений в\ запрашиваемой иÑтории конференции, ÑовмеÑтимой Ñ MUC." ::msgcat::mcset ru "Maximum number of status messages to keep. If the history\ size reaches this threshold, the oldest message will be deleted\ automatically when a new one is recorded." "МакÑимальное количеÑтво\ хранимых Ñообщений ÑтатуÑа. Когда количеÑтво Ñтих Ñообщений доÑтигает\ указанного порога, Ñамое Ñтарое Ñообщение автоматичеÑки удалÑетÑÑ Ð¿Ñ€Ð¸\ добавлении нового." ::msgcat::mcset ru "Maximum poll interval." "МакÑимальный интервал между\ HTTP-запроÑами." ::msgcat::mcset ru "Maximum width of tab buttons in tabbed mode."\ "МакÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ ÑˆÐ¸Ñ€Ð¸Ð½Ð° кнопок заголовков вкладок в режиме Ñо\ вкладками." ::msgcat::mcset ru "May" "Май" ::msgcat::mcset ru "mean" "Ñволочное" ::msgcat::mcset ru "Mechanism too weak" "Слишком Ñлабый механизм" ::msgcat::mcset ru "member" "член" ::msgcat::mcset ru "Message" "Сообщение" ::msgcat::mcset ru "Message and Headline options." "Параметры отображениÑ\ Ñообщений и новоÑтей." ::msgcat::mcset ru "Message archive" "Ðрхив Ñообщений" ::msgcat::mcset ru "Message body" "тело ÑообщениÑ" ::msgcat::mcset ru "Message delivered" "Сообщение доÑтавлено" ::msgcat::mcset ru "Message delivered to %s" "Сообщение доÑтавлено %s" ::msgcat::mcset ru "Message displayed" "Сообщение показано" ::msgcat::mcset ru "Message displayed to %s" "Сообщение показано %s" ::msgcat::mcset ru "message filters" "фильтры Ñообщений" ::msgcat::mcset ru "Message from %s" "Сообщение от %s" ::msgcat::mcset ru "Message from:" "Сообщение от:" ::msgcat::mcset ru "Message Recorder:" "Ðвтоответчик:" ::msgcat::mcset ru "Message stored on %s's server" "Сообщение Ñохранено на\ Ñервере %s" ::msgcat::mcset ru "Message stored on the server" "Сообщение Ñохранено на\ Ñервере" ::msgcat::mcset ru "Messages" "СообщениÑ" ::msgcat::mcset ru "Michail Litvak" "Михаил Литвак" ::msgcat::mcset ru "Middle mouse button" "СреднÑÑ ÐºÐ½Ð¾Ð¿ÐºÐ° мыши" ::msgcat::mcset ru "Middle Name" "ОтчеÑтво" ::msgcat::mcset ru "Middle Name:" "ОтчеÑтво:" ::msgcat::mcset ru "Minimize" "Минимизировать" ::msgcat::mcset ru "Minimize to systray (if systray icon is enabled,\ otherwise do nothing)" "Минимизировать в ÑиÑтемный лоток (еÑли значок\ в лотке включён, иначе ничего не делать)" ::msgcat::mcset ru "Minimum poll interval." "Минимальный интервал между\ HTTP-запроÑами." ::msgcat::mcset ru "Minimum width of tab buttons in tabbed mode."\ "ÐœÐ¸Ð½Ð¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ ÑˆÐ¸Ñ€Ð¸Ð½Ð° кнопок заголовков вкладок в режиме Ñо вкладками." ::msgcat::mcset ru "Misc:" "Дополнительно:" ::msgcat::mcset ru "Modem:" "Модем:" ::msgcat::mcset ru "moderator" "модератор" ::msgcat::mcset ru "Moderators" "Модераторы" ::msgcat::mcset ru "Modified: %s" "Изменены: %s" ::msgcat::mcset ru "Month:" "МеÑÑц:" ::msgcat::mcset ru "Mood" "СоÑтоÑние" ::msgcat::mcset ru "Mood:" "СоÑтоÑние:" ::msgcat::mcset ru "moody" "унылое" ::msgcat::mcset ru "Move down" "ПеремеÑтить вниз" ::msgcat::mcset ru "Move tab left/right" "ПеремеÑтить вкладку влево/вправо" ::msgcat::mcset ru "Move up" "ПеремеÑтить вверх" ::msgcat::mcset ru "Moving to extended away" "УÑтанавливаетÑÑ ÑоÑтоÑние\ \"Отошёл давно\" (по бездейÑтвию)" ::msgcat::mcset ru "MUC Ignore" "Игнорирование в MUC" ::msgcat::mcset ru "MUC Ignore Rules" "Правила Ð¸Ð³Ð½Ð¾Ñ€Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð² MUC" ::msgcat::mcset ru "Multiple signatures having different authenticity"\ "Разные подпиÑи имеют разную доÑтоверноÑть" ::msgcat::mcset ru "Mute sound" "Отключить звук" ::msgcat::mcset ru "Mute sound if Tkabber window is focused." "Отключить\ звук, еÑли Ñ„Ð¾ÐºÑƒÑ Ð¿Ñ€Ð¸Ð½Ð°Ð´Ð»ÐµÐ¶Ð¸Ñ‚ окну Tkabber'а." ::msgcat::mcset ru "Mute sound notification." "Отключить звук." ::msgcat::mcset ru "Mute sound when displaying delayed groupchat messages."\ "Отключить звук при получении отложенных Ñообщений в конференциÑÑ…." ::msgcat::mcset ru "Mute sound when displaying delayed personal chat\ messages." "Отключить звук при получении отложенных перÑональных\ Ñообщений." ::msgcat::mcset ru "My Resources" "Мои реÑурÑÑ‹" ::msgcat::mcset ru "my status is" "мой ÑÑ‚Ð°Ñ‚ÑƒÑ Ñ€Ð°Ð²ÐµÐ½" ::msgcat::mcset ru "Name" "ИмÑ" ::msgcat::mcset ru "Name " "Ðазвание" ::msgcat::mcset ru "Name:" "ИмÑ:" ::msgcat::mcset ru "Name: " "Ðазвание:" ::msgcat::mcset ru "nervous" "на нервах" ::msgcat::mcset ru "Network failure" "Ошибка в Ñети" ::msgcat::mcset ru "Network unreachable" "Сеть недоÑтупна" ::msgcat::mcset ru "neutral" "безразличное" ::msgcat::mcset ru "New group name:" "Ðовое Ð¸Ð¼Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ñ‹:" ::msgcat::mcset ru "New password:" "Ðовый пароль:" ::msgcat::mcset ru "New passwords do not match" "Ðовые пароли не Ñовпадают" ::msgcat::mcset ru "Next" "Далее" ::msgcat::mcset ru "Next bookmark" "След. закладка" ::msgcat::mcset ru "Next highlighted" "След. выделенное Ñообщение" ::msgcat::mcset ru "Nick" "ПÑевдоним" ::msgcat::mcset ru "Nick:" "ПÑевдоним:" ::msgcat::mcset ru "Nickname" "ПÑевдоним" ::msgcat::mcset ru "Nickname:" "ПÑевдоним:" ::msgcat::mcset ru "No active list" "Ðет активного ÑпиÑка" ::msgcat::mcset ru "No avatar to store" "Ðет аватары Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸" ::msgcat::mcset ru "No conferences for %s in progress..." "Ðет активной\ конференции Ð´Ð»Ñ %s..." ::msgcat::mcset ru "No default list" "Ðет ÑпиÑка по умолчанию" ::msgcat::mcset ru "No information available" "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð½ÐµÐ´Ð¾Ñтупна" ::msgcat::mcset ru "No reply" "Ðе отвечать" ::msgcat::mcset ru "No such abbreviation: %s" "Ðет такого ÑокращениÑ: %s" ::msgcat::mcset ru "No users in %s roster..." "Ð’ контактах %s нет\ пользователей..." ::msgcat::mcset ru "No users in roster..." "Ð’ контактах нет пользователей..." ::msgcat::mcset ru "Node" "Узел" ::msgcat::mcset ru "Node:" "Узел:" ::msgcat::mcset ru "None" "Ðет" ::msgcat::mcset ru "none" "нет" ::msgcat::mcset ru "Normal" "Обычное" ::msgcat::mcset ru "Normal message" "Сообщение типа \"normal\"" ::msgcat::mcset ru "Not Acceptable" "Ðеприемлемо" ::msgcat::mcset ru "Not Allowed" "Ðе разрешено" ::msgcat::mcset ru "Not Authorized" "Ðе авторизовано" ::msgcat::mcset ru "Not connected" "Соединение не уÑтановлено" ::msgcat::mcset ru "Not Found" "Ðе найдено" ::msgcat::mcset ru "Not Implemented" "Ðе реализовано" ::msgcat::mcset ru "Not logged in" "Ðе подключён" ::msgcat::mcset ru "Notes" "Заметки" ::msgcat::mcset ru "Notify only when available" "УведомлÑть только когда\ доÑтупен" ::msgcat::mcset ru "November" "ÐоÑбрь" ::msgcat::mcset ru "Number of groupchat messages to expire nick completion\ according to the last personally addressed message." "ЧиÑло\ Ñообщений, необходимое Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾, чтобы отключить автодополнение\ пÑевдонима автора поÑледнего ÑообщениÑ, адреÑованного перÑонально." ::msgcat::mcset ru "Number of HTTP poll client security keys to send before\ creating new key sequence." "ЧиÑло ключей безопаÑноÑти, поÑле\ передачи Ñерверу которых генерируетÑÑ Ð½Ð¾Ð²Ð°Ñ Ð¿Ð¾ÑледовательноÑть\ ключей." ::msgcat::mcset ru "October" "ОктÑбрь" ::msgcat::mcset ru "offended" "обиженное" ::msgcat::mcset ru "Offline Messages" "Офлайновые ÑообщениÑ" ::msgcat::mcset ru "OK" "Продолжить" ::msgcat::mcset ru "Old password is incorrect" "Ðеправильный Ñтарый пароль" ::msgcat::mcset ru "Old password:" "Старый пароль:" ::msgcat::mcset ru "on a bus" "еду в автобуÑе" ::msgcat::mcset ru "on a plane" "лечу в Ñамолёте" ::msgcat::mcset ru "on a train" "еду в поезде" ::msgcat::mcset ru "on a trip" "Ñ Ð² поездке" ::msgcat::mcset ru "on the phone" "разговариваю по телефону" ::msgcat::mcset ru "on vacation" "в отпуÑке" ::msgcat::mcset ru "on video phone" "разговариваю по видеотелефону" ::msgcat::mcset ru "One window per bare JID" "Одно окно Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾\ Ñокращенного JID (без реÑурÑа)" ::msgcat::mcset ru "One window per full JID" "Одно окно Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ полного\ JID" ::msgcat::mcset ru "Open" "Открыть" ::msgcat::mcset ru "Open chat" "Открытие окна разговора" ::msgcat::mcset ru "Open chat..." "Открытие окна разговора..." ::msgcat::mcset ru "Open new conversation" "Открыть новый разговор" ::msgcat::mcset ru "Open raw XML window" "Открыть окно XML" ::msgcat::mcset ru "Open statistics monitor" "Открыть монитор ÑтатиÑтики" ::msgcat::mcset ru "Opening IBB connection" "Открываем Ñоединение IBB" ::msgcat::mcset ru "Opening IQ-IBB connection" "Открываем Ñоединение IQ-IBB" ::msgcat::mcset ru "Opening SI connection" "Открываем Ñоединение SI" ::msgcat::mcset ru "Opening SOCKS5 listening socket" "Открываем принимающий\ Ñокет SOCKS5" ::msgcat::mcset ru "Opens a new chat window for the new nick of the room\ occupant" "Открывает новое окно Ð´Ð»Ñ Ñ€Ð°Ð·Ð³Ð¾Ð²Ð¾Ñ€Ð° Ñ Ð¿Ð¾Ñетителем,\ Ñменившим пÑевдоним" ::msgcat::mcset ru "Options for Conference Info module, that allows you to\ see list of participants in roster popup, regardless of whether you\ are currently joined with the conference." "Параметры модулÑ\ информации о конференциÑÑ…, позволÑющего видеть ÑпиÑок учаÑтников\ конференции во вÑплывающем окне, незавиÑимо от того, подключены Ð’Ñ‹ к\ конференции или нет." ::msgcat::mcset ru "Options for entity capabilities plugin." "ÐаÑтройки\ раÑширениÑ, управлÑющего информацией о возможноÑÑ‚ÑÑ… программ." ::msgcat::mcset ru "Options for external play program" "Параметры командной\ Ñтроки программы Ð¿Ñ€Ð¾Ð¸Ð³Ñ€Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð·Ð²ÑƒÐºÐ¾Ð²." ::msgcat::mcset ru "Options for main interface." "Параметры оÑновного\ интерфейÑа." ::msgcat::mcset ru "Options for module that automatically marks you as away\ after idle threshold." "Параметры модулÑ, автоматичеÑки\ уÑтанавливающего ÑоÑтоÑние \"Отошёл\" поÑле уÑтановленного периода\ бездейÑтвиÑ." ::msgcat::mcset ru "Options for Raw XML Input module, which allows you to\ monitor incoming/outgoing traffic from connection to server and send\ custom XML stanzas." "Параметры Ð¼Ð¾Ð´ÑƒÐ»Ñ Ð²Ð²Ð¾Ð´Ð° XML, позволÑющего\ проÑматривать входÑщий/иÑходÑщий поток XML Ñ Ñервера и поÑылать XML,\ Ñгенерированный вручную." ::msgcat::mcset ru "Organization" "ОрганизациÑ" ::msgcat::mcset ru "Organization Name" "ОрганизациÑ: название" ::msgcat::mcset ru "Organization Unit" "ОрганизациÑ: отдел" ::msgcat::mcset ru "Original from" "Изначально от кого" ::msgcat::mcset ru "Original to" "Изначально кому" ::msgcat::mcset ru "OS:" "ОС:" ::msgcat::mcset ru "outcast" "изгой" ::msgcat::mcset ru "owner" "владелец" ::msgcat::mcset ru "Pager:" "Пейджер:" ::msgcat::mcset ru "Parent group" "Группа уровнем выше" ::msgcat::mcset ru "Parent groups" "Группы уровнем выше" ::msgcat::mcset ru "participant" "учаÑтник" ::msgcat::mcset ru "Participants" "УчаÑтники" ::msgcat::mcset ru "partying" "Ñ Ð½Ð° вечеринке" ::msgcat::mcset ru "Passphrase:" "ÐŸÐ°Ñ€Ð¾Ð»ÑŒÐ½Ð°Ñ Ñ„Ñ€Ð°Ð·Ð°:" ::msgcat::mcset ru "Password change failed: %s" "Сменить пароль не удалоÑÑŒ:\ %s" ::msgcat::mcset ru "Password is changed" "Пароль изменен" ::msgcat::mcset ru "Password." "Пароль." ::msgcat::mcset ru "Password:" "Пароль:" ::msgcat::mcset ru "Path to the ispell executable." "Путь к иÑполнÑемому\ файлу ispell." ::msgcat::mcset ru "Paused a reply" "ОÑтановилÑÑ, Ð½Ð°Ð±Ð¸Ñ€Ð°Ñ Ð¾Ñ‚Ð²ÐµÑ‚" ::msgcat::mcset ru "Payment Required" "ТребуетÑÑ Ð¾Ð¿Ð»Ð°Ñ‚Ð°" ::msgcat::mcset ru "Periodically browse roster conferences" "ПериодичеÑкий\ проÑмотр конференций из контактов" ::msgcat::mcset ru "Personal" "Ð›Ð¸Ñ‡Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ" ::msgcat::mcset ru "Personal " "ДолжноÑть" ::msgcat::mcset ru "Personal eventing" "ПерÑональные уведомлениÑ" ::msgcat::mcset ru "Personal eventing via pubsub plugins options." "ÐаÑтройки\ раÑширений публикации и подпиÑки на перÑональные ÑобытиÑ." ::msgcat::mcset ru "Phone BBS" "Телефон BBS" ::msgcat::mcset ru "Phone Cell" "Телефон мобильный" ::msgcat::mcset ru "Phone Fax" "Телефон факÑ" ::msgcat::mcset ru "Phone Home" "Телефон домашний" ::msgcat::mcset ru "Phone ISDN" "Телефон ISDN" ::msgcat::mcset ru "Phone Message Recorder" "Телефон автоответчик" ::msgcat::mcset ru "Phone Modem" "Телефон модем" ::msgcat::mcset ru "Phone Pager" "Телефон пейджер" ::msgcat::mcset ru "Phone PCS" "Телефон PCS" ::msgcat::mcset ru "Phone Preferred" "Телефон предпочтительный" ::msgcat::mcset ru "Phone Video" "Телефон видео" ::msgcat::mcset ru "Phone Voice" "Телефон обычный" ::msgcat::mcset ru "Phone Work" "Телефон рабочий" ::msgcat::mcset ru "Phone:" "Телефон:" ::msgcat::mcset ru "Phones" "Телефоны" ::msgcat::mcset ru "Photo" "ФотографиÑ" ::msgcat::mcset ru "Ping server using urn:xmpp:ping requests." "Пинговать\ Ñервер запроÑами urn:xmpp:ping." ::msgcat::mcset ru "pixmaps management" "изображениÑ" ::msgcat::mcset ru "Plaintext" "Открытый неÑжатый текÑÑ‚" ::msgcat::mcset ru "playful" "игривое" ::msgcat::mcset ru "playing sports" "Ñпортивные игры" ::msgcat::mcset ru "Please define environment variable BROWSER" "Определите\ переменную Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñ BROWSER" ::msgcat::mcset ru "Please enter passphrase" "Введите парольную фразу" ::msgcat::mcset ru "Please join %s" "ПожалуйÑта приÑоединÑйтеÑÑŒ к %s" ::msgcat::mcset ru "Please try again" "Попробуйте еще раз" ::msgcat::mcset ru "Please, be patient while chats history is being converted\ to new format" "ПожалуйÑта подождите, пока иÑÑ‚Ð¾Ñ€Ð¸Ñ Ñ€Ð°Ð·Ð³Ð¾Ð²Ð¾Ñ€Ð¾Ð²\ преобразовываетÑÑ Ð² новый формат" ::msgcat::mcset ru "Please, be patient while Tkabber configuration directory\ is being transferred to the new location" "ПожалуйÑта подождите, пока\ Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Ñ Ð½Ð°Ñтройками Tkabber'а переноÑитÑÑ Ð² другое меÑто" ::msgcat::mcset ru "plugin management" "управление раÑширениÑми" ::msgcat::mcset ru "Plugins" "РаÑширениÑ" ::msgcat::mcset ru "Plugins options." "Параметры раÑширений." ::msgcat::mcset ru "PNG images" "Ð˜Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ PNG" ::msgcat::mcset ru "Policy Violation" "Ðарушение политики" ::msgcat::mcset ru "Popup menu" "ВывеÑти меню" ::msgcat::mcset ru "Port for outgoing HTTP file transfers (0 for assigned\ automatically). This is useful when sending files from behind a NAT\ with a forwarded port." "Порт Ð´Ð»Ñ Ð¸ÑходÑщей передачи файлов по HTTP\ (еÑли равен 0, то выбираетÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки). ПрименÑетÑÑ, когда файл\ поÑылаетÑÑ Ñ‡ÐµÑ€ÐµÐ· NAT через пробраÑываемый порт." ::msgcat::mcset ru "Port:" "Порт:" ::msgcat::mcset ru "Postal Code" "Почтовый индекÑ" ::msgcat::mcset ru "Postal Code:" "Почтовый индекÑ:" ::msgcat::mcset ru "Postal code:" "Почтовый индекÑ:" ::msgcat::mcset ru "Preferred:" "Предпочтительный:" ::msgcat::mcset ru "Prefix" "ПрефикÑ" ::msgcat::mcset ru "Prefix:" "ПрефикÑ:" ::msgcat::mcset ru "Presence" "ПриÑутÑтвие" ::msgcat::mcset ru "presence" "приÑутÑтвие" ::msgcat::mcset ru "Presence bar" "Панель приÑутÑтвиÑ/ÑтатуÑа" ::msgcat::mcset ru "Presence information" "приÑутÑтвие" ::msgcat::mcset ru "Presence is signed" "ПриÑутÑтвие подпиÑано" ::msgcat::mcset ru "Pretty print incoming and outgoing XML stanzas."\ "Форматировать XML перед выводом." ::msgcat::mcset ru "Pretty print XML" "Форматировать XML" ::msgcat::mcset ru "Prev" "Ðазад" ::msgcat::mcset ru "Prev bookmark" "Пред. закладка" ::msgcat::mcset ru "Prev highlighted" "Пред. выделенное Ñообщение" ::msgcat::mcset ru "Previous/Next history message" "Предыдущее/Ñледующее\ Ñообщение" ::msgcat::mcset ru "Previous/Next tab" "ПредыдущаÑ/ÑÐ»ÐµÐ´ÑƒÑŽÑ‰Ð°Ñ Ð²ÐºÐ»Ð°Ð´ÐºÐ°" ::msgcat::mcset ru "Priority." "Приоритет." ::msgcat::mcset ru "Priority:" "Приоритет:" ::msgcat::mcset ru "Privacy list is activated" "СпиÑок приватноÑти\ активирован" ::msgcat::mcset ru "Privacy list is not activated" "СпиÑок приватноÑти не\ активирован" ::msgcat::mcset ru "Privacy list is not created" "СпиÑок приватноÑти не\ Ñоздан" ::msgcat::mcset ru "Privacy lists" "СпиÑки приватноÑти" ::msgcat::mcset ru "Privacy lists are not implemented" "СпиÑки приватноÑти не\ реализованы" ::msgcat::mcset ru "Privacy lists are unavailable" "СпиÑки приватноÑти\ недоÑтупны" ::msgcat::mcset ru "Privacy lists error" "Ошибка ÑпиÑков приватноÑти" ::msgcat::mcset ru "Privacy rules" "ОбеÑпечение приватноÑти" ::msgcat::mcset ru "Profile" "Профиль" ::msgcat::mcset ru "Profile on" "Включить профилирование" ::msgcat::mcset ru "Profile report" "Отчет о профилировании" ::msgcat::mcset ru "Profiles" "Профили" ::msgcat::mcset ru "Propose to configure newly created MUC room. If set to\ false then the default room configuration is automatically accepted."\ "Предлагать конфигурировать вновь Ñозданную конференцию. ЕÑли\ уÑтановить в false, то автоматичеÑки принимаетÑÑ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ð¿Ð¾\ умолчанию." ::msgcat::mcset ru "Protocol:" "Протокол:" ::msgcat::mcset ru "proud" "горделивое" ::msgcat::mcset ru "Proxy" "ПрокÑи" ::msgcat::mcset ru "Proxy authentication required" "ТребуетÑÑ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ\ на прокÑи" ::msgcat::mcset ru "Proxy password:" "Пароль:" ::msgcat::mcset ru "Proxy port:" "Порт прокÑи:" ::msgcat::mcset ru "Proxy server:" "ПрокÑи Ñервер:" ::msgcat::mcset ru "Proxy type to connect." "Тип прокÑи Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ." ::msgcat::mcset ru "Proxy type:" "Тип прокÑи:" ::msgcat::mcset ru "Proxy username:" "Пользователь:" ::msgcat::mcset ru "Pub/sub" "Опу/под" ::msgcat::mcset ru "Publish" "Опубликовать" ::msgcat::mcset ru "Publish \"playback stopped\" instead" "Опубликовать\ \"воÑпроизведение оÑтановлено\" вмеÑто мелодии" ::msgcat::mcset ru "Publish node" "Опубликовать узел" ::msgcat::mcset ru "Publish user activity..." "Опубликовать занÑтие\ пользователÑ..." ::msgcat::mcset ru "Publish user location..." "Опубликовать меÑтонахождение\ пользователÑ" ::msgcat::mcset ru "Publish user mood..." "Опубликовать наÑтроение\ пользователÑ..." ::msgcat::mcset ru "Publish user tune..." "Опубликовать мелодию\ пользователÑ..." ::msgcat::mcset ru "Publishing is only possible while being online"\ "ÐŸÑƒÐ±Ð»Ð¸ÐºÐ°Ñ†Ð¸Ñ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð° лишь при активном подключении" ::msgcat::mcset ru "Purge all messages" "Удалить вÑе ÑообщениÑ" ::msgcat::mcset ru "Purge message" "Удалить Ñообщение" ::msgcat::mcset ru "Purge seen messages" "Удалить полученные ÑообщениÑ" ::msgcat::mcset ru "Purged all abbreviations" "Удалены вÑе ÑокращениÑ" ::msgcat::mcset ru "Question" "ВопроÑ" ::msgcat::mcset ru "Quick Help" "ÐšÑ€Ð°Ñ‚ÐºÐ°Ñ Ñправка" ::msgcat::mcset ru "Quick help" "ÐšÑ€Ð°Ñ‚ÐºÐ°Ñ Ñправка" ::msgcat::mcset ru "Quit" "Выйти" ::msgcat::mcset ru "Quote" "Цитировать" ::msgcat::mcset ru "Raise new tab." "Размещать новую вкладку поверх\ оÑтальных." ::msgcat::mcset ru "Rating:" "Оценка:" ::msgcat::mcset ru "Raw XML" "Окно XML" ::msgcat::mcset ru "Read on..." "Читать далее..." ::msgcat::mcset ru "reading" "читаю" ::msgcat::mcset ru "Reason" "Причина" ::msgcat::mcset ru "Reason:" "Причина:" ::msgcat::mcset ru "Receive" "Получить" ::msgcat::mcset ru "Receive error: Stream ID is in use" "Ошибка получениÑ: ID\ потока уже иÑпользуетÑÑ" ::msgcat::mcset ru "Receive file from %s" "Получение файла от %s" ::msgcat::mcset ru "Received by:" "Получено:" ::msgcat::mcset ru "Received/Sent" "Получено/Отправлено" ::msgcat::mcset ru "Recipient Error" "Ошибка получателÑ" ::msgcat::mcset ru "Recipient Unavailable" "Получатель недоÑтупен" ::msgcat::mcset ru "Reconnect to server if it does not reply (with result or\ with error) to ping (urn:xmpp:ping) request in specified time\ interval (in seconds)." "ПереподключатьÑÑ Ðº Ñерверу, еÑли он не\ ответил (возможно ошибкой) на пинг (urn:xmpp:ping) за указанный\ временной интервал (в Ñекундах)." ::msgcat::mcset ru "Redirect" "Перенаправление" ::msgcat::mcset ru "Redo" "Откатить откатку" ::msgcat::mcset ru "Region:" "Регион:" ::msgcat::mcset ru "Register" "РегиÑтрациÑ" ::msgcat::mcset ru "Register in %s" "РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð² %s" ::msgcat::mcset ru "Registration failed: %s" "ЗарегиÑтрироватьÑÑ Ð½Ðµ удалоÑÑŒ:\ %s" ::msgcat::mcset ru "Registration is successful!" "РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ ÑƒÑпешнаÑ!" ::msgcat::mcset ru "Registration Required" "ТребуетÑÑ Ñ€ÐµÐ³Ð¸ÑтрациÑ" ::msgcat::mcset ru "Registration: %s" "РегиÑтрациÑ: %s" ::msgcat::mcset ru "rehearsing" "у Ð¼ÐµÐ½Ñ Ñ€ÐµÐ¿ÐµÑ‚Ð¸Ñ†Ð¸Ñ" ::msgcat::mcset ru "relaxing" "отдыхаю" ::msgcat::mcset ru "relieved" "гора Ñ Ð¿Ð»ÐµÑ‡" ::msgcat::mcset ru "remorseful" "раÑкаиваюÑÑŒ" ::msgcat::mcset ru "Remote Connection Failed" "Ошибка удаленного ÑоединениÑ" ::msgcat::mcset ru "Remote control options." "ÐаÑтройки удалённого\ управлениÑ." ::msgcat::mcset ru "Remote Server Error" "Ошибка удаленного Ñервера" ::msgcat::mcset ru "Remote Server Not Found" "Сервер не найден" ::msgcat::mcset ru "Remote Server Timeout" "ИÑтекло Ð²Ñ€ÐµÐ¼Ñ Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ Ð¾Ñ‚Ð²ÐµÑ‚Ð°\ Ñервера" ::msgcat::mcset ru "Remove" "Удалить" ::msgcat::mcset ru "Remove all users in group..." "Удалить вÑе контакты в\ группе..." ::msgcat::mcset ru "Remove from list" "Удалить из ÑпиÑка" ::msgcat::mcset ru "Remove from roster..." "Удалить из контактов..." ::msgcat::mcset ru "Remove group..." "Удалить группу..." ::msgcat::mcset ru "Remove item..." "Удалить Ñлемент..." ::msgcat::mcset ru "Remove list" "Удалить ÑпиÑок" ::msgcat::mcset ru "Rename group..." "Переименовать группу..." ::msgcat::mcset ru "Rename roster group" "Переименование группы" ::msgcat::mcset ru "Repeat new password:" "Еще раз новый пароль:" ::msgcat::mcset ru "Replace opened connections" "Закрыть открытые ÑоединениÑ" ::msgcat::mcset ru "Replace opened connections." "Закрыть открытые\ ÑоединениÑ." ::msgcat::mcset ru "Reply" "Ответить" ::msgcat::mcset ru "Reply subject:" "Тема ответа:" ::msgcat::mcset ru "Reply to" "Отвечать" ::msgcat::mcset ru "Reply to current time (jabber:iq:time) requests."\ "Отвечать на запроÑÑ‹ времени (jabber:iq:time)." ::msgcat::mcset ru "Reply to entity time (urn:xmpp:time) requests." "Отвечать\ на запроÑÑ‹ о времени на компьютере Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ (urn:xmpp:time)." ::msgcat::mcset ru "Reply to idle time (jabber:iq:last) requests." "Отвечать\ на запроÑÑ‹ времени бездейÑÑ‚Ð²Ð¸Ñ (jabber:iq:last)." ::msgcat::mcset ru "Reply to ping (urn:xmpp:ping) requests." "Отвечать на\ пинг (urn:xmpp:ping)." ::msgcat::mcset ru "Reply to room" "Отвечать в конференцию" ::msgcat::mcset ru "Reply to version (jabber:iq:version) requests." "Отвечать\ на запроÑÑ‹ верÑии (jabber:iq:version)." ::msgcat::mcset ru "reply with" "ответить" ::msgcat::mcset ru "Report the list of current MUC rooms on disco#items\ query." "Отвечать на Ð·Ð°Ð¿Ñ€Ð¾Ñ disco#items о MUC-конференциÑÑ…, в которых\ Ð’Ñ‹ принимаете учаÑтие." ::msgcat::mcset ru "Request" "ЗапроÑить" ::msgcat::mcset ru "Request Error" "Ошибка запроÑа" ::msgcat::mcset ru "Request failed: %s" "Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð½Ðµ удалÑÑ: %s" ::msgcat::mcset ru "Request only unseen (which aren't displayed in the chat\ window) messages in the history in MUC compatible conference rooms."\ "Запрашивать только те ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¸Ð· иÑтории, которые не показаны в\ уже открытом окне (Ð´Ð»Ñ ÐºÐ¾Ð½Ñ„ÐµÑ€ÐµÐ½Ñ†Ð¸Ð¸, ÑовмеÑтимой Ñ MUC)." ::msgcat::mcset ru "Request subscription" "ЗапроÑить подпиÑку" ::msgcat::mcset ru "Request Timeout" "Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð¿Ñ€ÐµÐ²Ñ‹Ñил допуÑтимое времÑ" ::msgcat::mcset ru "Requesting conference list: %s" "Ð—Ð°Ð¿Ñ€Ð¾Ñ ÑпиÑка\ конференций: %s" ::msgcat::mcset ru "Requesting filter rules: %s" "Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð» фильтрованиÑ:\ %s" ::msgcat::mcset ru "Requesting ignore list: %s" "Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð¸Ð³Ð½Ð¾Ñ€Ð¸Ñ€ÑƒÐµÐ¼Ð¾Ð³Ð¾ ÑпиÑка:\ %s" ::msgcat::mcset ru "Requesting invisible list: %s" "Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð½ÐµÐ²Ð¸Ð´Ð¸Ð¼Ð¾Ð³Ð¾ ÑпиÑка:\ %s" ::msgcat::mcset ru "Requesting privacy list: %s" "Ð—Ð°Ð¿Ñ€Ð¾Ñ ÑпиÑка приватноÑти:\ %s" ::msgcat::mcset ru "Requesting privacy rules: %s" "Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð» обеÑпечениÑ\ приватноÑти: %s" ::msgcat::mcset ru "Requesting visible list: %s" "Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð²Ð¸Ð´Ð¸Ð¼Ð¾Ð³Ð¾ ÑпиÑка: %s" ::msgcat::mcset ru "Reset to current value" "УÑтановить текущее значение" ::msgcat::mcset ru "Reset to default value" "УÑтановить значение по\ умолчанию" ::msgcat::mcset ru "Reset to saved value" "УÑтановить Ñохранённое значение" ::msgcat::mcset ru "Reset to value from config file" "УÑтановить значение из\ конфигурационного файла" ::msgcat::mcset ru "Resource Constraint" "ÐедоÑтаточно реÑурÑов" ::msgcat::mcset ru "Resource." "РеÑурÑ." ::msgcat::mcset ru "Resource:" "РеÑурÑ:" ::msgcat::mcset ru "restless" "неугомонное" ::msgcat::mcset ru "Restricted XML" "Запрещённый XML" ::msgcat::mcset ru "Resubscribe" "ПереподпиÑатьÑÑ" ::msgcat::mcset ru "Resubscribe to all users in group..." "ПереподпиÑатьÑÑ ÐºÐ¾\ вÑем пользователÑм в группе..." ::msgcat::mcset ru "Retract node" "ОтказатьÑÑ Ð¾Ñ‚ узла" ::msgcat::mcset ru "Retrieve offline messages using POP3-like protocol."\ "Получать офлайновые ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ñ Ð¸Ñпользованием протокола типа POP3." ::msgcat::mcset ru "Retry to connect forever." "ПытатьÑÑ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡Ð°Ñ‚ÑŒÑÑ\ беÑконечно много раз." ::msgcat::mcset ru "Returning from auto-away" "Возврат из ÑоÑтоÑниÑ\ бездейÑтвиÑ" ::msgcat::mcset ru "Revoke Admin Privileges" "Отозвать права админиÑтратора" ::msgcat::mcset ru "Revoke Membership" "Отозвать членÑтво" ::msgcat::mcset ru "Revoke Moderator Privileges" "Отозвать права модератора" ::msgcat::mcset ru "Revoke Owner Privileges" "Отозвать права владельца" ::msgcat::mcset ru "Revoke Voice" "Отозвать право говорить" ::msgcat::mcset ru "Right" "Справа" ::msgcat::mcset ru "Right mouse button" "ÐŸÑ€Ð°Ð²Ð°Ñ ÐºÐ½Ð¾Ð¿ÐºÐ° мыши" ::msgcat::mcset ru "Role" "Роль" ::msgcat::mcset ru "Role:" "ДолжноÑть:" ::msgcat::mcset ru "Room %s is successfully created" "Комната %s уÑпешно\ Ñоздана" ::msgcat::mcset ru "Room is created" "Комната Ñоздана" ::msgcat::mcset ru "Room is destroyed" "Комната удалена" ::msgcat::mcset ru "Room:" "Комната:" ::msgcat::mcset ru "Roster" "Контакты" ::msgcat::mcset ru "Roster Files" "Файлы контактов" ::msgcat::mcset ru "Roster filter." "Фильтр контактов." ::msgcat::mcset ru "Roster group:" "Группа в контактах:" ::msgcat::mcset ru "Roster item may be dropped not only over group name but\ also over any item in group." "При перетаÑкивании контакта из одной\ группы контактов в другую, его можно отпуÑтить не только над\ названием группы, но и над любым контактом в Ñтой группе." ::msgcat::mcset ru "Roster Notes" "Заметки в контактах" ::msgcat::mcset ru "Roster of %s" "Контакты %s" ::msgcat::mcset ru "Roster options." "Параметры контактов." ::msgcat::mcset ru "roster plugins" "раÑÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ ÐºÐ¾Ð½Ñ‚Ð°ÐºÑ‚Ð¾Ð²" ::msgcat::mcset ru "Roster restoration completed" "ВоÑÑтановление ÑпиÑка\ контактов завершено" ::msgcat::mcset ru "Rule name already exists" "Правило Ñ Ñ‚Ð°ÐºÐ¸Ð¼ названием уже\ ÑущеÑтвует" ::msgcat::mcset ru "Rule Name:" "Ðазвание правила:" ::msgcat::mcset ru "running" "Ñовершаю пробежку" ::msgcat::mcset ru "running an errand" "хожу по делам" ::msgcat::mcset ru "sad" "печальное" ::msgcat::mcset ru "sarcastic" "Ñзвительное" ::msgcat::mcset ru "SASL auth error:\n%s" "Ошибка аутентификации SASL:\n%s" ::msgcat::mcset ru "SASL Certificate:" "SASL Ñертификат:" ::msgcat::mcset ru "SASL Port:" "SASL порт:" ::msgcat::mcset ru "Save as:" "Сохранить как:" ::msgcat::mcset ru "Save state" "Сохранить ÑоÑтоÑние" ::msgcat::mcset ru "Save state on exit" "СохранÑть ÑоÑтоÑние при выходе" ::msgcat::mcset ru "Save state on Tkabber exit." "СохранÑть ÑоÑтоÑние при\ выходе из Tkabber'а." ::msgcat::mcset ru "Save To Log" "Сохранить в журнал" ::msgcat::mcset ru "scheduled holiday" "у Ð¼ÐµÐ½Ñ Ð¿Ð»Ð°Ð½Ð¾Ð²Ñ‹Ð¹ выходной" ::msgcat::mcset ru "Screenname conversion" "Преобразование Ñкранного имени" ::msgcat::mcset ru "Screenname:" "Экранное имÑ:" ::msgcat::mcset ru "Screenname: %s\n\nConverted JID: %s" "Экранное имÑ:\ %s\n\nПреобразованный JID: %s" ::msgcat::mcset ru "Scroll chat window up/down" "Прокрутить окно разговора\ вверх/вниз" ::msgcat::mcset ru "Search" "ПоиÑк" ::msgcat::mcset ru "Search again" "ИÑкать Ñнова" ::msgcat::mcset ru "Search down" "ИÑкать вниз" ::msgcat::mcset ru "Search in %s" "ПоиÑк в %s" ::msgcat::mcset ru "Search in %s: No matching items found" "ПоиÑк в %s:\ Объекты, удовлетворÑющие критериÑм поиÑка, не найдены" ::msgcat::mcset ru "Search in Tkabber windows options." "ÐаÑтройки поиÑка в\ окнах Tkabber'а." ::msgcat::mcset ru "search plugins" "раÑÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð¸Ñка" ::msgcat::mcset ru "Search up" "ИÑкать вверх" ::msgcat::mcset ru "Search: %s" "ПоиÑк: %s" ::msgcat::mcset ru "searching" "поиÑк" ::msgcat::mcset ru "See Other Host" "Смотри другой хоÑÑ‚" ::msgcat::mcset ru "Select" "Выбрать" ::msgcat::mcset ru "Select Key for Signing %s Traffic" "Выбор ключа длÑ\ подпиÑÑ‹Ð²Ð°Ð½Ð¸Ñ Ñообщений %s" ::msgcat::mcset ru "Select month:" "Выберите меÑÑц:" ::msgcat::mcset ru "Self signed certificate" "Сертификат ÑамоподпиÑан" ::msgcat::mcset ru "Send" "Отправить" ::msgcat::mcset ru "Send broadcast message..." "ПоÑлать широковещательное\ Ñообщение..." ::msgcat::mcset ru "Send contacts to" "Отправить контакты" ::msgcat::mcset ru "Send contacts to %s" "Отправка контактов %s" ::msgcat::mcset ru "Send custom presence" "ПоÑлать Ñпециальное приÑутÑтвие" ::msgcat::mcset ru "Send file to %s" "Отправка файла %s" ::msgcat::mcset ru "Send file..." "Отправить файл..." ::msgcat::mcset ru "Send message" "Отправка ÑообщениÑ" ::msgcat::mcset ru "Send message of the day..." "ПоÑлать Ñообщение днÑ..." ::msgcat::mcset ru "Send message to %s" "Отправка ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ %s" ::msgcat::mcset ru "Send message to all users in group..." "Отправить\ Ñообщение вÑем пользователÑм в группе..." ::msgcat::mcset ru "Send message to group" "Отправка ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ðµ" ::msgcat::mcset ru "Send message to group %s" "Отправка ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ðµ %s" ::msgcat::mcset ru "Send message..." "Отправить Ñообщение..." ::msgcat::mcset ru "Send request to: " "Отправка запроÑа: " ::msgcat::mcset ru "Send subscription at %s" "Отправка запроÑа на подпиÑку на\ %s" ::msgcat::mcset ru "Send subscription request" "Отправка запроÑа на подпиÑку" ::msgcat::mcset ru "Send subscription request to %s" "Отправка запроÑа на\ подпиÑку %s" ::msgcat::mcset ru "Send subscription to: " "Отправка запроÑа на подпиÑку: " ::msgcat::mcset ru "Send to server" "Отправить на Ñервер" ::msgcat::mcset ru "Send users..." "Отправить контакты..." ::msgcat::mcset ru "Sending %s %s list" "Отправка %s %s ÑпиÑка" ::msgcat::mcset ru "Sending conference list: %s" "Отправка ÑпиÑка\ конференций: %s" ::msgcat::mcset ru "Sending configure form" "Отправка конфигурационной формы" ::msgcat::mcset ru "Sending ignore list: %s" "Отправка игнорируемого ÑпиÑка:\ %s" ::msgcat::mcset ru "Sending invisible list: %s" "Отправка невидимого ÑпиÑка:\ %s" ::msgcat::mcset ru "Sending visible list: %s" "Отправка видимого ÑпиÑка: %s" ::msgcat::mcset ru "September" "СентÑбрь" ::msgcat::mcset ru "Sergei Golovan" "Сергей Головань" ::msgcat::mcset ru "Serial number" "Серийный номер" ::msgcat::mcset ru "serious" "Ñерьёзное" ::msgcat::mcset ru "Server doesn't support hashed password authentication"\ "Сервер не поддерживает передачу шифрованных паролей" ::msgcat::mcset ru "Server doesn't support plain or digest authentication"\ "Сервер не поддерживает допуÑтимый тип аутентификации (plain или\ digest)" ::msgcat::mcset ru "Server Error" "Ошибка Ñервера" ::msgcat::mcset ru "Server haven't provided compress feature" "Сервер не\ поддерживает Ñжатие" ::msgcat::mcset ru "Server haven't provided non-SASL authentication feature"\ "Сервер не поддерживает аутентификацию non-SASL" ::msgcat::mcset ru "Server haven't provided SASL authentication feature"\ "Сервер не поддерживает аутентификацию SASL" ::msgcat::mcset ru "Server haven't provided STARTTLS feature" "Сервер не\ поддерживает STARTTLS" ::msgcat::mcset ru "Server haven't provided supported compress method"\ "Сервер не поддерживает доÑтупные методы ÑжатиÑ" ::msgcat::mcset ru "Server message" "Сообщение Ñервера" ::msgcat::mcset ru "Server name or IP-address." "Ð˜Ð¼Ñ Ñервера или IP-адреÑ." ::msgcat::mcset ru "Server name." "Ð˜Ð¼Ñ Ñервера." ::msgcat::mcset ru "Server port." "Порт Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ðº Ñерверу." ::msgcat::mcset ru "Server Port:" "Порт Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ:" ::msgcat::mcset ru "Server provided mechanism %s. It is forbidden" "Сервер\ предложил механизм %s. Он запрещен" ::msgcat::mcset ru "Server provided mechanisms %s. They are forbidden"\ "Сервер предложил механизмы %s. Они запрещены" ::msgcat::mcset ru "Server provided no SASL mechanisms" "Сервер не предложил\ механизмы SASL" ::msgcat::mcset ru "Server:" "Сервер:" ::msgcat::mcset ru "Service Discovery" "Обзор Ñлужб" ::msgcat::mcset ru "service discovery" "обзор Ñлужб" ::msgcat::mcset ru "Service info" "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ Ñлужбе" ::msgcat::mcset ru "Service statistics" "СтатиÑтика" ::msgcat::mcset ru "Service Unavailable" "Служба недоÑтупна" ::msgcat::mcset ru "Session key bits" "Размер ключа ÑеÑÑии" ::msgcat::mcset ru "Set" "УÑтановить" ::msgcat::mcset ru "Set bookmark" "УÑтановить закладку" ::msgcat::mcset ru "Set for current and future sessions" "УÑтановить длÑ\ текущей и Ñледующих ÑеÑÑий" ::msgcat::mcset ru "Set for current session only" "УÑтановить только длÑ\ текущей ÑеÑÑии" ::msgcat::mcset ru "Set priority to 0 when moving to extended away state."\ "СбраÑывать приоритет в 0 при переходе в ÑоÑтоÑние \"Отошёл давно\"." ::msgcat::mcset ru "Settings of rich text facility which is used to render\ chat messages and logs." "ÐаÑтройка подÑиÑтемы Ð¾Ñ„Ð¾Ñ€Ð¼Ð»ÐµÐ½Ð¸Ñ Ñ‚ÐµÐºÑта,\ ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¸ÑпользуетÑÑ Ð´Ð»Ñ Ð²Ñ‹Ð²Ð¾Ð´Ð° Ñообщений и протоколов разговоров." ::msgcat::mcset ru "SHA1 hash" "SHA1 Ñ…Ñш" ::msgcat::mcset ru "shaving" "бреюÑÑŒ" ::msgcat::mcset ru "shocked" "потрÑÑённое" ::msgcat::mcset ru "shopping" "хожу по магазинам" ::msgcat::mcset ru "Show" "Показать" ::msgcat::mcset ru "Show balloons with headline messages over tree nodes."\ "Показывать вÑплывающие окна Ñ Ñ‚ÐµÐºÑтом новоÑти над заголовками\ Ñообщений." ::msgcat::mcset ru "Show console" "Показать конÑоль" ::msgcat::mcset ru "Show detailed info on conference room members in roster\ item tooltips." "Показывать детальную информацию об учаÑтниках\ конференции во вÑплывающем окне, ÑоответÑтвующем конференции, в\ контактах." ::msgcat::mcset ru "Show emoticons" "Показать Ñмоциконки" ::msgcat::mcset ru "Show history" "Показать иÑторию" ::msgcat::mcset ru "Show images for emoticons." "Показывать Ñмоциконки в виде\ картинок." ::msgcat::mcset ru "Show info" "Показать информацию" ::msgcat::mcset ru "Show IQ requests in the status line." "Показывать\ IQ-запроÑÑ‹ в ÑтатуÑной Ñтроке." ::msgcat::mcset ru "Show main window" "Показать главное окно" ::msgcat::mcset ru "Show menu tearoffs when possible." "ИÑпользовать\ \"отрывающиеÑÑ\" меню, где Ñто возможно." ::msgcat::mcset ru "Show my own resources in the roster." "Показывать в\ контактах ÑобÑтвенные реÑурÑÑ‹." ::msgcat::mcset ru "Show native icons for contacts, connected to\ transports/services in roster." "ИÑпользовать оригинальные\ пиктограммы Ð´Ð»Ñ ÐºÐ¾Ð½Ñ‚Ð°ÐºÑ‚Ð¾Ð², подключённых через транÑпорты/Ñлужбы, в\ окне контактов." ::msgcat::mcset ru "Show native icons for transports/services in roster."\ "ИÑпользовать оригинальные пиктограммы Ð´Ð»Ñ Ñ‚Ñ€Ð°Ð½Ñпортов/Ñлужб в окне\ контактов." ::msgcat::mcset ru "Show number of unread messages in tab titles."\ "Показывать чиÑло непрочитанных Ñообщений в заголовках вкладок." ::msgcat::mcset ru "Show offline users" "Показывать неподключённые контакты" ::msgcat::mcset ru "Show online users only" "ПоказываютÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ активные\ пользователи" ::msgcat::mcset ru "Show only online users in roster." "Показывать в окне\ контактов только подключённые контакты." ::msgcat::mcset ru "Show only the number of personal unread messages in\ window title." "Показывать в заголовке окна только чиÑло личных\ непрочитанных Ñообщений." ::msgcat::mcset ru "Show own resources" "Показывать ÑобÑтвенные реÑурÑÑ‹" ::msgcat::mcset ru "Show palette of emoticons" "Показать меню Ñмоциконок" ::msgcat::mcset ru "Show presence bar." "Показывать панель\ приÑутÑтвиÑ/ÑтатуÑа." ::msgcat::mcset ru "Show status bar." "Показывать ÑтатуÑную Ñтроку." ::msgcat::mcset ru "Show subscription type in roster item tooltips."\ "Показывать тип подпиÑки на приÑутÑтвие во вÑплывающем окне в\ контактах." ::msgcat::mcset ru "Show TkCon console" "Показать конÑоль TkCon" ::msgcat::mcset ru "Show Toolbar." "Показывать панель инÑтрументов." ::msgcat::mcset ru "Show user or service info" "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ пользователе или\ Ñлужбе" ::msgcat::mcset ru "Show user or service info..." "Показать информацию о\ пользователе или Ñлужбе..." ::msgcat::mcset ru "shy" "заÑтенчивое" ::msgcat::mcset ru "SI connection closed" "Соединение SI закрыто" ::msgcat::mcset ru "sick" "болезненное" ::msgcat::mcset ru "Side where to place tabs in tabbed mode." "Сторона, Ñ\ которой размещать заголовки вкладок в режиме Ñ Ð²ÐºÐ»Ð°Ð´ÐºÐ°Ð¼Ð¸." ::msgcat::mcset ru "Sign traffic" "ПодпиÑывать ÑообщениÑ" ::msgcat::mcset ru "Signature not processed due to missing key" "ПодпиÑÑŒ не\ проверена из-за отÑутÑÑ‚Ð²Ð¸Ñ ÐºÐ»ÑŽÑ‡Ð°" ::msgcat::mcset ru "Single window" "Одно окно" ::msgcat::mcset ru "Size:" "Размер:" ::msgcat::mcset ru "skiing" "катаюÑÑŒ на лыжах" ::msgcat::mcset ru "sleeping" "Ñплю" ::msgcat::mcset ru "sleepy" "Ñонное" ::msgcat::mcset ru "Smart autoscroll" "\"УмнаÑ\" автопрокрутка" ::msgcat::mcset ru "socializing" "общеÑтвенно-Ð¿Ð¾Ð»ÐµÐ·Ð½Ð°Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ð°" ::msgcat::mcset ru "SOCKS authentication failed" "Ошибка аутентификации\ SOCKS" ::msgcat::mcset ru "SOCKS command not supported" "Команда SOCKS не\ поддерживаетÑÑ" ::msgcat::mcset ru "SOCKS connection not allowed by ruleset" "Соединение\ SOCKS не разрешено наÑтройками" ::msgcat::mcset ru "SOCKS request failed" "Ð—Ð°Ð¿Ñ€Ð¾Ñ SOCKS не удалÑÑ" ::msgcat::mcset ru "SOCKS server cannot identify username" "Сервер SOCKS не\ Ñмог идентифицировать Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ" ::msgcat::mcset ru "SOCKS server username identification failed"\ "Ð˜Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð½Ð° Ñервере SOCKS не удалаÑÑŒ" ::msgcat::mcset ru "Sort" "Сортировать" ::msgcat::mcset ru "Sort by date" "Сортировать по дате" ::msgcat::mcset ru "Sort by from" "Сортировать по адреÑу отправителÑ" ::msgcat::mcset ru "Sort by node" "Сортировать по имени узла" ::msgcat::mcset ru "Sort by type" "Сортировать по типу" ::msgcat::mcset ru "Sort items by JID/node" "Сортировать по JID/узлу" ::msgcat::mcset ru "Sort items by name" "Сортировать по имени" ::msgcat::mcset ru "Sound" "Звук" ::msgcat::mcset ru "sound" "звук" ::msgcat::mcset ru "Sound options." "ÐаÑтройки звука." ::msgcat::mcset ru "Sound to play when available presence is received."\ "Звук, который проигрываетÑÑ Ð¿Ñ€Ð¸ получении приÑутÑÑ‚Ð²Ð¸Ñ Ñ‚Ð¸Ð¿Ð°\ \"доÑтупен\"." ::msgcat::mcset ru "Sound to play when connected to Jabber server." "Звук,\ который проигрываетÑÑ Ð¿Ñ€Ð¸ подключении к Jabber-Ñерверу." ::msgcat::mcset ru "Sound to play when disconnected from Jabber server."\ "Звук, который проигрываетÑÑ Ð¿Ñ€Ð¸ отключении от Jabber-Ñервера." ::msgcat::mcset ru "Sound to play when groupchat message from me is\ received." "Звук, который проигрываетÑÑ Ð¿Ñ€Ð¸ получении ÑобÑтвенного\ ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¸Ð· конференции." ::msgcat::mcset ru "Sound to play when groupchat message is received." "Звук,\ который проигрываетÑÑ Ð¿Ñ€Ð¸ получении обычного ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¸Ð·\ конференции." ::msgcat::mcset ru "Sound to play when groupchat server message is received."\ "Звук, который проигрываетÑÑ Ð¿Ñ€Ð¸ получении Ñлужебного ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¸Ð·\ конференции." ::msgcat::mcset ru "Sound to play when highlighted (usually addressed\ personally) groupchat message is received." "Звук, который\ проигрываетÑÑ Ð¿Ñ€Ð¸ получении выделенного (обычно перÑонально\ адреÑованного) ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¸Ð· конференции." ::msgcat::mcset ru "Sound to play when personal chat message is received."\ "Звук, который проигрываетÑÑ Ð¿Ñ€Ð¸ получении ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¸Ð· разговора." ::msgcat::mcset ru "Sound to play when sending personal chat message." "Звук,\ который проигрываетÑÑ Ð¿Ñ€Ð¸ отправке ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¸Ð· разговора." ::msgcat::mcset ru "Sound to play when unavailable presence is received."\ "Звук, который проигрываетÑÑ Ð¿Ñ€Ð¸ получении приÑутÑÑ‚Ð²Ð¸Ñ Ñ‚Ð¸Ð¿Ð°\ \"недоÑтупен\"." ::msgcat::mcset ru "Source:" "ИÑточник:" ::msgcat::mcset ru "Specifies search mode while searching in chat, log or\ disco windows. \"substring\" searches exact substring, \"glob\" uses\ glob style matching, \"regexp\" allows to match regular expression."\ "Указывает режим поиÑка в окнах разговора, протокола и обзора Ñлужб.\ \"substring\" ищет подÑтроку, \"glob\" позволÑет иÑпользовать\ подÑтановочные Ñимволы, \"regexp\" иÑпользует регулÑрные выражениÑ." ::msgcat::mcset ru "Speed:" "СкороÑть:" ::msgcat::mcset ru "Spell check options." "Параметры проверки правопиÑаниÑ." ::msgcat::mcset ru "SSL & Compression" "SSL & Сжатие" ::msgcat::mcset ru "SSL certificate file (optional)." "Файл Ñертификата SSL\ (необÑзательный параметр)." ::msgcat::mcset ru "SSL certificate:" "Сертификат SSL:" ::msgcat::mcset ru "SSL certification authority file or directory\ (optional)." "Файл или Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Ñ†ÐµÐ½Ñ‚Ñ€Ð° Ñертификации (CA) SSL\ (необÑзательный параметр)." ::msgcat::mcset ru "SSL Info" "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð± SSL" ::msgcat::mcset ru "SSL Port:" "SSL порт:" ::msgcat::mcset ru "SSL private key file (optional)." "Файл Ñекретного ключа\ SSL ((необÑзательный параметр)." ::msgcat::mcset ru "Start chat" "Ðачать беÑеду" ::msgcat::mcset ru "Starting auto-away" "УÑтанавливаетÑÑ ÑоÑтоÑние \"Отошёл\"\ (по бездейÑтвию)" ::msgcat::mcset ru "STARTTLS failed" "STARTTLS не удалÑÑ" ::msgcat::mcset ru "STARTTLS successful" "STARTTLS уÑпешный" ::msgcat::mcset ru "State" "СоÑтоÑние" ::msgcat::mcset ru "State " "ОблаÑть" ::msgcat::mcset ru "State:" "ОблаÑть:" ::msgcat::mcset ru "Statistics" "СтатиÑтика" ::msgcat::mcset ru "Statistics monitor" "Монитор ÑтатиÑтики" ::msgcat::mcset ru "Status bar" "СтатуÑÐ½Ð°Ñ Ñтрока" ::msgcat::mcset ru "Stop autoscroll" "Отключение автопрокрутки" ::msgcat::mcset ru "Stop chat window autoscroll." "Отключить автопрокрутку\ окна разговора." ::msgcat::mcset ru "Store" "Сохранить" ::msgcat::mcset ru "Store group chats logs." "СохранÑть протоколы\ конференций." ::msgcat::mcset ru "Store private chats logs." "СохранÑть протоколы\ перÑональных разговоров." ::msgcat::mcset ru "store this message offline" "Ñохранить Ñообщение на\ Ñервере" ::msgcat::mcset ru "Stored collapsed roster groups." "Сохранённые\ закрытые/раÑпахнутые группы контактов." ::msgcat::mcset ru "Stored main window state (normal or zoomed)" "Сохранённое\ ÑоÑтоÑние (normal или zoomed) главного окна" ::msgcat::mcset ru "Stored show offline roster groups." "СохранённаÑ\ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð± отображении неподключённых контактов в группах\ контактов." ::msgcat::mcset ru "Stored user priority." "Сохранённый приоритет\ пользователÑ." ::msgcat::mcset ru "Stored user status." "Сохранённый ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ." ::msgcat::mcset ru "Stored user text status." "Сохранённый текÑтовый ÑтатуÑ\ пользователÑ." ::msgcat::mcset ru "Storing conferences failed: %s" "Ðе удалоÑÑŒ Ñохранить\ конференции: %s" ::msgcat::mcset ru "Storing roster notes failed: %s" "Ðе удалоÑÑŒ Ñохранить\ заметки к контактам: %s" ::msgcat::mcset ru "Stream Error%s%s" "Ошибка потока%s%s" ::msgcat::mcset ru "Stream initiation options." "Параметры SI-транÑпорта." ::msgcat::mcset ru "Stream method negotiation failed" "Ðе удалоÑÑŒ ÑоглаÑовать\ метод отправки потока" ::msgcat::mcset ru "Street:" "Улица:" ::msgcat::mcset ru "stressed" "напрÑжённое" ::msgcat::mcset ru "Strip leading \"http://jabber.org/protocol/\" from IQ\ namespaces in the status line." "ОпуÑкать\ \"http://jabber.org/protocol/\" при показе запроÑов в ÑтатуÑной\ Ñтроке." ::msgcat::mcset ru "studying" "учуÑÑŒ" ::msgcat::mcset ru "Subactivity" "Конкретнее" ::msgcat::mcset ru "Subactivity:" "Конкретнее:" ::msgcat::mcset ru "Subject" "Тема" ::msgcat::mcset ru "Subject is set to: %s" "Тема уÑтановлена в: %s" ::msgcat::mcset ru "Subject:" "Тема:" ::msgcat::mcset ru "Subject: " "Тема: " ::msgcat::mcset ru "Submit" "Отправить" ::msgcat::mcset ru "Subscribe" "ПодпиÑатьÑÑ" ::msgcat::mcset ru "Subscribe to a node" "ПодпиÑатьÑÑ Ð½Ð° узел" ::msgcat::mcset ru "Subscription" "ПодпиÑка на приÑутÑтвие" ::msgcat::mcset ru "Subscription request from %s" "Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° подпиÑку на\ приÑутÑтвие от %s" ::msgcat::mcset ru "Subscription request from:" "Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° подпиÑку на\ приÑутÑтвие от:" ::msgcat::mcset ru "Subscription Required" "ТребуетÑÑ Ð¿Ð¾Ð´Ð¿Ð¸Ñка" ::msgcat::mcset ru "Subscription:" "ПодпиÑка:" ::msgcat::mcset ru "Substrings to highlight in messages." "ПодÑтроки, которые\ Ñледует выделÑть в ÑообщениÑÑ…." ::msgcat::mcset ru "Suffix" "СуффикÑ" ::msgcat::mcset ru "Suffix:" "СуффикÑ:" ::msgcat::mcset ru "sunbathing" "загораю" ::msgcat::mcset ru "surprised" "удивлённое" ::msgcat::mcset ru "swimming" "плаваю" ::msgcat::mcset ru "Switch to tab number 1-9,10" "ПереключитьÑÑ Ð½Ð° вкладку\ 1-9,10" ::msgcat::mcset ru "System Shutdown" "Завершение работы ÑиÑтемы" ::msgcat::mcset ru "Systray icon blinks when there are unread messages."\ "Значок в ÑиÑтемном лотке мигает, еÑли еÑть непрочитанные ÑообщениÑ." ::msgcat::mcset ru "Systray icon options." "Параметры значка ÑиÑтемного\ лотка." ::msgcat::mcset ru "Systray:" "СиÑтемный лоток:" ::msgcat::mcset ru "Tabs:" "Вкладки:" ::msgcat::mcset ru "taking a bath" "принимаю ванну" ::msgcat::mcset ru "taking a shower" "принимаю душ" ::msgcat::mcset ru "talking" "разговариваю" ::msgcat::mcset ru "Telephone numbers" "Телефонные номера" ::msgcat::mcset ru "Templates" "Шаблоны" ::msgcat::mcset ru "Temporary auth failure" "Ð’Ñ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ° аутентификации" ::msgcat::mcset ru "Temporary Error" "Ð’Ñ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°" ::msgcat::mcset ru "Text status, which is set when Tkabber is moving to away\ state." "ОпиÑание ÑоÑтоÑниÑ, уÑтанавливаемое когда Tkabber переходит\ в ÑоÑтоÑние \"Отошёл\"." ::msgcat::mcset ru "Text:" "ТекÑÑ‚:" ::msgcat::mcset ru "the body is" "текÑÑ‚ ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ñ€Ð°Ð²ÐµÐ½" ::msgcat::mcset ru "the message is from" "Ñообщение от" ::msgcat::mcset ru "the message is sent to" "Ñообщение адреÑовано" ::msgcat::mcset ru "the message type is" "тип ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ñ€Ð°Ð²ÐµÐ½" ::msgcat::mcset ru "the option is set and saved." "параметр уÑтановлен и\ Ñохранён." ::msgcat::mcset ru "the option is set to its default value." "Ñтот параметр\ уÑтановлен в значение по умолчанию." ::msgcat::mcset ru "the option is set, but not saved." "параметр уÑтановлен,\ но не Ñохранён Ð´Ð»Ñ Ñледующих ÑеÑÑий." ::msgcat::mcset ru "the option is taken from config file." "параметр взÑÑ‚ из\ конфигурационного файла" ::msgcat::mcset ru "The signature is good but has expired" "ПодпиÑÑŒ\ допуÑтимаÑ, но её Ñрок иÑтёк" ::msgcat::mcset ru "The signature is good but the key has expired" "ПодпиÑÑŒ\ допуÑтимаÑ, но Ñрок ключа иÑтёк" ::msgcat::mcset ru "the subject is" "тема ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ñ€Ð°Ð²Ð½Ð°" ::msgcat::mcset ru "thirsty" "хочу пить" ::msgcat::mcset ru "This message is encrypted." "Это Ñообщение зашифровано." ::msgcat::mcset ru "This message was forwarded by %s\n" "Это Ñообщение\ переÑлал %s\n" ::msgcat::mcset ru "This message was forwarded to %s" "Это Ñообщение было\ переÑлано %s" ::msgcat::mcset ru "This message was sent by %s\n" "Это Ñообщение было\ отправлено %s\n" ::msgcat::mcset ru "Time" "ВремÑ" ::msgcat::mcset ru "time %s%s:" "Ð²Ñ€ÐµÐ¼Ñ %s%s:" ::msgcat::mcset ru "time %s%s: %s" "Ð²Ñ€ÐµÐ¼Ñ %s%s: %s" ::msgcat::mcset ru "Time interval before playing next sound (in\ milliseconds)." "Минимальный интервал между ÑоÑедними звуками (в\ миллиÑекундах)." ::msgcat::mcset ru "Time Zone:" "Ð’Ñ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ð·Ð¾Ð½Ð°:" ::msgcat::mcset ru "Time:" "ВремÑ:" ::msgcat::mcset ru "Timeout" "Таймаут" ::msgcat::mcset ru "Timeout for waiting for HTTP poll responses (if set to\ zero, Tkabber will wait forever)." "Таймаут Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ Ð¾Ñ‚Ð²ÐµÑ‚Ð° на\ HTTP-Ð·Ð°Ð¿Ñ€Ð¾Ñ (еÑли равен нулю, Tkabber будет ждать неограниченно\ долго)." ::msgcat::mcset ru "Timer" "Таймер" ::msgcat::mcset ru "Timestamp:" "Момент времени:" ::msgcat::mcset ru "Title" "Ðазвание" ::msgcat::mcset ru "Title:" "Ðазвание:" ::msgcat::mcset ru "Tkabber configuration directory transfer failed\ with:\n%s\n Tkabber will use the old directory:\n%s" "ПереноÑ\ директории Ñ Ð½Ð°Ñтройками Tkabber'а не удалÑÑ:\n%s\n Тkabber будет\ иÑпользовать Ñтарую директорию:\n%s" ::msgcat::mcset ru "Tkabber emoticons theme. To make new theme visible for\ Tkabber put it to some subdirectory of %s." "Тема Ñмоциконок\ Tkabber'а. Ð”Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ ÑобÑтвенной темы размеÑтите её в\ поддиректории директории %s." ::msgcat::mcset ru "Tkabber icon theme. To make new theme visible for Tkabber\ put it to some subdirectory of %s." "Тема пиктограмм Tkabber'а. Чтобы\ иметь возможноÑть включить ÑобÑтвенную тему, положите её в\ поддиректорию директории %s." ::msgcat::mcset ru "Tkabber save state options." "ÐаÑтройки ÑохранениÑ\ ÑоÑтоÑÐ½Ð¸Ñ Tkabber'а." ::msgcat::mcset ru "Tkabber Systray" "Tkabber в ÑиÑтемном лотке" ::msgcat::mcset ru "To" "Кому" ::msgcat::mcset ru "To:" "Кому:" ::msgcat::mcset ru "To: " "Кому: " ::msgcat::mcset ru "Toggle encryption" "Вкл./выкл. шифрование" ::msgcat::mcset ru "Toggle encryption (when possible)" "Вкл./выкл. шифрование\ (еÑли возможно)" ::msgcat::mcset ru "Toggle seen" "Переключить ÑтатуÑ" ::msgcat::mcset ru "Toggle showing offline users" "Вкл./выкл. показ\ отключённых пользователей" ::msgcat::mcset ru "Toggle signing" "Вкл./выкл. подпиÑÑŒ" ::msgcat::mcset ru "Toolbar" "Панель инÑтрументов" ::msgcat::mcset ru "Top" "Сверху" ::msgcat::mcset ru "Track:" "Трек:" ::msgcat::mcset ru "Transfer failed: %s" "Передача не удалаÑÑŒ: %s" ::msgcat::mcset ru "Transferring..." "Передача файла..." ::msgcat::mcset ru "traveling" "путешеÑтвую" ::msgcat::mcset ru "Try again" "Попробовать Ñнова" ::msgcat::mcset ru "TTL expired" "ЗакончилоÑÑŒ Ð²Ñ€ÐµÐ¼Ñ Ð¶Ð¸Ð·Ð½Ð¸ пакета" ::msgcat::mcset ru "Type" "Тип" ::msgcat::mcset ru "Unable to encipher data for %s: %s.\n\nEncrypting traffic\ to this user is now disabled.\n\nSend it as PLAINTEXT?" "Ðевозможно\ зашифровать данные Ð´Ð»Ñ %s: %s.\n\nШифрование Ñообщений Ð´Ð»Ñ Ñтого\ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ñ‚ÐµÐ¿ÐµÑ€ÑŒ отключено.\n\nОтоÑлать Ñообщение\ ÐЕЗÐШИФРОВÐÐÐЫМ?" ::msgcat::mcset ru "Unable to sign message body: %s.\n\nSigning traffic is\ now disabled.\n\nSend it WITHOUT a signature?" "Ðевозможно подпиÑать\ тело ÑообщениÑ: %s.\n\nПодпиÑывание Ñообщений теперь\ отключено.\n\nОтоÑлать Ñообщение БЕЗ ПОДПИСИ?" ::msgcat::mcset ru "Unable to sign presence information: %s.\n\nPresence will\ be sent, but signing traffic is now disabled." "Ðевозможно подпиÑать\ информацию о приÑутÑтвии: %s.\n\nПриÑутÑтвие будет отоÑлано, но\ подпиÑывание Ñообщений теперь отключено." ::msgcat::mcset ru "Unauthorized" "Ðе авторизовано" ::msgcat::mcset ru "Unavailable" "ÐедоÑтупен" ::msgcat::mcset ru "Unavailable presence" "ПриÑутÑтвие типа \"недоÑтупен\"" ::msgcat::mcset ru "Undefined" "Без группы" ::msgcat::mcset ru "Undefined Condition" "Ðеопределенное уÑловие" ::msgcat::mcset ru "Undo" "Откатка" ::msgcat::mcset ru "Unexpected Request" "Ðеожиданный запроÑ" ::msgcat::mcset ru "Unit:" "Отделение:" ::msgcat::mcset ru "Units" "Единицы" ::msgcat::mcset ru "unix plugins" "раÑÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ Ð´Ð»Ñ unix" ::msgcat::mcset ru "unknown" "неизвеÑÑ‚Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°" ::msgcat::mcset ru "Unknown address type" "ÐеизвеÑтный тип адреÑа" ::msgcat::mcset ru "Unknown error" "ÐеизвеÑÑ‚Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°" ::msgcat::mcset ru "Unpublish" "Отозвать публикацию" ::msgcat::mcset ru "Unpublish user activity" "Отозвать публикацию занÑтиÑ\ пользователÑ" ::msgcat::mcset ru "Unpublish user activity..." "Отменить публикацию занÑтиÑ\ пользователÑ..." ::msgcat::mcset ru "Unpublish user location" "Отменить публикацию\ меÑÑ‚Ð¾Ð½Ð°Ñ…Ð¾Ð¶Ð´ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ" ::msgcat::mcset ru "Unpublish user location..." "Отменить публикацию\ меÑÑ‚Ð¾Ð½Ð°Ñ…Ð¾Ð¶Ð´ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ..." ::msgcat::mcset ru "Unpublish user mood" "Отозвать публикацию ÑоÑтоÑниÑ\ пользователÑ" ::msgcat::mcset ru "Unpublish user mood..." "Отменить публикацию наÑтроениÑ\ пользователÑ..." ::msgcat::mcset ru "Unpublish user tune" "Отозвать публикацию мелодии\ пользователÑ" ::msgcat::mcset ru "Unpublish user tune..." "Отменить публикацию мелодии\ пользователÑ..." ::msgcat::mcset ru "Unpublishing is only possible while being online" "Отзыв\ публикации возможен лишь при активном подключении" ::msgcat::mcset ru "Unrecoverable Error" "ÐеуÑÑ‚Ñ€Ð°Ð½Ð¸Ð¼Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°" ::msgcat::mcset ru "Unregister" "ОтрегиÑтрироватьÑÑ" ::msgcat::mcset ru "Unsubscribe" "ОтпиÑатьÑÑ" ::msgcat::mcset ru "Unsubscribe from a node" "ОтпиÑатьÑÑ Ð¾Ñ‚ узла" ::msgcat::mcset ru "Unsubscribed from %s" "ОтпиÑаны от %s" ::msgcat::mcset ru "Unsupported compression method" "Ðеподдерживаемый метод\ ÑжатиÑ" ::msgcat::mcset ru "Unsupported Encoding" "ÐÐµÐ¿Ð¾Ð´Ð´ÐµÑ€Ð¶Ð¸Ð²Ð°ÐµÐ¼Ð°Ñ ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²ÐºÐ°" ::msgcat::mcset ru "Unsupported log dir format" "Ðеподдерживаемый формат\ директории протоколов." ::msgcat::mcset ru "Unsupported SOCKS authentication method"\ "Ðеподдерживаемый метод аутентификации SOCKS" ::msgcat::mcset ru "Unsupported SOCKS method" "Ðеподдерживаемый метод SOCKS" ::msgcat::mcset ru "Unsupported Stanza Type" "Ðеподдерживаемый тип Ñлемента" ::msgcat::mcset ru "Unsupported Version" "ÐÐµÐ¿Ð¾Ð´Ð´ÐµÑ€Ð¶Ð¸Ð²Ð°ÐµÐ¼Ð°Ñ Ð²ÐµÑ€ÑиÑ" ::msgcat::mcset ru "Up" "Вверх" ::msgcat::mcset ru "Update" "Обновить" ::msgcat::mcset ru "Update message of the day..." "Обновить Ñообщение днÑ..." ::msgcat::mcset ru "Uptime" "Ð’Ñ€ÐµÐ¼Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹" ::msgcat::mcset ru "URI:" "СÑылка:" ::msgcat::mcset ru "URL to connect to." "URL Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ (опроÑа)." ::msgcat::mcset ru "URL to poll:" "URL Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ:" ::msgcat::mcset ru "Usage: /abbrev WHAT FOR" "ИÑпользование: /abbrev ЧТО\ ÐÐ_ЧТО" ::msgcat::mcset ru "Usage: /unabbrev WHAT" "ИÑпользование: /unabbrev ЧТО" ::msgcat::mcset ru "Use aliases" "ИÑпользование пÑевдонимов включено" ::msgcat::mcset ru "Use aliases to show multiple users in one roster item."\ "ИÑпользовать aliases и показывать неÑкольких пользователей как один\ Ñлемент контактов." ::msgcat::mcset ru "Use client security keys" "ИÑпользовать ключи\ безопаÑноÑти" ::msgcat::mcset ru "Use colored messages" "ИÑпользовать цветные ÑообщениÑ" ::msgcat::mcset ru "Use colored nicks" "ИÑпользовать цветные пÑевдонимы" ::msgcat::mcset ru "Use colored nicks in chat windows." "ИÑпользовать цветные\ пÑевдонимы в окнах разговоров/конференций." ::msgcat::mcset ru "Use colored nicks in groupchat rosters." "ИÑпользовать\ цветные пÑевдонимы в ÑпиÑках учаÑтников конференций." ::msgcat::mcset ru "Use colored roster nicks" "ИÑпользовать цветные\ пÑевдонимы в ÑпиÑке учаÑтников" ::msgcat::mcset ru "Use connection:" "Соединение:" ::msgcat::mcset ru "Use explicitly-specified server address and port."\ "ИÑпользовать Ñвно указанные Ð°Ð´Ñ€ÐµÑ Ñервера и порт Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ." ::msgcat::mcset ru "Use hashed password" "ИÑпользовать шифр. пароль" ::msgcat::mcset ru "Use HTTP poll client security keys (recommended)."\ "ИÑпользовать ключи безопаÑноÑти HTTP-Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ (рекомендуетÑÑ)." ::msgcat::mcset ru "Use HTTP poll connection method." "ИÑпользовать\ HTTP-подключение." ::msgcat::mcset ru "Use mediated SOCKS5 connection if proxy is available."\ "ИÑпользовать Ñоединение SOCKS5 через поÑредника, еÑли он доÑтупен." ::msgcat::mcset ru "Use only whole words for emoticons." "Только целые Ñлова\ превращать в Ñмоциконки (не чаÑти Ñлов)." ::msgcat::mcset ru "Use Proxy" "ИÑпользовать прокÑи" ::msgcat::mcset ru "Use roster filter" "ИÑпользовать фильтр контактов" ::msgcat::mcset ru "Use roster filter." "ИÑпользовать фильтр контактов." ::msgcat::mcset ru "Use SASL authentication" "ИÑпользовать SASL длÑ\ аутентификации" ::msgcat::mcset ru "Use SASL authentication." "ИÑпользовать SASL длÑ\ аутентификации." ::msgcat::mcset ru "Use sound notification only when being available."\ "ИÑпользовать звук только в ÑоÑтоÑниÑÑ… \"Ð’ Ñети\" и \"Свободен длÑ\ разговора\"." ::msgcat::mcset ru "Use specified key ID for signing and decrypting\ messages." "ИÑпользовать ключ Ñ ÑƒÐºÐ°Ð·Ð°Ð½Ð½Ñ‹Ð¼ идентификатором Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñи\ и дешифровки Ñообщений." ::msgcat::mcset ru "Use SSL" "ИÑпользовать SSL" ::msgcat::mcset ru "Use Tabbed Interface (you need to restart)."\ "ИÑпользовать Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ñ Ð·Ð°ÐºÐ»Ð°Ð´ÐºÐ°Ð¼Ð¸ (поÑле Ð¿Ñ€Ð¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ñ‚Ñ€ÐµÐ±ÑƒÐµÑ‚ÑÑ\ реÑтарт)." ::msgcat::mcset ru "Use the same passphrase for signing and decrypting\ messages." "ИÑпользовать одну и ту же парольную фразу Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñи и\ ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ñообщений." ::msgcat::mcset ru "Use the specified function to hash supported features\ list." "ИÑпользовать указанный алгоритм Ð´Ð»Ñ Ñ…ÑÑˆÐ¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ ÑпиÑка\ реализованных возможноÑтей программы." ::msgcat::mcset ru "Use this module" "Подключить данный модуль" ::msgcat::mcset ru "User activity" "ЗанÑтие пользователÑ" ::msgcat::mcset ru "User activity publishing failed: %s" "Ðе удалоÑÑŒ\ опубликовать занÑтие пользователÑ: %s" ::msgcat::mcset ru "User activity unpublishing failed: %s" "Ðе удалоÑÑŒ\ отозвать публикацию занÑÑ‚Ð¸Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ: %s" ::msgcat::mcset ru "User already %s" "Пользователь уже %s" ::msgcat::mcset ru "User ID" "ID пользователÑ" ::msgcat::mcset ru "User info" "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ пользователе" ::msgcat::mcset ru "user interface" "Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ" ::msgcat::mcset ru "User location" "МеÑтонахождение пользователÑ" ::msgcat::mcset ru "User location publishing failed: %s" "ПубликациÑ\ меÑÑ‚Ð¾Ð½Ð°Ñ…Ð¾Ð¶Ð´ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð½Ðµ удалаÑÑŒ: %s" ::msgcat::mcset ru "User location unpublishing failed: %s" "Отмена публикации\ меÑÑ‚Ð¾Ð½Ð°Ñ…Ð¾Ð¶Ð´ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð½Ðµ удалаÑÑŒ: %s" ::msgcat::mcset ru "User mood" "СоÑтоÑние пользователÑ" ::msgcat::mcset ru "User mood publishing failed: %s" "Ðе удалоÑÑŒ опубликовать\ ÑоÑтоÑние пользователÑ: %s" ::msgcat::mcset ru "User mood unpublishing failed: %s" "Ðе удалоÑÑŒ отозвать\ публикацию ÑоÑтоÑÐ½Ð¸Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ: %s" ::msgcat::mcset ru "User name." "Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ." ::msgcat::mcset ru "User tune" "ÐœÐµÐ»Ð¾Ð´Ð¸Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ" ::msgcat::mcset ru "User tune publishing failed: %s" "Ðе удалоÑÑŒ опубликовать\ мелодию пользователÑ: %s" ::msgcat::mcset ru "User tune unpublishing failed: %s" "Ðе удалоÑÑŒ отозвать\ публикацию мелодии пользователÑ: %s" ::msgcat::mcset ru "User-Agent string." "Строка User-Agent." ::msgcat::mcset ru "Username Not Available" "Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð½ÐµÐ´Ð¾Ñтупно" ::msgcat::mcset ru "Username:" "Пользователь:" ::msgcat::mcset ru "Users" "Пользователи" ::msgcat::mcset ru "utilities" "утилиты" ::msgcat::mcset ru "Value" "Значение" ::msgcat::mcset ru "value is changed, but the option is not set." "значение\ изменено, но параметр не уÑтановлен." ::msgcat::mcset ru "vcard %s%s:" "Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ %s%s:" ::msgcat::mcset ru "vcard %s%s: %s" "Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ %s%s: %s" ::msgcat::mcset ru "vCard display options in chat windows." "Параметры\ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»ÐµÐ¹ vCard в окне разговора." ::msgcat::mcset ru "Version" "ВерÑиÑ" ::msgcat::mcset ru "version %s%s:" "верÑÐ¸Ñ %s%s:" ::msgcat::mcset ru "version %s%s: %s" "верÑÐ¸Ñ %s%s: %s" ::msgcat::mcset ru "Version:" "ВерÑиÑ:" ::msgcat::mcset ru "Video:" "Видео:" ::msgcat::mcset ru "View" "Вид" ::msgcat::mcset ru "Visible list" "Видимый ÑпиÑок" ::msgcat::mcset ru "visitor" "поÑетитель" ::msgcat::mcset ru "Visitors" "ПоÑетители" ::msgcat::mcset ru "Voice:" "Обычный:" ::msgcat::mcset ru "Waiting for activating privacy list" "Ждем, пока\ активируетÑÑ ÑпиÑок приватноÑти" ::msgcat::mcset ru "Waiting for authentication results" "Ждём результаты\ аутентификации" ::msgcat::mcset ru "Waiting for handshake results" "Ждём результаты\ рукопожатиÑ" ::msgcat::mcset ru "Waiting for roster" "Ждём контакты" ::msgcat::mcset ru "walking" "гулÑÑŽ" ::msgcat::mcset ru "walking the dog" "выгуливаю Ñобаку" ::msgcat::mcset ru "Warning" "Предупреждение" ::msgcat::mcset ru "Warning display options." "Параметры отображениÑ\ предупреждений." ::msgcat::mcset ru "Warning:" "Предупреждение:" ::msgcat::mcset ru "WARNING: %s\n" "ПРЕДУПРЕЖДЕÐИЕ: %s\n" ::msgcat::mcset ru "watching a movie" "Ñмотрю кино" ::msgcat::mcset ru "watching tv" "Ñмотрю телевизор" ::msgcat::mcset ru "Web Site" "Веб-Ñтраница:" ::msgcat::mcset ru "Web Site:" "Веб-Ñтраница:" ::msgcat::mcset ru "What action does the close button." "ДейÑтвие,\ Ñовершаемое при нажатии на кнопку Ð·Ð°ÐºÑ€Ñ‹Ñ‚Ð¸Ñ Ð¾ÐºÐ½Ð°." ::msgcat::mcset ru "When set, all changes to the ignore rules are applied\ only until Tkabber is closed\; they are not saved and thus will be\ not restored at the next run." "ЕÑли параметр уÑтановлен, то вÑе\ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð» Ð¸Ð³Ð½Ð¾Ñ€Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð±ÑƒÐ´ÑƒÑ‚ дейÑтвовать только до того, как\ Tkabber закроетÑÑ, и не будут воÑÑтановлены при Ñледующем запуÑке." ::msgcat::mcset ru "Whois" "Кто Ñто?" ::msgcat::mcset ru "whois %s: no info" "whois %s: нет информации" ::msgcat::mcset ru "windows plugins" "раÑÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ Ð´Ð»Ñ windows" ::msgcat::mcset ru "Work:" "Рабочий:" ::msgcat::mcset ru "working" "работаю" ::msgcat::mcset ru "working out" "\"качаюÑÑŒ\" на тренажёрах" ::msgcat::mcset ru "worried" "беÑпокойное" ::msgcat::mcset ru "writing" "пишу" ::msgcat::mcset ru "XML Not Well-Formed" "Ðеправильно Ñформированный XML" ::msgcat::mcset ru "XMPP stream options when connecting to server."\ "ÐаÑтройки XMPP-потока при подключении к Ñерверу." ::msgcat::mcset ru "Year:" "Год:" ::msgcat::mcset ru "You are unsubscribed from %s" "Ð’Ñ‹ отпиÑаны от %s" ::msgcat::mcset ru "You're using root directory %s for storing Tkabber\ logs!\n\nI refuse to convert logs database." "Ð’Ñ‹ храните журналы\ разговоров Tkabber'а в корневой директории %s!\n\nКонвертирование\ журналов отменÑетÑÑ." ::msgcat::mcset ru "Your new Tkabber config directory is now:\n%s\nYou can\ delete the old one:\n%s" "ÐÐ¾Ð²Ð°Ñ Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Ñ Ð½Ð°Ñтройками\ Tkabber'а:\n%s\nÐ’Ñ‹ можете удалить Ñтарую:\n%s" ::msgcat::mcset ru "Zip:" "ИндекÑ:" ::msgcat::mcset ru "\n\tJID: %s" ::msgcat::mcset ru "auto-away" ::msgcat::mcset ru "BBS:" ::msgcat::mcset ru "bwidget workarounds" ::msgcat::mcset ru "day" ::msgcat::mcset ru "days" ::msgcat::mcset ru "E-mail" ::msgcat::mcset ru "E-mail:" ::msgcat::mcset ru "Edit entities affiliations: %s" ::msgcat::mcset ru "History of availability status messages" ::msgcat::mcset ru "hour" ::msgcat::mcset ru "hours" ::msgcat::mcset ru "HTTPS" ::msgcat::mcset ru "IQ" ::msgcat::mcset ru "ISDN:" ::msgcat::mcset ru "Jabber ID" ::msgcat::mcset ru "jabber xml" ::msgcat::mcset ru "JID" ::msgcat::mcset ru "JID:" ::msgcat::mcset ru "kde" ::msgcat::mcset ru "List of users for chat." ::msgcat::mcset ru "List of users for userinfo." ::msgcat::mcset ru "minute" ::msgcat::mcset ru "minutes" ::msgcat::mcset ru "MUC" ::msgcat::mcset ru "negotiation" ::msgcat::mcset ru "Outcast" ::msgcat::mcset ru "Owner" ::msgcat::mcset ru "PCS:" ::msgcat::mcset ru "Pending" ::msgcat::mcset ru "Presence-in" ::msgcat::mcset ru "Presence-out" ::msgcat::mcset ru "privacy rules" ::msgcat::mcset ru "Publisher" ::msgcat::mcset ru "SASL" ::msgcat::mcset ru "second" ::msgcat::mcset ru "seconds" ::msgcat::mcset ru "SOCKS4a" ::msgcat::mcset ru "SOCKS5" ::msgcat::mcset ru "SSL" ::msgcat::mcset ru "SubID" ::msgcat::mcset ru "Subscribed" ::msgcat::mcset ru "UID" ::msgcat::mcset ru "UID:" ::msgcat::mcset ru "Unconfigured" ::msgcat::mcset ru "URL" ::msgcat::mcset ru "URL:" ::msgcat::mcset ru "UTC:" ::msgcat::mcset ru "whois %s: %s" ::msgcat::mcset ru "wmaker" #================================================================== namespace eval :: { proc load_russian_procs {} { rename format_time "" rename ru_format_time format_time } proc ru_word_form {t} { set modt [expr {$t % 10}] if {($t >= 10) && ($t < 20)} { return 0 } elseif {$modt == 1} { return 1 } elseif {($modt >= 2) && ($modt <= 4)} { return 2 } else { return 0 } } proc ru_format_time {t} { if {[cequal $t ""]} { return } set sec [expr {$t % 60}] set secs [lindex {"Ñекунд" "Ñекунда" "Ñекунды"} [ru_word_form $sec]] set t [expr {$t / 60}] set min [expr {$t % 60}] set mins [lindex {"минут" "минута" "минуты"} [ru_word_form $min]] set t [expr {$t / 60}] set hour [expr {$t % 24}] set hours [lindex {"чаÑов" "чаÑ" "чаÑа"} [ru_word_form $hour]] set day [expr {$t / 24}] set days [lindex {"дней" "день" "днÑ"} [ru_word_form $day]] set flag 0 set message "" if {$day != 0} { set flag 1 set message "$day $days" } if {$flag || ($hour != 0)} { set flag 1 set message [concat $message "$hour $hours"] } if {$flag || ($min != 0)} { set message [concat $message "$min $mins"] } return [concat $message "$sec $secs"] } hook::add postload_hook load_russian_procs } # vim:ft=tcl:ts=8:sw=4:sts=4:noet # Local Variables: # mode: tcl # End: tkabber-0.11.1/msgs/pl.rc0000644000175000017500000000266607735335160014457 0ustar sergeisergei! ------------------------------------------------------------------------------ ! pl.rc ! Definition of polish resources for BWidget ! ------------------------------------------------------------------------------ ! --- symbolic names of buttons ------------------------------------------------ *abortName: Przerwij *retryName: Ponów *ignoreName: Ignoruj *okName: OK *cancelName: Anuluj *yesName: Tak *noName: Nie ! --- symbolic names of label of SelectFont dialog ---------------------------- *boldName: Pogrubienie *italicName: Kursywa *underlineName: PodkreÅ›lenie *overstrikeName: PrzekreÅ›lenie *fontName: &Nazwa *sizeName: &Rozmiar *styleName: &Styl ! --- symbolic names of label of PasswdDlg dialog ----------------------------- *loginName: &Użytkownik *passwordName: &HasÅ‚o ! --- resource for SelectFont dialog ------------------------------------------ *SelectFont.title: Wybór czcionki *SelectFont.sampletext: PrzykÅ‚adowy tekst, ĄąĘęĆćÅłŃńÓ󯿏ź ! --- resource for MessageDlg dialog ------------------------------------------ *MessageDlg.noneTitle: Wiadomość *MessageDlg.infoTitle: Informacja *MessageDlg.questionTitle: Pytanie *MessageDlg.warningTitle: Ostrzeżenie *MessageDlg.errorTitle: Błąd ! --- resource for PasswdDlg dialog ------------------------------------------- *PasswdDlg.title: Podaj nazwÄ™ użytkownika i hasÅ‚o tkabber-0.11.1/msgs/uk.msg0000644000175000017500000037604311062233737014643 0ustar sergeisergei# $Id: uk.msg 1501 2008-09-11 15:23:11Z sergei $ # ukrainian messages file # writed by levsha@jabber.net.ua. Last change 10.03.2006 # updated by uzver@jabber.kiev.ua Last change 08.03.2007 # Vypravleno i dopovneno pereklad na Tkabber 0.9.9 SVN # Pereklady na plaginy dodani u vidpovidni teky /msgs kozhnohgo plaginu # charset - UTF8 # hmm.. ::msgcat::mcset uk "#" "â„–" ::msgcat::mcset uk "Aborted" "Перервано" ::msgcat::mcset uk "About" "Про програму" # Space at the end of the next word is to distinguish it from another "About" ::msgcat::mcset uk "About " "Про Ñебе " ::msgcat::mcset uk "Accept connections from the listed JIDs." "Приймати з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· перелічених JID" ::msgcat::mcset uk "Accept connections from my own JID." "Приймати з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· мого оÑобиÑтого JID" ::msgcat::mcset uk "Accept default config" "ПрийнÑти конфіг за замовчуваннÑм" ::msgcat::mcset uk "Access Error" "Помилка доÑтупу" ::msgcat::mcset uk "Account" "Обліковий запиÑ" ::msgcat::mcset uk "Action" "ДіÑ" ::msgcat::mcset uk "Activate lists at startup" "Ðктивувати ÑпиÑки при Ñтарті" ::msgcat::mcset uk "Activate visible/invisible/ignore lists before sending initial presence." \ "Ðктивувати видимий/невидимий/ігнорований ÑпиÑки перед тим, Ñк оголоÑити Ñвою приÑутніÑть в мережі." ::msgcat::mcset uk "Active Chats" "Ðктивні чати" ::msgcat::mcset uk "Activating privacy list failed: %s\n\nTry to reconnect. If problem persists, you may want to disable privacy list activation at start" \ "Ðе вдалоÑÑ Ð°ÐºÑ‚Ð¸Ð²ÑƒÐ²Ð°Ñ‚Ð¸ ÑпиÑок приватноÑті: %s\n\nСпробуйте перез'єднатиÑÑŒ. Якщо проблема залишитьÑÑ, можливо, треба вимкнути активацію ÑпиÑків приватноÑті при Ñтарті" ::msgcat::mcset uk "Active" "Ðктивний" ::msgcat::mcset uk "Add chats group in roster." "Додати групу чатів в роÑтер." ::msgcat::mcset uk "Add conference to roster..." "Додати конференцію в роÑтер..." ::msgcat::mcset uk "Add conference" "Додати конференцію" ::msgcat::mcset uk "Add conference..." "Додати конференцію..." ::msgcat::mcset uk "Add group by regexp on JIDs..." "Додати групу по регулÑрному виразу Ð´Ð»Ñ JID..." ::msgcat::mcset uk "Add item" "Додати елемент" ::msgcat::mcset uk "Add JID" "Додати JID" ::msgcat::mcset uk "Add list" "Додати ÑпиÑок" ::msgcat::mcset uk "Add new user..." "Додати нового кориÑтувача..." ::msgcat::mcset uk "Address 2:" "ÐдреÑа 2:" ::msgcat::mcset uk "Address Error" "Помилка адреÑи" ::msgcat::mcset uk "Address:" "ÐдреÑа:" ::msgcat::mcset uk "Address" "ÐдреÑа" ::msgcat::mcset uk "Address 2" "ÐдреÑа 2" ::msgcat::mcset uk "Add roster group by JID regexp" "Додати групу роÑтера по регулÑрному виразу Ð´Ð»Ñ JID" ::msgcat::mcset uk "Add user to roster..." "Додати кориÑтувача в роÑтер..." ::msgcat::mcset uk "Add user..." "Додати кориÑтувача..." ::msgcat::mcset uk "Add ->" "Додати ->" ::msgcat::mcset uk "Add" "Додати" ::msgcat::mcset uk "Admin tools" "ІнÑтрументи адмініÑтратора" ::msgcat::mcset uk "Affiliation" "Ранг" ::msgcat::mcset uk "Alexey Shchepin" "ОлекÑій Щєпін" ::msgcat::mcset uk "All" "Ð’Ñе" ::msgcat::mcset uk "All Files" "Ð’ÑÑ– файли" ::msgcat::mcset uk "All files" "Ð’ÑÑ– файли" ::msgcat::mcset uk "Allow downloading" "Дозволити завантаженнÑ" ::msgcat::mcset uk "Allow plaintext authentication mechanisms" \ "Дозволити механізми аутентифікації, що викориÑтовують відкритий текÑÑ‚" ::msgcat::mcset uk "Allow plaintext authentication mechanisms (when password is transmitted unencrypted)." \ "Дозволити механізми аутентифікації, що викориÑтовують відкритий текÑÑ‚ (при цьому пароль передаєтьÑÑ Ð½ÐµÐ·Ð°ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸Ð¼)." ::msgcat::mcset uk "An error occurred when searching in %s\n\n%s" "При пошуку в %s ÑталаÑÑŒ помилка\n\n%s" ::msgcat::mcset uk "Announce" "ОголошеннÑ" ::msgcat::mcset uk "Application Error" "Помилка прикладної програми" ::msgcat::mcset uk "Are you sure to remove group '%s' from roster? \n(Users which are in this group only, will be in undefined group.)" \ "Ви дійÑно хочете видалити групу '%s' з роÑтера? \n(Контакти, що Ñ” тільки в цій групі, будуть без групи.)" ::msgcat::mcset uk "Are you sure to remove all users in group '%s' from roster? \n(Users which are in another groups too, will not be removed from the roster.)" \ "Ви дійÑно хочете видалити вÑÑ– контакти з групи '%s' з роÑтера? \n(Контакти, що Ñ” не тільки в цій групі, не будуть видалені.)" ::msgcat::mcset uk "Are you sure to remove group '%s' from roster?" "Ви дійÑно хочете видалити групу '%s' з роÑтера?" ::msgcat::mcset uk "Are you sure to remove %s from roster?" \ "Ви дійÑно хочете видалити %s з роÑтера?" ::msgcat::mcset uk "Attached user:" "Прикріплений контакт:" ::msgcat::mcset uk "Authentication" "ÐутентифікаціÑ" ::msgcat::mcset uk "Authentication Error" "Помилка аутентифікації" ::msgcat::mcset uk "Authentication failed: %s\nCreate new account?" \ "ÐÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ Ð½Ðµ вдалаÑÑŒ: %s\nСтворити новий обліковий запиÑ?" ::msgcat::mcset uk "Authentication failed: %s" "ÐÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ Ð½Ðµ вдалаÑÑŒ: %s" ::msgcat::mcset uk "Authentication failed" "ÐÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ Ð½Ðµ вдалаÑÑŒ" ::msgcat::mcset uk "Authentication successful" "ÐÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾Ð¹ÑˆÐ»Ð° вдало" ::msgcat::mcset uk "Authors:" "Ðвтори:" ::msgcat::mcset uk "Automatically join conference upon connect" \ "Ðвтоматично приєднуватиÑÑ Ð´Ð¾ конференції при під'єднанні" ::msgcat::mcset uk "Available presence" "ПриÑутніÑть \"доÑтупний\"" ::msgcat::mcset uk "Available" "ДоÑтупний" ::msgcat::mcset uk "auto-away" # "Automatically away due to idle" goes to textstatus (probably no needs to translate) ::msgcat::mcset uk "Automatically away due to idle" ::msgcat::mcset uk "Available groups" "ДоÑтупні групи" ::msgcat::mcset uk "avatars" "аватари" ::msgcat::mcset uk "Avatar" "Ðватара" ::msgcat::mcset uk "Away" "Відійшов" ::msgcat::mcset uk "Bad Format" "Ðевірний формат" ::msgcat::mcset uk "Bad Namespace Prefix" "Ðевірний Ð¿Ñ€ÐµÑ„Ñ–ÐºÑ Ð¿Ñ€Ð¾Ñтору назв" ::msgcat::mcset uk "Bad Request" "Ðевірний запит" ::msgcat::mcset uk "balloon help" "підказка, що Ñпливає" ::msgcat::mcset uk "Ban" "Заборона входу до кімнати" ::msgcat::mcset uk "BBS:" ::msgcat::mcset uk "Begin date" "Початкова дата" ::msgcat::mcset uk "Birthday:" "День народженнÑ:" ::msgcat::mcset uk "Birthday" "День народженнÑ" ::msgcat::mcset uk "Blocking communication options." \ "Параметри Ð±Ð»Ð¾ÐºÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ¾Ð¼ÑƒÐ½Ñ–ÐºÐ°Ñ†Ñ–Ñ—." ::msgcat::mcset uk "Blocking communication (XMPP privacy lists) options." \ "Параметри Ð±Ð»Ð¾ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½ÑŒ (правил Ð·Ð°Ð±ÐµÐ·Ð¿ÐµÑ‡ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¸Ð²Ð°Ñ‚Ð½Ð¾Ñті XMPP)." ::msgcat::mcset uk "Browse error: %s" "Помилка переглÑду: %s" ::msgcat::mcset uk "Browser" "ПереглÑд" ::msgcat::mcset uk "Browse..." "ПроглÑнути..." ::msgcat::mcset uk "Browse" "ПроглÑнути" ::msgcat::mcset uk "browsing" "переглÑданнÑ" ::msgcat::mcset uk "bwidget workarounds" ::msgcat::mcset uk " by " " " ::msgcat::mcset uk " by %s" " %s" ::msgcat::mcset uk "Cache headlines on exit and restore on start." \ "Кешувати новини при виході Ñ– відновлювати при Ñтарті." ::msgcat::mcset uk "Cancel" "Відмінити" ::msgcat::mcset uk "Can't receive file: %s" "Ðе вдалоÑÑŒ прийнÑти файл: %s" ::msgcat::mcset uk "Cell:" "Мобільний:" ::msgcat::mcset uk "Certificate has expired" "Строк дії Ñертифікату закінчивÑÑ" ::msgcat::mcset uk "change message type to" "змінити тип Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð½Ð°" ::msgcat::mcset uk "Change password" "Зміна паролю" ::msgcat::mcset uk "Change password..." "Змінити пароль..." ::msgcat::mcset uk "Change Presence Priority" "Змінити пріоритет наÑвноÑті" ::msgcat::mcset uk "Change priority..." "Змінити пріоритет..." ::msgcat::mcset uk "Change security preferences for %s" "Зміна параметрів безпеки Ð´Ð»Ñ %s" ::msgcat::mcset uk "Chat message" "Chat повідомленнÑ" ::msgcat::mcset uk "Chat message events plugin options." \ "Параметри плагіна, що відповідає за ÑÐ¿Ð¾Ð²Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¸ обробці повідомлень у вікні розмови." ::msgcat::mcset uk "Chat message window state plugin options." \ "Параметри плагіна, що відповідає за ÑÐ¿Ð¾Ð²Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ Ñтан вікна розмови." ::msgcat::mcset uk "Chat options." "Параметри розмови." ::msgcat::mcset uk "Chat window is active" "Вікно розмови активне" ::msgcat::mcset uk "Chat window is inactive" "Вікно розмови неактивне" ::msgcat::mcset uk "Chat window is gone" "Вікно розмови зачинено" ::msgcat::mcset uk "Chats" "Розмови" ::msgcat::mcset uk "Chats:" "Розмови:" ::msgcat::mcset uk "Chat with %s" "Розмова з %s" ::msgcat::mcset uk "Chat" "РозмовлÑти" ::msgcat::mcset uk "Chat " "Розмова" ::msgcat::mcset uk "Check spell after every entered symbol." \ "ПеревірÑти Ð¿Ñ€Ð°Ð²Ð¾Ð¿Ð¸Ñ Ð¿Ñ–ÑÐ»Ñ ÐºÐ¾Ð¶Ð½Ð¾Ð³Ð¾ введеного Ñимволу." ::msgcat::mcset uk "Cipher" "Метод шифруваннÑ" ::msgcat::mcset uk "City:" "МіÑто:" ::msgcat::mcset uk "City" "МіÑто" ::msgcat::mcset uk "Clear bookmarks" "ОчиÑтити закладки" ::msgcat::mcset uk "Clear chat window" "ОчиÑтити вікно розмови" ::msgcat::mcset uk "Clear" "ОчиÑтити" ::msgcat::mcset uk "Client:" "Клієнт:" ::msgcat::mcset uk "Client" "Клієнт" ::msgcat::mcset uk "Close all tabs" "Закрити вÑÑ– закладки" ::msgcat::mcset uk "Close other tabs" "Закрити інші закладки" ::msgcat::mcset uk "Close tab" "Закрити закладку" ::msgcat::mcset uk "Close Tkabber" "Закрити Tkabber" ::msgcat::mcset uk "Close" "Закрити" ::msgcat::mcset uk "Color message bodies in chat windows." \ "Кольорові Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ñƒ вікнах розмови." ::msgcat::mcset uk "Command to be run when you click a URL in a message. '%s' will be replaced with this URL (e.g. \"galeon -n %s\")." \ "Команда, Ñка буде виконана при натиÑканні на URL, що міÑтитьÑÑ Ð² повідомленні. ЗаміÑть '%s' буде підÑтавлено URL (наприклад: \"galeon -n %s\")." ::msgcat::mcset uk "Complete nickname" "Доповнювати пÑевдонім до кінцÑ" ::msgcat::mcset uk "Compression" "СтиÑненнÑ" ::msgcat::mcset uk "Compression negotiation failed" "Узгодити ÑтиÑÐ½ÐµÐ½Ð½Ñ Ð½Ðµ вдалоÑÑ" ::msgcat::mcset uk "Compression negotiation successful" "СтиÑÐ½ÐµÐ½Ð½Ñ Ð±ÑƒÐ»Ð¾ узгоджено уÑпішно" ::msgcat::mcset uk "Compression setup failed" "СтиÑнути потік не вдалоÑÑ" ::msgcat::mcset uk "Composing a reply" "Пише відповідь" ::msgcat::mcset uk "Condition" "Умова" ::msgcat::mcset uk "Conference room %s will be destroyed permanently.\n\nProceed?" "ÐšÐ¾Ð½Ñ„ÐµÑ€ÐµÐ½Ñ†Ñ–Ñ %s буде назавжди видалена.\n\nПродовжити?" ::msgcat::mcset uk "configuration" "конфігураціÑ" ::msgcat::mcset uk "Configure form: %s" "Конфігураційна форма: %s" ::msgcat::mcset uk "Configure room" "Конфігурувати кімнату" ::msgcat::mcset uk "Configure service" "Конфігурувати Ñлужбу" ::msgcat::mcset uk "Conflict" "Конфлікт" ::msgcat::mcset uk "Connection closed" "З'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð·Ð°ÐºÑ€Ð¸Ñ‚Ð¾" ::msgcat::mcset uk "Connection Timeout" "Ð§Ð°Ñ Ð·'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð²Ð¸Ñ‡ÐµÑ€Ð¿Ð°Ð²ÑÑ" ::msgcat::mcset uk "connections" "З'єднаннÑ" ::msgcat::mcset uk "Connection:" "З'єднаннÑ:" ::msgcat::mcset uk "Connection" "З'єднаннÑ" ::msgcat::mcset uk "Connect via alternate server" "ПідключитиÑÑŒ через альтернативний Ñервер" ::msgcat::mcset uk "Connect via HTTP polling" "ПідключитиÑÑŒ викориÑтовуючи HTTP опитуваннÑ" ::msgcat::mcset uk "Contact Information" "Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ контакти" ::msgcat::mcset uk "continue processing rules" "продовжити обробку правил" ::msgcat::mcset uk "Convert screenname" "Перетворити екранну назву" ::msgcat::mcset uk "Convert" "Перетворити" ::msgcat::mcset uk "Copy headline to clipboard" "Скопіювати новину в буфер обміну" ::msgcat::mcset uk "Copy selection to clipboard" "Скопіювати виділену чаÑтину в буфер обміну" ::msgcat::mcset uk "Copy URL to clipboard" "Скопіювати URL в буфер обміну" ::msgcat::mcset uk "Correct word" "Виправити Ñлово" ::msgcat::mcset uk "Country:" "Країна:" ::msgcat::mcset uk "Country" "Країна" ::msgcat::mcset uk "Create node" "Створити вузол" ::msgcat::mcset uk "Created: %s" "Створено: %s" ::msgcat::mcset uk "Creating default privacy list" "Створюємо ÑпиÑок приватноÑті за замовчуваннÑм" ::msgcat::mcset uk "Creating default privacy list failed: %s\n\nTry to reconnect. If problem persists, you may want to disable privacy list activation at start" \ "Ðе вдалоÑÑ Ñтворити ÑпиÑок приватноÑті за замовчуваннÑм: %s\n\nСпробуйте перепід'єднатиÑÑ. Якщо проблема залишитьÑÑ, можливо, треба вимкнути активацію ÑпиÑків приватноÑті при Ñтарті" ::msgcat::mcset uk "cryptographics" "криптографіÑ" ::msgcat::mcset uk "Current groups" "Поточні групи" ::msgcat::mcset uk "Customization of the One True Jabber Client." \ "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ”Ð´Ð¸Ð½Ð¾Ð³Ð¾ правильного клієнта Jabber." ::msgcat::mcset uk "Customize" "ÐалаштуваннÑ" ::msgcat::mcset uk "Data form" "Форма Ð´Ð»Ñ Ð·Ð°Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ" ::msgcat::mcset uk "Data purported sent by %s can't be deciphered.\n\n%s." \ "Дані, ймовірно відправлені від %s, неможливо розшифрувати.\n\n%s." ::msgcat::mcset uk "Date:" "Дата:" ::msgcat::mcset uk "Day:" "День:" ::msgcat::mcset uk "Default directory for downloaded files." \ "Тека за замовчуваннÑм Ð´Ð»Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð¸Ñ… файлів." ::msgcat::mcset uk "Default message type (if not specified explicitly)." \ "Тип Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð·Ð° замовчуваннÑм (Ñкщо не вказаний Ñвно)" ::msgcat::mcset uk "Default nested roster group delimiter." "Розділювач за замовчуваннÑм Ð´Ð»Ñ Ð²ÐºÐ»Ð°Ð´ÐµÐ½Ð¸Ñ… груп роÑтера." ::msgcat::mcset uk "Default" "За замовчуваннÑм" ::msgcat::mcset uk "Delay between getting focus and updating window or tab title in milliseconds." \ "Затримка між отриманнÑм фокуÑа Ñ– Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ° вікна чи закладки (в міліÑекундах)." ::msgcat::mcset uk "Delete all" "Видалити вÑе" ::msgcat::mcset uk "Delete message of the day" "Видалити Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð´Ð½Ñ" ::msgcat::mcset uk "Delete seen" "Видалити переглÑнуте" ::msgcat::mcset uk "Delete" "Видалити" ::msgcat::mcset uk "Description:" "ОпиÑ:" ::msgcat::mcset uk "Description:" "ОпиÑ:" ::msgcat::mcset uk "Description:" "ОпиÑ:" ::msgcat::mcset uk "Description:" "ОпиÑ:" ::msgcat::mcset uk "Destroy room" "Знищити кімнату" ::msgcat::mcset uk "Details" "Деталі" ::msgcat::mcset uk "Directory to store logs." "Тека Ð´Ð»Ñ Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ð¶ÑƒÑ€Ð½Ð°Ð»Ñ–Ð²." ::msgcat::mcset uk "Dir" "Куди" ::msgcat::mcset uk "Disabled\n" "Вимкнений\n" ::msgcat::mcset uk "Disconnected" "Роз'єднано" ::msgcat::mcset uk "Discover service" "ОглÑнути Ñлужбу" ::msgcat::mcset uk "Discovery" "ОглÑд" ::msgcat::mcset uk "Display %s in chat window when using /vcard command." "Показувати %s у вікні розмови при викориÑтанні команди /vcard." ::msgcat::mcset uk "Display description of user status in chat windows." \ "Показувати Ð¾Ð¿Ð¸Ñ ÑтатуÑу Ñпіврозмовника у вікні розмови." ::msgcat::mcset uk "Display headlines in single/multiple windows." \ "Показувати новини в одному/кількох вікнах." ::msgcat::mcset uk "Display SSL warnings." "Показувати Ð¿Ð¾Ð¿ÐµÑ€ÐµÐ´Ð¶ÐµÐ½Ð½Ñ SSL." ::msgcat::mcset uk "Display status tooltip when main window is minimized to systray." \ "Показувати Ñпливаюче віконце, коли головне вікно звернуте до ÑиÑтемного трею." ::msgcat::mcset uk "Do not display headline descriptions as tree nodes." \ "Ðе показувати Ð¾Ð¿Ð¸Ñ Ð½Ð¾Ð²Ð¸Ð½Ð¸ у виглÑді гілки повідомленнÑ." ::msgcat::mcset uk "Do not disturb" "Ðе турбувати" ::msgcat::mcset uk "Do nothing" "Ðічого не робити" ::msgcat::mcset uk "Down" "Вниз" ::msgcat::mcset uk "Edit admin list" "Редагувати ÑпиÑок адмініÑтраторів" ::msgcat::mcset uk "Edit ban list" "Редагувати ÑпиÑок заборон" ::msgcat::mcset uk "Edit chat user colors" "Редагувати кольори Ñпіврозмовників" ::msgcat::mcset uk "Edit groups for %s" "Зміна груп Ð´Ð»Ñ %s" ::msgcat::mcset uk "Edit ignore list" "Ð ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ð½Ð½Ñ ÑпиÑку ігнорованих" ::msgcat::mcset uk "Edit ignore list " "Редагувати ÑпиÑок ігнорованих " ::msgcat::mcset uk "Edit invisible list" "Ð ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ð½Ð½Ñ ÑпиÑку невидимоÑті" ::msgcat::mcset uk "Edit invisible list " "Редагувати ÑпиÑок невидимоÑті " ::msgcat::mcset uk "Edit item..." "Редагувати пункт..." ::msgcat::mcset uk "Edit item notes..." "Редагувати нотатки пункту..." ::msgcat::mcset uk "Edit list" "Редагувати ÑпиÑок" ::msgcat::mcset uk "Edit member list" "Редагувати ÑпиÑок учаÑників" ::msgcat::mcset uk "Edit message filters" "Редагувати фільтри повідомлень" ::msgcat::mcset uk "Edit moderator list" "Редагувати ÑпиÑок модераторів" ::msgcat::mcset uk "Edit my info..." "Редагувати інформацію про Ñебе..." ::msgcat::mcset uk "Edit nick colors..." "Редагувати кольори пÑевдонімів..." ::msgcat::mcset uk "Edit nick color..." "Ð ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ¾Ð»ÑŒÐ¾Ñ€Ñƒ пÑевдоніму..." ::msgcat::mcset uk "Edit nickname for %s" "Ð ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñевдоніму %s" ::msgcat::mcset uk "Edit owner list" "Редагувати ÑпиÑок влаÑників" ::msgcat::mcset uk "Edit privacy list" "Редагувати ÑпиÑок приватноÑті" ::msgcat::mcset uk "Edit properties for %s" "Ð ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ð»Ð°ÑтивоÑтей %s" ::msgcat::mcset uk "Edit rule" "Ð ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð»Ð°" ::msgcat::mcset uk "Edit roster notes for %s" "Зміна приміток Ð´Ð»Ñ %s" ::msgcat::mcset uk "Edit %s color" "Ð ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ¾Ð»ÑŒÐ¾Ñ€Ñƒ %s" ::msgcat::mcset uk "Edit security..." "Редагувати безпеку..." ::msgcat::mcset uk "Edit visible list" "Редагувати ÑпиÑок видимоÑті" ::msgcat::mcset uk "Edit voice list" "Редагувати ÑпиÑок права голоÑу" ::msgcat::mcset uk "Edit" "Редагувати" ::msgcat::mcset uk "E-mail:" ::msgcat::mcset uk "E-mail" #::msgcat::mcset uk "Email:" ::msgcat::mcset uk "emoticons" "іконки емоцій" ::msgcat::mcset uk "Emphasize" "Ðкцентувати" ::msgcat::mcset uk "Empty rule name" "ÐŸÐ¾Ñ€Ð¾Ð¶Ð½Ñ Ð½Ð°Ð·Ð²Ð° правила" ::msgcat::mcset uk "Enable chat window autoscroll only when last message is shown." \ "Вмикати автоматичне Ð¿Ñ€Ð¾Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ Ñ‚Ñ–Ð»ÑŒÐºÐ¸ Ñкщо видно оÑтаннє повідомленнÑ." ::msgcat::mcset uk "Enabled\n" "Увімкнено\n" ::msgcat::mcset uk "Enable KDE tray icon." "ВикориÑтовувати іконку в ÑиÑтемному треї KDE." ::msgcat::mcset uk "Enable freedesktop systray icon." "Увімкнути freedesktop іконку в ÑиÑтемному треї." ::msgcat::mcset uk "Enable highlighting plugin." "Увімкнути модуль підÑвіченнÑ." ::msgcat::mcset uk "Enable jabberd 1.4 mod_filter support (obsolete)." \ "Увімкнути підтримку Ð¼Ð¾Ð´ÑƒÐ»Ñ mod_filter з jabberd 1.4 (заÑтаріле)" ::msgcat::mcset uk "Enable Jidlink transport %s." "Дозволити викориÑÑ‚Ð°Ð½Ð½Ñ Jidlink-транÑпорта %s" ::msgcat::mcset uk "Enable nested roster groups." "Дозволити вкладені групи в роÑтері." ::msgcat::mcset uk "Enable rendering of XHTML messages." \ "Дозволити Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½ÑŒ, форматованих за допомогою XHTML." ::msgcat::mcset uk "Enable remote control." "Увімкнути віддалений контроль" ::msgcat::mcset uk "Enable sending chat message events." \ "Увімкнути розÑÐ¸Ð»Ð°Ð½Ð½Ñ Ñповіщень про обробку повідомлень у вікні розмови." ::msgcat::mcset uk "Enable sending chat state notifications." \ "Увімкнути розÑÐ¸Ð»Ð°Ð½Ð½Ñ Ñповіщень про Ñтан вікна розмови." ::msgcat::mcset uk "Enable SI transport %s." "Дозволити викориÑÑ‚Ð°Ð½Ð½Ñ SI-транÑпорта %s" ::msgcat::mcset uk "Enable windows tray icon." "ВикориÑтовувати іконку в ÑиÑтемному треї Windows" ::msgcat::mcset uk "Encrypt traffic" "Шифрувати трафік" ::msgcat::mcset uk "Encryption (STARTTLS)" "Ð¨Ð¸Ñ„Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ (STARTTLS)" ::msgcat::mcset uk "Encryption (legacy SSL)" "Ð¨Ð¸Ñ„Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ (Ñтарий SSL)" ::msgcat::mcset uk "Enter screenname of contact you want to add" \ "Введіть екранне ім'Ñ ÐºÐ¾Ð½Ñ‚Ð°ÐºÑ‚Ñƒ, Ñкий Ви хочете додати" ::msgcat::mcset uk "Error" "Помилка" ::msgcat::mcset uk "Error:" "Помилка:" ::msgcat::mcset uk "Error completing command: %s" "Помилка при завершенні команди: %s" ::msgcat::mcset uk "Error displaying %s in browser\n\n%s" "Помилка при відкритті %s в переглÑдачі\n\n%s" ::msgcat::mcset uk "Error executing command: %s" "Помилка при виконанні команди: %s" ::msgcat::mcset uk "Error getting info: %s" "Помилка при отриманні інформації: %s" ::msgcat::mcset uk "Error getting items: %s" "помилка при отриманні елементів: %s" ::msgcat::mcset uk "Error in signature processing" "Помилка при перевірці підпиÑу" ::msgcat::mcset uk "Error in signature verification software: %s." \ "Помилка в програмі перевірки цифрового підпиÑу: %s." ::msgcat::mcset uk "Error negotiate: %s" "Помилка узгодженнÑ: %s" ::msgcat::mcset uk "Error requesting data: %s" "Помилка запиту даних: %s" ::msgcat::mcset uk "Error %s" "Помилка %s" ::msgcat::mcset uk "Error while converting screenname: %s." \ "Помилка при перетворенні екранного імені: %s" ::msgcat::mcset uk "Execute command" "Виконати команду" ::msgcat::mcset uk "Expiry date" "Дата Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ Ñтроку дії" ::msgcat::mcset uk "Explicitly specify host and port to connect" "Вказати Ñвно адреÑу Ñ– порт Ð´Ð»Ñ Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ" ::msgcat::mcset uk "Export roster..." "ЕкÑпортувати роÑтер..." ::msgcat::mcset uk "Export to XHTML" "ЕкÑпорт в XHTML" ::msgcat::mcset uk "Extended away" "Давно відійшов" ::msgcat::mcset uk "extension management" "ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð»Ð°Ð³Ñ–Ð½Ð°Ð¼Ð¸" ::msgcat::mcset uk "External program, which is to be executed to play sound. If empty, Snack library is used (if available) to play sound." \ "Ð—Ð¾Ð²Ð½Ñ–ÑˆÐ½Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð°, Ñка буде виконуватиÑÑŒ Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð²Ð°Ð½Ð½Ñ Ð·Ð²ÑƒÐºÑƒ. Якщо параметр порожній, то Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð²Ð°Ð½Ð½Ñ Ð±ÑƒÐ´Ðµ викориÑтовуватиÑÑ Ð±Ñ–Ð±Ð»Ñ–Ð¾Ñ‚ÐµÐºÐ° Snack в разі Ñ—Ñ— наÑвноÑті." ::msgcat::mcset uk "Extras from %s" "Додаток від %s" ::msgcat::mcset uk "Extras from:" "Додаток від:" ::msgcat::mcset uk "Failed to connect: %s" "ÐŸÑ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ð½Ðµ вдалоÑÑŒ: %s" ::msgcat::mcset uk "Family Name:" "Прізвище:" ::msgcat::mcset uk "Family Name" "Прізвище" ::msgcat::mcset uk "Fax:" "ФакÑ:" ::msgcat::mcset uk "Feature Not Implemented" "Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ Ð½Ðµ реалізована" ::msgcat::mcset uk "Fetch all messages" "Отримати вÑÑ– повідомленнÑ" ::msgcat::mcset uk "Fetch GPG key" "Отримати ключ GPG" ::msgcat::mcset uk "Fetch message" "Отримати повідомленнÑ" ::msgcat::mcset uk "Fetch unseen messages" "Отримати неотримані повідомленнÑ" ::msgcat::mcset uk "File Transfer options." "Параметри передачі файлів." ::msgcat::mcset uk "file transfer" "передача файла" ::msgcat::mcset uk "Filters" "Фільтри" ::msgcat::mcset uk "Finish" "Закінчити" ::msgcat::mcset uk "First Name:" "Ім'Ñ:" ::msgcat::mcset uk "Font to use in roster, chat windows etc." \ "Шрифт Ð´Ð»Ñ Ñ€Ð¾Ñтера, вікон розмови Ñ– Ñ‚.д." ::msgcat::mcset uk "Forbidden" "Заборонено" ::msgcat::mcset uk "Format Error" "Помилка формату" ::msgcat::mcset uk "Format of timestamp in chat message.\ Refer to Tcl documentation of 'clock' command for description of format. Examples: \[%R\] \u2013 \[20:37\] \[%T\] \u2013 \[20:37:12\] \[%a %b %d %H:%M:%S %Z %Y\] \u2013 \[Thu Jan 01 03:00:00 MSK 1970\]" "Формат виводу дати та чаÑу в повідомленнÑÑ… розмов.\ (Ð”Ð»Ñ Ð¾Ð¿Ð¸Ñу формату звернітьÑÑ Ð´Ð¾ документації Tcl по команді 'clock'.) Приклади: \[%R\] \u2013 \[20:37\] \[%T\] \u2013 \[20:37:12\] \[%a %b %d %H:%M:%S %Z %Y\] \u2013 \[Чтв Січ 01 03:00:00 MSK 1970\]" ::msgcat::mcset uk "Format of timestamp in delayed chat messages delayed for more than 24 hours." \ "Формат виводу дати та чаÑу в повідомленнÑÑ…, відправлених більш ніж 24 години тому." ::msgcat::mcset uk "Format of timestamp in headline tree view. Set to empty string if you don't want to see timestamps." \ "Формат виводу дати/чаÑу у вікні новин. Ð”Ð»Ñ Ñ‚Ð¾Ð³Ð¾, щоб зовÑім не показувати дату/чаÑ, вÑтановіть цю опцію Ñк порожній Ñ€Ñдок." ::msgcat::mcset uk "Forward headline" "ПереÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð¾Ð²Ð¸Ð½Ð¸" ::msgcat::mcset uk "forward message to" "переÑлати Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð´Ð¾" ::msgcat::mcset uk "Forward to %s" "ПереÑлати до %s" ::msgcat::mcset uk "Forward..." "ПереÑлати..." ::msgcat::mcset uk "Free to chat" "Вільний Ð´Ð»Ñ Ñ€Ð¾Ð·Ð¼Ð¾Ð²Ð¸" ::msgcat::mcset uk "From/To" "Від кого/Кому" ::msgcat::mcset uk "From:" "Від кого:" ::msgcat::mcset uk "From: " "Від кого: " ::msgcat::mcset uk "Full Name:" "Повне ім'Ñ:" ::msgcat::mcset uk "Full Name" "Повне ім'Ñ" ::msgcat::mcset uk "Geographical position" "Географічне положенні" ::msgcat::mcset uk "Generic IQ" "Загальний IQ-запит" ::msgcat::mcset uk "Get items" "Отримати елементи" ::msgcat::mcset uk "GIF images" "Ð—Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ GIF" ::msgcat::mcset uk "Gone" "Об'єкт змінив адреÑу" ::msgcat::mcset uk "Google selection" "Шукати виділений текÑÑ‚ в Google" ::msgcat::mcset uk "Got roster" "Отримано роÑтер" ::msgcat::mcset uk "GPG-encrypt outgoing messages where possible." \ "Шифрувати вихідні Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð· допомогою GPG, Ñкщо це можливо." ::msgcat::mcset uk "GPG-sign outgoing messages and presence updates." \ "ПідпиÑувати вихідні Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ñ– Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¸ÑутноÑті за допомогою GPG." ::msgcat::mcset uk "GPG options (signing and encryption)." "Параметри GPG (цифровий Ð¿Ñ–Ð´Ð¿Ð¸Ñ Ñ– шифруваннÑ)." ::msgcat::mcset uk "Grant Admin Privileges" "Ðадати адмініÑтративні привілеї" ::msgcat::mcset uk "Grant Membership" "Ðадати членÑтво" ::msgcat::mcset uk "Grant Moderator Privileges" "Ðадати привілеї модератора" ::msgcat::mcset uk "Grant Owner Privileges" "Ðадати привілеї влаÑника" ::msgcat::mcset uk "Grant Voice" "Ðадати право говорити" ::msgcat::mcset uk "Groupchat message highlighting plugin options." \ "Параметри Ð¼Ð¾Ð´ÑƒÐ»Ñ Ð²Ð¸Ð´Ñ–Ð»ÐµÐ½Ð½Ñ Ñлів в групових повідомленнÑÑ…." ::msgcat::mcset uk "Group:" "Група:" ::msgcat::mcset uk "Group:" "Група:" ::msgcat::mcset uk "Handshake failed" "РукоÑтиÑÐºÐ°Ð½Ð½Ñ Ð½Ðµ вдалоÑÑŒ" ::msgcat::mcset uk "Handshake successful" "РукоÑтиÑÐºÐ°Ð½Ð½Ñ ÑƒÑпішне" ::msgcat::mcset uk "Headline message" "Заголовок новини" ::msgcat::mcset uk "Headlines" "Ðовини" ::msgcat::mcset uk "Help" "Допомога" ::msgcat::mcset uk "&Help" "&Допомога" ::msgcat::mcset uk "Hide Main Window" "Сховати головне вікно" ::msgcat::mcset uk "Hide/Show roster" "Сховати/показати роÑтер" ::msgcat::mcset uk "Highlight current nickname in messages." "ВиділÑти поточний пÑевдонім в повідомленнÑÑ…." ::msgcat::mcset uk "Highlight only whole words in messages." "ВиділÑти тільки цілі Ñлова в повідомленнÑÑ…." ::msgcat::mcset uk "History for %s" "ІÑÑ‚Ð¾Ñ€Ñ–Ñ Ð´Ð»Ñ %s" ::msgcat::mcset uk "Home:" "Домашній:" ::msgcat::mcset uk "Host Gone" "ХоÑÑ‚ більше не обÑлуговуєтьÑÑ" ::msgcat::mcset uk "Host Unknown" "Ðевідомий хоÑÑ‚" ::msgcat::mcset uk "Host:" "ХоÑÑ‚:" ::msgcat::mcset uk "HTTP options." "Параметри HTTP." ::msgcat::mcset uk "HTTP Poll" "HTTP-опитуваннÑ" ::msgcat::mcset uk "HTTP proxy address." "ÐдреÑа HTTP-прокÑÑ–." ::msgcat::mcset uk "HTTP proxy password." "Пароль Ð´Ð»Ñ HTTP-прокÑÑ–." ::msgcat::mcset uk "HTTP proxy port." "Порт Ð´Ð»Ñ Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ð´Ð¾ HTTP-прокÑÑ–." ::msgcat::mcset uk "HTTP proxy username." "Ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача Ð´Ð»Ñ Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ð´Ð¾ HTTP-прокÑÑ–." ::msgcat::mcset uk "Iconize" "Іконізувати" ::msgcat::mcset uk "Idle for %s" "Ð§Ð°Ñ Ð±ÐµÐ·Ð´Ñ–ÑльноÑті %s" ::msgcat::mcset uk "Idle threshold in minutes after that Tkabber marks you as away." \ "Період бездіÑльноÑті в хвилинах, піÑÐ»Ñ Ñкого Tkabber вÑтановить Ñтан \"Відійшов\"." ::msgcat::mcset uk "Idle threshold in minutes after that Tkabber marks you as extended away." \ "Період бездіÑльноÑті в хвилинах, піÑÐ»Ñ Ñкого Tkabber вÑтановить Ñтан \"Давно відійшов\"." ::msgcat::mcset uk "Ignore list" "СпиÑок ігнорованих" ::msgcat::mcset uk "Image" "ЗображеннÑ" ::msgcat::mcset uk "I'm not online" "Я не в мережі" ::msgcat::mcset uk "Import roster..." "Імпортувати роÑтер..." ::msgcat::mcset uk "Improper Addressing" "Ðевірна адреÑаціÑ" ::msgcat::mcset uk "Incorrect encoding" "Ðевірне кодуваннÑ" ::msgcat::mcset uk "Indentation for pretty-printed XML subtags." "ВідÑтупи Ð´Ð»Ñ Ð½Ð°Ð¾Ñ‡Ð½Ð¾Ð³Ð¾ Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ XML підтегів." ::msgcat::mcset uk "Info:" "ІнформаціÑ:" ::msgcat::mcset uk "Info/Query options." "Параметри інформації/запитів." ::msgcat::mcset uk "Information" "ІнформаціÑ" ::msgcat::mcset uk "Instructions" "ІнÑтрукціÑ" ::msgcat::mcset uk "Internal Server Error" "Ð’Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° Ñервера" ::msgcat::mcset uk "Interval (in minutes) after error reply on request of participants list." \ "Інтервал (в хвилинах) піÑÐ»Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸ у відповідь на запит ÑпиÑку учаÑників." ::msgcat::mcset uk "Interval (in minutes) between requests of participants list." \ "Інтервал (в хвилинах) між запитами ÑпиÑку учаÑників." ::msgcat::mcset uk "Interval:" "Інтервал:" ::msgcat::mcset uk "Invalid authzid" "ÐеприпуÑтимий authzid" ::msgcat::mcset uk "Invalid From" "ÐеприпуÑтимий From" ::msgcat::mcset uk "Invalid ID" "ÐеприпуÑтимий ID" ::msgcat::mcset uk "Invalid mechanism" "ÐеприпуÑтимий механізм" ::msgcat::mcset uk "Invalid Namespace" "ÐеприпуÑтимий проÑтір назв" ::msgcat::mcset uk "Invalid signature" "ÐеприпуÑтимий підпиÑ" ::msgcat::mcset uk "invalid userstatus value " "ÐеприпуÑтиме Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ÑтатуÑу кориÑтувача " ::msgcat::mcset uk "Invalid XML" "ÐеприпуÑтимий XML" ::msgcat::mcset uk "Invisible" "Ðевидимий" ::msgcat::mcset uk "Invisible list" "Ðевидимий ÑпиÑок" ::msgcat::mcset uk "Invited to:" "Запрошений до:" ::msgcat::mcset uk "Invite %s to conferences" "Ð—Ð°Ð¿Ñ€Ð¾ÑˆÐµÐ½Ð½Ñ %s в конференцію" ::msgcat::mcset uk "Invite to conference..." "ЗапроÑити в конференцію..." ::msgcat::mcset uk "Invite users to %s" "ЗапроÑити кориÑтувачів в %s" ::msgcat::mcset uk "Invite users..." "ЗапроÑити кориÑтувачів..." ::msgcat::mcset uk "Invite" "ЗапроÑити" ::msgcat::mcset uk "IP address:" "IP адреÑа:" ::msgcat::mcset uk "IQ" ::msgcat::mcset uk "ISDN:" ::msgcat::mcset uk "is now" "тепер" ::msgcat::mcset uk "Ispell dictionary encoding. If it is empty, system encoding is used." \ "ÐšÐ¾Ð´ÑƒÐ²Ð°Ð½Ð½Ñ Ñловника перевірки правопиÑу. Якщо порожнє, то викориÑтовуєтьÑÑ ÑиÑтемне кодуваннÑ." ::msgcat::mcset uk "Issuer" "Видавник" ::msgcat::mcset uk "Item Not Found" "Елемент не знайдений" ::msgcat::mcset uk "Jabber Browser" "ПереглÑд Ñлужб" ::msgcat::mcset uk "jabber iq" "ІнформаціÑ" ::msgcat::mcset uk "jabber presence" "приÑутніÑть" ::msgcat::mcset uk "jabber registration" "реєÑтраціÑ" ::msgcat::mcset uk "jabber xml" ::msgcat::mcset uk "JID:" ::msgcat::mcset uk "JID" ::msgcat::mcset uk "Jidlink connection closed" "З'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Jidlink закрито" ::msgcat::mcset uk "Jidlink options." "Параметри Jidlink-транÑпорту." ::msgcat::mcset uk "JID Malformed" "Ðевірний JID" ::msgcat::mcset uk "JID regexp:" "РегулÑрний вираз Ð´Ð»Ñ JID:" ::msgcat::mcset uk "Join conference" "ПриєднатиÑÑŒ до конференції" ::msgcat::mcset uk "Join groupchat" "ПриєднатиÑÑŒ до групової розмови" ::msgcat::mcset uk "Join group" "ПриєднатиÑÑŒ до групи" ::msgcat::mcset uk "Join group..." "ПриєднатиÑÑŒ до групи..." ::msgcat::mcset uk "Join group dialog data (groups)." \ "Дані Ð´Ð»Ñ Ð´Ñ–Ð°Ð»Ð¾Ð³Ñƒ Ð¿Ñ€Ð¸Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð´Ð¾ групи (групи)" ::msgcat::mcset uk "Join group dialog data (nicks)." \ "Дані Ð´Ð»Ñ Ð´Ñ–Ð°Ð»Ð¾Ð³Ñƒ Ð¿Ñ€Ð¸Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð´Ð¾ групи (пÑевдоніми)" ::msgcat::mcset uk "Join group dialog data (servers)." \ "Дані Ð´Ð»Ñ Ð´Ñ–Ð°Ð»Ð¾Ð³Ñƒ Ð¿Ñ€Ð¸Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð´Ð¾ групи (Ñервери)" ::msgcat::mcset uk "Join..." "ПриєднатиÑÑŒ..." ::msgcat::mcset uk "Join" "ПриєднатиÑÑŒ" ::msgcat::mcset uk "JPEG images" "Ð—Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ JPEG" ::msgcat::mcset uk "kde" ::msgcat::mcset uk "Keep trying" "Продовжувати Ñпроби" ::msgcat::mcset uk "Key ID" "ID ключа" ::msgcat::mcset uk "Key:" "Ключ:" ::msgcat::mcset uk "Kick" "Вигнати" ::msgcat::mcset uk "Last Activity or Uptime" "ТриваліÑть бездіÑльноÑті чи триваліÑть роботи" ::msgcat::mcset uk "Last activity" "ТриваліÑть бездіÑльноÑті" ::msgcat::mcset uk "Last Name:" "Прізвище:" ::msgcat::mcset uk "last %s%s: %s" "триваліÑть бездіÑльноÑті/роботи %s%s: %s" ::msgcat::mcset uk "last %s%s:" "триваліÑть бездіÑльноÑті/роботи %s%s:" ::msgcat::mcset uk "Latitude:" "Широта:" ::msgcat::mcset uk "Latitude" "Широта" ::msgcat::mcset uk "List name" "Ðазва ÑпиÑку" ::msgcat::mcset uk "List of browsed JIDs." "СпиÑок переглÑнутих JID." ::msgcat::mcset uk "List of discovered JID nodes." "СпиÑок переглÑнутих вузлів JID." ::msgcat::mcset uk "List of discovered JIDs." "СпиÑок переглÑнутих JID." ::msgcat::mcset uk "List of JIDs to whom headlines have been sent." "СпиÑок JID, Ñким були надіÑлані новини." ::msgcat::mcset uk "List of logout reasons." "СпиÑок причин відключеннÑ." ::msgcat::mcset uk "List of message destination JIDs." "СпиÑок JID адреÑатів повідомленнÑ." ::msgcat::mcset uk "List of users for chat." "СпиÑок кориÑтувачів Ð´Ð»Ñ Ñ‡Ð°Ñ‚Ñƒ." ::msgcat::mcset uk "List of users for userinfo." "СпиÑок кориÑтувачів Ð´Ð»Ñ Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ— про кориÑтувачів" ::msgcat::mcset uk "Load Image" "Завантажити зображеннÑ" ::msgcat::mcset uk "Loading photo failed: %s." "Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ Ñтільницю: %s." ::msgcat::mcset uk "Location" "ÐдреÑа" ::msgcat::mcset uk "Logging options." "Параметри протоколюваннÑ." ::msgcat::mcset uk "Login options." "Параметри підключеннÑ." ::msgcat::mcset uk "Login" "ПідключеннÑ" ::msgcat::mcset uk "Log in..." "ПідключитиÑÑŒ..." ::msgcat::mcset uk "Log in" "ПідключитиÑÑŒ" ::msgcat::mcset uk "Logout with reason" "Ð’Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ð· вказаною причиною" ::msgcat::mcset uk "Log out with reason..." "ВідключитиÑÑŒ з вказаною причиною..." ::msgcat::mcset uk "Logout" "ВідключеннÑ" ::msgcat::mcset uk "Log out" "ВідключитиÑÑŒ" ::msgcat::mcset uk "Log out" "ВідключитиÑÑŒ" ::msgcat::mcset uk "Longitude:" "Довгота:" ::msgcat::mcset uk "Longitude" "Довгота" ::msgcat::mcset uk "Main window:" "Головне вікно:" ::msgcat::mcset uk "Malformed signature block" "Ðевірно Ñформований підпиÑ" ::msgcat::mcset uk "Manually edit rules" "Вручну редагувати правила" ::msgcat::mcset uk "Mark all seen" "Відмітити вÑÑ– Ñк переглÑнуті" ::msgcat::mcset uk "Mark all unseen" "Відмітити вÑÑ– Ñк не переглÑнуті" ::msgcat::mcset uk "Marshall T. Rose" "Маршал Т. Роуз" ::msgcat::mcset uk "Match case while searching in chat, log or disco windows." \ "РозрізнÑти регіÑтр Ñимволів при пошуку у вікнах чату, протоколу чи оглÑду Ñлужб" ::msgcat::mcset uk "Maximum number of characters in the history in MUC compatible conference rooms." \ "МакÑимальна кількіÑть Ñимволів в Ñ–Ñторії ÑуміÑних з MUC кімнат конференцій." ::msgcat::mcset uk "Maximum number of stanzas in the history in MUC compatible conference rooms." \ "МакÑимальна кількіÑть повідомлень в Ñ–Ñторії ÑуміÑних з MUC кімнат конференцій." ::msgcat::mcset uk "Maximum poll interval." "МакÑимальний інтервал HTTP-опитуваннÑ." ::msgcat::mcset uk "/me has set the subject to: %s" "/me змінив(ла) тему на: %s" ::msgcat::mcset uk "Mechanism too weak" "Занадто Ñлабкий механізм" ::msgcat::mcset uk "Message" "ПовідомленнÑ" ::msgcat::mcset uk "Message and Headline options." "Параметри повідомлень Ñ– новин." ::msgcat::mcset uk "Message archive" "Ðрхів повідомлень" ::msgcat::mcset uk "Message body" "Тіло повідомленнÑ" ::msgcat::mcset uk "Message delivered to %s" "ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð´Ð¾Ñтавлене %s" ::msgcat::mcset uk "Message delivered" "ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð´Ð¾Ñтавлене" ::msgcat::mcset uk "Message displayed to %s" "ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ð¾ÐºÐ°Ð·Ð°Ð½Ðµ %s" ::msgcat::mcset uk "Message displayed" "ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿Ð¾ÐºÐ°Ð·Ð°Ð½Ðµ" ::msgcat::mcset uk "message filters" "фільтри повідомлень" ::msgcat::mcset uk "Message from %s" "ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð²Ñ–Ð´ %s" ::msgcat::mcset uk "Message from:" "ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð²Ñ–Ð´:" ::msgcat::mcset uk "Message Recorder:" "Ðвтовідповідач:" ::msgcat::mcset uk "Message stored on %s's server" "ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ðµ на Ñервері %s" ::msgcat::mcset uk "Message stored on the server" "ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ðµ на Ñервері" ::msgcat::mcset uk "Messages" "ПовідомленнÑ" ::msgcat::mcset uk "Michail Litvak" "Михайло Литвак" ::msgcat::mcset uk "Middle Name:" "По батькові:" ::msgcat::mcset uk "Middle Name" "По батькові" ::msgcat::mcset uk "Minimize" "Мінімізувати" ::msgcat::mcset uk "Minimize to systray (if systray icon is enabled, otherwise do nothing)" "Мінімізувати до ÑиÑтемного трею (Ñкщо іконка в треї увімкнена, в іншому разі нічого не робити)" ::msgcat::mcset uk "Minimum poll interval." "Мінімальний інтервал HTTP-опитуваннÑ." ::msgcat::mcset uk "Misc:" "Додатково:" ::msgcat::mcset uk "Modem:" "Модем:" ::msgcat::mcset uk "Moderators" "Модератори" ::msgcat::mcset uk "Modified: %s" "Змінені: %s" ::msgcat::mcset uk "Month:" "МіÑÑць:" ::msgcat::mcset uk "Move down" "ПереміÑтити донизу" ::msgcat::mcset uk "Move tab left/right" "ПереміÑтити закладку вліво/вправо" ::msgcat::mcset uk "Move up" "ПереміÑтити догори" ::msgcat::mcset uk "Moving to extended away" \ "Ð’ÑтановлюєтьÑÑ Ñтан \"Давно відійшов\" (по бездіÑльноÑті)" ::msgcat::mcset uk "MUC" "MUC" ::msgcat::mcset uk "Multiple signatures having different authenticity" \ "Різні підпиÑи мають різну доÑтовірніÑть" ::msgcat::mcset uk "Mute sound" "Вимкнути звук" ::msgcat::mcset uk "Mute sound if Tkabber window is focused." "Вимкнути звук, Ñкщо Ñ„Ð¾ÐºÑƒÑ Ð½Ð°Ð»ÐµÐ¶Ð¸Ñ‚ÑŒ вікну Tkabber'а." ::msgcat::mcset uk "Mute sound notification." "Вимкнути звукові ÑповіщеннÑ." ::msgcat::mcset uk "Mute sound when displaying delayed groupchat messages." \ "Вимкнути звук при показі відкладених групових повідомлень." ::msgcat::mcset uk "Mute sound when displaying delayed personal chat messages." \ "Вимкнути звук при показі відкладених перÑональних повідомлень чату." ::msgcat::mcset uk "my status is" "мій ÑтатуÑ" ::msgcat::mcset uk "Name:" "Ім’Ñ:" ::msgcat::mcset uk "Name" "Ім’Ñ" # Space at the end of the next word is to distinguish it from another "Name:" ::msgcat::mcset uk "Name " "Ðазва " ::msgcat::mcset uk "Name: " "Ðазва: " ::msgcat::mcset uk "Name: " "Ðазва: " ::msgcat::mcset uk "negotiation" ::msgcat::mcset uk "New group name:" "Ðова назва групи:" ::msgcat::mcset uk "New passwords do not match" "Ðові паролі не Ñпівпадають" ::msgcat::mcset uk "New password:" "Ðовий пароль:" ::msgcat::mcset uk "Next" "Далі" ::msgcat::mcset uk "Next bookmark" "ÐаÑтупна закладка" ::msgcat::mcset uk "Next highlighted" "ÐаÑтупне виділене повідомленнÑ" ::msgcat::mcset uk "Nickname:" "ПÑевдонім:" ::msgcat::mcset uk "Nickname:" "ПÑевдонім:" ::msgcat::mcset uk "Nickname:" "ПÑевдонім:" ::msgcat::mcset uk "Nickname" "ПÑевдонім" ::msgcat::mcset uk "Nick:" "ПÑевдонім:" ::msgcat::mcset uk "Nick" "ПÑевдонім" ::msgcat::mcset uk "No active list" "Ðемає активного ÑпиÑку" ::msgcat::mcset uk "No avatar to store" "Ðемає аватари Ð´Ð»Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ" ::msgcat::mcset uk "No conferences for %s in progress..." "ВідÑутні активні конференції Ð´Ð»Ñ %s..." ::msgcat::mcset uk "No default list" "ВідÑутній ÑпиÑок за умовчаннÑм" ::msgcat::mcset uk "No information available" "Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð²Ñ–Ð´ÑутнÑ" ::msgcat::mcset uk "no mechanism available" "нема доÑтупних механізмів" ::msgcat::mcset uk "Node:" "Вузол:" ::msgcat::mcset uk "Node" "Вузол" ::msgcat::mcset uk "None" "Ðемає" ::msgcat::mcset uk "Normal" "Звичайне" ::msgcat::mcset uk "Normal message" "Звичайне повідомленнÑ" ::msgcat::mcset uk "Not Acceptable" "ÐезаÑтоÑовне" ::msgcat::mcset uk "Not Allowed" "Ðе дозволено" ::msgcat::mcset uk "Not Authorized" "Ðе авторизовано" ::msgcat::mcset uk "Not Found" "Ðе знайдено" ::msgcat::mcset uk "- nothing -" "- нічого -" ::msgcat::mcset uk "Notes" "Примітки" ::msgcat::mcset uk "Notify only when available" "Сповіщати тільки коли доÑтупний" ::msgcat::mcset uk "Not Implemented" "Ðе реалізовано" ::msgcat::mcset uk "Not logged in" "Від'єднаний" ::msgcat::mcset uk "No users in %s roster..." "ВідÑутні кориÑтувачі в роÑтері %s..." ::msgcat::mcset uk "No users in roster..." "ВідÑутні кориÑтувачі в роÑтері..." ::msgcat::mcset uk "\nAlternative venue: %s" "\nÐльтернативне міÑце збору: %s" ::msgcat::mcset uk "\nReason is: %s" "\nПричина: %s" ::msgcat::mcset uk "\nReason: %s" "\nПричина: %s" ::msgcat::mcset uk "\nRoom is empty at %s" "\nКімната Ð¿Ð¾Ñ€Ð¾Ð¶Ð½Ñ Ð½Ð° %s" ::msgcat::mcset uk "\nRoom participants at %s:" "\nУчаÑники конференції на %s:" ::msgcat::mcset uk "\n\tAffiliation: %s" "\n\tРанг: %s" ::msgcat::mcset uk "\n\tCan't browse: %s" "\n\tÐеможливо переглÑнути: %s" ::msgcat::mcset uk "\n\tClient: %s" "\n\tКлієнт: %s" ::msgcat::mcset uk "\n\tJID: %s" "JID: %s" ::msgcat::mcset uk "\n\tName: %s" "\n\tІм’Ñ: %s" ::msgcat::mcset uk "\n\tOS: %s" "\n\tОС: %s" ::msgcat::mcset uk "\n\tPresence is signed:" "\n\tПриÑутніÑть підпиÑана:" ::msgcat::mcset uk "Number of children:" "ЧиÑло гілок:" ::msgcat::mcset uk "Number of groupchat messages to expire nick completion according to the last personally addressed message." \ "КількіÑть повідомлень, необхідна Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾, щоб відключити Ð°Ð²Ñ‚Ð¾Ð´Ð¾Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð¿Ñевдоніма автора оÑтаннього повідомленнÑ, адреÑованого перÑонально." ::msgcat::mcset uk "Number of HTTP poll client security keys to send before creating new key sequence." \ "КількіÑть клієнтÑьких ключів безпеки HTTP Ð¾Ð¿Ð¸Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ´Ð°Ñ‡Ñ– перед генерацією нової поÑлідовноÑті ключів." ::msgcat::mcset uk "Offline Messages" "Офлайнові повідомленнÑ" ::msgcat::mcset uk "OK" "Добре" ::msgcat::mcset uk "Old password is incorrect" "Ðевірний Ñтарий пароль" ::msgcat::mcset uk "Old password:" "Старий пароль:" ::msgcat::mcset uk "One window per bare JID" "Одне вікно Ð´Ð»Ñ ÐºÐ¾Ð¶Ð½Ð¾Ð³Ð¾ Ñкороченого JID (без реÑурÑа)" ::msgcat::mcset uk "One window per full JID" "Одне вікно Ð´Ð»Ñ ÐºÐ¾Ð¶Ð½Ð¾Ð³Ð¾ повного JID" ::msgcat::mcset uk "Open chat..." "Відкрити вікно розмови..." ::msgcat::mcset uk "Opening DTCP active connection" "Ð’Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ð°ÐºÑ‚Ð¸Ð²Ð½Ð¾Ð³Ð¾ DTCP з’єднаннÑ" ::msgcat::mcset uk "Opening DTCP passive connection" "Ð’Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ð¿Ð°Ñивного DTCP з’єднаннÑ" ::msgcat::mcset uk "Opening IBB connection" "Ð’Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ IBB з’єднаннÑ" ::msgcat::mcset uk "Opening Jidlink connection" "Ð’Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Jidlink з’єднаннÑ" ::msgcat::mcset uk "Opening SI connection" "Ð’Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ SI з’єднаннÑ" ::msgcat::mcset uk "Opening SOCKS5 listening socket" "Ð’Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ SOCKS5 Ñокета Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð¹Ð¾Ð¼Ñƒ" ::msgcat::mcset uk "Open chat" "Відкрити вікно розмови" ::msgcat::mcset uk "Open chat..." "Відкрити вікно розмови..." ::msgcat::mcset uk "Open raw XML window" "Відкрити вікно \â€Ñирого\†XML" ::msgcat::mcset uk "Open statistics monitor" "Відкрити монітор ÑтатиÑтики" ::msgcat::mcset uk "Open" "Відкрити" ::msgcat::mcset uk "Options for Conference Info module, that allows you to see list of participants in roster popup, regardless of whether you are currently joined with the conference." \ "Параметри Ð¼Ð¾Ð´ÑƒÐ»Ñ Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ— про конференції, що дозволÑÑ” бачити ÑпиÑок учаÑників конференції у Ñпливаючому вікні незалежно від того, підключені Ви до конференції чи ні." ::msgcat::mcset uk "Options for external play program" \ "Параметри Ð´Ð»Ñ Ð·Ð¾Ð²Ð½Ñ–ÑˆÐ½ÑŒÐ¾Ñ— програми програваннÑ." ::msgcat::mcset uk "Options for main interface." "Параметри оÑновного інтерфейÑу." ::msgcat::mcset uk "Options for module that automatically marks you as away after idle threshold." \ "Параметри модулÑ, що автоматично вÑтановлює Ñтан \"Відійшов\" піÑÐ»Ñ Ð²Ñтановленого періоду бездіÑльноÑті." ::msgcat::mcset uk "Options for Raw XML Input module, which allows you to monitor incoming/outgoing traffic from connection to server and send custom XML stanzas." \ "Параметри Ð¼Ð¾Ð´ÑƒÐ»Ñ Ð²Ð²Ð¾Ð´Ñƒ \â€Ñирого\†XML, що дозволÑÑ” переглÑдати вхідний/вихідний XML потік Ð·â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· Ñервером Ñ– відправлÑти влаÑноруч Ñтворений XML." ::msgcat::mcset uk "Organization Name" "Ðазва організації" ::msgcat::mcset uk "Organization Unit" "Відділ організації" ::msgcat::mcset uk "Organization" "ОрганізаціÑ" ::msgcat::mcset uk "OS:" "ОС:" ::msgcat::mcset uk "Pager:" "Пейджер:" ::msgcat::mcset uk "Parent groups" "Групи рівнем вище" ::msgcat::mcset uk "Parent group" "Група рівнем вище" ::msgcat::mcset uk "Participants" "УчаÑники" ::msgcat::mcset uk "Passphrase:" "Парольна фраза:" ::msgcat::mcset uk "Password change failed: %s" "Помилка зміни паролю: %s" ::msgcat::mcset uk "Password is changed" "Пароль змінено" ::msgcat::mcset uk "Password:" "Пароль:" ::msgcat::mcset uk "Password:" "Пароль:" ::msgcat::mcset uk "Password." "Пароль." ::msgcat::mcset uk "Path to the ispell executable." "ШлÑÑ… до виконуваного файлу ispell." ::msgcat::mcset uk "Paused a reply" "ЗупинивÑÑ Ð¿Ñ€Ð¸ друці відповіді" ::msgcat::mcset uk "Payment Required" "ВимагаєтьÑÑ Ð¾Ð¿Ð»Ð°Ñ‚Ð°" ::msgcat::mcset uk "PCS:" ::msgcat::mcset uk "Periodically browse roster conferences" \ "Періодичний переглÑд конференцій з роÑтера" ::msgcat::mcset uk "Personal" "ОÑобиÑта інформаціÑ" # Space at the end of the next word is to distinguish it from another "Personal" ::msgcat::mcset uk "Personal " "ПоÑада " ::msgcat::mcset uk "Phone Home" "Домашній телефон" ::msgcat::mcset uk "Phone Work" "Робочий телефон" ::msgcat::mcset uk "Phone Voice" "Звичайний (голоÑовий) телефон" ::msgcat::mcset uk "Phone Fax" "Телефон факÑ" ::msgcat::mcset uk "Phone Pager" "Телефон пейджер" ::msgcat::mcset uk "Phone Message Recorder" "Телефон автовідповідач" ::msgcat::mcset uk "Phone Cell" "Мобільний телефон" ::msgcat::mcset uk "Phone Video" "Відео телефон" ::msgcat::mcset uk "Phone BBS" "Телефон BBS" ::msgcat::mcset uk "Phone Modem" "Телефон модем" ::msgcat::mcset uk "Phone ISDN" "Телефон ISDN" ::msgcat::mcset uk "Phone PCS" "Телефон PCS" ::msgcat::mcset uk "Phone Preferred" "Телефон переважний" ::msgcat::mcset uk "Phones" "Телефони" ::msgcat::mcset uk "Phone:" "Телефон:" ::msgcat::mcset uk "Photo" "ФотографіÑ" ::msgcat::mcset uk "Plaintext" "Відкритий текÑÑ‚" ::msgcat::mcset uk "Please define environment variable BROWSER" \ "Будь лаÑка вÑтановіть змінну Ð¾Ñ‚Ð¾Ñ‡ÐµÐ½Ð½Ñ BROWSER" ::msgcat::mcset uk "Please enter passphrase" "Будь лаÑка введіть парольну фразу" ::msgcat::mcset uk "Please join %s" "ПриєднайтеÑÑŒ будь лаÑка до %s" ::msgcat::mcset uk "Please try again" "Спробуйте ще раз" ::msgcat::mcset uk "plugin management" "ÑƒÐ¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ Ð¿Ð»Ð°Ð³Ñ–Ð½Ð°Ð¼Ð¸" ::msgcat::mcset uk "Plugins" "Плагіни" ::msgcat::mcset uk "Plugins options." "Параметри плагінів." ::msgcat::mcset uk "PNG images" "Ð—Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ PNG" ::msgcat::mcset uk "Policy Violation" "ÐŸÐ¾Ñ€ÑƒÑˆÐµÐ½Ð½Ñ Ð¿Ð¾Ð»Ñ–Ñ‚Ð¸ÐºÐ¸" ::msgcat::mcset uk "Port:" "Порт:" ::msgcat::mcset uk "Postal Code:" "Поштовий індекÑ:" ::msgcat::mcset uk "Postal Code" "Поштовий індекÑ" ::msgcat::mcset uk "Preferred:" "Переважний:" ::msgcat::mcset uk "Prefix:" "ПрефікÑ:" ::msgcat::mcset uk "Prefix" "ПрефікÑ" ::msgcat::mcset uk "Presence-in" ::msgcat::mcset uk "Presence is signed" "ПриÑутніÑть підпиÑана" ::msgcat::mcset uk "Presence-out" ::msgcat::mcset uk "presence" "приÑутніÑть" ::msgcat::mcset uk "Presence" "ПриÑутніÑть" ::msgcat::mcset uk "Presence" "ПриÑутніÑть" ::msgcat::mcset uk "Presence bar" "Панель приÑутноÑті/ÑтатуÑу" ::msgcat::mcset uk "Presence information" "приÑутніÑть" ::msgcat::mcset uk "Pretty print incoming and outgoing XML stanzas." "Форматувати XML перед виводом." ::msgcat::mcset uk "Pretty print XML" "Форматувати XML" ::msgcat::mcset uk "Prev" "Ðазад" ::msgcat::mcset uk "Prev bookmark" "ÐŸÐ¾Ð¿ÐµÑ€ÐµÐ´Ð½Ñ Ð·Ð°ÐºÐ»Ð°Ð´ÐºÐ°" ::msgcat::mcset uk "Prev highlighted" "Попереднє виділене повідомленнÑ" ::msgcat::mcset uk "Previous/Next history message" "Попереднє/наÑтупне Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ñ–Ñторії" ::msgcat::mcset uk "Previous/Next tab" "ПопереднÑ/наÑтупна закладка" ::msgcat::mcset uk "Priority:" "Пріоритет:" ::msgcat::mcset uk "Priority." "Пріоритет." ::msgcat::mcset uk "Privacy list is activated" "СпиÑок приватноÑті активований" ::msgcat::mcset uk "Privacy list is not activated" "СпиÑок приватноÑті не активований" ::msgcat::mcset uk "Privacy list is not created" "СпиÑок приватноÑті не Ñтворено" ::msgcat::mcset uk "Privacy lists" "СпиÑки приватноÑті" ::msgcat::mcset uk "privacy rules" "правила приватноÑті" ::msgcat::mcset uk "Privacy rules" "Правила приватноÑті" ::msgcat::mcset uk "Privacy lists are not implemented" "СпиÑки приватноÑті не реалізовані" ::msgcat::mcset uk "Privacy lists are unavailable" "СпиÑки приватноÑті недоÑтупні" ::msgcat::mcset uk "Privacy lists error" "Помилка ÑпиÑків приватноÑті" ::msgcat::mcset uk ". Proceed?\n\n" ". Продовжити?\n\n" ::msgcat::mcset uk "Profile on" "Увімкнути профілюваннÑ" ::msgcat::mcset uk "Profile report" "Звіт про профілюваннÑ" ::msgcat::mcset uk "Profiles" "Профілі" ::msgcat::mcset uk "Profile" "Профіль" ::msgcat::mcset uk "Propose to configure newly created MUC room. If set to false then the default room configuration is automatically accepted." \ "Пропонувати конфігурувати знов Ñтворену конференцію. Якщо вÑтановити у false, то автоматично приймаєтьÑÑ ÐºÐ¾Ð½Ñ„Ñ–Ð³ÑƒÑ€Ð°Ñ†Ñ–Ñ Ð·Ð° замовчуваннÑм." ::msgcat::mcset uk "Proxy Login:" "КориÑтувач прокÑÑ–:" ::msgcat::mcset uk "Proxy Password:" "Пароль прокÑÑ–:" ::msgcat::mcset uk "Proxy Port:" "Порт прокÑÑ–:" ::msgcat::mcset uk "Proxy Server:" "ПрокÑÑ– Ñервер:" ::msgcat::mcset uk "Proxy" "ПрокÑÑ–" ::msgcat::mcset uk "Pub/sub" "Pub/sub" ::msgcat::mcset uk "Publish node" "Опублікувати вузол" ::msgcat::mcset uk "Purge all messages" "Видалити вÑÑ– повідомленнÑ" ::msgcat::mcset uk "Purge message" "Видалити повідомленнÑ" ::msgcat::mcset uk "Purge seen messages" "Видалити прочитані повідомленнÑ" ::msgcat::mcset uk "Question" "ЗапитаннÑ" ::msgcat::mcset uk "Quick help" "Коротка допомога" ::msgcat::mcset uk "Quick Help" "Коротка допомога" ::msgcat::mcset uk "Quit" "Вийти" ::msgcat::mcset uk "Quote" "Цитувати" ::msgcat::mcset uk "Raise new tab." "Розміщувати нову закладку над іншими." ::msgcat::mcset uk "Raw XML" "\"Ñирий\" XML" ::msgcat::mcset uk "Reason" "ПідÑтава" ::msgcat::mcset uk "Reason:" "ПідÑтава:" ::msgcat::mcset uk "Received/Sent" "ПрийнÑто/Відправлено" ::msgcat::mcset uk "Received by:" "ПрийнÑто:" ::msgcat::mcset uk "Receive file from %s" "ÐžÑ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ від %s" ::msgcat::mcset uk "Receive" "Отримати" ::msgcat::mcset uk "Receiving file failed: %s" "ÐžÑ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ не вдалоÑÑŒ: %s" ::msgcat::mcset uk "Recipient Error" "Помилка адреÑата" ::msgcat::mcset uk "Recipient Unavailable" "ÐдреÑат не доÑтупний" ::msgcat::mcset uk "Redirect" "ПеренаправленнÑ" ::msgcat::mcset uk "Redo" "Відмінити відміну" ::msgcat::mcset uk "Register in %s" "РеєÑÑ‚Ñ€Ð°Ñ†Ñ–Ñ Ð² %s" ::msgcat::mcset uk "Register" "РеєÑтраціÑ" ::msgcat::mcset uk "Registration failed: %s" "РеєÑÑ‚Ñ€Ð°Ñ†Ñ–Ñ Ð½Ðµ вдалаÑÑŒ: %s" ::msgcat::mcset uk "Registration is successful!" "РеєÑÑ‚Ñ€Ð°Ñ†Ñ–Ñ Ð²Ð´Ð°Ð»Ð°!" ::msgcat::mcset uk "Registration Required" "Потрібна реєÑтраціÑ" ::msgcat::mcset uk "Registration: %s" "РеєÑтраціÑ: %s" ::msgcat::mcset uk "Remote Connection Failed" "Помилка віддаленого з'єднаннÑ" ::msgcat::mcset uk "Remote control options." "Параметри віддаленого керуваннÑ." ::msgcat::mcset uk "Remote Server Error" "Помилка віддаленого Ñервера" ::msgcat::mcset uk "Remote Server Not Found" "Віддалений Ñервер не знайдено" ::msgcat::mcset uk "Remote Server Timeout" "ЗакінчивÑÑ Ñ‡Ð°Ñ Ð¾Ñ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ñ–Ð´Ð¿Ð¾Ð²Ñ–Ð´Ñ– віддаленого Ñервера" ::msgcat::mcset uk "Remove all users in group..." "Видалити вÑÑ–Ñ… кориÑтувачів в групі..." ::msgcat::mcset uk "Remove from list" "Видалити зі ÑпиÑку" ::msgcat::mcset uk "Remove from roster..." "Видалити з роÑтера..." ::msgcat::mcset uk "Remove item..." "Видалити елемент..." ::msgcat::mcset uk "Remove group..." "Видалити групу..." ::msgcat::mcset uk "Remove list" "Видалити ÑпиÑок" ::msgcat::mcset uk "<- Remove" "<- Видалити" ::msgcat::mcset uk "Remove" "Видалити" ::msgcat::mcset uk "Rename group..." "Перейменувати групу..." ::msgcat::mcset uk "Rename roster group" "ÐŸÐµÑ€ÐµÐ¹Ð¼ÐµÐ½ÑƒÐ²Ð°Ð½Ð½Ñ Ð³Ñ€ÑƒÐ¿Ð¸" ::msgcat::mcset uk "Repeat new password:" "Повторіть новий пароль:" ::msgcat::mcset uk "Replace opened connections." "Закрити відкриті з’єднаннÑ." ::msgcat::mcset uk "Replace opened connections" "Замінити відкриті з’єднаннÑ" ::msgcat::mcset uk "Reply subject:" "Тема відповіді:" ::msgcat::mcset uk "Reply to current time (jabber:iq:time) requests." \ "Відповідати на запити чаÑу (jabber:iq:time)." ::msgcat::mcset uk "Reply to idle time (jabber:iq:last) requests." \ "Відповідати на запити чаÑу бездіÑльноÑті (jabber:iq:last)." ::msgcat::mcset uk "Reply to version (jabber:iq:version) requests." \ "Відповідати на запити верÑÑ–Ñ— (jabber:iq:version)." ::msgcat::mcset uk "reply with" "ВідповіÑти" ::msgcat::mcset uk "Reply" "ВідповіÑти" ::msgcat::mcset uk "Report the list of current MUC rooms on disco#items query." \ "Відповідати на запит disco#items про MUC-конференції, в Ñких Ви приймаєте учаÑть." ::msgcat::mcset uk "Request Error" "Помилка запиту" ::msgcat::mcset uk "Request failed: %s" "Запит не вдавÑÑ: %s" ::msgcat::mcset uk "Requesting filter rules: %s" "Запит правил фільтрації: %s" ::msgcat::mcset uk "Requesting ignore list: %s" "Запит ÑпиÑку ігнорованих: %s" ::msgcat::mcset uk "Requesting invisible list: %s" "Запит ÑпиÑку невидимоÑті: %s" ::msgcat::mcset uk "Requesting privacy list: %s" "Запит ÑпиÑку приватноÑті: %s" ::msgcat::mcset uk "Requesting privacy rules: %s" "Запит правил приватноÑті: %s" ::msgcat::mcset uk "Requesting visible list: %s" "Запит видимого ÑпиÑку: %s" ::msgcat::mcset uk "Request only unseen (which aren't displayed in the chat window) messages in the history in MUC compatible conference rooms." \ "Запитувати тільки ті Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ñ–Ñторії, Ñкі не показані у вже відкритих вікнах (Ð´Ð»Ñ ÐºÐ¾Ð½Ñ„ÐµÑ€ÐµÐ½Ñ†Ñ–Ñ—, ÑуміÑної з MUC)." ::msgcat::mcset uk "Request Timeout" "Запит перевищив допуÑтимий чаÑ" ::msgcat::mcset uk "Request" "ЗапроÑити" ::msgcat::mcset uk "Reset to current value" "Ð’Ñтановити в Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñк зараз" ::msgcat::mcset uk "Reset to default value" "Ð’Ñтановити в Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð·Ð° замовчуваннÑм" ::msgcat::mcset uk "Reset to saved value" "Ð’Ñтановити в збережене значеннÑ" ::msgcat::mcset uk "Reset to value from config file" "Ð’Ñтановити Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð· конфігураційного файла" ::msgcat::mcset uk "Resource:" "РеÑурÑ:" ::msgcat::mcset uk "Resource." "РеÑурÑ." ::msgcat::mcset uk "Resource Constraint" "Ðе доÑтатньо реÑурÑів" ::msgcat::mcset uk "Restricted XML" "Заборонений XML" ::msgcat::mcset uk "Resubscribe to all users in group..." \ "ПерепідпиÑатиÑÑŒ до вÑÑ–Ñ… кориÑтувачів у групі..." ::msgcat::mcset uk "Resubscribe" "ПерепідпиÑатиÑÑŒ" ::msgcat::mcset uk "Retract node" "ВідмовитиÑÑŒ від вузла" ::msgcat::mcset uk "Retrieve offline messages using POP3-like protocol." \ "Отримати офлайнові Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸Ñтовуючи протокол, Ñхожий на POP3." ::msgcat::mcset uk "Retry to connect forever." "ÐамагатиÑÑŒ підключатиÑÑŒ поÑтійно." ::msgcat::mcset uk "Returning from auto-away" "ÐŸÐ¾Ð²ÐµÑ€Ð½ÐµÐ½Ð½Ñ Ð·Ñ– Ñтану бездіÑльноÑті" ::msgcat::mcset uk "Revoke Admin Privileges" "Забрати адмініÑтративні привілеї" ::msgcat::mcset uk "Revoke Membership" "Забрати членÑтво" ::msgcat::mcset uk "Revoke Moderator Privileges" "Забрати модераторÑькі привілеї" ::msgcat::mcset uk "Revoke Owner Privileges" "Забрати права влаÑника" ::msgcat::mcset uk "Revoke Voice" "Відізвати право говорити" ::msgcat::mcset uk "Right mouse button" "Права кнопка миші" ::msgcat::mcset uk "Role:" "ПоÑада:" ::msgcat::mcset uk "Role" "Роль" ::msgcat::mcset uk "Room is created" "Кімната Ñтворена" ::msgcat::mcset uk "Room is destroyed" "Кімната видалена" ::msgcat::mcset uk "Room %s is successfully created" "Кімната %s Ñтворена уÑпішно" ::msgcat::mcset uk "Roster Files" "Файли роÑтерів" ::msgcat::mcset uk "Roster item may be dropped not only over group name but also over any item in group." \ "При перетÑгуванні контакта з однієї групи роÑтера в іншу, його можна відпуÑтити не тільки над назвою групи але й над будь-Ñким контактом в цій групі." ::msgcat::mcset uk "Roster Notes" "Примітки у контактах" ::msgcat::mcset uk "Roster of %s" "РоÑтер %s" ::msgcat::mcset uk "Roster options." "Параметри роÑтера." ::msgcat::mcset uk "Roster" "РоÑтер" ::msgcat::mcset uk "Rule name already exists" "Така назва правила вже Ñ–Ñнує" ::msgcat::mcset uk "Rule Name:" "Ðазва правила:" ::msgcat::mcset uk "SASL" ::msgcat::mcset uk "SASL Certificate:" "SASL Ñертифікат:" ::msgcat::mcset uk "SASL auth error: %s" "Помилка аутентифікації SASL: %s" ::msgcat::mcset uk "SASL Port:" "SASL порт:" ::msgcat::mcset uk "Save as:" "Зберегти Ñк:" ::msgcat::mcset uk "Screenname conversion" "ÐšÐ¾Ð½Ð²ÐµÑ€Ñ‚Ð°Ñ†Ñ–Ñ ÐµÐºÑ€Ð°Ð½Ð½Ð¾Ð³Ð¾ імені" ::msgcat::mcset uk "Screenname: %s\n\nConverted JID: %s" "Екранне ім’Ñ: %s\n\nПеретворений JID: %s" ::msgcat::mcset uk "Screenname:" "Екранні ім’Ñ:" ::msgcat::mcset uk "Scroll chat window up/down" "Прогорнути вікно розмови догори/донизу" ::msgcat::mcset uk "Search again" "Шукати знову" ::msgcat::mcset uk "searching" "пошук" ::msgcat::mcset uk "Search in %s: No matching items found" \ "Пошук в %s: не знайдено об’єктів, що підходÑть" ::msgcat::mcset uk "Search in %s" "Пошук в %s" ::msgcat::mcset uk "Search in Tkabber windows options." "Параметри пошуку у вікнах Ткаббера." ::msgcat::mcset uk "Search: %s" "Пошук: %s" ::msgcat::mcset uk "Search" "Пошук" ::msgcat::mcset uk "Search down" "Шукати вниз" ::msgcat::mcset uk "Search up" "Шукати вгору" ::msgcat::mcset uk "See Other Host" "ДивиÑÑŒ інший хоÑÑ‚" ::msgcat::mcset uk "Select Key for Signing %s Traffic" "Вибір ключа Ð´Ð»Ñ Ð¿Ñ–Ð´Ð¿Ð¸ÑÑƒÐ²Ð°Ð½Ð½Ñ Ñ‚Ñ€Ð°Ñ„Ñ–ÐºÑƒ %s" ::msgcat::mcset uk "Select month:" "Виберіть міÑÑць:" ::msgcat::mcset uk "Select" "Вибрати" ::msgcat::mcset uk "Self signed certificate" "СамопіпиÑаний Ñертифікат" ::msgcat::mcset uk "Send broadcast message..." "Відправити широкомовне повідомленнÑ..." ::msgcat::mcset uk "Send contacts to %s" "Відправка контактів до %s" ::msgcat::mcset uk "Send contacts to" "Відправити контакти" ::msgcat::mcset uk "Send custom presence" "Відправити Ñпеціальну приÑутніÑть" ::msgcat::mcset uk "Send file to %s" "Відправка файла до %s" ::msgcat::mcset uk "Send file via Jidlink..." "Відправити файл через Jidlink..." ::msgcat::mcset uk "Send file..." "Відправити файл..." ::msgcat::mcset uk "Sending %s %s list" "Ð’Ñ–Ð´Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ %s %s ÑпиÑку" ::msgcat::mcset uk "Sending configure form" "Ð’Ñ–Ð´Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ ÐºÐ¾Ð½Ñ„Ñ–Ð³ÑƒÑ€Ð°Ñ†Ñ–Ð¹Ð½Ð¾Ñ— форми" ::msgcat::mcset uk "Sending ignore list: %s" "Ð’Ñ–Ð´Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ ÑпиÑку ігнорованих: %s" ::msgcat::mcset uk "Sending invisible list: %s" "Ð’Ñ–Ð´Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ ÑпиÑку невидимоÑті: %s" ::msgcat::mcset uk "Sending visible list: %s" "ÐžÑ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð²Ð¸Ð´Ð¸Ð¼Ð¾Ð³Ð¾ ÑпиÑку: %s" ::msgcat::mcset uk "Send message of the day..." "Відправити Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð´Ð½Ñ..." ::msgcat::mcset uk "Send message to all users in group..." \ "Відправити Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð²Ñім контактам групи..." ::msgcat::mcset uk "Send message to group %s" "Відправка Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð³Ñ€ÑƒÐ¿Ñ– %s" ::msgcat::mcset uk "Send message to group" "Відправка Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð³Ñ€ÑƒÐ¿Ñ–" ::msgcat::mcset uk "Send message to %s" "Відправка Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð´Ð¾ %s" ::msgcat::mcset uk "Send message..." "Відправити повідомленнÑ..." ::msgcat::mcset uk "Send message" "Відправка повідомленнÑ" ::msgcat::mcset uk "Send subscription at %s" "Відправка запиту на передплату на %s" ::msgcat::mcset uk "Send subscription to %s" "Відправка запиту на передплату до %s" ::msgcat::mcset uk "Send subscription to: " "Відправка запиту на підпиÑку до: " ::msgcat::mcset uk "Send subscription" "Відправка запиту на підпиÑку" ::msgcat::mcset uk "Send to server" "Відправити на Ñервер" ::msgcat::mcset uk "Send users..." "Відправити контакти..." ::msgcat::mcset uk "Send" "Відправити" ::msgcat::mcset uk "Send" "Відправити" ::msgcat::mcset uk "Sergei Golovan" "Сергій Головань" ::msgcat::mcset uk "Serial number" "Серійний номер" ::msgcat::mcset uk "Server doesn't support hashed password authentication" \ "Сервер не підтримує Ð¿ÐµÑ€ÐµÐ´Ð°Ð²Ð°Ð½Ð½Ñ ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ… паролів" ::msgcat::mcset uk "Server doesn't support plain or digest authentication" \ "Сервер не підтримує допуÑтимий тип аутентифікації (plain або digest)" ::msgcat::mcset uk "Server Error" "Помилка Ñервера" ::msgcat::mcset uk "Server haven't provided compress feature" "Сервер не підтримує ÑтиÑненнÑ" ::msgcat::mcset uk "Server haven't provided supported compress method" "Сервер не підтримує доÑтупні методи ÑтиÑненнÑ" ::msgcat::mcset uk "Server haven't provided SASL authentication feature" "Сервер не підтримує аутентифікацію SASL" ::msgcat::mcset uk "Server haven't provided non-SASL authentication feature" \ "Сервер не підтримує аутентифікацію non-SASL" ::msgcat::mcset uk "Server name or IP-address." "Ðазва чи ip-адреÑа Ñервера." ::msgcat::mcset uk "Server name." "Ðазва Ñервера." ::msgcat::mcset uk "Server Port:" "Порт Ñервера:" ::msgcat::mcset uk "Server port." "Порт Ñервера." ::msgcat::mcset uk "Server:" "Сервер:" ::msgcat::mcset uk "Server:" "Сервер:" ::msgcat::mcset uk "service discovery" "оглÑд Ñлужб" ::msgcat::mcset uk "Service Discovery" "ОглÑд Ñлужб" ::msgcat::mcset uk "Service info" "Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ Ñлужбу" ::msgcat::mcset uk "Service statistics" "СтатиÑтика Ñлужби" ::msgcat::mcset uk "Service Unavailable" "Служба не доÑтупна" ::msgcat::mcset uk "&Services" "&Служби" ::msgcat::mcset uk "Set bookmark" "Ð’Ñтановити закладку" ::msgcat::mcset uk "Set for current session only" "Ð’Ñтановити тільки Ð´Ð»Ñ Ñ†Ñ–Ñ”Ñ— ÑеÑÑ–Ñ—" ::msgcat::mcset uk "Set for current and future sessions" "Ð’Ñтановити Ð´Ð»Ñ Ñ†Ñ–Ñ”Ñ— та наÑтупних ÑеÑій" ::msgcat::mcset uk "Set priority to 0 when moving to extended away state." \ "Ð’Ñтановлювати нульовий пріоритет при переході в Ñтан \"Давно відійшов\"." ::msgcat::mcset uk "Set" "Ð’Ñтановити" ::msgcat::mcset uk "%s: %s/%s, Description: %s, Version: %s\nNumber of children: %s" \ "%s: %s/%s, ОпиÑ: %s, ВерÑÑ–Ñ: %s\nÐомер гілки : %s" ::msgcat::mcset uk "%s is paused a reply" "%s зупинив друк відповіді" ::msgcat::mcset uk "%s has activated chat window" "%s активував вікно розмови" ::msgcat::mcset uk "%s has inactivated chat window" "%s деактивував вікно розмови" ::msgcat::mcset uk "%s has gone chat window" "%s закрив вікно розмови" ::msgcat::mcset uk "%s has been banned" "%s заборонено входити до кімнати" ::msgcat::mcset uk "%s has been kicked" "%s вигнали з кімнати" ::msgcat::mcset uk "%s has been kicked because of membership loss" "%s вигнали геть з кімнати Ñк результат втрати членÑтва" ::msgcat::mcset uk "%s has been kicked because room became members-only" "%s вигнали геть з кімнати, тому, що кімната Ñтала тільки Ð´Ð»Ñ Ñ‡Ð»ÐµÐ½Ñ–Ð²" ::msgcat::mcset uk "%s has left" "%s вийшов(ла) з кімнати" ::msgcat::mcset uk "%s Headlines" "%s заголовки новин" ::msgcat::mcset uk "Show console" "Показати конÑоль" ::msgcat::mcset uk "Show detailed info on conference room members in roster item tooltips." \ "Показувати детальну інформацію про учаÑників конференції у Ñпливаючому вікні елементів роÑтера." ::msgcat::mcset uk "Show emoticons" "Показати іконки емоцій" ::msgcat::mcset uk "Show history" "Показати Ñ–Ñторію" ::msgcat::mcset uk "Show info" "Показати інформацію" ::msgcat::mcset uk "Show IQ requests in the status line." "Показувати IQ-запити в Ñ€Ñдку ÑтатуÑу." ::msgcat::mcset uk "Show Main Window" "Показати головне вікно" ::msgcat::mcset uk "Show menu tearoffs when possible." \ "Відкривати меню, що \"відриваютьÑÑ\", де це можливо." ::msgcat::mcset uk "Show native icons for contacts, connected to transports/services in roster." \ "ВикориÑтовувати оригінальні іконки Ð´Ð»Ñ ÐºÐ¾Ð½Ñ‚Ð°ÐºÑ‚Ñ–Ð², що підключені через транÑпорти/Ñлужби в роÑтері." ::msgcat::mcset uk "Show native icons for transports/services in roster." \ "ВикориÑтовувати оригінальні іконки Ð´Ð»Ñ Ñ‚Ñ€Ð°Ð½Ñпортів/Ñлужби в роÑтері." ::msgcat::mcset uk "Show number of unread messages in tab titles." \ "Показувати кількіÑть непрочитаних повідомлень в заголовках закладок." ::msgcat::mcset uk "Show offline users" "Показувати контакти, що в не в мережі" ::msgcat::mcset uk "Show online users only" "Показувати тільки контакти, що в мережі" ::msgcat::mcset uk "Show only online users in roster." \ "Показувати в роÑтері тільки контакти, що в мережі." ::msgcat::mcset uk "Show status bar." "Показувати Ñ€Ñдок ÑтатуÑу." ::msgcat::mcset uk "Show subscription type in roster item tooltips." \ "Показувати тип передплати на приÑутніÑть у Ñпливаючому вікні елементів роÑтера." ::msgcat::mcset uk "Show tabs below the main window." "Показувати заголовки вкладок в нижній чаÑтині вікна." ::msgcat::mcset uk "Show Toolbar." "Показувати панель інÑтрументів." ::msgcat::mcset uk "Show" "Показати" ::msgcat::mcset uk "SI connection closed" "SI Ð·â€™Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð·Ð°ÐºÑ€Ð¸Ñ‚Ð¾" ::msgcat::mcset uk "Signature not processed due to missing key" "ÐŸÑ–Ð´Ð¿Ð¸Ñ Ð½Ðµ перевірено через відÑутніÑть ключа" ::msgcat::mcset uk "%s info" "Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ %s" ::msgcat::mcset uk "Single window" "Одне вікно" ::msgcat::mcset uk "%s invites you to conference room %s" "%s запрошує Ð’Ð°Ñ Ð´Ð¾ конференції %s" ::msgcat::mcset uk "%s is composing a reply" "%s пише відповідь" ::msgcat::mcset uk "%s is now known as %s" "%s тепер відомий(а) Ñк %s" ::msgcat::mcset uk "%s is %s" "%s тепер %s" ::msgcat::mcset uk "Size:" "Розмір:" ::msgcat::mcset uk "Smart autoscroll" "\"Розумне\" автоматичне прогортаннÑ" ::msgcat::mcset uk "%s msgs" "%s пов." ::msgcat::mcset uk "Sort" "Сортувати" ::msgcat::mcset uk "Sort by date" "Сортувати за датою" ::msgcat::mcset uk "Sort by from" "Сортувати за адреÑою відправника" ::msgcat::mcset uk "Sort by node" "Сортувати за назвою вузла" ::msgcat::mcset uk "Sort by type" "Сортувати за типом" ::msgcat::mcset uk "Sort items by name" "Сортувати елементи по імені" ::msgcat::mcset uk "Sort items by JID" "Сортувати елементи по JID" ::msgcat::mcset uk "Sort items by JID/node" "Сортувати елементи по JID/вузлу" ::msgcat::mcset uk "Sound" "Звук" ::msgcat::mcset uk "sound" "звук" ::msgcat::mcset uk "Sound options." "Параметри звуку." ::msgcat::mcset uk "Sound to play when connected to Jabber server." \ "Звук, Ñкий програєтьÑÑ Ð¿Ñ€Ð¸ підключенні до Jabber-Ñервера." ::msgcat::mcset uk "Sound to play when available presence is received." \ "Звук, Ñкий програєтьÑÑ Ð¿Ñ€Ð¸ отриманні приÑутноÑті типу \"доÑтупний\"." ::msgcat::mcset uk "Sound to play when unavailable presence is received." \ "Звук, Ñкий програєтьÑÑ Ð¿Ñ€Ð¸ отриманні приÑутноÑті типу \"недоÑтупний\"." ::msgcat::mcset uk "Sound to play when sending personal chat message." \ "Звук, Ñкий програєтьÑÑ Ð¿Ñ€Ð¸ відправці Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð· розмови." ::msgcat::mcset uk "Sound to play when personal chat message is received." \ "Звук, Ñкий програєтьÑÑ Ð¿Ñ€Ð¸ отриманні Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð· розмови." ::msgcat::mcset uk "Sound to play when groupchat server message is received." \ "Звук, Ñкий програєтьÑÑ Ð¿Ñ€Ð¸ отриманні Ñлужбового Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð· конференції." ::msgcat::mcset uk "Sound to play when groupchat message from me is received." \ "Звук, Ñкий програєтьÑÑ Ð¿Ñ€Ð¸ отриманні оÑобиÑтого Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð· конференції." ::msgcat::mcset uk "Sound to play when groupchat message is received." \ "Звук, Ñкий програєтьÑÑ Ð¿Ñ€Ð¸ отриманні звичайного Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð· конференції." ::msgcat::mcset uk "Sound to play when highlighted (usually addressed personally) groupchat message is received." \ "Звук, Ñкий програєтьÑÑ Ð¿Ñ€Ð¸ отриманні виділеного (переважно перÑонально адреÑованого) Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð· конференції." ::msgcat::mcset uk "Specifies search mode while searching in chat, log or disco windows. \"substring\" searches exact substring, \"glob\" uses glob style matching, \"regexp\" allows to match regular expression." \ "Вказує метод пошуку в вікнах чату, протоколу чи оглÑду Ñлужб. \"substring\" шукає підрÑдок, \"glob\" дозволÑÑ” викориÑтовувати підÑтановочні Ñимволи, \"regexp\" викориÑтовує регулÑрні вирази." ::msgcat::mcset uk "Spell check options." "Параметри перевірки правопиÑу." ::msgcat::mcset uk "%s purportedly signed by %s can't be verified.\n\n%s." \ "%s, підпиÑане %s, неможливо перевірити.\n\n%s." ::msgcat::mcset uk "%s request from %s" "Запит %s від %s" ::msgcat::mcset uk "SSL" ::msgcat::mcset uk "SSL & Compression" "SSL & СтиÑненнÑ" ::msgcat::mcset uk "SSL certification authority file or directory (optional)." \ "Файл чи тека центру Ñертифікації (CA) SSL (необов’Ñзковий параметр)." ::msgcat::mcset uk "SSL certificate file (optional)." "Файл Ñертифіката SSL (необов’Ñзково)." ::msgcat::mcset uk "SSL Certificate:" "SSL Ñертифікат:" ::msgcat::mcset uk "SSL Info" "Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ SSL" ::msgcat::mcset uk "SSL Port:" "SSL порт:" ::msgcat::mcset uk "SSL private key file (optional)." \ "Файл Ñекретного ключа SSL (необов’Ñзково)." ::msgcat::mcset uk "%s SSL Certificate Info" "Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ SSL Ñертифіката %s" ::msgcat::mcset uk "Start chat" "Розпочати розмову" ::msgcat::mcset uk "Starting auto-away" "Ðвтоматичне вÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ñтану \"Відійшов\"" ::msgcat::mcset uk "STARTTLS failed" "STARTTLS не вдавÑÑ" ::msgcat::mcset uk "STARTTLS successful" "STARTTLS уÑпішний" ::msgcat::mcset uk "State " "ОблаÑть" ::msgcat::mcset uk "State:" "ОблаÑть:" ::msgcat::mcset uk "State" "Стан" ::msgcat::mcset uk "Statistics monitor" "Монітор ÑтатиÑтики" ::msgcat::mcset uk "Statistics" "СтатиÑтика" ::msgcat::mcset uk "Status bar" "РÑдок ÑтатуÑу" ::msgcat::mcset uk "Stop autoscroll" "Вимкнути автопрогортаннÑ" ::msgcat::mcset uk "Stop chat window autoscroll." "Зупинити Ð°Ð²Ñ‚Ð¾Ð¿Ñ€Ð¾Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ Ð²Ñ–ÐºÐ½Ð° розмови." ::msgcat::mcset uk "Store" "Зберегти" ::msgcat::mcset uk "Stored collapsed roster groups." "Збережені згорнуті/розгорнуті групи роÑтера." ::msgcat::mcset uk "Stored main window state (normal or zoomed)" "Збережений Ñтан (normal або zoomed) головного вікна" ::msgcat::mcset uk "Stored show offline roster groups." \ "Збережене Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð½ÐµÐ¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ… груп роÑтера." ::msgcat::mcset uk "Store group chats logs." "Зберігати Ñ–Ñторію групових розмов." ::msgcat::mcset uk "Store private chats logs." "Зберігати Ñ–Ñторію перÑональних розмов." ::msgcat::mcset uk "store this message offline" "зберегти це Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð½Ð° Ñервері" ::msgcat::mcset uk "Storing conferences failed: %s" "Ðе вдалоÑÑ Ð·Ð±ÐµÑ€ÐµÐ³Ñ‚Ð¸ конференції: %s" ::msgcat::mcset uk "Storing roster notes failed: %s" "Ðе вдалоÑÑ Ð·Ð±ÐµÑ€ÐµÐ³Ñ‚Ð¸ примітки до контактів: %s" ::msgcat::mcset uk "Stored user priority." "Збережений пріоритет кориÑтувача." ::msgcat::mcset uk "Stored user status." "Збережений ÑÑ‚Ð°Ñ‚ÑƒÑ ÐºÐ¾Ñ€Ð¸Ñтувача." ::msgcat::mcset uk "Stored user text status." "Збережений текÑтовий ÑÑ‚Ð°Ñ‚ÑƒÑ ÐºÐ¾Ñ€Ð¸Ñтувача." ::msgcat::mcset uk "Stream Error%s%s" "Помилка потоку%s%s" ::msgcat::mcset uk "Stream initiation options." "Параметри SI-транÑпорта." ::msgcat::mcset uk "Stream method negotiation failed" "Ð£Ð·Ð³Ð¾Ð´Ð¶ÐµÐ½Ð½Ñ Ð¼ÐµÑ‚Ð¾Ð´Ñƒ відправки потоку не вдалоÑÑŒ" ::msgcat::mcset uk "Strip leading \"http://jabber.org/protocol/\" from IQ namespaces in the status line." \ "ОпуÑкати \"http://jabber.org/protocol/\" в запитах в Ñ€Ñдку ÑтатуÑу." ::msgcat::mcset uk "Subject:" "Тема:" ::msgcat::mcset uk "Subject: " "Тема: " ::msgcat::mcset uk "Subject" "Тема" ::msgcat::mcset uk "Subject is set to: %s" "Тема вÑтановлена у: %s" ::msgcat::mcset uk "Submit" "Відправити" ::msgcat::mcset uk "Subscribe request from %s" "Запит на передплату інформації про приÑутніÑть від %s" ::msgcat::mcset uk "Subscribe request from:" "Запит на передплату інформації про приÑутніÑть від:" ::msgcat::mcset uk "Subscribe to a node" "Передплатити вузол" ::msgcat::mcset uk "Subscribe" "Передплатити" ::msgcat::mcset uk "Subscription Required" "ВимагаєтьÑÑ Ð¿ÐµÑ€ÐµÐ´Ð¿Ð»Ð°Ñ‚Ð°" ::msgcat::mcset uk "Substrings to highlight in messages." \ "ЧаÑтини Ñ€Ñдків, Ñкі виділÑти в повідомленнÑÑ…." ::msgcat::mcset uk "Suffix:" "СуфікÑ:" ::msgcat::mcset uk "Suffix" "СуфікÑ" ::msgcat::mcset uk "Switch to tab number 1-9,10" "ПеремкнутиÑÑ Ð½Ð° закладку 1-9,10" ::msgcat::mcset uk "System Shutdown" "Ð—Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ñ€Ð¾Ð±Ð¾Ñ‚Ð¸ ÑиÑтеми" ::msgcat::mcset uk "Systray icon blinks when there are unread messages." \ "Іконка в ÑиÑтемному треї миготить, Ñкщо Ñ” непрочитані повідомленнÑ." ::msgcat::mcset uk "Systray icon options." "Параметри іконки ÑиÑтемного трею." ::msgcat::mcset uk "Tabs:" "Закладки:" ::msgcat::mcset uk "Telephone numbers" "Телефонні номери" ::msgcat::mcset uk "Templates" "Шаблони" ::msgcat::mcset uk "Temporary auth failure" "ТимчаÑова помилка аутентифікації" ::msgcat::mcset uk "Temporary Error" "ТимчаÑова помилка" ::msgcat::mcset uk "Text status, which is set when Tkabber is moving to away state." \ "ТекÑÑ‚ Ñтану, Ñкий вÑтановлюєтьÑÑ ÐºÐ¾Ð»Ð¸ Tkabber переходить в Ñтан \"Відійшов\"." ::msgcat::mcset uk "Text:" "ТекÑÑ‚:" ::msgcat::mcset uk "the body is" "текÑÑ‚ повідомленнÑ" ::msgcat::mcset uk "the message is from" "Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð²Ñ–Ð´" ::msgcat::mcset uk "the message is sent to" "Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð°Ð´Ñ€ÐµÑовано" ::msgcat::mcset uk "the message type is" "тип повідомленнÑ" ::msgcat::mcset uk "the option is set and saved." \ "параметр вÑтановлений Ñ– збережений." ::msgcat::mcset uk "the option is set, but not saved." \ "параметр вÑтановлений, але не збережений Ð´Ð»Ñ Ð½Ð°Ñтупних ÑеÑій." ::msgcat::mcset uk "the option is set to its default value." \ "цей параметр вÑтановлений в Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð·Ð° замовчуваннÑм." ::msgcat::mcset uk "the option is taken from config file." \ "параметр взÑто з конфігураційного файлу" ::msgcat::mcset uk "The signature is good but has expired" "ÐŸÑ–Ð´Ð¿Ð¸Ñ Ð´Ð¾Ð¿ÑƒÑтимий, але його Ñтрок дії закінчивÑÑ" ::msgcat::mcset uk "The signature is good but the key has expired" "ÐŸÑ–Ð´Ð¿Ð¸Ñ Ð´Ð¾Ð¿ÑƒÑтимий, але Ñтрок дії ключа закінчивÑÑ" ::msgcat::mcset uk "the subject is" "тема повідомленнÑ" ::msgcat::mcset uk "This message is encrypted." "ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð·Ð°ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¾." ::msgcat::mcset uk "Time interval before playing next sound (in milliseconds)." \ "Інтервал перед програваннÑм наÑтупного звуку (в міліÑекундах)." ::msgcat::mcset uk "Timeout for waiting for HTTP poll responses (if set to zero, Tkabber will wait forever)." \ "Тайм-аут Ð¾Ñ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ñ–Ð´Ð¿Ð¾Ð²Ñ–Ð´Ñ– запиту HTTP-Ð¾Ð¿Ð¸Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ (Ñкщо вÑтановлений в нуль, Tkabber буде чекати необмежено довго)." ::msgcat::mcset uk "Timer" "Таймер" ::msgcat::mcset uk "time %s%s: %s" "Ñ‡Ð°Ñ %s%s: %s" ::msgcat::mcset uk "time %s%s:" "Ñ‡Ð°Ñ %s%s:" ::msgcat::mcset uk "Time Zone:" "ЧаÑовий поÑÑ:" ::msgcat::mcset uk "Time:" "ЧаÑ:" ::msgcat::mcset uk "Time" "ЧаÑ" ::msgcat::mcset uk "Title:" "Заголовок:" ::msgcat::mcset uk "Title" "Заголовок" ::msgcat::mcset uk "Tkabber icon theme. To make new theme visible for Tkabber put it to some subdirectory of %s." \ "Тема піктограм Tkabber'а. Щоб мати можливіÑть увімкнути Ñвою тему, покладіть Ñ—Ñ— до підтеки теки %s." ::msgcat::mcset uk "Tkabber Systray" "Tkabber трей" ::msgcat::mcset uk "Toggle encryption (when possible)" "Перемкнути ÑˆÐ¸Ñ„Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ (Ñкщо можливо)" ::msgcat::mcset uk "Toggle encryption" "Перемкнути шифруваннÑ" ::msgcat::mcset uk "Toggle seen" "Перемкнути ÑтатуÑ" ::msgcat::mcset uk "Toggle showing offline users" "Перемкнути показ контактів не в мережі" ::msgcat::mcset uk "Toggle signing" "Перемкнути підпиÑуваннÑ" ::msgcat::mcset uk "Toolbar" "Панель інÑтрументів" ::msgcat::mcset uk "To:" "Кому:" ::msgcat::mcset uk "To: " "Кому: " ::msgcat::mcset uk "Transferring..." "Передача..." ::msgcat::mcset uk "Try again" "Спробувати знову" ::msgcat::mcset uk "Type" "Тип" ::msgcat::mcset uk "UID:" ::msgcat::mcset uk "UID" ::msgcat::mcset uk ">>> Unable to decipher data: %s <<<" ">>> Ðеможливо розшифрувати дані: %s <<<" ::msgcat::mcset uk "Unable to encipher data for %s: %s.\n\nEncrypting traffic to this user is now disabled.\n\nSend it as PLAINTEXT?" \ "Ðеможливо зашифрувати дані Ð´Ð»Ñ %s: %s.\n\nÐ¨Ð¸Ñ„Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½ÑŒ Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ контакту тепер вимкнено.\n\nВідправити Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ ÐЕЗÐШИФРОВÐÐИМ?" ::msgcat::mcset uk "Unable to sign message body: %s.\n\nSigning traffic is now disabled.\n\nSend it WITHOUT a signature?" \ "Ðеможливо підпиÑати тіло повідомленнÑ: %s.\n\nПідпиÑÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½ÑŒ тепер відключено.\n\nВідіÑлати Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð‘Ð•Ð— ПІДПИСУ?" ::msgcat::mcset uk "Unable to sign presence information: %s.\n\nPresence will be sent, but signing traffic is now disabled." \ "Ðеможливо підпиÑати інформацію про приÑутніÑть: %s.\n\nÐ†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ приÑутніÑть буде відіÑлана, але підпиÑÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½ÑŒ тепер відключено." ::msgcat::mcset uk "Unauthorized" "Ðе авторизовано" ::msgcat::mcset uk "Unavailable presence" "Стан приÑутноÑті \"недоÑтупний\"" ::msgcat::mcset uk "Unavailable" "ÐедоÑтупний" ::msgcat::mcset uk "Undefined Condition" "Ðевизначена умова" ::msgcat::mcset uk "Undefined" "Ðевизначено" ::msgcat::mcset uk "Undo" "Відмінити" ::msgcat::mcset uk "Unexpected Request" "Ðеочікуваний запит" ::msgcat::mcset uk "Units" "Одиниці" ::msgcat::mcset uk "Unit:" "Відділ:" ::msgcat::mcset uk "Unrecoverable Error" "ÐеуÑувна помилка" ::msgcat::mcset uk "Unregister" "ВідреєÑтрувавÑÑ" ::msgcat::mcset uk "Unsubscribed from %s" "ВідпиÑано від %s" ::msgcat::mcset uk "Unsubscribe" "ВідпиÑатиÑÑŒ" ::msgcat::mcset uk "Unsubscribe from a node" "ВідпиÑатиÑÑŒ від вузла" ::msgcat::mcset uk "Unsupported compression method" "Ðепідтримуваний метод ÑтиÑненнÑ" ::msgcat::mcset uk "Unsupported Encoding" "Ðепідтримуване кодуваннÑ" ::msgcat::mcset uk "Unsupported Stanza Type" "Ðепідтримуваний тип елементу" ::msgcat::mcset uk "Unsupported Version" "Ðепідтримувана верÑÑ–Ñ" ::msgcat::mcset uk "Update message of the day..." "Оновити Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð´Ð½Ñ..." ::msgcat::mcset uk "Uptime" "ТриваліÑть роботи" ::msgcat::mcset uk "Up" "Догори" ::msgcat::mcset uk "URL:" ::msgcat::mcset uk "URL" ::msgcat::mcset uk "URL to connect to." "URL Ð´Ð»Ñ Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ (опитуваннÑ)." ::msgcat::mcset uk "URL to poll:" "URL Ð´Ð»Ñ Ð¾Ð¿Ð¸Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ:" ::msgcat::mcset uk "Use aliases to show multiple users in one roster item." \ "ВикориÑтовувати пÑевдоніми Ð´Ð»Ñ Ð¿Ð¾ÐºÐ°Ð·Ñƒ кількох контактів в одному елементі роÑтера." ::msgcat::mcset uk "Use aliases" "ВикориÑтовувати пÑевдоніми" ::msgcat::mcset uk "Use client security keys" "ВикориÑтовувати ключі безпеки клієнта" ::msgcat::mcset uk "Use colored messages" "ВикориÑтовувати кольорові повідомленнÑ" ::msgcat::mcset uk "Use colored nicks in chat windows." \ "ВикориÑтовувати кольорові пÑевдоніми у вікнах розмов." ::msgcat::mcset uk "Use colored nicks in groupchat rosters." \ "ВикориÑтовувати кольорові пÑевдоніми в роÑтерах групових розмов." ::msgcat::mcset uk "Use colored nicks" "ВикориÑтовувати кольорові пÑевдоніми" ::msgcat::mcset uk "Use colored roster nicks" "ВикориÑтовувати кольорові пÑевдоніми в роÑтері" ::msgcat::mcset uk "Use explicitly-specified server address and port." \ "ВикориÑтовувати Ñвно вказану адреÑу Ñервера Ñ– порт." ::msgcat::mcset uk "Use hashed password" "ВикориÑтовувати хешований пароль" ::msgcat::mcset uk "Use HTTP poll client security keys (recommended)." \ "ВикориÑтовувати клієнтÑькі ключі безпеки Ð´Ð»Ñ HTTP-Ð¾Ð¿Ð¸Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ (рекомендуєтьÑÑ)." ::msgcat::mcset uk "Use HTTP poll connection method." "ВикориÑтовувати HTTP-опитуваннÑ." ::msgcat::mcset uk "Use HTTP proxy to connect." "ВикориÑтовувати HTTP прокÑÑ–-Ñервер Ð´Ð»Ñ Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ." ::msgcat::mcset uk "Use Proxy" "ВикориÑтовувати прокÑÑ–" ::msgcat::mcset uk "Use SASL authentication" "ВикориÑтовувати SASL Ð´Ð»Ñ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ—" ::msgcat::mcset uk "Use SASL authentication." "ВикориÑтовувати SASL Ð´Ð»Ñ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ—." ::msgcat::mcset uk "Use specified key ID for signing and decrypting messages." \ "ВикориÑтовувати ключ з вказаним ідентифікатором Ð´Ð»Ñ Ð¿Ñ–Ð´Ð¿Ð¸Ñу Ñ– Ð´ÐµÑˆÐ¸Ñ„Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½ÑŒ." ::msgcat::mcset uk "Use the same passphrase for signing and decrypting messages." \ "ВикориÑтовувати єдину парольну фразу Ð´Ð»Ñ Ð¿Ñ–Ð´Ð¿Ð¸Ñу Ñ– ÑˆÐ¸Ñ„Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½ÑŒ." ::msgcat::mcset uk "User-Agent string." "РÑдок User-Agent." ::msgcat::mcset uk "User already %s" "КориÑтувач вже %s" ::msgcat::mcset uk "User ID" "ID кориÑтувача" ::msgcat::mcset uk "User info" "Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ кориÑтувача" ::msgcat::mcset uk "user interface" "Ñ–Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ ÐºÐ¾Ñ€Ð¸Ñтувача" ::msgcat::mcset uk "Username Not Available" "Ð†Ð¼â€™Ñ ÐºÐ¾Ñ€Ð¸Ñтувача не доÑтупне" ::msgcat::mcset uk "User name." "Ð†Ð¼â€™Ñ ÐºÐ¾Ñ€Ð¸Ñтувача." ::msgcat::mcset uk "Username:" "КориÑтувач:" ::msgcat::mcset uk "Users" "КориÑтувачі" ::msgcat::mcset uk "Use sound notification only when being available." \ "ВикориÑтовувати звук тільки коли Ñ Ð´Ð¾Ñтупний." ::msgcat::mcset uk "Use SSL" "ВикориÑтовувати SSL" ::msgcat::mcset uk "Use Tabbed Interface (you need to restart)." \ "ВикориÑтовувати Ñ–Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð· закладками (піÑÐ»Ñ Ð·Ð¼Ñ–Ð½Ð¸ потрібен реÑтарт)." ::msgcat::mcset uk "Use this module" "ВикориÑтовувати цей модуль" ::msgcat::mcset uk "UTC:" ::msgcat::mcset uk "utilities" "утиліти" ::msgcat::mcset uk "Value" "ЗначеннÑ" ::msgcat::mcset uk "value is changed, but the option is not set." \ "Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð·Ð¼Ñ–Ð½ÐµÐ½Ð¾, але параметр не вÑтановлено." ::msgcat::mcset uk "vCard display options in chat windows." "Параметри Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð¿Ð¾Ð»Ñ–Ð² vCard у вікні розмови." ::msgcat::mcset uk "vcard %s%s: %s" "Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ %s%s: %s" ::msgcat::mcset uk "vcard %s%s:" "Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ %s%s:" ::msgcat::mcset uk "version %s%s: %s" "верÑÑ–Ñ %s%s: %s" ::msgcat::mcset uk "version %s%s:" "верÑÑ–Ñ %s%s:" ::msgcat::mcset uk "Version:" "ВерÑÑ–Ñ:" ::msgcat::mcset uk "Version" "ВерÑÑ–Ñ" ::msgcat::mcset uk "Video:" "Відео:" ::msgcat::mcset uk "View" "ВиглÑд" ::msgcat::mcset uk "Visible list" "Видимий ÑпиÑок" ::msgcat::mcset uk "Visitors" "Відвідувачі" ::msgcat::mcset uk "Voice:" "ГолоÑовий:" ::msgcat::mcset uk "Waiting for activating privacy list" "ÐžÑ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ñ–Ñ— ÑпиÑку приватноÑті" ::msgcat::mcset uk "Waiting for handshake results" "ÐžÑ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ñ€ÐµÐ·ÑƒÐ»ÑŒÑ‚Ð°Ñ‚Ñ–Ð² рукоÑтиÑканнÑ" ::msgcat::mcset uk "Waiting for authentication results" "ÐžÑ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ñ€ÐµÐ·ÑƒÐ»ÑŒÑ‚Ð°Ñ‚Ñ–Ð² аутентифікації" ::msgcat::mcset uk "Waiting for roster" "ÐžÑ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ñ€Ð¾Ñтера" ::msgcat::mcset uk "Warning display options." "Параметри Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð¿Ð¾Ð¿ÐµÑ€ÐµÐ´Ð¶ÐµÐ½ÑŒ." ::msgcat::mcset uk "Warning" "ПопередженнÑ" ::msgcat::mcset uk "Warning:" "ПопередженнÑ:" ::msgcat::mcset uk "Web Site:" "Веб Ñайт:" ::msgcat::mcset uk "Web Site" "Веб Ñторінка:" ::msgcat::mcset uk "What action does the close button." \ "ДіÑ, що виконуєтьÑÑ Ð¿Ñ€Ð¸ натиÑканні на кнопку Ð·Ð°ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ð²Ñ–ÐºÐ½Ð°." ::msgcat::mcset uk "Whois" "Хто це?" ::msgcat::mcset uk "whois %s: %s" ::msgcat::mcset uk "whois %s: no info" "whois %s: нема інформації" ::msgcat::mcset uk "wmaker" ::msgcat::mcset uk "Work:" "Робочий:" ::msgcat::mcset uk "XML Not Well-Formed" "Ðевірно Ñформований XML" ::msgcat::mcset uk "XMPP stream options when connecting to server." \ "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ XMPP-потоку при підключенні до Ñервера." ::msgcat::mcset uk "Year:" "Рік:" ::msgcat::mcset uk "Zip:" "ІндекÑ:" ::msgcat::mcset uk "Enable freedesktop system tray icon." "Увімкнути freedesktop іконку в ÑиÑтемному треї" ::msgcat::mcset uk "Owner" "ВлаÑник" ::msgcat::mcset uk "Publisher" "Видавець" ::msgcat::mcset uk "Outcast" ::msgcat::mcset uk "Pending" ::msgcat::mcset uk "Unconfigured" "Ðе конфігурований" ::msgcat::mcset uk "Subscribed" "ПідпиÑаний" ::msgcat::mcset uk "Edit entities affiliations: %s" ::msgcat::mcset uk "Jabber ID" "Jabber ID" ::msgcat::mcset uk "SubID" "SubID" ::msgcat::mcset uk "Subscription" "ПідпиÑка" ::msgcat::mcset uk "second" "Ñекунда" ::msgcat::mcset uk "seconds" "Ñекунди" ::msgcat::mcset uk "minute" "хвилина" ::msgcat::mcset uk "minutes" "хвилини" ::msgcat::mcset uk "hour" "година" ::msgcat::mcset uk "hours" "годин" ::msgcat::mcset uk "day" "день" ::msgcat::mcset uk "days" "днів" ::msgcat::mcset uk "Add Conference to Roster" "Додати конференцію в роÑтер" ::msgcat::mcset uk "Conference:" "КонференціÑ:" ::msgcat::mcset uk "Roster group:" "Група роÑтера" ::msgcat::mcset uk "Cached service categories and types (from disco#info)." "Кешовані Ñлужбові категорії Ñ– типи (з disco#info)." ::msgcat::mcset uk "Save To Log" "Зберегти до потоколу" ::msgcat::mcset uk "customization" "приÑтоÑуваннÑ" ::msgcat::mcset uk "pixmaps management" "ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ–ÐºÑмапами" ::msgcat::mcset uk "jabber roster" "роÑтер" ::msgcat::mcset uk "jabber messages" "повідомленнÑ" ::msgcat::mcset uk "jabber chat/muc" "чат/конференції" ::msgcat::mcset uk "general plugins" "ОÑновні плагіни" ::msgcat::mcset uk "roster plugins" "Плагіни роÑтера" ::msgcat::mcset uk "search plugins" "Пошукові плагіни" ::msgcat::mcset uk "unix plugins" "плагіни Ð´Ð»Ñ unix" ::msgcat::mcset uk "windows plugins" "плагіни Ð´Ð»Ñ windows" ::msgcat::mcset uk "macintosh plugins" "плагіни Ð´Ð»Ñ macintosh" ::msgcat::mcset uk "%s plugin" "%s плагін" ::msgcat::mcset uk "Transfer failed: %s" "Передача не вдалаÑÑ: %s" ::msgcat::mcset uk "Opening IQ-IBB connection" "Ð’Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ IQ-IBB з'єднаннÑ" ::msgcat::mcset uk "Original from" "Першопочатково від кого" ::msgcat::mcset uk "Original to" "Першопочатково кому" ::msgcat::mcset uk "Reply to" "ВідповіÑти" ::msgcat::mcset uk "Reply to room" "ВідповіÑти до кімнати" ::msgcat::mcset uk "No reply" "Ðе відповідати" ::msgcat::mcset uk "To" "До" ::msgcat::mcset uk "Carbon copy" "КопіÑ" ::msgcat::mcset uk "Blind carbon copy" "Ðевидима копіÑ" ::msgcat::mcset uk "This message was forwarded by %s\n" "Це Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿ÐµÑ€ÐµÑлав %s\n" ::msgcat::mcset uk "This message was sent by %s\n" "Це Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð±ÑƒÐ»Ð¾ переÑлано %s\n" ::msgcat::mcset uk "Extended addressing fields:" "ÐŸÐ¾Ð»Ñ Ñ€Ð¾Ð·ÑˆÐ¸Ñ€ÐµÐ½Ð¾Ñ— адреÑації" ::msgcat::mcset uk "Forwarded by:" "ПереÑлано:" ::msgcat::mcset uk "Group: " "Група: " ::msgcat::mcset uk "Server haven't provided STARTTLS feature" "Сервер не підтримує STARTTLS" ::msgcat::mcset uk "Use mediated SOCKS5 connection if proxy is available." "ВикориÑтовувати з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ SOCKS5 через поÑередника, Ñкщо прокÑÑ– доÑтупний." ::msgcat::mcset uk "List of proxy servers for SOCKS5 bytestreams (all available servers will be tried for mediated connection)." \ "Перелік прокÑÑ– Ñерверів Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ´Ð°Ñ‡Ñ– потоку SOCKS5 (Ñпроба викориÑтовувати Ñк поÑередника буде вжита Ð´Ð»Ñ Ð²ÑÑ–Ñ… доÑтупних Ñерверів" ::msgcat::mcset uk "Illegal result" "Ðевірний результат" ::msgcat::mcset uk "Cannot connect to proxy" "Ðе вдалоÑÑ Ð·'єднатиÑÑ Ð· прокÑÑ–" ::msgcat::mcset uk "Cannot negotiate proxy connection" "Ðе вдалоÑÑ ÑƒÐ·Ð³Ð¾Ð´Ð¸Ñ‚Ð¸ з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· прокÑÑ–" ::msgcat::mcset uk "Show my own resources in the roster." "Показувати мої оÑобиÑті реÑурÑи в роÑтері" ::msgcat::mcset uk "This message was forwarded to %s" "Це Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð±ÑƒÐ»Ð¾ переÑлано %s" ::msgcat::mcset uk "All unread messages were forwarded to %s." "Ð’ÑÑ– непрочитані Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð±ÑƒÐ»Ð¸ переÑланні %s" ::msgcat::mcset uk "unknown" "невідома помилка" ::msgcat::mcset uk "Show presence bar." "Показувати панель приÑутноÑті/ÑтатуÑу." ::msgcat::mcset uk "Show balloons with headline messages over tree nodes." "Показувати плаваюче віконце з новинами понад гілкою повідомлень." ::msgcat::mcset uk "Maximum number of log messages to show in newly opened chat window (if set to negative then the number is unlimited)." \ "МакÑимальне чиÑло повідомлень протоколу, що буде показане у щойно відкритому вікні чату (Ñкщо від'ємне, то Ñ—Ñ… кількіÑть необмежена)." ::msgcat::mcset uk "Maximum interval length in hours for which log messages should be shown in newly opened chat window (if set to negative then the interval is unlimited)." \ "МакÑимальний вік повідомлень в годинах, що будуть показані у щойно відкритому вікні чату (Ñкщо від'ємне, то Ñ—Ñ… вік необмежений)." ::msgcat::mcset uk "Show user or service info" "Показати інформацію про кориÑтувача, або ÑервіÑ" #::msgcat::mcset uk "I would like to add you to my roster." "Ви не проти Ñкщо Ñ Ð´Ð¾Ð´Ð°Ð¼ Ð²Ð°Ñ Ð´Ð¾ мого роÑтера" ::msgcat::mcset uk "You are unsubscribed from %s" "Ви були відпиÑані від %s" ::msgcat::mcset uk "Port for outgoing HTTP file transfers (0 for assigned automatically). This is useful when sending files from behind a NAT with a forwarded port." \ "Порт Ð´Ð»Ñ Ð²Ð¸Ñ…Ñ–Ð´Ð½Ð¾Ñ— передачі файлів по протоколу ÐТТР (0 - вÑтановлюєтьÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡Ð½Ð¾). Буде кориÑним у випадку відÑÐ¸Ð»Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð² через NAT з портфорвардінгом" ::msgcat::mcset uk "Force advertising this hostname (or IP address) for outgoing HTTP file transfers." \ "ПримуÑово виголошувати дане ім'Ñ Ñ…Ð¾Ñту (чи IP адреÑ) Ð´Ð»Ñ Ð²Ð¸Ñ…Ñ–Ð´Ð½Ð¾Ñ— передачі файлів по протоколу ÐТТР" ::msgcat::mcset uk "Commands" "Команди" ::msgcat::mcset uk "Delete current node and subnodes" "Видалити поточний вузол Ñ– підвузли" ::msgcat::mcset uk "Delete subnodes" "Видалити підвузли" ::msgcat::mcset uk "Clear window" "ОчиÑтити вікно" ::msgcat::mcset uk "Show user or service info..." "Показати інформацію про кориÑтувача, або ÑервіÑ..." ::msgcat::mcset uk "Conferences" "Конференції" ::msgcat::mcset uk "Read on..." "Читати..." ::msgcat::mcset uk "Display warning dialogs when signature verification fails." "Відображати помилки при невдалій перевірці підпиÑу." ::msgcat::mcset uk "Settings of rich text facility which is used to render chat messages and logs." "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ–Ð´ÑиÑтеми розширеного текÑту, Ñка викориÑтовуєтьÑÑ Ð´Ð»Ñ Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½ÑŒ чату Ñ– логів." ::msgcat::mcset uk "Handling of \"stylecodes\". Stylecodes are (groups of) special formatting symbols used to emphasize parts of the text by setting them with boldface, italics or underlined styles, or as combinations of these." \ "ВикориÑÑ‚Ð°Ð½Ð½Ñ ÐºÐ¾Ð´Ñ–Ð² Ñтилів(\"stylecodes\"). Коди Ñтилів - це Ñпеціальні форматувальні Ñимволи, Ñкі викориÑтовуютьÑÑ Ð´Ð»Ñ Ð½Ð°Ð´Ð°Ð½Ð½Ñ Ñ‚ÐµÐºÑту різного виглÑду, а Ñаме: жирний, курÑивний чи підкреÑлений текÑÑ‚, або Ñ—Ñ… комбінації." ::msgcat::mcset uk "Emphasize stylecoded messages using different fonts." "Відображати Ñтильові Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸Ñтовуючи різні шрифти." ::msgcat::mcset uk "Receive error: Stream ID is in use" "Помилка отримуваннÑ: Stream ID вже викориÑтовуєтьÑÑ" ::msgcat::mcset uk "Jidlink connection failed" "З'єднатиÑÑ Ñ‡ÐµÑ€ÐµÐ· Jidlink не вдалоÑÑ" ::msgcat::mcset uk "Jidlink transfer failed" "Ðевдача при передачі через Jidlink" ::msgcat::mcset uk "Handling of \"emoticons\". Emoticons (also known as \"smileys\") are small pictures resembling a human face used to represent user's emotion. They are typed in as special mnemonics like :) or can be inserted using menu." \ "ВикориÑÑ‚Ð°Ð½Ð½Ñ Ñмайлів. Смайлики (англійÑькою - emoticons чи smileys) - це маленькі малюнки Ñхожі на Ð¾Ð±Ð»Ð¸Ñ‡Ñ‡Ñ Ð»ÑŽÐ´Ð¸Ð½Ð¸, Ñк викориÑтовуютьÑÑ Ð´Ð»Ñ Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ ÐµÐ¼Ð¾Ñ†Ñ–Ð¹. Вони можуть бути надруковані Ñк :), або додані через меню." ::msgcat::mcset uk "Tkabber emoticons theme. To make new theme visible for Tkabber put it to some subdirectory of %s." \ "Тема Ñмайликів у Ткаббері. Щоб зробити нову тему видимою Ð´Ð»Ñ Ð¢ÐºÐ°Ð±Ð±ÐµÑ€Ð°, потрібно поклаÑти Ñ—Ñ— до Ñкої-небудь піддиректорії у %s." ::msgcat::mcset uk "Use only whole words for emoticons." "ВикориÑтовувати лише цілі Ñлова Ð´Ð»Ñ Ñмайликів." ::msgcat::mcset uk "Handle ROTFL/LOL smileys -- those like :))) -- by \"consuming\" all that parens and rendering the whole word with appropriate icon." "ЗамінÑти ROTFL/LOL Ñмайли, Ñко :))) чи інші, одним Ñмайлом відкинувши зайві чаÑтини" ::msgcat::mcset uk "Default protocol for sending files." "Протокол за замовчуваннÑм Ð´Ð»Ñ Ð²Ñ–Ð´ÑÐ¸Ð»Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð²." ::msgcat::mcset uk "Can't open file \"%s\": %s" "Ðеможливо відкрити файл \"%s\": %s" ::msgcat::mcset uk "Protocol:" "Протокол:" ::msgcat::mcset uk "Tkabber icon theme. To make new theme visible for Tkabber put it to some subdirectory of %s." "Іконки Ð´Ð»Ñ Ð¢ÐºÐ°Ð±Ð±ÐµÑ€Ð°. Щоб нові теми були доÑтупними Ð´Ð»Ñ Ð¢ÐºÐ°Ð±Ð±ÐµÑ€Ð°, то покладіть Ñ—Ñ… до підтеки %s." ::msgcat::mcset uk "Generate chat messages when room occupant or chat peer changes his/her status and/or status message" "Генерувати Ð¿Ð¾Ð²Ñ‹Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ñ‡Ð°Ñ‚Ñƒ коли учаÑник конференції чи ÑпівбеÑідник по чату змінює Ñвій ÑÑ‚Ð°Ñ‚ÑƒÑ Ñ‡Ð¸ ÑтатуÑне повідомленнÑ" ::msgcat::mcset uk "%s has entered" "%s увійшов" ::msgcat::mcset uk "Generate status messages when occupants enter/exit MUC compatible conference rooms." "Генерувати ÑтатуÑні повідомленнÑ, коли учаÑники заходÑть/залишають ÑуміÑні з MUC конференції." ::msgcat::mcset uk "and" "Ñ–" ::msgcat::mcset uk "doesn't want to be disturbed" "не хоче, щоб його турбували" ::msgcat::mcset uk "is available" "доÑтупний" ::msgcat::mcset uk "is away" "відійшов" ::msgcat::mcset uk "is extended away" "відійшов давно" ::msgcat::mcset uk "is free to chat" "вільний Ð´Ð»Ñ Ñ‡Ð°Ñ‚Ñƒ" ::msgcat::mcset uk "is invisible" "невидимий" ::msgcat::mcset uk "is unavailable" "недоÑтупний" ::msgcat::mcset uk "Tkabber emoticons theme. To make new theme visible for Tkabber put it to some subdirectory of %s." "Смалики Ð´Ð»Ñ Ð¢ÐºÐ°Ð±Ð±ÐµÑ€Ð°. Щоб нові теми були доÑтупними Ð´Ð»Ñ Ð¢ÐºÐ°Ð±Ð±ÐµÑ€Ð°, то покладіть Ñ—Ñ… до підтеки %s." ::msgcat::mcset uk "Fetch nickname" "Отримати пÑевдонім" ::msgcat::mcset uk "Fetch user nicknames" "Отримати пÑевдоніми кориÑтувача" ::msgcat::mcset uk "File path:" "ШлÑÑ… до файлу:" ::msgcat::mcset uk "Generate enter/exit messages" "Генерувати повідомленнÑ, типу увійшов/вийшов" ::msgcat::mcset uk "Load state on Tkabber start." "Завантажити Ñтан при Ñтарті Ткаббера." ::msgcat::mcset uk "Load state on start" "Завантажувати Ñтан під Ñ‡Ð°Ñ Ñтарту" ::msgcat::mcset uk "Save state" "Зберегти Ñтан" ::msgcat::mcset uk "Save state on Tkabber exit." "Зберегти Ñтан при завершенні Ткаббера." ::msgcat::mcset uk "Save state on exit" "Зберігати Ñтан при виході" ::msgcat::mcset uk "Tkabber save state options." "Параметри Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ñтану." ::msgcat::mcset uk "April" "Квітень" ::msgcat::mcset uk "August" "Серпень" ::msgcat::mcset uk "Chats history is converted.\nBackup of the old history is stored in %s" "ІÑторію чатів зконвертовано.\nРезервна ÐºÐ¾Ð¿Ñ–Ñ Ñтарої Ñ–Ñторії збережена в %s" ::msgcat::mcset uk "Conversion is finished" "ÐšÐ¾Ð½Ð²ÐµÑ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¾" ::msgcat::mcset uk "Converting Log Files" "ÐšÐ¾Ð½Ð²ÐµÑ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð² Ñ–Ñторії" ::msgcat::mcset uk "December" "Грудень" ::msgcat::mcset uk "February" "Лютий" ::msgcat::mcset uk "File %s is corrupt. History for %s (%s) is NOT converted\n" "Файл %s пошкоджений. ІÑÑ‚Ð¾Ñ€Ñ–Ñ Ð´Ð»Ñ %s (%s) не була зконвертована\n" ::msgcat::mcset uk "File %s is corrupt. History for %s is NOT converted\n" "Файл %s пошкоджений. ІÑÑ‚Ð¾Ñ€Ñ–Ñ Ð´Ð»Ñ %s не була зконвертована\n" ::msgcat::mcset uk "January" "Січень" ::msgcat::mcset uk "July" "Липень" ::msgcat::mcset uk "June" "Червень" ::msgcat::mcset uk "March" "Березень" ::msgcat::mcset uk "May" "Травень" ::msgcat::mcset uk "November" "ЛиÑтопад" ::msgcat::mcset uk "October" "Жовтень" ::msgcat::mcset uk "Please, be patient while chats history is being converted to new format" "Будь-лаÑка, зачекайте поки Ñ–ÑÑ‚Ð¾Ñ€Ñ–Ñ Ð±ÑƒÐ´Ðµ зконвертована у новий формат" ::msgcat::mcset uk "September" "ВереÑень" ::msgcat::mcset uk "Show TkCon console" "Показати ТКконÑоль" ::msgcat::mcset uk "Could not start ispell server. Check your ispell path and dictionary name. Ispell is disabled now" "Ðевдалий запуÑк ispell Ñервера. Перевірте шлÑÑ… до ispell Ñ– назву Ñловника. Ispell вимкнено" ::msgcat::mcset uk "Enable spellchecker in text input windows." "Увімкнути перевірку правопиÑу в полÑÑ… вводу текÑта." ::msgcat::mcset uk "Timeout" "Таймаут" ::msgcat::mcset uk "Edit MUC ignore rules" "Редагувати правила ігнору Ð´Ð»Ñ Ð³Ñ€ÑƒÐ¿Ð¾Ð²Ð¸Ñ… чатів" ::msgcat::mcset uk "Error loading MUC ignore rules, purged." "Помилка Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð» ігнору Ð´Ð»Ñ Ð³Ñ€ÑƒÐ¿Ð¾Ð²Ð¸Ñ… чатів, очищено." ::msgcat::mcset uk "Ignore chat messages" "Ігнорувати Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ñ‡Ð°Ñ‚Ñƒ" ::msgcat::mcset uk "Ignore groupchat messages" "Ігнорувати Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð² груповому чаті" ::msgcat::mcset uk "Ignoring groupchat and chat messages from selected occupants of multi-user conference rooms." "Ð†Ð³Ð½Ð¾Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½ÑŒ в груповому Ñ– звичайному чаті з обраних учаÑників групових чатів." ::msgcat::mcset uk "MUC Ignore" "Ð†Ð³Ð½Ð¾Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð² групових чатах" ::msgcat::mcset uk "MUC Ignore Rules" "Правила Ñ–Ð³Ð½Ð¾Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð² групових чатах" ::msgcat::mcset uk "Reconnect to server if it does not reply (with result or with error) to ping (urn:xmpp:ping) request in specified time interval (in seconds)." "Перез'єднатиÑÑ Ð· Ñервером у разі відÑутноÑті відповіді (з результатом чи з помилкою) на запити типу пінг (urn:xmpp:ping) через N Ñекунд" ::msgcat::mcset uk "Reply to ping (urn:xmpp:ping) requests." "Відповідь на запити типу пінг (urn:xmpp:ping)." ::msgcat::mcset uk "Attention" "Увага" ::msgcat::mcset uk "Please stand by..." "Будь-лаÑка, заждіть" ::msgcat::mcset uk "Please, be patient while Tkabber configuration directory is being transferred to the new location" "Будь-лаÑка, зачекайте доки тека з налаштуваннÑми Ткаббера буде Ð¿ÐµÑ€ÐµÐ¼Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð½Ð° нове міÑце" ::msgcat::mcset uk "Tkabber configuration directory transfer failed with:\n%s\n Tkabber will use the old directory:\n%s" "ÐŸÐµÑ€ÐµÐ¼Ñ–Ñ‰ÐµÐ½Ð½Ñ Ñ‚ÐµÐºÐ¸ з налаштуваннÑми Ткаббера невдалоÑÑ Ð·:\n%s\n Ткаббер буде викориÑтовувати Ñтару теку:\n%s" ::msgcat::mcset uk "Your new Tkabber config directory is now:\n%s\nYou can delete the old one:\n%s" "Зараз ваші Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¢ÐºÐ°Ð±Ð±ÐµÑ€Ð° знаходÑтьÑÑ Ð² теці:\n%s\nВи можете видалити попередню теку з налаштуваннÑми:\n%s" ::msgcat::mcset uk "Copy JID to clipboard" "Копіювати JID до буферу обміна" ::msgcat::mcset uk "Activate search panel" "Ðктивувати панель пошуку" ::msgcat::mcset uk "Common:" "Загальний:" ::msgcat::mcset uk "Middle mouse button" "Ð¡ÐµÑ€ÐµÐ´Ð½Ñ ÐºÐ½Ð¾Ð¿ÐºÐ° мишки" ::msgcat::mcset uk "Show palette of emoticons" "Показувати палітру іконок емоцій" ::msgcat::mcset uk "%s has changed nick to %s." "%s змінив пÑевдонім на %s." ::msgcat::mcset uk "Open new conversation" "Відкрити нову розмову" ::msgcat::mcset uk "Opens a new chat window for the new nick of the room occupant" "Відкриває нове вікно чату Ð´Ð»Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ пÑевдоніма учаÑника кімнати" ::msgcat::mcset uk "" "нема" ::msgcat::mcset uk "Encrypt traffic (when possible)" "Шифрувати Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ (Ñкщо можливо)" ::msgcat::mcset uk "Encryption" "ШифруваннÑ" ::msgcat::mcset uk "Sign traffic" "ПідпиÑувати повідомленнÑ" ::msgcat::mcset uk "Attached URL:" "Прикріплене поÑиланнÑ:" ::msgcat::mcset uk "File %s cannot be opened: %s. History for %s (%s) is NOT converted\n" "Файл %s неможливо відкрити: %s. ІÑÑ‚Ð¾Ñ€Ñ–Ñ Ð´Ð»Ñ %s (%s) не була зконвертована\n" ::msgcat::mcset uk "File %s cannot be opened: %s. History for %s is NOT converted\n" "Файл %s неможливо відкрити: %s. ІÑÑ‚Ð¾Ñ€Ñ–Ñ Ð´Ð»Ñ %s не була зконвертована\n" ::msgcat::mcset uk "Ignore" "ІгноруваннÑ" ::msgcat::mcset uk "When set, all changes to the ignore rules are applied only until Tkabber is closed\; they are not saved and thus will be not restored at the next run." "Якщо вÑтановлено, то вÑÑ– зміни до правил Ñ–Ð³Ð½Ð¾Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð±ÑƒÐ´ÑƒÑ‚ÑŒ дійÑні допоки увімкнений Ткаббер\; вони не збережені, а отже не будуть відновлені при наÑтупному запуÑку." ::msgcat::mcset uk "Ping server using urn:xmpp:ping requests." "Пінгувати Ñервер викориÑтовуючи запити urn:xmpp:ping." ::msgcat::mcset uk "Show images for emoticons." "Показувати малюнки до Ñмайликів." ::msgcat::mcset uk "Complete nickname or command" "Доповнювати до ÐºÑ–Ð½Ñ†Ñ Ð¿Ñевдонім чи команду" ::msgcat::mcset uk "Abbreviations:" "СкороченнÑ:" ::msgcat::mcset uk "Added abbreviation:\n%s: %s" "Додано ÑкороченнÑ:\n%s: %s" ::msgcat::mcset uk "Deleted abbreviation: %s" "Видалено cкороченнÑ: %s" ::msgcat::mcset uk "No such abbreviation: %s" "Ðемає такого cкороченнÑ: %s" ::msgcat::mcset uk "Purged all abbreviations" "Знищено вÑÑ– cкороченнÑ" ::msgcat::mcset uk "Usage: /abbrev WHAT FOR" "ВикориÑтаннÑ: /abbrev ДЛЯ ЧОГО" ::msgcat::mcset uk "Usage: /unabbrev WHAT" "ВикориÑтаннÑ: /abbrev ЩО" ::msgcat::mcset uk "Chats History" "ІÑÑ‚Ð¾Ñ€Ñ–Ñ Ð Ð¾Ð·Ð¼Ð¾Ð²" ::msgcat::mcset uk "Chats history" "ІÑÑ‚Ð¾Ñ€Ñ–Ñ Ñ€Ð¾Ð·Ð¼Ð¾Ð²" ::msgcat::mcset uk "Full-text search" "ПовнотекÑтовий пошук" ::msgcat::mcset uk "JIDs" "JIDs" ::msgcat::mcset uk "Logs" "Логи" ::msgcat::mcset uk "To be done..." "Буде виконано..." ::msgcat::mcset uk "Unsupported log dir format" "Ðепідтримуваний формат теки логів" ::msgcat::mcset uk "Generate chat messages when chat peer changes his/her status and/or status message" "Генерувати Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ñ‡Ð°Ñ‚Ñƒ, Ñкщо його учаÑник змінює Ñвій ÑÑ‚Ð°Ñ‚ÑƒÑ Ñ‡Ð¸ ÑтатуÑне повідомленнÑ" ::msgcat::mcset uk "Generate groupchat messages when occupant changes his/her status and/or status message" "Генерувати Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð³Ñ€ÑƒÐ¿Ð¾Ð²Ð¾Ð³Ð¾ чату, Ñкщо його учаÑник змінює Ñвій ÑÑ‚Ð°Ñ‚ÑƒÑ Ñ‡Ð¸ ÑтатуÑне повідомленнÑ" ::msgcat::mcset uk "Show own resources in roster." "Показувати оÑобиÑті реÑурÑи в роÑтері." ::msgcat::mcset uk "My Resources" "Мої РеÑурÑи" ::msgcat::mcset uk "Activate visible/invisible/ignore/conference lists before sending initial presence." "Ðктивувати видимий/невидимий/ігнорований ÑпиÑки, а також ÑпиÑок конференцій перед оголошеннÑм Ñвоєї приÑутноÑті." ::msgcat::mcset uk "Changing accept messages from roster only: %s" "Заміна на прийом повідомлень тільки від кориÑтувачів з роÑтера: %s" ::msgcat::mcset uk "Edit conference list" "Редагувати ÑпиÑок конференцій" ::msgcat::mcset uk "Requesting conference list: %s" "ЗапитуєтьÑÑ ÑпиÑок конференцій: %s" ::msgcat::mcset uk "Sending conference list: %s" "ВідÑилаєтьÑÑ ÑпиÑок конференцій: %s" ::msgcat::mcset uk "Accept messages from roster users only" "Приймати Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ñ‚Ñ–Ð»ÑŒÐºÐ¸ від кориÑтувачів з роÑтера" ::msgcat::mcset uk "Edit conference list " "Редагувати ÑпиÑок конференцій " ::msgcat::mcset uk "Show own resources" "Показувати оÑобиÑті реÑурÑи" ::msgcat::mcset uk "Client message" "ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð²Ñ–Ð´ клієнта" ::msgcat::mcset uk "JID list" "СпиÑок JID" ::msgcat::mcset uk "Server message" "ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð²Ñ–Ð´ Ñервера" ::msgcat::mcset uk "WARNING: %s\n" "УВÐГÐ: %s\n" ::msgcat::mcset uk "Approve subscription" "Підтвердити підпиÑку" ::msgcat::mcset uk "Decline subscription" "ВідмовитиÑÑ Ð²Ñ–Ð´ підпиÑки" ::msgcat::mcset uk "Grant subscription" "Ðадати підпиÑку" ::msgcat::mcset uk "Request subscription" "Запитати підпиÑку" ::msgcat::mcset uk "Send request to: " "ВідіÑлати запит до:" ::msgcat::mcset uk "Send subscription request" "ВідіÑлати запит на підпиÑку" ::msgcat::mcset uk "Send subscription request to %s" "ВідіÑлати запит на підпиÑку до %s" ::msgcat::mcset uk "Subscription request from %s" "Запит на підпиÑку від %s" ::msgcat::mcset uk "Subscription request from:" "Запит на підпиÑку від:" ::msgcat::mcset uk "Ask:" "Запит:" ::msgcat::mcset uk "Subscription:" "ПідпиÑка:" namespace eval :: { proc load_ukrainian_procs {} { rename format_time "" rename uk_format_time format_time } proc uk_word_form {t} { set modt [expr {$t % 10}] if {($t >= 10) && ($t < 20)} { return 0 } elseif {$modt == 1} { return 1 } elseif {($modt >= 2) && ($modt <= 4)} { return 2 } else { return 0 } } proc uk_format_time {t} { if {[cequal $t ""]} { return } set sec [expr {$t % 60}] set secs [lindex {"Ñекунд" "Ñекунда" "Ñекунди"} [uk_word_form $sec]] set t [expr {$t / 60}] set min [expr {$t % 60}] set mins [lindex {"хвилин" "хвилина" "хвилини"} [uk_word_form $min]] set t [expr {$t / 60}] set hour [expr {$t % 24}] set hours [lindex {"годин" "година" "години"} [uk_word_form $hour]] set day [expr {$t / 24}] set days [lindex {"днів" "день" "дні"} [uk_word_form $day]] set flag 0 set message "" if {$day != 0} { set flag 1 set message "$day $days" } if {$flag || ($hour != 0)} { set flag 1 set message [concat $message "$hour $hours"] } if {$flag || ($min != 0)} { set message [concat $message "$min $mins"] } return [concat $message "$sec $secs"] } hook::add postload_hook load_ukrainian_procs } # vim:ft=tcl:ts=8:sw=4:sts=4:noet # Local Variables: # mode: tcl # End: tkabber-0.11.1/msgs/uk.rc0000644000175000017500000000322110516662614014445 0ustar sergeisergei! $Id: uk.rc 768 2006-10-22 12:35:24Z sergei $ ! ------------------------------------------------------------------------------ ! uk.rc ! Definition of ukrainian resources for BWidget ! ------------------------------------------------------------------------------ ! --- symbolic names of buttons ------------------------------------------------ *abortName: Перервати *retryName: Повторити *ignoreName: Ігнорувати *okName: Продовжити *cancelName: Відмінити *yesName: Так *noName: ÐÑ– ! --- symbolic names of label of SelectFont dialog ---------------------------- *boldName: Ðапівжирний *italicName: КурÑивний *underlineName: ПідкреÑлений *overstrikeName: ПерекреÑлений *fontName: Шрифт *sizeName: Розмір *styleName: ВиглÑд ! --- symbolic names of label of PasswdDlg dialog ----------------------------- *loginName: Ім'Ñ *passwordName: Пароль ! --- resource for SelectFont dialog ------------------------------------------ *SelectFont.title: Вибір шрифта *SelectFont.sampletext: Sample text, приклад текÑта ! --- resource for MessageDlg dialog ------------------------------------------ *MessageDlg.noneTitle: ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ *MessageDlg.infoTitle: Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ *MessageDlg.questionTitle: ÐŸÐ¸Ñ‚Ð°Ð½Ð½Ñ *MessageDlg.warningTitle: Увага! *MessageDlg.errorTitle: Помилка ! --- resource for PasswdDlg dialog ------------------------------------------- *PasswdDlg.title: Ð£Ð²ÐµÐ´ÐµÐ½Ð½Ñ Ñ–Ð¼ÐµÐ½Ñ– Ñ– Ð¿Ð°Ñ€Ð¾Ð»Ñ tkabber-0.11.1/msgs/nl.msg0000644000175000017500000021601011062233737014620 0ustar sergeisergei# $Id: nl.msg 1501 2008-09-11 15:23:11Z sergei $ # Dutch messages file # Author: Sander Devrieze s (.) devrieze (A.T) pandora (. )be # Please notify me of errors or incoherencies. # avatars.tcl ::msgcat::mcset nl "No avatar to store" "Geen avatar om op te slaan" # browser.tcl ::msgcat::mcset nl "Browser" "Browser" ::msgcat::mcset nl "JID:" "Jabber ID:" ::msgcat::mcset nl "Browse" "Browse" ::msgcat::mcset nl "Browse error: %s" "Fout tijdens browsen: %s" ::msgcat::mcset nl "Description:" "Beschrijving:" ::msgcat::mcset nl "Version:" "Versie:" ::msgcat::mcset nl "Number of children:" "Aantal kinderen:" ::msgcat::mcset nl "List of browsed JIDs." "Lijst van onderzochte Jabber ID's" ::msgcat::mcset nl "Sort items by JID" "Items sorteren op Jabber ID" # chats.tcl ::msgcat::mcset nl "Default message type (if not specified explicitly)." "Standaard berichttype." ::msgcat::mcset nl "Normal" "Normaal" ::msgcat::mcset nl "Chat " "Chat" ::msgcat::mcset nl "Enable messages emphasize." "Benadrukken van berichten aanzetten." ::msgcat::mcset nl "Display description of user status in chat windows." "Aanwezigheid van contactpersoon in chatvenster weergeven." ::msgcat::mcset nl "/me has changed the subject to: %s" "/me veranderde het onderwerp in: %s" ::msgcat::mcset nl ">>> Unable to decipher data: %s <<<" ">>> Kon gegevens niet ontcijferen: %s <<<" ::msgcat::mcset nl "Chat with %s" "Chat met %s" ::msgcat::mcset nl "Toggle encryption" "Versleuteling aan/afzetten" ::msgcat::mcset nl "To:" "Aan:" ::msgcat::mcset nl "Subject:" "Onderwerp:" ::msgcat::mcset nl "Error %s" "Fout %s" ::msgcat::mcset nl "Disconnected" "Verbinding verbroken" ::msgcat::mcset nl "Invite %s to conferences" "%s uitnodigen op chatruimte" ::msgcat::mcset nl "Invite users..." "Contactpersonen uitnodigen..." ::msgcat::mcset nl "Invite" "Uitnodigen" ::msgcat::mcset nl "Please join %s" "Betreed %s" ::msgcat::mcset nl "Invite users to %s" "Contactpersonen uitnodigen op %s" ::msgcat::mcset nl "Send custom presence" "Aangepaste aanwezigheid verzenden" ::msgcat::mcset nl "Chat options." "Chatinstellingen" ::msgcat::mcset nl "Enable chat window autoscroll only when last message is shown." "Zet automatisch schuiven in chatvenster aan wanneer laatste bericht getoond is." ::msgcat::mcset nl "Stop chat window autoscroll." "Automatisch schuiven in chatvenster stoppen." ::msgcat::mcset nl "Moderators" "Moderators" ::msgcat::mcset nl "Participants" "Deelnemers" ::msgcat::mcset nl "Visitors" "Bezoekers" ::msgcat::mcset nl "Users" "Gebruikers" ::msgcat::mcset nl "No conferences for %s in progress..." "Geen groepsgesprekken voor %s aan de gang..." ::msgcat::mcset nl "No users in %s roster..." "Geen contactpersonen in %s roster..." # custom.tcl ::msgcat::mcset nl "Customization of the One True Jabber Client." "Instellingen van de Enige Ware Jabber Client." ::msgcat::mcset nl "Open" "Open" ::msgcat::mcset nl "Parent group" "Bovenliggende groep" ::msgcat::mcset nl "Parent groups" "Bovenliggende groepen" ::msgcat::mcset nl "State" "Status" ::msgcat::mcset nl "you have edited the value, but you have not set the option." "U bewerkte de waarde maar stelde geen optie in." ::msgcat::mcset nl "this option is unchanged from its standard setting." "Deze optie is gelijk aan de standaardwaarde." ::msgcat::mcset nl "you have set this option, but not saved it for future sessions." "U stelde deze optie in maar bewaarde ze niet voor volgende sessies." ::msgcat::mcset nl "this option has been set and saved." "Deze optie werd ingesteld en bewaard." ::msgcat::mcset nl "Set for Current Session" "Voor huidige sessie instellen" ::msgcat::mcset nl "Set for Future Sessions" "Voor volgende sessies instellen" ::msgcat::mcset nl "Reset to Current" "Huidige waarde herstellen" ::msgcat::mcset nl "Reset to Saved" "Bewaarde waarde herstellen" ::msgcat::mcset nl "Reset to Default" "Standaardwaarde herstellen" # datagathering.tcl ::msgcat::mcset nl "Instructions" "Instructies" ::msgcat::mcset nl "First Name:" "Voornaam:" ::msgcat::mcset nl "Last Name:" "Achternaam:" ::msgcat::mcset nl "Zip:" "Postcode:" ::msgcat::mcset nl "Phone:" "Telefoon:" ::msgcat::mcset nl "Date:" "Datum:" ::msgcat::mcset nl "Misc:" "Diverse:" ::msgcat::mcset nl "Text:" "Tekst:" ::msgcat::mcset nl "Key:" "Sleutel:" ::msgcat::mcset nl "Error requesting data: %s" "Fout tijdens aanvragen van gegevens: %s" ::msgcat::mcset nl "Error submitting data: %s" "Fout tijdens voorleggen van gegevens: %s" ::msgcat::mcset nl "Data form" "Gegevensformulier" ::msgcat::mcset nl "Configure service" "Dienst configureren" ::msgcat::mcset nl "Email:" "E-mail:" # default.tcl ::msgcat::mcset nl "Command to be run when you click a URL in a message. '%s' will be replaced with this URL (e.g. \"galeon -n %s\")." "Uit te voeren commando wanneer u klikt op een URL in een bericht. '%s' zal worden vervangen door deze URL (bv. \"galeon -n %s\")." ::msgcat::mcset nl "Error displaying %s in browser\n\n%s" "Fout bij thet laten zien van %s in webbrowser\n\n%s" ::msgcat::mcset nl "Please define environment variable BROWSER" "Geen de omgevingsvariabele BROWSER op." # disco.tcl ::msgcat::mcset nl "Node:" "Node:" ::msgcat::mcset nl "Error getting info: %s" "Fout tijdens afhalen van informatie: %s" ::msgcat::mcset nl "Error getting items: %s" "Fout tijdens afhalen van items: %s" ::msgcat::mcset nl "Error negotiate: %s" "Fout tijdens tot stand brengen: %s" ::msgcat::mcset nl "Discover service" "Services verkennen" ::msgcat::mcset nl "List of discovered JIDs." "Lijst van gevonden Jabber ID's." ::msgcat::mcset nl "List of discovered JID nodes." "Lijst van gevonden Jabber ID-nodes." ::msgcat::mcset nl "Sort items by name" "Items sorteren op naam" ::msgcat::mcset nl "Sort items by JID/node" "Item sorteren op Jabber ID/node" ::msgcat::mcset nl "%s: %s/%s, Description: %s, Version: %s\nNumber of children: %s" "%s: %s/%s, Beschrijving: %s, Versie: %s\nAantal kinderen: %s" # emoticons.tcl # filetransfer.tcl ::msgcat::mcset nl "File Transfer options." "Opties voor bestandsoverdracht" ::msgcat::mcset nl "Default directory for downloaded files." "Standaardmap voor afgehaalde bestanden" ::msgcat::mcset nl "Send file to %s" "Bestand verzenden naar %s" ::msgcat::mcset nl "File to send:" "Bestand om te verzenden:" ::msgcat::mcset nl "Browse..." "Bladeren..." ::msgcat::mcset nl "Description:" "Beschrijving:" ::msgcat::mcset nl "IP address:" "IP-adres:" ::msgcat::mcset nl "File not found or not regular file: %s" "Bestand niet gevonden of geen regulier bestand: %s" ::msgcat::mcset nl "Receive file from %s" "Bestand ontvangen van %s" ::msgcat::mcset nl "Save as:" "Opslaan als:" ::msgcat::mcset nl "Receive" "Ontvangen" ::msgcat::mcset nl "Request failed: %s" "Aanvraag mislukte: %s" ::msgcat::mcset nl "Transferring..." "Bezig met overdracht..." ::msgcat::mcset nl "Size:" "Grootte:" ::msgcat::mcset nl "Connection closed" "Verbinding verbroken" ::msgcat::mcset nl "Send file" "Bestand verzenden" # filters.tcl ::msgcat::mcset nl "I'm not online" "Ik ben niet online¸" ::msgcat::mcset nl "the message is from" "het bericht is van" ::msgcat::mcset nl "the message is sent to" "het bericht werd verzonden naar" ::msgcat::mcset nl "the subject is" "het onderwerp is" ::msgcat::mcset nl "the body is" "de inhoud van het bericht is" ::msgcat::mcset nl "my status is" "mijn status is" ::msgcat::mcset nl "the message type is" "het berichttype is" ::msgcat::mcset nl "change message type to" "wijzig berichttype in" ::msgcat::mcset nl "forward message to" "bericht doorsturen naar" ::msgcat::mcset nl "reply with" "antwoorden met" ::msgcat::mcset nl "store this message offline" "dit bericht offline opslaan" ::msgcat::mcset nl "continue processing rules" "verder gaan met uitvoeren van regels" ::msgcat::mcset nl "Filters" "Filters" ::msgcat::mcset nl "Add" "Toevoegen" ::msgcat::mcset nl "Edit" "Bewerken" ::msgcat::mcset nl "Remove" "Verwijderen" ::msgcat::mcset nl "Move up" "Omhoog" ::msgcat::mcset nl "Move down" "Omlaag" ::msgcat::mcset nl "Edit rule" "Instellingregel bewerken" ::msgcat::mcset nl "Rule Name:" "Regelnaam:" ::msgcat::mcset nl "Empty rule name" "Lege regelnaam" ::msgcat::mcset nl "Rule name already exists" "Regelnaam bestaat al" ::msgcat::mcset nl "Condition" "Toestand" ::msgcat::mcset nl "Action" "Actie" ::msgcat::mcset nl "Requesting filter rules: %s" "Aanvragen van filterregels: %s" # gpgme.tcl ::msgcat::mcset nl "Encrypt traffic" "Verkeer versleutelen" ::msgcat::mcset nl "Change security preferences for %s" "Veiligheidsvoorkeuren van %s wijzigen" ::msgcat::mcset nl "Select" "Selecteren" ::msgcat::mcset nl "Please enter passphrase" "Voer passphrase in" ::msgcat::mcset nl "Please try again" "Probeer opnieuw" ::msgcat::mcset nl "Key ID" "Sleutel-id" ::msgcat::mcset nl "User ID" "Gebruikers-id" ::msgcat::mcset nl "Passphrase:" "Passphrase:" ::msgcat::mcset nl "Error in signature verification software: %s." "Fout in de software die de handtekening moet nakijken:" ::msgcat::mcset nl "%s purportedly signed by %s can't be verified.\n\n%s." "%s wat beweerd word gehandtekend te zijn door %s, kan niet nagekeken worden.\n\n%s." ::msgcat::mcset nl "Unable to sign presence information: %s.\n\nPresence will be sent, but signing traffic is now disabled." "Kon aanwezigheidsinformatie niet ondertekenen: %s..\n\nDe aanwezigheid zal verzonden worden maar het ondertekenen van verkeer staat nu af." ::msgcat::mcset nl "Unable to sign message body: %s.\n\nSigning traffic is now disabled.\n\nSend it WITHOUT a signature?" "Kon berichtinhoud niet ondertekenen: %s.\n\nOndertekenen van verkeer staat nu af.\n\nWilt u het ZONDER handtekening verzenden?" ::msgcat::mcset nl "Data purported sent by %s can't be deciphered.\n\n%s." "De gegevens die worden beweerd verzonden te zijn door %s kunnen niet ontcijferd worden.\n\n%s." ::msgcat::mcset nl "Unable to encipher data for %s: %s.\n\nEncrypting traffic to this user is now disabled.\n\nSend it as PLAINTEXT?" "De gegevens voor %s kunnen niet ontcijferd worden: %s.\n\nDe versleuteling van verkeer naar deze contactpersoon staat nu af.\n\nWilt u het verzenden als PLATTE TEKST?" ::msgcat::mcset nl "GPG options (signing and encryption)." "Opties van GPG (ondertekenen en versleutelen)" ::msgcat::mcset nl "Use the same passphrase for signing and decrypting messages." "Dezelfde passphrase gebruiken voor ondertekenen en ontcijferen van berichten." ::msgcat::mcset nl "GPG-sign outgoing messages and presence updates." "Uitgaande berichten en aanwezigheidswijzigingen met GPG ondertekenen." ::msgcat::mcset nl "GPG-encrypt outgoing messages where possible." "Uitgaande berichten versleutelen met GPG wanneer mogelijk." ::msgcat::mcset nl "Use specified key ID for signing and decrypting messages." "Specifieke sleutel-ID gebruiken om berichten te ondertekenen en versleutelen." ::msgcat::mcset nl "Select Key for Signing %s Traffic" "Sleutel selecteren om %s-verkeer te onderteken" ::msgcat::mcset nl "Fetch GPG key" "GPG-sleutel ophalen" # iface.tcl ::msgcat::mcset nl "Show tabs below the main window." "Tabbladen onder het hoofdvenster laten zien" ::msgcat::mcset nl "Show presence bar." "Aanwezigheidsbalk laten zien" ::msgcat::mcset nl "Show status bar." "Statusbalk laten zien" ::msgcat::mcset nl "Font to use in roster, chat windows etc." "Lettertype voor roster, chatvensters,..." ::msgcat::mcset nl "Show menu tearoffs when possible." "Scheuren in menu laten zien wanneer mogelijk" ::msgcat::mcset nl "What action does the close button." "Actie voor de afsluitknop" ::msgcat::mcset nl "Close Tkabber" "Tkabber afsluiten" ::msgcat::mcset nl "Do nothing" "Niets doen" ::msgcat::mcset nl "Minimize" "Minimaliseren" ::msgcat::mcset nl "Iconize" "Minimaliseren naar systeemvak" ::msgcat::mcset nl "Stored main window state (normal or zoomed)" "Hoofdvenstergegevens opslaan (normaal of ingezoomd)" ::msgcat::mcset nl "View" "Bekijken" ::msgcat::mcset nl "Toolbar" "Werkbalk" ::msgcat::mcset nl "Presence bar" "Aanwezigheidsbalk" ::msgcat::mcset nl "Status bar" "Statusbalk" ::msgcat::mcset nl "Add user to roster..." "Contactpersoon aan roster toevoegen..." ::msgcat::mcset nl "Add conference to roster..." "Chatruimte aan roster toevoegen..." ::msgcat::mcset nl "Plugins" "Plugins" ::msgcat::mcset nl "Search in chat window" "Chatvenster doorzoeken" ::msgcat::mcset nl "Right mouse button" "Rechtermuisknop" ::msgcat::mcset nl "Options for main interface." "Opties voor het hoofdvenster." ::msgcat::mcset nl "Raise new tab." "Nieuw tabblad naar voorgrond brengen." ::msgcat::mcset nl "Delay between getting focus and updating window or tab title in milliseconds." "Vertragen tussen verkrijgen van focus en bijwerken van venster- of tabbladopschrift (milliseconden)." ::msgcat::mcset nl "Presence" "Aanwezigheid" ::msgcat::mcset nl "Free to chat" "Beschikbaar voor gesprek" ::msgcat::mcset nl "Away" "Afwezig" ::msgcat::mcset nl "Extended away" "Langdurig afwezig" ::msgcat::mcset nl "Do not disturb" "Niet storen" ::msgcat::mcset nl "Invisible" "Onzichtbaar" ::msgcat::mcset nl "Change priority..." "Prioriteit wijzigen..." ::msgcat::mcset nl "Log in..." "Aanmelden..." ::msgcat::mcset nl "Log out" "Afmelden" ::msgcat::mcset nl "Log out with reason..." "Afmelden met reden..." ::msgcat::mcset nl "Customize" "Instellingen" ::msgcat::mcset nl "Profile on" "Profiel op" ::msgcat::mcset nl "Profile report" "Profielrapport" ::msgcat::mcset nl "Quit" "Afsluiten" ::msgcat::mcset nl "Send message..." "Bericht verzenden..." ::msgcat::mcset nl "Roster" "Roster" ::msgcat::mcset nl "Add user..." "Contactpersoon toevoegen..." ::msgcat::mcset nl "Add conference..." "Chatruimte toevoegen..." ::msgcat::mcset nl "Add group by regexp on JIDs..." "Groep toevoegen via reguliere expressie op Jabber ID's..." ::msgcat::mcset nl "Show online users only" "Alleen contactpersonen die online zijn laten zien" ::msgcat::mcset nl "Use aliases" "Bijnamen aanzetten" ::msgcat::mcset nl "Export roster..." "Roster exporteren..." ::msgcat::mcset nl "Import roster..." "Roster importeren..." ::msgcat::mcset nl "Periodically browse roster conferences" "Blader periodisch door chatruimtes in het roster" ::msgcat::mcset nl "Browser" "Browser" ::msgcat::mcset nl "Discovery" "Discovery" ::msgcat::mcset nl "Join group..." "Groep betreden..." ::msgcat::mcset nl "Chats" "Chats" ::msgcat::mcset nl "Generate event messages" "Gebeurtenisberichten genereren" ::msgcat::mcset nl "Stop autoscroll" "Automatisch schuiven stoppen" ::msgcat::mcset nl "Smart autoscroll" "Slim automatisch schuiven" ::msgcat::mcset nl "Sound" "Geluid" ::msgcat::mcset nl "Privacy rules" "Instellingen voor privacy" ::msgcat::mcset nl "Manually edit rules..." "Instellingen manueel bewerken..." ::msgcat::mcset nl "Edit invisible list..." "Lijst 'onzichtbaar' bewerken..." ::msgcat::mcset nl "Edit ignore list..." "Lijst 'negeren' bewerken..." ::msgcat::mcset nl "Activate lists at startup" "Lijsten tijdens opstarten activeren" ::msgcat::mcset nl "Message filters..." "Berichtenfilters" ::msgcat::mcset nl "Message archive" "Berichtenarchief" ::msgcat::mcset nl "Change password..." "Wachtwoord wijzigen..." ::msgcat::mcset nl "Show user info..." "Informatie over contactpersoon laten zien..." ::msgcat::mcset nl "Edit my info..." "Mijn gegevens bewerken..." ::msgcat::mcset nl "Avatar" "Avatar" ::msgcat::mcset nl "Announce" "Publiceren" ::msgcat::mcset nl "Allow downloading" "Downloaden toestaan" ::msgcat::mcset nl "Send to server" "Naar server verzenden" ::msgcat::mcset nl "Admin tools" "Hulpmiddelen voor beheerder" ::msgcat::mcset nl "Open raw XML window" "XML-console" ::msgcat::mcset nl "Send broadcast message..." "Broadcastbericht verzenden..." ::msgcat::mcset nl "Send message of the day..." "Bericht van de dag verzenden (motd)..." ::msgcat::mcset nl "Update message of the day..." "Bericht van de dag bijwerken (motd)..." ::msgcat::mcset nl "Delete message of the day" "Bericht van de dag verwijderen (motd)" ::msgcat::mcset nl "Help" "Help" ::msgcat::mcset nl "Quick help" "Snelle hulp" ::msgcat::mcset nl "Quick Help" "Snelle hulp" ::msgcat::mcset nl "Main window:" "Hoofdvenster:" ::msgcat::mcset nl "Tabs:" "Tabbladen:" ::msgcat::mcset nl "Chats:" "Chats:" ::msgcat::mcset nl "Close tab" "Tabblad sluiten" ::msgcat::mcset nl "Previous/Next tab" "Vorig/volgend tabblad" ::msgcat::mcset nl "Move tab left/right" "Tabblad naar links/rechts verplaatsen" ::msgcat::mcset nl "Switch to tab number 1-9,10" "Naar tabblad nummer 1-9,10 gaan" ::msgcat::mcset nl "Hide/Show roster" "Roster verbergen/laten zien" ::msgcat::mcset nl "Complete nickname" "Bijnaam aanvullen" ::msgcat::mcset nl "Previous/Next history message" "Vorig/volgend bericht in geschiedenis" ::msgcat::mcset nl "Show emoticons" "Emoticons laten zien" ::msgcat::mcset nl "Undo" "Ongedaan maken" ::msgcat::mcset nl "Redo" "Opnieuw" ::msgcat::mcset nl "Scroll chat window up/down" "Chatvenster omhoog/omlaag schuiven" ::msgcat::mcset nl "Correct word" "Woord verbeteren" ::msgcat::mcset nl "About" "Over" ::msgcat::mcset nl "Authors:" "Auteurs:" ::msgcat::mcset nl "Alexey Shchepin" "Alexey Shchepin" ::msgcat::mcset nl "Marshall T. Rose" "Marshall T. Rose" ::msgcat::mcset nl "Sergei Golovan" "Sergei Golovan" ::msgcat::mcset nl "Michail Litvak" "Michail Litvak" ::msgcat::mcset nl "Add new user..." "Nieuwe contactpersoon toevoegen..." ::msgcat::mcset nl "Jabber Browser" "Jabber Browser" ::msgcat::mcset nl "Service Discovery" "Service Discovery" ::msgcat::mcset nl "Toggle showing offline users" "Laten zien van contactpersonen die offline zijn aan/afzetten" ::msgcat::mcset nl "Toggle signing" "Ondertekenen aan/afzetten" ::msgcat::mcset nl "Toggle encryption (when possible)" "Versleuteling aan/afzetten (wanneer mogelijk)" ::msgcat::mcset nl "Cancel" "Annuleren" ::msgcat::mcset nl "Close" "Sluiten" ::msgcat::mcset nl "Close other tabs" "Andere tabbladen sluiten" ::msgcat::mcset nl "Close all tabs" "Alle tabbladen sluiten" ::msgcat::mcset nl "Send" "Verzenden" ::msgcat::mcset nl "Show number of unread messages in tab titles." "Aantal ongelezen berichten laten zien in tabbladen." ::msgcat::mcset nl "Emphasize" "Benadrukken" ::msgcat::mcset nl "SSL Info" "Informatie over SSL" ::msgcat::mcset nl "%s SSL Certificate Info" "Informatie over SSL certificaat van %s" ::msgcat::mcset nl "Issuer" "Uitgever" ::msgcat::mcset nl "Begin date" "Aanmaakdatum" ::msgcat::mcset nl "Expiry date" "Verloopdatum" ::msgcat::mcset nl "Serial number" "Seriële nummer" ::msgcat::mcset nl "Cipher" "Cijfer" ::msgcat::mcset nl "Enabled\n" "Aangezet\n" ::msgcat::mcset nl "Disabled\n" "Uigezet\n" # ilogin.tcl ::msgcat::mcset nl "Don't use SSL" "SSL uitschakelen" ::msgcat::mcset nl "Use legacy SSL" "Legacy SSL gebruiken" ::msgcat::mcset nl "Use STARTTLS" "STARTTLS gebruiken" ::msgcat::mcset nl "Use SASL authentication" "Authenticatie met SASL doen" ::msgcat::mcset nl "Use SASL authentication." "Authenticatie met SASL doen." ::msgcat::mcset nl "Allow plaintext SASL mechanisms" "SASL-mechanismes met platte tekst toestaan" ::msgcat::mcset nl "SASL Port:" "Poort voor SASL:" ::msgcat::mcset nl "SASL Certificate:" "Certificaat voor SASL:" ::msgcat::mcset nl "SSL options when connecting to server." "Opties voor SSL bij verbinden met server." ::msgcat::mcset nl "SSL CA file (optional)." "SSL CA-bestand (optioneel)." ::msgcat::mcset nl "SSL private key file (optional)." "Bestand met SSL-privésleutel (optioneel)." ::msgcat::mcset nl "User-Agent string." "Clientidentificatie." ::msgcat::mcset nl "Allow plaintext SASL authentication mechanisms." "SASL-mechanismes voor authenticatie met platte tekst toestaan." ::msgcat::mcset nl "Authentication failed: %s" "Authenticatie mislukte: %s" # iq.tcl ::msgcat::mcset nl "Info/Query options." "Opties voor info/query." ::msgcat::mcset nl "Show IQ requests in the status line." "IQ-aanvragen in de statusbalk weergeven." ::msgcat::mcset nl "Strip leading \"http://jabber.org/protocol/\" from IQ namespaces in the status line." "\"http://jabber.org/protocol/\" aan het begin van IQ-namespaces in de statusbalk afstropen." ::msgcat::mcset nl "%s request from %s" "%s vroeg aan van %s" # itemedit.tcl ::msgcat::mcset nl "Edit properties for %s" "Eigenschappen van %s bewerken" ::msgcat::mcset nl "Edit nickname for %s" "Bijnaam van %s aanpassen" ::msgcat::mcset nl "Nickname:" "Bijnaam:" ::msgcat::mcset nl "Edit groups for %s" "Groepen van %s bewerken" ::msgcat::mcset nl "Available groups" "Beschikbare groepen" ::msgcat::mcset nl "Group:" "Groep:" ::msgcat::mcset nl "Current groups" "Huidige groepen" ::msgcat::mcset nl "Add ->" "Toevoegen ->" ::msgcat::mcset nl "<- Remove" "<- Verwijderen" ::msgcat::mcset nl "Automatically join conference upon connect" "Chatruimte automatisch betreden tijdens verbinden" # jidlink.tcl ::msgcat::mcset nl "Opening Jidlink connection" "Bezig met openen van Jidlink-verbinding" ::msgcat::mcset nl "Jidlink connection closed" "Jidlink-verbinding verbroken" ::msgcat::mcset nl "Jidlink options." "Opties voor Jidlink." ::msgcat::mcset nl "Enable Jidlink transport for outgoing file transfers (it is obsolete)." "Jidlink-transport aanzetten voor uitgaande bestandsoverdrachten (verouderd)." ::msgcat::mcset nl "via Jidlink..." "via Jidlink..." ::msgcat::mcset nl "Send file request failed: %s" "Bestandsaanvraag verzenden mislukte: %s" ::msgcat::mcset nl "Receiving file failed: %s" "Bestand downloaden mislukte: %s" ::msgcat::mcset nl "Enable Jidlink transport %s." "Jidlink-transport %s aanzetten." # joingrdialog.tcl ::msgcat::mcset nl "Join group" "Chatruimte betreden" ::msgcat::mcset nl "Nick:" "Bijnaam:" ::msgcat::mcset nl "Group:" "Chatruimte:" ::msgcat::mcset nl "Server:" "Server:" ::msgcat::mcset nl "Join" "Betreden" ::msgcat::mcset nl "Address:" "Adres:" ::msgcat::mcset nl "Nickname:" "Bijnaam:" ::msgcat::mcset nl "Password:" "Wachtwoord:" ::msgcat::mcset nl "Name: " "Naam:" ::msgcat::mcset nl "Description:" "Beschrijving:" ::msgcat::mcset nl "Connection:" "Verbinding:" ::msgcat::mcset nl "Join group dialog data (nicks)." "Gegevens van venster om chatruimte te betreden (bijnamen)." ::msgcat::mcset nl "Join group dialog data (groups)." "Gegevens van venster om chatruimtes te betreden (chatruimtes)." ::msgcat::mcset nl "Join group dialog data (servers)." "Gegevens van venster om chatruimtes te betreden (servers)." # ifaceck/widgets.tcl ::msgcat::mcset nl "Question" "Vraag" ::msgcat::mcset nl "Error" "Fout" # plugins/si/socks5.tcl ::msgcat::mcset nl "Opening SOCKS5 listening socket" "Bezig met openen van socket voor SOCKS5" # login.tcl ::msgcat::mcset nl "Warning display options." "Weergaveopties voor waarschuwingen." ::msgcat::mcset nl "Display SSL warnings." "SSL-waarschuwingen weergeven." ::msgcat::mcset nl "SSL certificate file (optional)." "Bestand van SSL-certificaat (optioneel)." ::msgcat::mcset nl ". Proceed?\n\n" "Wilt u verder gaan?\n\n" ::msgcat::mcset nl "Keep trying" "Blijf proberen" ::msgcat::mcset nl "Retry to connect forever." "Probeer steeds opnieuw te verbinden." ::msgcat::mcset nl "URL to connect to." "URL om op te verbinden." ::msgcat::mcset nl "Failed to connect: %s" "Verbinden mislukte: %s" ::msgcat::mcset nl "SSL" "SSL" ::msgcat::mcset nl "SASL" "SASL" ::msgcat::mcset nl "Use hashed password transmission." "Door elkaar gehaalde wachtwoordtransmissie aanzetten." ::msgcat::mcset nl "Can't authenticate: Remote server doesn't support\nplain or digest authentication method" "Kan niet verifiëren: server ondersteunt de authenticatiemethodes\nplain of digest niet." ::msgcat::mcset nl "Warning: Remote server doesn't support\nhashed password authentication.\n\nProceed with PLAINTEXT authentication?" "Waarschuwing: server ondersteunt\n door elkaar gehaalde wachtwoordauthenticatie niet.\n\nWilt u verder gaan met PLATTE TEKST authenticatie?" ::msgcat::mcset nl "Login options." "Opties voor aanmelden." ::msgcat::mcset nl "User name." "Gebruikersnaam." ::msgcat::mcset nl "Password." "Wachtwoord." ::msgcat::mcset nl "Resource." "Bron." ::msgcat::mcset nl "Server name." "Naam van server." ::msgcat::mcset nl "Server port." "Poort van server." ::msgcat::mcset nl "Priority." "Prioriteit." ::msgcat::mcset nl "SSL port." "Poort voor SSL." ::msgcat::mcset nl "Use HTTP proxy to connect." "Gebruik een HTTP-proxy om te verbinden." ::msgcat::mcset nl "HTTP proxy address." "Adres van HTTP-proxy." ::msgcat::mcset nl "HTTP proxy port." "Poort van HTTP-proxy." ::msgcat::mcset nl "HTTP proxy username." "Gebruikersnaam voor HTTP-proxy." ::msgcat::mcset nl "HTTP proxy password." "Wachtwoord van HTTP-proxy." ::msgcat::mcset nl "Use explicitly-specified server address." "Serveradres handmatig invoeren." ::msgcat::mcset nl "Server name or IP-address." "Servernaam of IP-adres." ::msgcat::mcset nl "Login" "Aanmelden" ::msgcat::mcset nl "Username:" "Gebruikersnaam:" ::msgcat::mcset nl "Password:" "Wachtwoord:" ::msgcat::mcset nl "Server:" "Server:" ::msgcat::mcset nl "Resource:" "Bron:" ::msgcat::mcset nl "Use hashed password" "Door elkaar gehaald wachtwoord gebruiken" ::msgcat::mcset nl "Connect via alternate server" "Via alternatieve server verbinden" ::msgcat::mcset nl "Use SSL" "SSL gebruiken" ::msgcat::mcset nl "SSL Port:" "Poort van SSL:" ::msgcat::mcset nl "Use Proxy" "Proxy gebruiken" ::msgcat::mcset nl "Proxy Server:" "Proxyserver:" ::msgcat::mcset nl "Proxy Port:" "Poort van proxy:" ::msgcat::mcset nl "Proxy Login:" "Gebruikersnaam voor proxy:" ::msgcat::mcset nl "Proxy Password:" "Wachtwoord voor proxy:" ::msgcat::mcset nl "Profiles" "Profielen" ::msgcat::mcset nl "Profile" "Profiel" ::msgcat::mcset nl "Authentication failed: %s\nCreate new account?" "Authenticatie mislukte: %s\nWilt u een nieuwe account aanmaken?" ::msgcat::mcset nl "Registration failed: %s" "Registratie mislukte: %s" ::msgcat::mcset nl "Change password" "Wachtwoord wijzigen" ::msgcat::mcset nl "Old password:" "Oud wachtwoord:" ::msgcat::mcset nl "New password:" "Nieuw wachtwoord:" ::msgcat::mcset nl "Repeat new password:" "Herhaal nieuw wachtwoord:" ::msgcat::mcset nl "Old password is incorrect" "Het oude wachtwoord is foutief" ::msgcat::mcset nl "New passwords do not match" "Het nieuwe wachtwoord komt niet overeen" ::msgcat::mcset nl "Password is changed" "Het wachtwoord is gewijzigd" ::msgcat::mcset nl "Password change failed: %s" "Wijzigen van wachtwoord mislukte: %s" ::msgcat::mcset nl "Logout with reason" "Afmelden met reden" ::msgcat::mcset nl "Reason:" "Reden:" ::msgcat::mcset nl "Priority:" "Prioriteit:" ::msgcat::mcset nl "Replace opened connections." "Geopende verbindingen herplaatsen." ::msgcat::mcset nl "List of logout reasons." "Lijst met redenen voor afmelden." ::msgcat::mcset nl "Replace opened connections" "Geopende verbindingen herplaatsen" ::msgcat::mcset nl "Logout" "Afmelden" ::msgcat::mcset nl "Account" "Account" ::msgcat::mcset nl "Connection" "Verbinding" ::msgcat::mcset nl "SSL Certificate:" "SSL-certificaat:" ::msgcat::mcset nl "Proxy" "Proxy" ::msgcat::mcset nl "HTTP Poll" "HTTP-poll" ::msgcat::mcset nl "Connect via HTTP polling" "Via HTTP-polling verbinden" ::msgcat::mcset nl "URL to poll:" "URL om te pollen:" ::msgcat::mcset nl "Use client security keys" "Veiligheidssleutels van client gebruiken" ::msgcat::mcset nl "Server Port:" "Poort van server:" ::msgcat::mcset nl "Use HTTP poll connection method." "Via HTTP-poll verbinden." ::msgcat::mcset nl "Use HTTP poll client security keys (recommended)." "HTTP-poll veiligheidsleutels gebruiken (aangeraden)." ::msgcat::mcset nl "Number of HTTP poll client security keys to send before creating new key sequence." "Aantal HTTP-poll veiligheidsleutels om te verzenden voor de aanmaak van een nieuwe reeks sleutels." ::msgcat::mcset nl "Timeout for waiting for HTTP poll responses (if set to zero, Tkabber will wait forever)." "Timeout voor wachten op antwoorden van HTTP-poll (de waarde '0' betekent 'oneindig')." ::msgcat::mcset nl "Minimum poll interval." "Minimum poll-interval." ::msgcat::mcset nl "Maximum poll interval." "Maximum poll-interval." # messages.tcl ::msgcat::mcset nl "Message from %s" "Bericht van %s" ::msgcat::mcset nl "Message from" "Bericht van" ::msgcat::mcset nl "Extras from %s" "Extra's van %s" ::msgcat::mcset nl "Extras from" "Extra's van" ::msgcat::mcset nl "Reply" "Antwoorden" ::msgcat::mcset nl "Attached user:" "Bijgevoegde contactpersoon:" ::msgcat::mcset nl "Attached file:" "Bijlage:" ::msgcat::mcset nl "Invited to:" "Uitnodigen op:" ::msgcat::mcset nl "Message body" "Berichtinhoud" ::msgcat::mcset nl "Send message to %s" "Bericht verzenden naar %s" ::msgcat::mcset nl "Send message" "Bericht verzenden" ::msgcat::mcset nl "This message is encrypted." "Dit bericht is versleuteld." ::msgcat::mcset nl "Subscribe request from %s" "Autorisatieaanvraag van %s" ::msgcat::mcset nl "Subscribe request from" "Autorisatieaanvraag van" ::msgcat::mcset nl "Subscribe" "Autoriseren" ::msgcat::mcset nl "Unsubscribe" "Autorisatie ongedaan maken" ::msgcat::mcset nl "Send subscription" "Autorisatie verzenden" ::msgcat::mcset nl "Send subscription to %s" "Autorisatie verzenden naar %s" ::msgcat::mcset nl "Send subscription to " "Autorisatie verzenden naar" ::msgcat::mcset nl "Headlines" "Koppen" ::msgcat::mcset nl "Mark all seen" "Als gezien markeren" ::msgcat::mcset nl "Mark all unseen" "Als ongezien markeren" ::msgcat::mcset nl "Delete all" "Allen verwijderen" ::msgcat::mcset nl "Sort" "Sorteren" ::msgcat::mcset nl "Forward..." "Doorsturen..." ::msgcat::mcset nl "Forward to %s" "Doorsturen naar %s" ::msgcat::mcset nl "%s invites you to conference room %s" "%s nodigt u uit om chatruimte %s te betreden" ::msgcat::mcset nl "\nReason is: %s" "\nReden is: %s" ::msgcat::mcset nl "Chat" "Chat" ::msgcat::mcset nl "Quote" "Citeren" ::msgcat::mcset nl "Reply subject:" "Onderwerp van antwoord:" ::msgcat::mcset nl "Delete" "Verwijderen" ::msgcat::mcset nl "%s Headlines" "%s koppen" ::msgcat::mcset nl "Forward headline" "Kop doorsturen" ::msgcat::mcset nl "Message and Headline options." "Bericht- en kopopties" ::msgcat::mcset nl "Cache headlines on exit and restore on start." "Koppen bufferen bij beëindigen en herstellen bij opstarten." ::msgcat::mcset nl "Display headlines in single/multiple windows." "Koppen weergeven in enkel/meervoudige vensters." ::msgcat::mcset nl "Single window" "Enkelvoudig venster" ::msgcat::mcset nl "One window per bare JID" "Eén venster per kale Jabber ID" ::msgcat::mcset nl "One window per full JID" "Eén venster per volledige Jabber ID" ::msgcat::mcset nl "Do not display headline descriptions as tree nodes." "Kopbeschrijvingen niet weergeven als boomnodes." ::msgcat::mcset nl "List of message destination JIDs." "Lijst van Jabber ID's waarheen berichten werden verzonden" ::msgcat::mcset nl "List of JIDs to whom headlines have been sent." "Lijst van Jabber ID's waarheen koppen werden verzonden" ::msgcat::mcset nl "Send message to group %s" "Bericht naar groep %s verzenden" ::msgcat::mcset nl "Send message to group" "Bericht naar groep verzenden" ::msgcat::mcset nl "Copy headline to clipboard" "Kop naar klembord kopiëren" ::msgcat::mcset nl "Copy URL to clipboard" "URL naar klembord kopiëren" # muc.tcl ::msgcat::mcset nl "Generate event messages in MUC compatible conference rooms." "Gebeurtenisberichten in chatruimtes genereren die compatibel zijn met MUC." ::msgcat::mcset nl "Report the list of current MUC rooms on disco#items query." "De lijst met huidige chatruimtes rapporteren na een disco#items-aanvraag." ::msgcat::mcset nl "Whois" "Whois" ::msgcat::mcset nl "Kick" "Kick" ::msgcat::mcset nl "Ban" "Verbannen" ::msgcat::mcset nl "Grant Voice" "Medezeggenschap verlenen" ::msgcat::mcset nl "Revoke Voice" "Medezeggenschap intrekken" ::msgcat::mcset nl "Grant Membership" "Lidmaatschap verlenen" ::msgcat::mcset nl "Revoke Membership" "Lidmaatschap intrekken" ::msgcat::mcset nl "Grant Moderator Privileges" "Moderatorrechten verlenen" ::msgcat::mcset nl "Revoke Moderator Privileges" "Moderatorrechten intrekken" ::msgcat::mcset nl "Grant Administrative Privileges" "Beheerdersrechten verlenen" ::msgcat::mcset nl "Revoke Administrative Privileges" "Beheerdersrechten intrekken" ::msgcat::mcset nl "Grant Ownership Privileges" "Eigenaarschapsrechten verlenen" ::msgcat::mcset nl "Revoke Ownership Privileges" "Eigenaarschapsrechten intrekken" ::msgcat::mcset nl "%s has been banned" "%s werd verbannen" ::msgcat::mcset nl "%s has been kicked" "%s werd gekicked" ::msgcat::mcset nl " by %s" " door %s" ::msgcat::mcset nl "%s is now known as %s" "%s is nu gekend als %s" ::msgcat::mcset nl "%s has become available" "%s betrad de chatruimte" ::msgcat::mcset nl "%s has left" "%s verliet de chatruimte" ::msgcat::mcset nl "MUC" "MUC" ::msgcat::mcset nl "Configure room..." "Chatruimte configureren..." ::msgcat::mcset nl "Edit owner list..." "Eigenaarslijst bewerken..." ::msgcat::mcset nl "Edit admin list..." "Beheerderslijst bewerken..." ::msgcat::mcset nl "Edit moderator list..." "Moderatorslijst bewerken..." ::msgcat::mcset nl "Edit ban list..." "Lijst met verbannen personen bewerken..." ::msgcat::mcset nl "Edit member list..." "Ledenlijst bewerken..." ::msgcat::mcset nl "Edit voice list..." "Medezeggenschapslijst bewerken..." ::msgcat::mcset nl "Destroy room" "Chatruimte vernietigen" ::msgcat::mcset nl "Join conference" "Chatruimte betreden" ::msgcat::mcset nl "Join groupchat" "Chatruimte betreden" ::msgcat::mcset nl "\n\tJID: %s" "\n\tJabber ID: %s" ::msgcat::mcset nl "\n\tAffiliation: %s" "\n\tAfdeling: %s" ::msgcat::mcset nl "Maximum number of characters in the history in MUC compatible conference rooms." "Maximum aantal tekens in de geschiedenis van chatruimtes (MUC)." ::msgcat::mcset nl "Maximum number of stanzas in the history in MUC compatible conference rooms." "Maximum aantal stanza's in de geschiedenis van chatruimtes (MUC)." ::msgcat::mcset nl "Request only unseen (which aren't displayed in the chat window) messages in the history in MUC compatible conference rooms." "Enkel ongelezen berichten aanvragen van chatruimtes (MUC)." ::msgcat::mcset nl "Conference room %s will be destroyed permanently.\n\nProceed?" "De chatruimte %s zal verwijderd worden.\n\nWilt u verder gaan?" ::msgcat::mcset nl "Nick" "Bijnaam" ::msgcat::mcset nl "Role" "Rol" ::msgcat::mcset nl "Affiliation" "Band" ::msgcat::mcset nl "Reason" "Reden" # presence.tcl ::msgcat::mcset nl "Change Presence Priority" "Prioriteit van aanwezigheid wijzigen" ::msgcat::mcset nl "Not logged in" "Niet aangemeld" ::msgcat::mcset nl "invalid userstatus value " "ongeldige waarde voor aanwezigheid van contactpersoon" ::msgcat::mcset nl "Available" "Beschikbaar" ::msgcat::mcset nl "Unavailable" "Onbeschikbaar" # privacy.tcl ::msgcat::mcset nl "Requesting privacy rules: %s" "Bezig met aanvragen van instellingen voor privacy: %s" ::msgcat::mcset nl "Add list" "Lijst toevoegen" ::msgcat::mcset nl "Active" "Actief" ::msgcat::mcset nl "Remove list" "Lijst verwijderen" ::msgcat::mcset nl "Add item" "Item toevoegen" ::msgcat::mcset nl "No default list" "Geen standaardlijst:" ::msgcat::mcset nl "No active list" "Geen actieve lijst" ::msgcat::mcset nl "Default" "Standaard:" ::msgcat::mcset nl "Edit list" "Lijst bewerken" ::msgcat::mcset nl "Requesting privacy list: %s" "Bezig met aanvragen van privacygegevens: %s" ::msgcat::mcset nl "Requesting ignore list: %s" "Bezig met aanvragen van negeerlijst: %s" ::msgcat::mcset nl "Requesting invisible list: %s" "Bezig met aanvragen van de lijst 'onzichtbaar': %s" ::msgcat::mcset nl "Requesting visible list: %s" "Bezig met aanvragen van de lijst 'zichtbaar': %s" ::msgcat::mcset nl "Sending ignore list: %s" "Bezig met verzenden van negeerlijst: %s" ::msgcat::mcset nl "Sending invisible list: %s" "Bezig met verzenden van de lijst 'onzichtbaar': %s" ::msgcat::mcset nl "Sending visible list: %s" "Bezig met verzenden van de lijst 'zichtbaar': %s" ::msgcat::mcset nl "Edit ignore list" "Negeerlijst bewerken" ::msgcat::mcset nl "Edit invisible list" "Lijst 'onzichtbaar' bewerken" ::msgcat::mcset nl "Edit visible list" "Lijst 'zichtbaar' bewerken" ::msgcat::mcset nl "Blocking communication options." "Communicatieopties blokkeren." ::msgcat::mcset nl "Activate visible/invisible/ignore lists before sending initial presence." "Zichtbaar/onzichtbaar/negeer-lijsten activeren voor verzenden van aanwezigheid." ::msgcat::mcset nl "Privacy lists" "Privacylijsten" ::msgcat::mcset nl "List name" "Lijstnaam" ::msgcat::mcset nl "Edit privacy list" "Privacylijst bewerken" ::msgcat::mcset nl "Type" "Soort" ::msgcat::mcset nl "Presence-in" "Inkomende aanwezigheid" ::msgcat::mcset nl "Presence-out" "Uitgaande aanwezigheid" ::msgcat::mcset nl "Up" "Omhoog" ::msgcat::mcset nl "Down" "Omlaag" ::msgcat::mcset nl "Add JID" "Jabber ID toevoegen" ::msgcat::mcset nl "Remove from list" "Van lijst verwijderen" ::msgcat::mcset nl "Waiting for activating privacy list" "Bezig met wachten om privacylijst te activeren" ::msgcat::mcset nl "Privacy list is activated" "Privacylijst staat aan" ::msgcat::mcset nl "Privacy list is not activated" "Privacylist staat af" # register.tcl ::msgcat::mcset nl "Register in %s" "Registreren in %s" ::msgcat::mcset nl "Unsubscribed from %s" "Autorisatie van %s werd verwijderd" ::msgcat::mcset nl "We unsubscribed from %s" "Autorisatie van %s werd verwijderd" ::msgcat::mcset nl "Register" "Registreren" ::msgcat::mcset nl "Registration: %s" "Registratie: %s" ::msgcat::mcset nl "Registration is successful!" "Registratie is geslaagd!" # roster.tcl ::msgcat::mcset nl "Add chats group in roster." "Chatruimtes aan roster toevoegen." ::msgcat::mcset nl "Show detailed info on conference room members in roster item tooltips." "Gedetaileerde informatie over leden van de chatruimte laten zien via rosteritem-tekstballonnen." ::msgcat::mcset nl "Active Chats" "Actieve chats" ::msgcat::mcset nl "Show offline users" "Contactpersonen die offline zijn laten zien" ::msgcat::mcset nl "Show only online users in roster." "Enkel contactpersonen die online zijn laten zien in roster." ::msgcat::mcset nl "Show native icons for transports/services in roster." "Oorspronkelijke pictogrammen laten zien voor transporten/diensten in het roster." ::msgcat::mcset nl "Show native icons for contacts, connected to transports/services in roster." "Oorspronkelijke pictogrammen laten zien voor contactpersonen verbonden met transporten/diensten in het roster." ::msgcat::mcset nl "Undefined" "Ongedefinieerd" ::msgcat::mcset nl "is now" "is nu" ::msgcat::mcset nl "Are you sure to remove %s from roster?" "Bent u zeker dat u %s wilt verwijderen uit uw roster?" ::msgcat::mcset nl "Add roster group by JID regexp" "Rostergroep toevoegen via reguliere expressie op Jabber ID " ::msgcat::mcset nl "New group name:" "Nieuwe groepnaam:" ::msgcat::mcset nl "JID regexp:" "reguliere expressie op Jabber ID:" ::msgcat::mcset nl "Start chat" "Chat starten" ::msgcat::mcset nl "Invite to conference..." "Uitnodigen op chatruimte..." ::msgcat::mcset nl "Resubscribe" "Opnieuw autoriseren" ::msgcat::mcset nl "Send users..." "Contactpersonen verzenden..." ::msgcat::mcset nl "Send file via HTTP..." "Bestand via HTTP verzenden..." ::msgcat::mcset nl "Send file via Jidlink..." "Bestand via Jidlink verzenden..." ::msgcat::mcset nl "Show info" "Informatie over contactpersoon laten zien" ::msgcat::mcset nl "Show history" "Geschiedenis laten zien" ::msgcat::mcset nl "Edit item..." "Item bewerken..." ::msgcat::mcset nl "Edit security..." "Beveiliging aanpassen..." ::msgcat::mcset nl "Join..." "Betreden..." ::msgcat::mcset nl "Log in" "Aanmelden" ::msgcat::mcset nl "Log out" "Afmelden" ::msgcat::mcset nl "Send contacts to" "Contactpersonen verzenden naar" ::msgcat::mcset nl "Send" "Verzenden" ::msgcat::mcset nl "No users in roster..." "Geen contactpersonen in het roster..." ::msgcat::mcset nl "Contact Information" "Informatie over contactpersoon" ::msgcat::mcset nl "Resubscribe to all users in group..." "Opnieuw op alle contactpersonen in deze groep autoriseren..." ::msgcat::mcset nl "Roster options." "Rosteropties." ::msgcat::mcset nl "Are you sure to remove group '%s' from roster?" "Bent u zeker dat u groep '%s' uit uw roster wilt verwijderen" ::msgcat::mcset nl "Rename roster group" "Rostergroep hernoemen" ::msgcat::mcset nl "Roster Files" "Bestanden in roster" ::msgcat::mcset nl "All Files" "Alle bestanden" ::msgcat::mcset nl "Roster of %s" "Roster van %s" ::msgcat::mcset nl "%s is available" "%s is beschikbaar" ::msgcat::mcset nl "%s is free to chat" "%s is beschikbaar om te chatten" ::msgcat::mcset nl "%s is away" "%s is afwezig" ::msgcat::mcset nl "%s is extended away" "%s is langdurig afwezig" ::msgcat::mcset nl "%s doesn't want to be disturbed" "%s wilt niet gestoord worden" ::msgcat::mcset nl "%s is invisible" "%s is onzichtbaar" ::msgcat::mcset nl "%s is unavailable" "%s is niet beschikbaar" # roster_nested.tcl ::msgcat::mcset nl "Enable nested roster groups." "Genestelde rostergroepen aanzetten." ::msgcat::mcset nl "Default nested roster group delimiter." "Standaard genestelde rostergroep afbakenen." # search.tcl ::msgcat::mcset nl "#" "#" ::msgcat::mcset nl "Search in %s" "Zoeken in %s" ::msgcat::mcset nl "Search: %s" "Zoek: %s" ::msgcat::mcset nl "Search again" "Opnieuw zoeken" ::msgcat::mcset nl "OK" "OK" ::msgcat::mcset nl "Try again" "Opnieuw proberen" ::msgcat::mcset nl "An error occurred when searching in %s\n\n%s" "Er deed zich een fout voor tijdens het zoeken in %s\n\n%s" ::msgcat::mcset nl "Search" "Zoeken" ::msgcat::mcset nl "Search in %s: No matching items found" "Zoeken in %s: geen overeenkomende items gevonden" # si.tcl ::msgcat::mcset nl "Opening SI connection" "Bezig met openen van SI-verbinding" ::msgcat::mcset nl "Stream method negotiation failed" "Totstandbrenging van streammethode mislukte" ::msgcat::mcset nl "SI connection closed" "SI-verbinding verbroken" ::msgcat::mcset nl "Enable SI transport %s." "SI-transport %s aanzetten" # splash.tcl ::msgcat::mcset nl "auto-away" "automatisch afwezig" ::msgcat::mcset nl "avatars" "avatars" ::msgcat::mcset nl "balloon help" "tekstballon" ::msgcat::mcset nl "browsing" "browsing" ::msgcat::mcset nl "configuration" "configuratie" ::msgcat::mcset nl "connections" "verbindingen" ::msgcat::mcset nl "cryptographics" "GPG" ::msgcat::mcset nl "emoticons" "emoticons" ::msgcat::mcset nl "extension management" "beheer van uitbreidingen" ::msgcat::mcset nl "file transfer" "bestandsoverdracht" ::msgcat::mcset nl "jabber chat" "chat" ::msgcat::mcset nl "jabber groupchats" "chatruimtes" ::msgcat::mcset nl "jabber iq" "Jabber iq" ::msgcat::mcset nl "jabber presence" "aanwezigheid" ::msgcat::mcset nl "jabber registration" "registratie" ::msgcat::mcset nl "jabber xml" "xml" ::msgcat::mcset nl "kde" "kde" ::msgcat::mcset nl "message filters" "berichtenfilters" ::msgcat::mcset nl "message/headline" "bericht/kop" ::msgcat::mcset nl "plugin management" "pluginbeheer" ::msgcat::mcset nl "presence" "aanwezigheid" ::msgcat::mcset nl "rosters" "rosters" ::msgcat::mcset nl "searching" "zoeken" ::msgcat::mcset nl "text undo" "tekst ongedaan maken" ::msgcat::mcset nl "user interface" "gebruikersinterface" ::msgcat::mcset nl "utilities" "gereedschappen" ::msgcat::mcset nl "wmaker" "wmaker" ::msgcat::mcset nl "service discovery" "service discovery" ::msgcat::mcset nl "jidlink" "jidlink" ::msgcat::mcset nl "multi-user chat" "chatruimtes" ::msgcat::mcset nl "negotiation" "totstandbrenging" ::msgcat::mcset nl "privacy rules" "instellingen voor privacy" ::msgcat::mcset nl "sound" "geluid" ::msgcat::mcset nl "bwidget workarounds" "workaround voor bwidget" # plugins/general/sound.tcl ::msgcat::mcset nl "Sound options." "Geluid." ::msgcat::mcset nl "Mute sound notification." "Geluid uitschakelen." ::msgcat::mcset nl "Use sound notification only when being available." "Geluiden enkel afspelen tijdens het beschikbaar zijn." ::msgcat::mcset nl "Mute sound when displaying delayed groupchat messages." "Geluid uitschakelen tijdens het weergeven van vertraagde berichten in chatruimte." ::msgcat::mcset nl "Mute sound when displaying delayed personal chat messages." "Geluid uitschakelen tijdens het weergeven van vertraagde persoonlijke berichten." ::msgcat::mcset nl "Options for external play program" "Opties voor externe afspeeltoepassing" ::msgcat::mcset nl "Time interval before playing next sound (in milliseconds)." "Tijdsinterval tussen het afspelen van 2 geluiden (in milliseconden)." ::msgcat::mcset nl "Mute sound if Tkabber window is focused." "Geluid uitschakelen als het venster van Tkabber geselecteerd is." ::msgcat::mcset nl "External program, which is to be executed to play sound. If empty, Snack library is used (if available) to play sound." "Externe toepassing die moet uitgevoerd worden om geluid af te spelen. Indien niets is ingevuld, dan zal de bibliotheek Snack gebruikt worden (indien aanwezig) om geluid af te spelen." ::msgcat::mcset nl "Sound to play when connected to Jabber server." "Geluid om af te spelen bij het tot stand komen van de verbinding met de Jabber-server." ::msgcat::mcset nl "Sound to play when available presence is received." "Geluid om af te spelen bij het ontvangen van de aanwezigheid 'beschikbaar'." ::msgcat::mcset nl "Sound to play when unavailable presence is received." "Geluid om af te spelen bij het ontvangen van de aanwezigheid 'onbeschikbaar'." ::msgcat::mcset nl "Sound to play when sending personal chat message." "Geluid om af te spelen bij het verzenden van een bericht." ::msgcat::mcset nl "Sound to play when personal chat message is received." "Geluid om af te spelen bij het ontvangen van een bericht." ::msgcat::mcset nl "Sound to play when groupchat server message is received." "Geluid om af te spelen bij het ontvangen van een bericht van een chatruimte." ::msgcat::mcset nl "Sound to play when groupchat message from me is received." "Geluid om af te spelen bij het ontvangen van eigen bericht in een chatruimte." ::msgcat::mcset nl "Sound to play when groupchat message is received." "Geluid om af te spelen bij het ontvangen van een bericht in een chatruimte." ::msgcat::mcset nl "Sound to play when highlighted (usually addressed personally) groupchat message is received." "Geluid om af te spelen bij het ontvangen van een geaccentueerd bericht in een chatruimte." ::msgcat::mcset nl "Mute sound" "Geluid uitschakelen" ::msgcat::mcset nl "Notify only when available" "Enkel notificeren wanneer beschikbaar" # subscribe_gateway.tcl ::msgcat::mcset nl "Send subscription at %s" "Autorisatie verzenden naar %s" ::msgcat::mcset nl "Enter screenname of contact you want to add" "Voer de schermnaam in van de contactpersoon die u wilt toevoegen" ::msgcat::mcset nl "Screenname conversion" "Omzetting van schermnaam" ::msgcat::mcset nl "Convert" "Omzetten" ::msgcat::mcset nl "Screenname:" "Schermnaam:" ::msgcat::mcset nl "Error while converting screenname: %s." "Fout bij omzetten van de schermnaam: %s" ::msgcat::mcset nl "Screenname: %s\n\nConverted JID: %s" "Schermnaam: %s\n\nOmgezette Jabber ID: %s" ::msgcat::mcset nl "Convert screenname" "Schermnaam omzetten" # userinfo.tcl ::msgcat::mcset nl "Show user info" "Informatie over contactpersoon laten zien" ::msgcat::mcset nl "Show" "Laten zien" ::msgcat::mcset nl "%s info" "Informatie over %s" ::msgcat::mcset nl "Personal" "Persoonlijk" ::msgcat::mcset nl "Name" "Naam" ::msgcat::mcset nl "Full Name:" "Volledige naam:" ::msgcat::mcset nl "Family Name:" "Achternaam:" ::msgcat::mcset nl "Name:" "Voornaam:" ::msgcat::mcset nl "Middle Name:" "Tussennaam:" ::msgcat::mcset nl "Prefix:" "Voorvoegsel:" ::msgcat::mcset nl "Suffix:" "Achtervoegsel:" ::msgcat::mcset nl "Nickname:" "Bijnaam:" ::msgcat::mcset nl "Information" "Informatie" ::msgcat::mcset nl "E-mail:" "E-mail:" ::msgcat::mcset nl "Web Site:" "Website:" ::msgcat::mcset nl "JID:" "Jabber ID:" ::msgcat::mcset nl "UID:" "UID:" ::msgcat::mcset nl "Phones" "Telefoons" ::msgcat::mcset nl "Telephone numbers" "Telefoonnummers" ::msgcat::mcset nl "Home:" "Thuis:" ::msgcat::mcset nl "Work:" "Werk:" ::msgcat::mcset nl "Voice:" "Voicemail:" ::msgcat::mcset nl "Fax:" "Fax:" ::msgcat::mcset nl "Pager:" "Pieper:" ::msgcat::mcset nl "Message Recorder:" "Antwoordapparaat:" ::msgcat::mcset nl "Cell:" "GSM:" ::msgcat::mcset nl "Video:" "Video:" ::msgcat::mcset nl "BBS:" "BBS:" ::msgcat::mcset nl "Modem:" "Modem:" ::msgcat::mcset nl "ISDN:" "ISDN:" ::msgcat::mcset nl "PCS:" "PCS:" ::msgcat::mcset nl "Preferred:" "Voorkeur:" ::msgcat::mcset nl "Location" "Locatie" ::msgcat::mcset nl "Address" "Adres" ::msgcat::mcset nl "Address:" "Adres:" ::msgcat::mcset nl "Address 2:" "Adres 2:" ::msgcat::mcset nl "City:" "Stad:" ::msgcat::mcset nl "State:" "Provincie:" ::msgcat::mcset nl "Postal Code:" "Postcode:" ::msgcat::mcset nl "Country:" "Land:" ::msgcat::mcset nl "Geographical position" "Geografische positie" ::msgcat::mcset nl "Latitude:" "Breedtegraad:" ::msgcat::mcset nl "Longitude:" "Lengtegraad:" ::msgcat::mcset nl "Organization" "Organisatie" ::msgcat::mcset nl "Details" "Details" # Space at the end of the next word is to distinguish it from another "Name:" ::msgcat::mcset nl "Name: " "Naam: " ::msgcat::mcset nl "Unit:" "Afdeling:" # Space at the end of the next word is to distinguish it from another "Personal" ::msgcat::mcset nl "Personal " "Persoonlijk " ::msgcat::mcset nl "Title:" "Titel:" ::msgcat::mcset nl "Role:" "Functie:" # Space at the end of the next word is to distinguish it from another "About" ::msgcat::mcset nl "About " "Over " ::msgcat::mcset nl "Birthday" "Verjaardag" ::msgcat::mcset nl "Birthday:" "Verjaardag:" ::msgcat::mcset nl "Year:" "Jaar:" ::msgcat::mcset nl "Month:" "Maand:" ::msgcat::mcset nl "Day:" "Dag:" ::msgcat::mcset nl "Photo" "Foto" ::msgcat::mcset nl "URL:" "URL:" ::msgcat::mcset nl "URL" "URL" ::msgcat::mcset nl "Image" "Afbeelding" ::msgcat::mcset nl "None" "Geen" ::msgcat::mcset nl "Load Image" "Afbeelding laden" ::msgcat::mcset nl "Client" "Client" ::msgcat::mcset nl "Client:" "Client:" ::msgcat::mcset nl "Last Activity or Uptime" "Laatste activiteit of uptime:" ::msgcat::mcset nl "Interval:" "Interval:" ::msgcat::mcset nl "Description:" "Beschrijving:" ::msgcat::mcset nl "Computer" "Computer" ::msgcat::mcset nl "OS:" "Besturingssysteem:" ::msgcat::mcset nl "Time:" "Tijd:" ::msgcat::mcset nl "Time Zone:" "Tijdszone:" ::msgcat::mcset nl "UTC:" "UTC:" ::msgcat::mcset nl "Presence" "Aanwezigheid" ::msgcat::mcset nl "Presence is signed" "Aanwezigheid is ondertekend" ::msgcat::mcset nl " by " " door " ::msgcat::mcset nl "User info" "Informatie over contactpersoon" ::msgcat::mcset nl "Service info" "Informatie over dienst" ::msgcat::mcset nl "Last activity" "Laatste activiteit" ::msgcat::mcset nl "Uptime" "Uptime" ::msgcat::mcset nl "Time" "Tijd" ::msgcat::mcset nl "Version" "Versie" ::msgcat::mcset nl "List of users for userinfo." "Lijst van contactpersonen voor userinfo." # ifacetk/iface.tcl ::msgcat::mcset nl "Use Tabbed Interface (you need to restart)." "Interface met tabbladen aanzetten (u moet Tkabber hiervoor herstarten)." ::msgcat::mcset nl "Show Toolbar." "Werkbalk laten zien." # ifacetk/iroster.tcl ::msgcat::mcset nl "Send contacts to %s" "Contactpersonen verzenden naar %s" ::msgcat::mcset nl "Use aliases to show multiple users in one roster item." "Bijnamen gebruiken om meerdere contactpersonen in één rosteritem te laten zien." ::msgcat::mcset nl "Show subscription type in roster item tooltips." "Autorisatie laten zien in rosteritem-tekstballonnen." ::msgcat::mcset nl "Stored collapsed roster groups." "Ingeklapte bewaarde rostergroepen." ::msgcat::mcset nl "via HTTP..." "via HTTP..." ::msgcat::mcset nl "Remove item..." "Item verwijderen..." ::msgcat::mcset nl "Rename group..." "Groep hernoemen..." ::msgcat::mcset nl "Send message to all users in group..." "Bericht verzenden naar alle contactpersonen in groep..." ::msgcat::mcset nl "Remove group..." "Groep verwijderen..." ::msgcat::mcset nl "Remove all users in group..." "Alle contactpersonen in de groep verwijderen..." ::msgcat::mcset nl "Are you sure to remove group '%s' from roster? \n(Users which are in this group only, will be in undefined group.)" "Bent u zeker dat u groep '%s' wilt verwijderen uit uw roster? \n(Contactpersonen die enkel in deze groep zitten, zullen in de groep 'Ongedefinieerd' komen.)" ::msgcat::mcset nl "Are you sure to remove all users in group '%s' from roster? \n(Users which are in another groups too, will not be removed from the roster.)" "Bent u zeker dat u alle contactpersonen in groep '%s' wilt verwijderen uit uw roster? \n(Contactpersonen die ook in andere groepen zitten, zullen niet verwijderd worden uit uw roster.)" ::msgcat::mcset nl "Send file..." "Bestand verzenden..." # jabberlib-tclxml/jabberlib.tcl ::msgcat::mcset nl "Authentication failed" "Authenticatie mislukte" ::msgcat::mcset nl "Authentication successful" "Authenticatie is gelukt" ::msgcat::mcset nl "Waiting for authentication mechanisms" "Bezig met wachten op authenticatiemechanismes" ::msgcat::mcset nl "Got authentication mechanisms" "Authenticatiemechanismes gekregen" ::msgcat::mcset nl "Waiting for authentication results" "Bezig met wachten op authenticatieresultaten" ::msgcat::mcset nl "Waiting for stream" "Bezig met wachten op stream" ::msgcat::mcset nl "Got stream" "Stream gekregen" ::msgcat::mcset nl "Got roster" "Roster gekregen" ::msgcat::mcset nl "Waiting for roster" "Wachten voor roster" ::msgcat::mcset nl "Server haven't provided SASL authentication feature" "De server ondersteunt geen authenticatie via SASL" ::msgcat::mcset nl "Server haven't provided non-SASL authentication feature" "De server ondersteunt geen authenticatie via 'non-SASL'" ::msgcat::mcset nl "Server haven't provided STARTTLS feature" "De server ondersteunt geen STARTTLS" ::msgcat::mcset nl "Waiting for stream features" "Bezig met wachten op mogelijkheden van de stream" ::msgcat::mcset nl "Got stream features" "Mogelijkheden van de stream gekregen" ::msgcat::mcset nl "Resource Constraint" "Bronbeperking" # jabberlib-tclxml/jlibsasl.tcl ::msgcat::mcset nl "Aborted" "Afgebroken" ::msgcat::mcset nl "Incorrect encoding" "Foutieve codering" ::msgcat::mcset nl "Invalid authzid" "Ongeldige authzid" ::msgcat::mcset nl "Invalid mechanism" "Ongeldig mechanisme" ::msgcat::mcset nl "Mechanism too weak" "Mechanisme is te zwak" ::msgcat::mcset nl "Temporary auth failure" "Tijdelijk autorisatieprobleem" # jabberlib-tclxml/streamerror.tcl ::msgcat::mcset nl "Bad Format" "Slecht formaat" ::msgcat::mcset nl "Bad Namespace Prefix" "Slecht namespace-voorvoegsel" ::msgcat::mcset nl "Connection Timeout" "Tijdslimiet voor verbinden overschreden" ::msgcat::mcset nl "Host Unknown" "Host onbekend" ::msgcat::mcset nl "Improper Addressing" "Foutieve adressering" ::msgcat::mcset nl "Invalid From" "Ongeldige afzender" ::msgcat::mcset nl "Invalid ID" "Ongeldige ID" ::msgcat::mcset nl "Invalid Namespace" "Ongeldige namespace" ::msgcat::mcset nl "Invalid XML" "Ongeldige XML" ::msgcat::mcset nl "Policy Violation" "Schending van beleid" ::msgcat::mcset nl "Restricted XML" "Beperk XML" ::msgcat::mcset nl "See Other Host" "Bekijk andere host" ::msgcat::mcset nl "Unsupported Encoding" "Niet ondersteunde codering" ::msgcat::mcset nl "Unsupported Stanza Type" "Niet ondersteunde stanza" ::msgcat::mcset nl "Unsupported Version" "Niet ondersteunde versie" ::msgcat::mcset nl "XML Not Well-Formed" "Slecht gevormde XML" ::msgcat::mcset nl "Stream Error%s%s" "Streamfout%s%s" # plugins/chat/bookmark_highlighted.tcl ::msgcat::mcset nl "Prev highlighted" "Vorige geaccentueerde" ::msgcat::mcset nl "Next highlighted" "Volgende geaccentueerde" # plugins/chat/clear.tcl ::msgcat::mcset nl "Clear chat window" "Chatvenster leegmaken" # plugins/chat/draw_timestamp.tcl ::msgcat::mcset nl "Format of timestamp in delayed chat messages delayed for more than 24 hours." "Formaat van tijd in berichten die meer dan 24 uur vertraagd werden." # plugins/chat/events.tcl ::msgcat::mcset nl "Message stored on the server" "Bericht is opgeslagen op de server" ::msgcat::mcset nl "Message stored on %s's server" "Bericht is opgeslagen op de server van %s" ::msgcat::mcset nl "Message delivered" "Bericht is afgeleverd" ::msgcat::mcset nl "Message delivered to %s" "Bericht is afgeleverd bij %s" ::msgcat::mcset nl "Message displayed" "Bericht is weergegeven" ::msgcat::mcset nl "Message displayed to %s" "Bericht is weergegeven bij %s" ::msgcat::mcset nl "Composing a reply" "Bezig met opstellen van antwoord" ::msgcat::mcset nl "%s is composing a reply" "%s stelt momenteel een aantwoord op" # plugins/chat/highlight.tcl ::msgcat::mcset nl "Groupchat message highlighting plugin options." "Opties voor accentuering van berichten in een chatruimte." ::msgcat::mcset nl "Enable highlighting plugin." "Accentueringsplugin aanzetten." ::msgcat::mcset nl "Highlight current nickname in messages." "Huidige bijnaam in berichten accentueren." ::msgcat::mcset nl "Substrings to highlight in messages." "Deelreeksen om te accentueren in berichten." ::msgcat::mcset nl "Highlight only whole words in messages." "Alleen hele woorden in berichten accentueren." # plugins/chat/info_commands.tcl ::msgcat::mcset nl "Full Name" "Volledige naam" ::msgcat::mcset nl "Family Name" "Achternaam" ::msgcat::mcset nl "Middle Name" "Tussennaam" ::msgcat::mcset nl "Prefix" "Voorvoegsel" ::msgcat::mcset nl "Suffix" "Achtervoegsel" ::msgcat::mcset nl "Nickname" "Bijnaam" ::msgcat::mcset nl "E-mail" "E-mail" ::msgcat::mcset nl "Web Site" "Website" ::msgcat::mcset nl "JID" "Jabber ID" ::msgcat::mcset nl "UID" "UID" ::msgcat::mcset nl "City" "Stad" ::msgcat::mcset nl "State " "Provincie" ::msgcat::mcset nl "Country" "Land" ::msgcat::mcset nl "time %s%s: %s" "tijd? %s%s: %s" ::msgcat::mcset nl "time %s%s:" "tijd? %s%s:" ::msgcat::mcset nl "last %s%s: %s" "laatst %s%s:" ::msgcat::mcset nl "last %s%s:" "laatst %s%s:" ::msgcat::mcset nl "version %s%s: %s" "versie %s%s: %s" ::msgcat::mcset nl "version %s%s:" "versie %s%s:" ::msgcat::mcset nl "vcard %s%s: %s" "vcard %s%s: %s" ::msgcat::mcset nl "vcard %s%s:" "vcard %s%s:" ::msgcat::mcset nl "vCard display options in chat windows." ::msgcat::mcset nl "Phone Home" "Telefoon thuis" ::msgcat::mcset nl "Phone Work" "Telefoon werk" ::msgcat::mcset nl "Phone Voice" "Nummer voicemail" ::msgcat::mcset nl "Phone Fax" "Faxnummer" ::msgcat::mcset nl "Phone Pager" "Nummer pieper" ::msgcat::mcset nl "Phone Message Recorder" "Nummer antwoordapparaat" ::msgcat::mcset nl "Phone Cell" "GSM-nummer" ::msgcat::mcset nl "Phone Video" "Nummer video" ::msgcat::mcset nl "Phone BBS" "Nummer BBS" ::msgcat::mcset nl "Phone Modem" "Nummer modem" ::msgcat::mcset nl "Phone ISDN" "Nummer ISDN" ::msgcat::mcset nl "Phone PCS" "Nummer PCS" ::msgcat::mcset nl "Phone Preferred" "Voorkeur" ::msgcat::mcset nl "Address 2" "Adres 2" ::msgcat::mcset nl "Postal Code" "Postcode" ::msgcat::mcset nl "Latitude" "Breedtegraad" ::msgcat::mcset nl "Longitude" "Lengtegraad" ::msgcat::mcset nl "Organization Name" "Organisatie" ::msgcat::mcset nl "Organization Unit" "Afdeling" ::msgcat::mcset nl "Title" "Titel" ::msgcat::mcset nl "Display %s in chat window when using /vcard command." "%s in chatvenster laten zien bij gebruik van het commando /vcard." # plugins/chat/logger.tcl ::msgcat::mcset nl "Logging options." "Logopties." ::msgcat::mcset nl "Directory to store logs." "Map om logs in op te slaan." ::msgcat::mcset nl "Store private chats logs." "Logs van privéchats opslaan." ::msgcat::mcset nl "Store group chats logs." "Logs van chatruimtes opslaan." ::msgcat::mcset nl "History for %s" "Geschiedenis voor %s" ::msgcat::mcset nl "Export to XHTML" "Naar XHTML exporteren" ::msgcat::mcset nl "Match case while searching in log window." "Hoofdlettergevoelig zoeken in logvenster." ::msgcat::mcset nl "Use regexp match while searching in log window (otherwise substring is searched)." "Gebruik reguliere expressie om te zoeken in het logvenster" ::msgcat::mcset nl "Search:" "Zoeken:" ::msgcat::mcset nl "Search up" "Achterwaarts zoeken" ::msgcat::mcset nl "Search down" "Zoeken" ::msgcat::mcset nl "Select month:" "Maand selecteren:" ::msgcat::mcset nl "Current" "Huidig" ::msgcat::mcset nl "All" "Alle" # plugins/chat/draw_xhtml_message.tcl ::msgcat::mcset nl "Enable rendering of XHTML messages." "Weergave van XHTML-berichten aanzetten." # plugins/chat/complete_last_nick.tcl ::msgcat::mcset nl "Number of groupchat messages to expire nick completion according to the last personally addressed message." "Aantal berichten in chatruimte om te laten verlopen bijnaam-aanvulling volgens het laatste persoonlijke bericht." # plugins/chat/nick_colors.tcl ::msgcat::mcset nl "Use colored nicks in chat windows." "Gekleurde bijnamen aanzetten in chatvensters." ::msgcat::mcset nl "Use colored nicks in groupchat rosters." "Gekleurde bijnamen aanzetten in chatruimtes." ::msgcat::mcset nl "Color message bodies in chat windows." "Gekleurde berichtinhoud aanzetten in chatvensters." ::msgcat::mcset nl "Use colored nicks" "Gekleurde bijnamen aanzetten" ::msgcat::mcset nl "Use colored roster nicks" "Gekleurde bijnamen in roster aanzetten" ::msgcat::mcset nl "Use colored messages" "Gekleurde berichten aanzetten" ::msgcat::mcset nl "Edit nick colors..." "Kleuren voor bijnaam bewerken..." ::msgcat::mcset nl "Edit chat user colors" "Kleuren voor contactpersoon bewerken" ::msgcat::mcset nl "Edit %s color" "%s-kleur bewerken" ::msgcat::mcset nl "Edit nick color..." "Kleur voor bijnaam bewerken..." # plugins/chat/popupmenu.tcl ::msgcat::mcset nl "Copy selection to clipboard" "Selectie kopiëren naar klembord" ::msgcat::mcset nl "Google selection" "Selectie opzoeken in Google" ::msgcat::mcset nl "Set bookmark" "Bladwijzer instellen" ::msgcat::mcset nl "Prev bookmark" "Vorige bladwijzer" ::msgcat::mcset nl "Next bookmark" "Volgende bladwijzer" ::msgcat::mcset nl "Clear bookmarks" "Bladwijzers verwijderen" # plugins/general/tkcon.tcl ::msgcat::mcset nl "Show console" "Commandoregel laten zien" # plugins/jidlink/dtcp.tcl ::msgcat::mcset nl "Opening DTCP active connection" "DTCP actieve verbinding openen" ::msgcat::mcset nl "Opening DTCP passive connection" "DTCP passieve verbinding openen" # plugins/jidlink/ibb.tcl ::msgcat::mcset nl "Opening IBB connection" "IBB verbinding openen" # plugins/clientinfo.tcl ::msgcat::mcset nl "\n\tName: %s" "\n\tNaam: %s" ::msgcat::mcset nl "\n\tClient: %s" "\n\tClient: %s" ::msgcat::mcset nl "\n\tOS: %s" "\n\tBesturingssysteem: %s" # plugins/filetransfer/si.tcl ::msgcat::mcset nl "Stream initiation options." "Opties voor streaminitiatie." ::msgcat::mcset nl "Enable SI transport for outgoing file transfers." "SI-transport aanzetten voor uitgaande bestandsoverdrachten." ::msgcat::mcset nl "via SI..." "via SI..." ::msgcat::mcset nl "Send file via SI..." "Bestand via SI verzenden..." # plugins/filetransfer/http.tcl ::msgcat::mcset nl "HTTP options." "HTTP-opties." ::msgcat::mcset nl "Enable HTTP transport for outgoing file transfers." "HTTP-transport aanzetten voor uitgaande bestandsoverdrachten." ::msgcat::mcset nl "Error while sending file. Peer reported: %s" "Fout bij verzenden van bestand. Foutmelding: %s" ::msgcat::mcset nl "Can't receive file: %s" "Kan bestand niet downloaden: %s" # plugins/general/annotations.tcl ::msgcat::mcset nl "Storing roster notes failed: %s" "Rosteraantekeningen opslaan mislukte: %s" ::msgcat::mcset nl "Edit roster notes for %s" "Rosteraantekeningen bewerken voor %s" ::msgcat::mcset nl "Store" "Bewaren" ::msgcat::mcset nl "Created: %s" "Aangemaakt: %s" ::msgcat::mcset nl "Modified: %s" "Gewijzigd: %s" ::msgcat::mcset nl "Edit item notes..." "Itemaantekeningen bewerken..." ::msgcat::mcset nl "Notes" "Aantekeningen" ::msgcat::mcset nl "Roster Notes" "Rosteraantekeningen" # plugins/general/autoaway.tcl # "Automatically away due to idle" goes to textstatus (probably no needs to translate) ::msgcat::mcset nl "Automatically away due to idle" # rest should be translated ::msgcat::mcset nl "Returning from auto-away" "Terug van 'automatisch afwezig'" ::msgcat::mcset nl "Moving to extended away" "Naar 'langdurig afwezig' gaan" ::msgcat::mcset nl "Starting auto-away" "Naar 'automatisch afwezig' gaan" ::msgcat::mcset nl "Idle for %s" "Stil voor %s" ::msgcat::mcset nl "Options for module that automatically marks you as away after idle threshold." "Opties voor module die u automatisch als afwezig markeert na een stilheidsdrempelwaarde." ::msgcat::mcset nl "Idle threshold in minutes after that Tkabber marks you as away." "Stilheidsdrempelwaarde nadat Tkabber u markeert als afwezig (in minuten)." ::msgcat::mcset nl "Idle threshold in minutes after that Tkabber marks you as extended away." "Stilheidsdrempelwaarde nadat Tkabber u markeert als langdurig afwezig (in minuten)." ::msgcat::mcset nl "Text status, which is set when Tkabber is moving to away state." "Tekstboodschap die ingesteld moet worden bij het overgaan naar de aanwezigheid 'afwezig'." ::msgcat::mcset nl "Set priority to 0 when moving to extended away state." "Prioriteit wijzigen naar 0 bij overgaan naar de aanwezigheid 'langdurig afwezig'." # plugins/general/conferences.tcl ::msgcat::mcset nl "Storing conferences failed: %s" "Opslaan van chatruimtes mislukte: %s" ::msgcat::mcset nl "Add conference" "Chatruimte toevoegen" # plugins/general/conferenceinfo.tcl ::msgcat::mcset nl "Options for Conference Info module, that allows you to see list of participants in roster popup, regardless of whether you are currently joined with the conference." "Opties voor de chatruimte-informatiemodule die u in staat stelt om de deelnemerslijst in een rosterpopup te zien, onachtzaam of u momenteel al dan niet de chatruimte betreden hebt." ::msgcat::mcset nl "Use this module" "Deze module aanzetten" ::msgcat::mcset nl "\n\tCan't browse: %s" "\n\tKan niet browsen: %s" ::msgcat::mcset nl "\nRoom participants at %s:" "\nDeelnemers van chatruimte op %s" ::msgcat::mcset nl "\nRoom is empty at %s" "\nChatruimte is leeg op %s" ::msgcat::mcset nl "Interval (in minutes) between requests of participants list." "Interval (minuten) tussen aanvragen van deelnemerslijst." ::msgcat::mcset nl "Interval (in minutes) after error reply on request of participants list." "Interval (minuten) na fout bij aanvraag deelnemerslijst." # plugins/general/message_archive.tcl ::msgcat::mcset nl "Messages" "Berichten" ::msgcat::mcset nl "Received/Sent" "Ontvangen/verzonden" ::msgcat::mcset nl "Dir" "Map" ::msgcat::mcset nl "From/To" "Van/naar" ::msgcat::mcset nl "From:" "Van:" ::msgcat::mcset nl "To:" "Naar:" ::msgcat::mcset nl "Subject" "Onderwerp" # plugins/general/offline.tcl ::msgcat::mcset nl "Retrieve offline messages using POP3-like protocol." "Offline berichten ophalen zoals POP3" ::msgcat::mcset nl "Offline Messages" "Offline berichten" ::msgcat::mcset nl "Sort by from" "Volgens afzender sorteren" ::msgcat::mcset nl "Sort by node" "Volgens node sorteren" ::msgcat::mcset nl "Sort by type" "Volgens soort sorteren" ::msgcat::mcset nl "Fetch unseen messages" "Ongelezen berichten ophalen" ::msgcat::mcset nl "Fetch all messages" "Alle berichten ophalen" ::msgcat::mcset nl "Purge seen messages" "Gelezen berichten verwijderen" ::msgcat::mcset nl "Purge all messages" "Alle berichten verwijderen" ::msgcat::mcset nl "Fetch message" "Bericht ophalen" ::msgcat::mcset nl "Purge message" "Bericht verwijderen" # plugins/general/presenceinfo.tcl ::msgcat::mcset nl "\n\tPresence is signed:" "\n\tAanwezigheid is ondertekend:" # plugins/general/rawxml.tcl ::msgcat::mcset nl "Options for Raw XML Input module, which allows you to monitor incoming/outgoing traffic from connection to server and send custom XML stanzas." "Opties voor de module om ruwe XML in te voeren, die u toelaat om mee te luisteren met inkomend/uitgaand verkeer van de verbinding met de server en om aangepaste XML-stanza's te versturen." ::msgcat::mcset nl "Raw XML" "Ruwe XML" ::msgcat::mcset nl "Templates" "Sjablonen" ::msgcat::mcset nl "Clear" "Wissen" ::msgcat::mcset nl "Message" "Bericht" ::msgcat::mcset nl "Normal message" "Normaal bericht" ::msgcat::mcset nl "Chat message" "Chatbericht" ::msgcat::mcset nl "Headline message" "Kop" ::msgcat::mcset nl "Available presence" "Aanwezigheid 'beschikbaar'" ::msgcat::mcset nl "Unavailable presence" "Aanwezigheid 'onbeschikbaar'" ::msgcat::mcset nl "IQ" "IQ" ::msgcat::mcset nl "Generic IQ" "Algemene IQ" ::msgcat::mcset nl "Pub/sub" "Publish-Subscribe" ::msgcat::mcset nl "Create node" "Node aanmaken" ::msgcat::mcset nl "Publish node" "Node publiceren" ::msgcat::mcset nl "Retract node" "Node intrekken" ::msgcat::mcset nl "Subscribe to a node" "Op een node inschrijven" ::msgcat::mcset nl "Unsubscribe from a node" "Van een node uitschrijven" ::msgcat::mcset nl "Get items" "Items downloaden" # plugins/general/stats.tcl ::msgcat::mcset nl "Statistics monitor" "Statistiekenmonitor" ::msgcat::mcset nl "Statistics" "Statistieken" ::msgcat::mcset nl "Node" "Node" ::msgcat::mcset nl "Name " "Naam" ::msgcat::mcset nl "Value" "Waarde" ::msgcat::mcset nl "Units" "Onderdeel" ::msgcat::mcset nl "Timer" "Tijdopnemer" ::msgcat::mcset nl "Request" "Aanvragen" ::msgcat::mcset nl "Set" "Instellen" ::msgcat::mcset nl "Open statistics monitor" "Statistiekenmonitor openen" # plugins/unix/dockingtray.tcl ::msgcat::mcset nl "Hide Main Window" "Hoofdvenster verbergen" ::msgcat::mcset nl "Show Main Window" "Hoofdvenster laten zien" ::msgcat::mcset nl "When you have unread messages the systray icon will start to blink." "Wanneer u ongelezen berichten hebt, zal het pictogram in het systeemvak beginnen te knipperen." # plugins/unix/systray.tcl ::msgcat::mcset nl "Minimize to systray" "Minimaliseren naar systeemvak" ::msgcat::mcset nl "Log in/out..." "Aan/afmelden" # plugins/unix/ispell.tcl ::msgcat::mcset nl "- nothing -" "- niets -" ::msgcat::mcset nl "Spell check options." "Opties van spellingscontrole." ::msgcat::mcset nl "Path to the ispell executable." "Pad naar het uitvoerbaar bestand van ISpell." ::msgcat::mcset nl "Check spell after every entered symbol." "Spelling controleren na elk ingevoerd teken." ::msgcat::mcset nl "Ispell dictionary. If it is empty, default dictionary is used." "ISpell woordenboek. Als dit leeg is dan zal het standaardwoordenboek gebruikt worden." ::msgcat::mcset nl "Ispell dictionary encoding. If it is empty, system encoding is used." "ISpell woordenboek encodering. Als dit leeg is dan zal de systeemencodering gebruikt worden." ::msgcat::mcset nl "Plugins options." "Pluginopties." # plugins/unix/wmdock.tcl ::msgcat::mcset nl "%s msgs" "%s berichten" ::msgcat::mcset nl "%s is %s" "%s is %s" # plugins/windows/taskbar.tcl ::msgcat::mcset nl "When you have unread messages the taskbar icon will start to blink." "Het pictogram van de taakbalk zal gaan knipperen wanneer u ongelezen berichten hebt." # plugins/iq/time.tcl ::msgcat::mcset nl "Reply to current time (jabber:iq:time) requests." "Op aanvragen voor de huidige tijd (jabber:iq:time) antwoorden." # plugins/general/stats.tcl ::msgcat::mcset nl "Service statistics" "Statistieken van diensten" # plugins/iq/version.tcl ::msgcat::mcset nl "Reply to version (jabber:iq:version) requests." "Op versieaanvraagen (jabber:iq:version) antwoorden." # error types ::msgcat::mcset nl "Authentication Error" "Authenticatiefout" ::msgcat::mcset nl "Unrecoverable Error" "Onherstelbare fout" ::msgcat::mcset nl "Warning" "Waarschuwing" ::msgcat::mcset nl "Request Error" "Fout in aanvraag" ::msgcat::mcset nl "Temporary Error" "Tijdelijke fout" # error messages ::msgcat::mcset nl "Bad Request" "Foutieve aanvraag" ::msgcat::mcset nl "Conflict" "Conflict" ::msgcat::mcset nl "Feature Not Implemented" "Functie niet geïmplementeerd" ::msgcat::mcset nl "Forbidden" "Verboden" ::msgcat::mcset nl "Gone" "Gegaan" ::msgcat::mcset nl "Internal Server Error" "Interne serverfout" ::msgcat::mcset nl "Item Not Found" "Item niet gevonden" ::msgcat::mcset nl "JID Malformed" "Slecht gevormde Jabber ID" ::msgcat::mcset nl "Not Acceptable" "Niet accepteerbaar" ::msgcat::mcset nl "Not Allowed" "Niet toegestaan" ::msgcat::mcset nl "Not Authorized" "Niet geautoriseerd" ::msgcat::mcset nl "Payment Required" "Betaling vereist" ::msgcat::mcset nl "Recipient Unavailable" "Ontvanger onbeschikbaar" ::msgcat::mcset nl "Registration Required" "Registratie vereist" ::msgcat::mcset nl "Remote Server Not Found" "Server niet gevonden" ::msgcat::mcset nl "Remote Server Timeout" "Servertimeout" ::msgcat::mcset nl "Service Unavailable" "Dienst niet beschikbaar" ::msgcat::mcset nl "Subscription Required" "Autorisatie vereist" ::msgcat::mcset nl "Undefined Condition" "Ongedefinieerde conditie" ::msgcat::mcset nl "Unexpected Request" "Onverwachte aanvraag" ::msgcat::mcset nl "Redirect" "Omleiden" # Local Variables: # mode: tcl # End: tkabber-0.11.1/msgs/fr.msg0000644000175000017500000007667111014357121014626 0ustar sergeisergei# $Id: fr.msg 1433 2008-05-19 20:08:49Z sergei $ # French Messages # Author: Vincent Ricard # TODO: find a good translation to 'headline', for now : 'message informatif' # avatars.tcl ::msgcat::mcset fr "No avatar to store" "Aucun avatar à stocker" # browser.tcl ::msgcat::mcset fr "JBrowser" "JNavigateur" ::msgcat::mcset fr "JID:" "JID :" ::msgcat::mcset fr "Browse" "Naviguer" ::msgcat::mcset fr "%s: %s/%s, Description: %s, Version: %s\nNumber of children: %s" "%s: %s/%s, Description : %s, Version : %s\nNombres d'enfants : %s" ::msgcat::mcset fr "List of browsed JIDs." "Liste des JIDs passés en revue." ::msgcat::mcset fr "Browse error: %s" "Erreur de navigation : %s" # chats.tcl ::msgcat::mcset fr "Chat with %s" "Discussion avec %s" ::msgcat::mcset fr "Disconnected" "Déconnecté" ::msgcat::mcset fr "Error %s" "Erreur %s" ::msgcat::mcset fr "Error %s: %s" "Erreur %s : %s" ::msgcat::mcset fr "Invite" "Inviter" ::msgcat::mcset fr "Invite users..." "Inviter des utilisateurs..." ::msgcat::mcset fr "Invite users to %s" "Inviter des utilisateurs à %s" ::msgcat::mcset fr "Invite %s to conferences" "Inviter %s à des conférences" ::msgcat::mcset fr "Moderators" "Modérateurs" ::msgcat::mcset fr "No conferences in progress..." "Pas de conférences en cours..." ::msgcat::mcset fr "Participants" "Participants" ::msgcat::mcset fr "Please join %s" "Veuillez joindre %s" ::msgcat::mcset fr "Subject:" "Sujet :" ::msgcat::mcset fr "Users" "Utilisateurs" ::msgcat::mcset fr "Visitors" "Visiteurs" ::msgcat::mcset fr "/me has changed the subject to: %s" "/me a changé le sujet pour : %s" ::msgcat::mcset fr ">>> Unable to decipher data: %s <<<" ">>> Incapable de décoder les données : %s <<<" # custom.tcl ::msgcat::mcset fr "Customization of the One True Jabber Client." "Personnalisation d'un vrai client Jabber." ::msgcat::mcset fr "Customize" "Personnaliser" ::msgcat::mcset fr "Open" "Ouvrir" ::msgcat::mcset fr "Parent group:" "Groupe parent :" ::msgcat::mcset fr "Parent groups:" "Groupes parent :" ::msgcat::mcset fr "State" "Etat" ::msgcat::mcset fr "you have edited the value, but you have not set the option." ::msgcat::mcset fr "this option is unchanged from its standard setting." ::msgcat::mcset fr "you have set this option, but not saved it for future sessions." ::msgcat::mcset fr "this option has been set and saved." "cette option a été configuré et sauvegardée" ::msgcat::mcset fr "Set for Current Session" "configurer pour la session courante" ::msgcat::mcset fr "Set for Future Sessions" "configurer pour les sessions futures" ::msgcat::mcset fr "Reset to Current" "Réinitialiser à la valeur courante" ::msgcat::mcset fr "Reset to Saved" "Réinitialiser à la valeur sauvegardée" ::msgcat::mcset fr "Reset to Default" "Réinitialiser à la valeur par défaut" # datagathering.tcl ::msgcat::mcset fr "Configure service" "Configurer les services" ::msgcat::mcset fr "Data form" "Formulaire" ::msgcat::mcset fr "Date:" "Date :" ::msgcat::mcset fr "Email:" "E-mail :" ::msgcat::mcset fr "Error requesting data: %s" "Erreur lors de la demande de données : %s" ::msgcat::mcset fr "Error submitting data: %s" "Erreur lors de l'envoi de données : %s" ::msgcat::mcset fr "First Name:" "Prénom :" ::msgcat::mcset fr "Instructions" "Instructions :" ::msgcat::mcset fr "Key:" "Clef :" ::msgcat::mcset fr "Last Name:" "Nom :" ::msgcat::mcset fr "Misc:" "Divers :" ::msgcat::mcset fr "Phone:" "Téléphone :" ::msgcat::mcset fr "Text:" "Texte :" ::msgcat::mcset fr "Zip:" "Code postal :" # disco.tcl ::msgcat::mcset fr "Error getting info: %s" "Erreur lors de la récupération de l'info : %s" ::msgcat::mcset fr "Error getting items: %s" "Erreur lors de la récupération des objets : %s" ::msgcat::mcset fr "Error negotiate: %s" "Erreur lors de la négociation : %s" ::msgcat::mcset fr "Jabber Discovery" "Découverte Jabber" ::msgcat::mcset fr "Discover service" "Service découverte" ::msgcat::mcset fr "List of discovered JIDs." "Liste des JIDs découverts" ::msgcat::mcset fr "List of discovered JID nodes." "Liste des noeuds JID découverts" ::msgcat::mcset fr "Node:" "NÅ“ud :" # emoticons.tcl # filetransfer.tcl ::msgcat::mcset fr "Browse..." "Naviguer..." ::msgcat::mcset fr "Connection closed" "Connexion fermée" ::msgcat::mcset fr "Default directory for downloaded files." "Répertoire par défaut pour les fichiers téléchargés." ::msgcat::mcset fr "Description:" "Description :" ::msgcat::mcset fr "IP address:" "Adresse IP :" ::msgcat::mcset fr "File not found or not regular file: %s" "Fichier non trouvé ou fichier irrégulier: %s" ::msgcat::mcset fr "File to Send:" "Fichier à envoyer :" ::msgcat::mcset fr "File Transfer options." "Options de transfert de fichiers." ::msgcat::mcset fr "Receive" "Recevoir" ::msgcat::mcset fr "Receive file from %s" "Fichier reçu de %s" ::msgcat::mcset fr "Request failed: %s" "Echec de la requête : %s" ::msgcat::mcset fr "Save as:" "Sauvegarder sous :" ::msgcat::mcset fr "Send file to %s" "Envoyer un fichier à %s" ::msgcat::mcset fr "Size:" "Taille :" ::msgcat::mcset fr "Transferring..." "Transfert en cours..." # filters.tcl ::msgcat::mcset fr "I'm not online" "Je ne suis pas connecté" ::msgcat::mcset fr "the message is from" "le message est de" ::msgcat::mcset fr "the message is sent to" "le message est envoyé à" ::msgcat::mcset fr "the subject is" "le sujet est" ::msgcat::mcset fr "the body is" "le corps est" ::msgcat::mcset fr "my status is" "mon statut est" ::msgcat::mcset fr "the message type is" "le type du message est" ::msgcat::mcset fr "change message type to" "changer le type du message pour" ::msgcat::mcset fr "forward message to" "transférer le message à" ::msgcat::mcset fr "reply with" "Répondre avec" ::msgcat::mcset fr "store this message offline" "stocker ce message hors connexion" ::msgcat::mcset fr "continue processing rules" "continuer l'application des règles" ::msgcat::mcset fr "Filters" "Filtres" ::msgcat::mcset fr "Add" "Ajouter" ::msgcat::mcset fr "Edit" "Editer" ::msgcat::mcset fr "Remove" "Supprimer" ::msgcat::mcset fr "Move up" "Déplacer vers le haut" ::msgcat::mcset fr "Move down" "Déplacer ver le bas" ::msgcat::mcset fr "Edit rule" "Editer la règle" ::msgcat::mcset fr "Rule Name:" "Nom de la rèle :" ::msgcat::mcset fr "Empty rule name" "Le nom de la règle est vide" ::msgcat::mcset fr "Rule name already exists" "Le nom de la règle existe déjà" ::msgcat::mcset fr "Condition" "Condition" ::msgcat::mcset fr "Action" "Action" # gpgme.tcl ::msgcat::mcset fr "Encrypt traffic" "Crypter le trafic" ::msgcat::mcset fr "Change security preferences for %s" "Changer les préférences de sécurité pour %s" ::msgcat::mcset fr "Select Key for Signing Traffic" "Sélectionner une clef pour signer le trafic" ::msgcat::mcset fr "Select" "Sélectionner" ::msgcat::mcset fr "Please enter passphrase" "Veuillez entrer une phrase de passe" ::msgcat::mcset fr "Please try again" "Veuillez réessayer" ::msgcat::mcset fr "Key ID" "ID de clef" ::msgcat::mcset fr "User ID" "ID utilisateur" ::msgcat::mcset fr "Passphrase:" "Phrase de passe :" ::msgcat::mcset fr "Error in signature verification software: %s." "Erreur avec le logiciel de vérification de signature : %s." ::msgcat::mcset fr "%s purportedly signed by %s can't be verified.\n\n%s." "%s soi-disant signé par %s, ne peut pas être vérifier.\n\n%s." ::msgcat::mcset fr "Unable to sign presence information: %s.\n\nPresence will be sent, but signing traffic is now disabled." "Incapable de signer l'information de présence : %s.\n\nLa présence sera envoyée, mais la signature du trafic est maintenant désactivée." ::msgcat::mcset fr "Unable to sign message body: %s.\n\nSigning traffic is now disabled.\n\nSend it WITHOUT a signature?" "Incapable de signer le corps du message : %s.\n\nLa signature du trafic est maintenant désactivée.\n\nEnvoyer SANS signature ?" ::msgcat::mcset fr "Data purported sent by %s can't be deciphered.\n\n%s." "Les données soi-disant envoyées par %s ne peuvent pas être décodées.\n\n%s." ::msgcat::mcset fr "Unable to encipher data for %s: %s.\n\nEncrypting traffic to this user is now disabled.\n\nSend it as PLAINTEXT?" "Incapable de coder les données pour %s : %s.\n\nLe codage du trafic avec cet utilisateur est maintenant désactivé.\n\nEnvoyer le texte EN CLAIR ?" # iface.tcl ::msgcat::mcset fr "Presence" "Présence" ::msgcat::mcset fr "Online" "En ligne" ::msgcat::mcset fr "Free to chat" "Libre pour discuter" ::msgcat::mcset fr "Away" "Absent" ::msgcat::mcset fr "Extended Away" "Absence prolongée" ::msgcat::mcset fr "Do not disturb" "Ne pas déranger" ::msgcat::mcset fr "Invisible" "Invisible" ::msgcat::mcset fr "Log in..." "Connexion..." ::msgcat::mcset fr "Log out" "Déconnexion" ::msgcat::mcset fr "Log out with reason..." "Déconnexion avec une raison..." ::msgcat::mcset fr "Quit" "Quitter" ::msgcat::mcset fr "Services" "Services" ::msgcat::mcset fr "Send message..." "Envoyer un message..." ::msgcat::mcset fr "Roster" "Liste de contacts" ::msgcat::mcset fr "Add user..." "Ajouter un utilisateur..." ::msgcat::mcset fr "Add conference..." "Ajouter une conférence..." ::msgcat::mcset fr "Browser" "Navigateur" ::msgcat::mcset fr "Join group..." "Joindre un groupe..." ::msgcat::mcset fr "Chats" "Discussions" ::msgcat::mcset fr "Create room..." "Créer un salon..." ::msgcat::mcset fr "Stop autoscroll" "Arrêter le défilement automatique" ::msgcat::mcset fr "Sound" "Son" ::msgcat::mcset fr "Mute" "Muet" ::msgcat::mcset fr "Filters..." "Filtres..." ::msgcat::mcset fr "Change password..." "Changer le mot de passe..." ::msgcat::mcset fr "Show user info..." "Montrer les informations de l'utilisateur..." ::msgcat::mcset fr "Edit my info..." "Editer mes informations..." ::msgcat::mcset fr "Avatar" "Avatar" ::msgcat::mcset fr "Announce" "Annoncer" ::msgcat::mcset fr "Allow downloading" "Autoriser le téléchargement" ::msgcat::mcset fr "Send to server" "Envoyer au serveur" ::msgcat::mcset fr "Jidlink" ::msgcat::mcset fr "Admin tools" "Outils d'administration" ::msgcat::mcset fr "Send raw XML..." "Envoyer du XML brut..." ::msgcat::mcset fr "Send broadcast message..." "Envoyer un message de diffusion..." ::msgcat::mcset fr "Send message of the day..." "Envoyer le message du jour..." ::msgcat::mcset fr "Update message of the day..." "Effacer le message du jour..." ::msgcat::mcset fr "Delete message of the day" "Effacer le message du jour" ::msgcat::mcset fr "Help" "Aide" ::msgcat::mcset fr "Quick help" "Aide rapide" ::msgcat::mcset fr "Discovery" "Découverte" ::msgcat::mcset fr "Quick Help" "Aide rapide" ::msgcat::mcset fr "Main window:" "Fenêtre principale :" ::msgcat::mcset fr "Tabs:" "Onglets :" ::msgcat::mcset fr "Chats:" "Discussions :" ::msgcat::mcset fr "Close tab" "Fermer l'onglet" ::msgcat::mcset fr "Previous/Next tab" "Onglet précédent/suivant" ::msgcat::mcset fr "Hide/Show roster" "Cacher/Montrer la liste de contacts" ::msgcat::mcset fr "Complete nickname" "Completer le surnom" ::msgcat::mcset fr "Previous/Next history message" "Message précédent/suivant de l'historique" ::msgcat::mcset fr "Show emoticons" "Montrer les émoticons" ::msgcat::mcset fr "Undo" "Défaire" ::msgcat::mcset fr "Redo" "Refaire" ::msgcat::mcset fr "Scroll chat window up/down" "Faire défiler la fenêtre de discussion vers le haut/bas" ::msgcat::mcset fr "Correct word" "Corriger le mot" ::msgcat::mcset fr "About" "A propos" ::msgcat::mcset fr "Authors:" "Auteurs :" ::msgcat::mcset fr "Alexey Shchepin" "Alexey Shchepin" ::msgcat::mcset fr "Marshall T. Rose" "Marshall T. Rose" ::msgcat::mcset fr "Sergei Golovan" "Sergei Golovan" ::msgcat::mcset fr "Michail Litvak" "Michail Litvak" ::msgcat::mcset fr "Add new user..." "Ajouter un nouvel utilisateur..." ::msgcat::mcset fr "Jabber Browser" "Navigateur Jabber" #::msgcat::mcset ru "Join group..." "ПриÑоединитьÑÑ Ðº группе..." ::msgcat::mcset fr "Show online & offline users" "Montrer les utilisateurs connectés et déconnectés" ::msgcat::mcset fr "Show online users only" "Montrer uniquement les utilisateurs connectés" ::msgcat::mcset ru "Toggle signing" "Вкл./выкл. подпиÑÑŒ" ::msgcat::mcset ru "Toggle encryption (when possible)" "Вкл./выкл. шифрование (еÑли возможно)" ::msgcat::mcset fr "Cancel" "Annuler" ::msgcat::mcset fr "Close" "Fermer" ::msgcat::mcset fr "Close other tabs" "Fermer les autres onglets" ::msgcat::mcset fr "Close all tabs" "Fermer tous les onglets" ::msgcat::mcset fr "Send" "Envoyer" ::msgcat::mcset fr "Privacy rules..." "Règles de confidentialité..." # ifaceck/widgets.tcl ::msgcat::mcset fr "Question" "Question" ::msgcat::mcset fr "Warning" "Avertissement" ::msgcat::mcset fr "Error" "Erreur" # itemedit.tcl ::msgcat::mcset fr "Edit properties for %s" "Editer les propriétés de %s" ::msgcat::mcset fr "Edit nickname for %s" "Editer le surnom de %s" ::msgcat::mcset fr "Nickname:" "Surnom :" ::msgcat::mcset fr "Edit groups for %s" "Editer les groupes de %s" ::msgcat::mcset fr "Available groups" "Groupes disponibles" ::msgcat::mcset fr "Group:" "Groupe :" ::msgcat::mcset fr "Current groups" "Groupes courants" ::msgcat::mcset fr "Add ->" "Ajouter ->" ::msgcat::mcset fr "<- Remove" "<- Supprimer" # jabberlib-tclxml/jabberlib.tcl ::msgcat::mcset fr "Authentication failed" "Echec de l'authentification" ::msgcat::mcset fr "Authentication successful" "Authentification réussie" ::msgcat::mcset fr "Got authentication mechanisms" "Récupération des mécanismes d'authentification" ::msgcat::mcset fr "Got roster" "Récupération de la liste des contacts" ::msgcat::mcset fr "Got stream" "Récupération du flux" ::msgcat::mcset fr "Waiting for authentication mechanisms" "Attente des mécanismes d'authentification" ::msgcat::mcset fr "Waiting for authentication results" "Attente des résultats d'authentification" ::msgcat::mcset fr "Waiting for roster" "Attente de la liste des contacts" ::msgcat::mcset fr "Waiting for stream" "Attente de flux" # jidlink.tcl ::msgcat::mcset fr "Opening Jidlink connection" "Ouverture d'une connexion Jidlink" ::msgcat::mcset fr "Jidlink connection closed" "Connexion Jidlink fermée" # joingrdialog.tcl ::msgcat::mcset fr "Join group" "Joindre un groupe" ::msgcat::mcset fr "Nick:" "Surnom :" ::msgcat::mcset fr "Group:" "Groupe :" ::msgcat::mcset fr "Server:" "Serveur :" ::msgcat::mcset fr "use v2 protocol" "utiliser la version 2 du protocole" ::msgcat::mcset fr "Join" "Joindre" ::msgcat::mcset fr "Add group" "Ajouter un groupe" ::msgcat::mcset fr "Get conference info failed: %s" "Echec lors de la récupération des informations de la conférence : %s" ::msgcat::mcset fr "Join failed: %s" "Impossible de rejoindre la conférence : %s" ::msgcat::mcset fr "Create Room" "Créer un salon" ::msgcat::mcset fr "Address:" "Addresse :" ::msgcat::mcset fr "Nickname:" "Surnom :" ::msgcat::mcset fr "Password:" "Mot de passe :" ::msgcat::mcset fr "Name: " "Nom :" ::msgcat::mcset fr "Description:" "Description :" ::msgcat::mcset fr "Create" "Créer" ::msgcat::mcset fr "Connection:" "Connexion :" # login.tcl ::msgcat::mcset fr "Login" "Connexion" ::msgcat::mcset fr "Login options." "Options de connexion." ::msgcat::mcset fr "Username:" "Nom d'utilisateur :" ::msgcat::mcset fr "User name." "Nom d'utilisateur." ::msgcat::mcset fr "Password:" "Mot de passe :" ::msgcat::mcset fr "Password." "Mot de passe." ::msgcat::mcset fr "Server:" "Serveur :" ::msgcat::mcset fr "Server name." "Nom du serveur." ::msgcat::mcset fr "Server name or IP-address." "Nom du serveur ou adresse IP." ::msgcat::mcset fr "Resource:" "Ressource :" ::msgcat::mcset fr "Resource." "Ressource." ::msgcat::mcset fr "Server port." "Port du serveur." ::msgcat::mcset fr "Use hashed password" "Utiliser un mot de passe hache" ::msgcat::mcset fr "Connect via alternate server" "Se connecter via un serveur de remplacement" ::msgcat::mcset fr "Use SSL" "Utiliser SSL" ::msgcat::mcset fr "Use SSL to connect to server." "Utiliser SSL pour se connecter au serveur." ::msgcat::mcset fr "SSL Port:" "Port SSL :" ::msgcat::mcset fr "SSL port." "Port SSL." ::msgcat::mcset fr "Use Proxy" "Utiliser un proxy" ::msgcat::mcset fr "Use HTTP proxy to connect." "Utiliser un proxy HTTP pour se connecter." ::msgcat::mcset fr "Proxy Server:" "Serveur proxy :" ::msgcat::mcset fr "HTTP proxy address." "Adresse du proxy HTTP." ::msgcat::mcset fr "Proxy Port:" "Port proxy :" ::msgcat::mcset fr "HTTP proxy port." "Port du proxy HTTP." ::msgcat::mcset fr "Proxy Login:" "Identifiant proxy :" ::msgcat::mcset fr "HTTP proxy username." "Nom d'utilisateur pour le proxy HTTP." ::msgcat::mcset fr "Proxy Password:" "Mot de passe proxy :" ::msgcat::mcset fr "HTTP proxy password." "Mot de passe pour le proxy HTTP." ::msgcat::mcset fr "Profiles" "Profiles" ::msgcat::mcset fr "Authentication failed: %s\nCreate new account?" "L'authentification a échoué : %s\nCréer un nouveau compte ?" ::msgcat::mcset fr "Registration failed: %s" "L'enregistrement a échoué : %s" ::msgcat::mcset fr "Change password" "Changer le mot de passe" ::msgcat::mcset fr "Old password:" "Ancien mot de passe :" ::msgcat::mcset fr "New password:" "Nouveau mot de passe :" ::msgcat::mcset fr "Repeat new password:" "Répétez le nouveau mot de passe :" ::msgcat::mcset fr "Old password is incorrect" "L'ancien mot de passe est incorrect" ::msgcat::mcset fr "New passwords do not match" "Les nouveaux mots de passe ne correspondent pas" ::msgcat::mcset fr "Password is changed" "Le mot de passe est changé" ::msgcat::mcset fr "Password change failed: %s" "Le changement de mot de passe a échoué : %s" ::msgcat::mcset fr "Logout" "Se déconecter" ::msgcat::mcset fr "Logout with reason" "Se déconecter avec une raison" ::msgcat::mcset fr "List of logout reasons." "Liste des raisons de déconnexion." ::msgcat::mcset fr "Reason:" "Raison :" ::msgcat::mcset fr "Priority:" "Priorité :" ::msgcat::mcset fr "Priority." "Priorité." ::msgcat::mcset fr "Replace opened connections." "Remplacer les connexions ouvertes." ::msgcat::mcset fr "Replace opened connections" "Remplacer les connexions ouvertes" ::msgcat::mcset fr "Use explicitly-specified server address." "Utiliser une adresse d'un serveur explicitement spécifié." # messages.tcl ::msgcat::mcset fr "Message from %s" "Message de %s" ::msgcat::mcset fr "Message from" "Message de" ::msgcat::mcset fr "Extras from %s" "Extras de %s" ::msgcat::mcset fr "Extras from" "Extras de" ::msgcat::mcset fr "Reply" "Répondre" ::msgcat::mcset fr "Attached user:" "Utilisateur attaché :" ::msgcat::mcset fr "Attached file:" "Fichier attaché :" ::msgcat::mcset fr "Invited to:" "Inviter :" ::msgcat::mcset fr "Message body" "Corps du message" ::msgcat::mcset fr "Send message to %s" "Envoyer un message à %s" ::msgcat::mcset fr "Send message" "Envoyer un message" ::msgcat::mcset fr "This message is encrypted." "Ce message est crypté." ::msgcat::mcset fr "Subscribe request from %s" "Requête d'enregistrement de %s" ::msgcat::mcset fr "Subscribe request from" "Requête d'enregistrement de" ::msgcat::mcset fr "Subscribe" "S'abonner" ::msgcat::mcset fr "Unsubscribe" "Se désabonner" ::msgcat::mcset fr "Send subscription" "Envoyer un abonnement" ::msgcat::mcset fr "Send subscription to %s" "Envoyer un abonnement à %s" ::msgcat::mcset fr "Send subscription to " "Envoyer un abonnement à " ::msgcat::mcset fr "Headlines" "Messages informatifs" ::msgcat::mcset ru "Toggle seen" "Вкл./выкл. отображение проÑмотренных" ::msgcat::mcset fr "Sort" "Tri" # muc.tcl ::msgcat::mcset fr "Whois" "Qui est-ce" ::msgcat::mcset fr "Kick" "Ejecter" ::msgcat::mcset fr "Ban" "Exclure" #::msgcat::mcset ru "Grant Voice" "" #::msgcat::mcset ru "Revoke Voice" "" #::msgcat::mcset ru "Grant Membership" "" #::msgcat::mcset ru "Revoke Membership" "" #::msgcat::mcset ru "Grant Moderator Privilege" "" #::msgcat::mcset ru "Revoke Moderator Privilege" "" #::msgcat::mcset ru "MUC" "" ::msgcat::mcset fr "Configure" "Configurer" ::msgcat::mcset fr "Edit ban list..." "Editer la liste des exclus..." ::msgcat::mcset fr "Edit member list..." "Editer la liste des membres..." ::msgcat::mcset fr "Edit moderator list..." "Editer la liste des modérateurs..." ::msgcat::mcset ru "Edit voice list..." ::msgcat::mcset fr "Destroy" "Détruire" # plugins/chat/draw_xhtml_message.tcl ::msgcat::mcset fr "Enable rendering of XHTML messages." "Activer le rendu des messages XHTML" # presence.tcl #::msgcat::mcset fr "Away" "Absent" ::msgcat::mcset fr "Change Presence Priority" "Changer la priorité de présence" #::msgcat::mcset fr "Do not disturb" "Ne pas dérangé" ::msgcat::mcset fr "Extended Away" "Absence prolongée" #::msgcat::mcset fr "Free to chat" "Libre pour discuter" ::msgcat::mcset fr "invalid userstatus value " "Valeur pour le statut utilisateur invalide " #::msgcat::mcset fr "Invisible" "Invisible" ::msgcat::mcset fr "Not logged in" "Non connecté" ::msgcat::mcset fr "Offline" "Déconnecté" #::msgcat::mcset fr "Online" "En ligne" # register.tcl ::msgcat::mcset fr "Register in %s" "S'enregistrer à %s" ::msgcat::mcset fr "Unsubscribed from %s" "Se désabonner de %s" ::msgcat::mcset fr "We unsubscribed from %s" "Nous sommes désabonnés de %s" # roster.tcl ::msgcat::mcset fr "Active Chats" "Discussions actives" ::msgcat::mcset fr "Are you sure to remove %s from roster?" "Etes-vous sûr de supprimer %s de la liste de contacts ?" ::msgcat::mcset fr "available" "disponible" ::msgcat::mcset fr "away" "absent(e)" ::msgcat::mcset fr "Contact Information" "Information du contact" ::msgcat::mcset fr "Edit item..." "Editer l'objet..." ::msgcat::mcset fr "Edit security..." "Editer la sécurité..." ::msgcat::mcset fr "is now" "est maintenant" ::msgcat::mcset fr "Invite to conference..." "Inviter à une conférence..." ::msgcat::mcset fr "Join..." "Joindre..." ::msgcat::mcset fr "Log in" "Se connecter" ::msgcat::mcset fr "Log out" "Se déconnecter" ::msgcat::mcset fr "No users in roster..." "Pas de contacts dans la liste..." ::msgcat::mcset fr "Raw XML" "XML brut" ::msgcat::mcset fr "Remove..." "Supprimer..." ::msgcat::mcset fr "Resubscribe" "Se réabonner" ::msgcat::mcset fr "Send" "Envoyer" ::msgcat::mcset fr "Send contacts to %s" "Envoyer des contacts à %s" ::msgcat::mcset fr "Send file..." "Envoyer un fichier..." ::msgcat::mcset fr "Send file via Jidlink..." "Envoyer un fichier via Jidlink..." ::msgcat::mcset fr "Send users..." "Envoyer des utilisateurs..." ::msgcat::mcset fr "Show history" "Montrer l'historique" ::msgcat::mcset fr "Show info" "Montrer les informations" ::msgcat::mcset fr "Start chat" "Démarrer la discussion" ::msgcat::mcset fr "unavailable" "indisponible" ::msgcat::mcset fr "Undefined" "Indéfini" ::msgcat::mcset fr "xa" "en absence prolongée" # search.tcl ::msgcat::mcset fr "Search in" "Rechercher dans" ::msgcat::mcset fr "Search again" "Rechercher encore" ::msgcat::mcset fr "OK" "OK" ::msgcat::mcset fr "Try again" "Essayer encore" ::msgcat::mcset fr "An error is occurred when searching in %s\n\n%s" "Une erreur est survenue lors de la recherche de %s\n\n%s" ::msgcat::mcset fr "Search in %s" "Rechercher dans %s" ::msgcat::mcset fr "Search: %s" "Rechercher : %s" ::msgcat::mcset fr "An error occurred when searching in %s\n\n%s" "Une erreur est survenue lors de la recherche de %s\n\n%s" ::msgcat::mcset fr "Search in %s: No matching items found" "Rechercher dans %s : aucune correspondance trouvée" ::msgcat::mcset fr "Search" "Rechercher" # splash.tcl ::msgcat::mcset fr "auto-away" "absence automatique" ::msgcat::mcset fr "avatars" "avatars" ::msgcat::mcset fr "balloon help" "bulle d'aide" ::msgcat::mcset fr "browsing" "navigation" ::msgcat::mcset fr "configuration" "configuration" ::msgcat::mcset fr "connections" "connexions" ::msgcat::mcset fr "cryptographics" "cryptographie" ::msgcat::mcset fr "emoticons" "émoticons" ::msgcat::mcset fr "extension management" "gestion des extensions" ::msgcat::mcset fr "file transfer" "transfert de fichiers" ::msgcat::mcset fr "jabber chat" "discussion jabber" ::msgcat::mcset fr "jabber groupchats" "groupes de discussion jabber" ::msgcat::mcset fr "jabber iq" "jabber iq" ::msgcat::mcset fr "jabber presence" "présence jabber" ::msgcat::mcset fr "jabber registration" "enregistrement jabber" ::msgcat::mcset fr "jabber xml" ::msgcat::mcset fr "kde" ::msgcat::mcset fr "message filters" "Filtres de messages" ::msgcat::mcset fr "message/headline" "message informatif" ::msgcat::mcset fr "plugin management" "Gestion des plugins" ::msgcat::mcset fr "presence" "présence" ::msgcat::mcset fr "rosters" "liste de contacts" ::msgcat::mcset fr "searching" "recherche" ::msgcat::mcset fr "text undo" "défaire le texte" ::msgcat::mcset fr "user interface" "interface utilisateur" ::msgcat::mcset fr "utilities" "utilités" ::msgcat::mcset fr "wmaker" # userinfo.tcl ::msgcat::mcset fr "Show user info" "Montrer les informations de l'utilisateur" ::msgcat::mcset fr "Show" "Montrer" ::msgcat::mcset fr "%s info" "Informations de %s" ::msgcat::mcset fr "Personal" "Informations personnelles" ::msgcat::mcset fr "Name" "Nom" ::msgcat::mcset fr "Full Name:" "Nom complet :" ::msgcat::mcset fr "Family Name:" "Nom de famille :" ::msgcat::mcset fr "Name:" "Nom :" ::msgcat::mcset fr "Middle Name:" "Autre nom :" ::msgcat::mcset fr "Prefix:" "Préfixe :" ::msgcat::mcset fr "Suffix:" "Suffixe :" ::msgcat::mcset fr "Nickname:" "Surnom :" ::msgcat::mcset fr "Information" "Informations" ::msgcat::mcset fr "E-mail:" "E-Mail :" ::msgcat::mcset fr "Web Site:" "Site web :" ::msgcat::mcset fr "JID:" "JID :" ::msgcat::mcset fr "UID:" "UID :" ::msgcat::mcset fr "Phones" "Téléphones" ::msgcat::mcset fr "Telephone numbers" "Numéros de téléphone" ::msgcat::mcset fr "Home:" "Maison :" ::msgcat::mcset fr "Work:" "Travail :" ::msgcat::mcset fr "Voice:" "Voix :" ::msgcat::mcset fr "Fax:" "Fax :" ::msgcat::mcset fr "Pager:" "Alphapage :" ::msgcat::mcset fr "Message Recorder:" "Répondeur :" ::msgcat::mcset fr "Cell:" "Cellulaire :" ::msgcat::mcset fr "Video:" "Vidéo :" ::msgcat::mcset fr "BBS:" "BBS :" ::msgcat::mcset fr "Modem:" "Modem :" ::msgcat::mcset fr "ISDN:" "RNIS :" ::msgcat::mcset fr "PCS:" "PCS :" ::msgcat::mcset fr "Preferred:" "Préféré :" ::msgcat::mcset fr "Location" "Localisation" ::msgcat::mcset fr "Address" "Adresse" ::msgcat::mcset fr "Address:" "Adresse :" ::msgcat::mcset fr "Address 2:" "Adresse 2 :" ::msgcat::mcset fr "City:" "Ville :" ::msgcat::mcset fr "State:" "Etat :" ::msgcat::mcset fr "Postal Code:" "Code postal :" ::msgcat::mcset fr "Country:" "Pays :" ::msgcat::mcset fr "Geographical position" "Position géographique" ::msgcat::mcset fr "Latitude:" "Latitude :" ::msgcat::mcset fr "Longitude:" "Longitude :" ::msgcat::mcset fr "Organization" "Organisation" ::msgcat::mcset fr "Details" "Détails" # Space at the end of the next word is to distinguish it from another "Name:" ::msgcat::mcset fr "Name: " "Nom :" ::msgcat::mcset fr "Unit:" "Unité :" # Space at the end of the next word is to distinguish it from another "Personal" ::msgcat::mcset fr "Personal " "Personnel" ::msgcat::mcset fr "Title:" "Titre :" ::msgcat::mcset fr "Role:" "Rôle :" # Space at the end of the next word is to distinguish it from another "About" ::msgcat::mcset fr "About " "A propos" ::msgcat::mcset fr "Birthday" "Date de naissance" ::msgcat::mcset fr "Birthday:" "Date de naissance :" ::msgcat::mcset fr "Photo" "Photo" ::msgcat::mcset fr "URL:" "URL :" ::msgcat::mcset fr "URL" "URL" ::msgcat::mcset fr "Image" "Image" ::msgcat::mcset fr "None" "Aucune" ::msgcat::mcset fr "Load Image" "Charger une image" ::msgcat::mcset fr "Avatar" "Avatar" ::msgcat::mcset fr "Client Info" "Info client" ::msgcat::mcset fr "Client" "Client" ::msgcat::mcset fr "Client:" "Client :" ::msgcat::mcset fr "Last activity" "Dernière date d'activité" ::msgcat::mcset fr "Last Activity or Uptime" "Dernière date d'activité" ::msgcat::mcset fr "Interval:" "Intervalle :" ::msgcat::mcset fr "Description:" "Description :" ::msgcat::mcset fr "Computer" "Ordinateur" ::msgcat::mcset fr "OS:" "SE :" ::msgcat::mcset fr "Time" "Heure" ::msgcat::mcset fr "Time:" "Heure :" ::msgcat::mcset fr "Time Zone:" "Fuseau horaire :" ::msgcat::mcset fr "UTC:" "UTC :" ::msgcat::mcset fr "Presence" "Présence" ::msgcat::mcset fr "Presence id signed" "Id de présence signé" ::msgcat::mcset fr " by " " par " ::msgcat::mcset fr "Year:" "Année :" ::msgcat::mcset fr "Month:" "Mois :" ::msgcat::mcset fr "Day:" "Jour :" ::msgcat::mcset fr "Presence is signed" "Présence signée" ::msgcat::mcset fr "List of users for userinfo." "Liste des utilisateurs pour userinfo" ::msgcat::mcset fr "Service info" "Informations du service" ::msgcat::mcset fr "Uptime" "Durée de la connexion" ::msgcat::mcset fr "User info" "Informations de l'utilisateur" ::msgcat::mcset fr "Version" "Version" ::msgcat::mcset fr "Version:" "Version :" # utils.tcl ::msgcat::mcset fr "day" "jour" ::msgcat::mcset fr "days" "jours" ::msgcat::mcset fr "hour" "heure" ::msgcat::mcset fr "hours" "heures" ::msgcat::mcset fr "minute" "minute" ::msgcat::mcset fr "minutes" "minutes" ::msgcat::mcset fr "second" "seconde" ::msgcat::mcset fr "seconds" "secondes" # plugins/chat/clear.tcl ::msgcat::mcset fr "Clear chat window" "Effacer la fenêtre de discusssion" # plugins/chat/draw_xhtml_message.tcl ::msgcat::mcset fr "Enable rendering of XHTML messages" "Activer le rendu des messages XHTML" # plugins/chat/events.tcl ::msgcat::mcset fr "Message stored on the server" "Message stocké sur le serveur" ::msgcat::mcset fr "Message stored on %s's server" "Message stocké sur le serveur de %s" ::msgcat::mcset fr "Message delivered" "Message délivré" ::msgcat::mcset fr "Message delivered to %s" "Message délivré à %s" ::msgcat::mcset fr "Message displayed" "Message affiché" ::msgcat::mcset fr "Message displayed to %s" "Message affiché chez %s" ::msgcat::mcset fr "Composing a reply" "Rédaction d'une réponse" ::msgcat::mcset fr "%s is composing a reply" "%s rédige une réponse" # plugins/chat/logger.tcl ::msgcat::mcset fr "Logging options." "Options de journalisation." ::msgcat::mcset fr "Directory to store logs." "Répertoire pour stocker les journaux." ::msgcat::mcset fr "Store private chats logs." "Stocker les journaux des discussions privées." ::msgcat::mcset fr "Store group chats logs." "Stocker les journaux des discussions de groupe." ::msgcat::mcset fr "History for %s" "Historique pour %s" ::msgcat::mcset fr "Search direction" "Sens de la recherche" ::msgcat::mcset fr "Export to XHTML" "Exporter en XHTML" # plugins/clientinfo.tcl ::msgcat::mcset fr "\n\tClient: %s" "\n\tClient : %s" ::msgcat::mcset fr "\n\tOS: %s" "\n\tSE : %s" ::msgcat::mcset fr "\n\tName: %s" "\n\tNom : %s" # plugins/general/message_archive.tcl ::msgcat::mcset fr "Messages" "Messages" # plugins/general/tkcon.tcl ::msgcat::mcset fr "Show Console" "Montrer la console" # plugins/jidlink/dtcp.tcl ::msgcat::mcset fr "Opening DTCP active connection" "Ouverture d'une connexion DTCP active" ::msgcat::mcset fr "Opening DTCP passive connection" "Ouverture d'une connexion DTCP passive" # plugins/jidlink/ibb.tcl ::msgcat::mcset fr "Opening IBB connection" "Ouverture d'une connexion IBB" # unix/autoaway.tcl # "Automatically away due to idle" goes to textstatus (probably no needs to translate) ::msgcat::mcset fr "Automatically away due to idle" "Absence automatique suite à une inactivité" # rest should be translated ::msgcat::mcset fr "Returning from auto-away" "Retour d'une absence automatique" ::msgcat::mcset fr "Moving to extended away" "Passage en absence prolongée" ::msgcat::mcset fr "Starting auto-away" "Début de l'absence automatique" ::msgcat::mcset fr "Idle for %s" "Inactivité de %s" # unix/dockingtray.tcl ::msgcat::mcset fr "Hide Main Window" "Cacher la fenêtre principale" ::msgcat::mcset fr "Show Main Window" "Montrer la fenêtre principale" # unix/ispell.tcl ::msgcat::mcset fr "- nothing -" "- rien -" # unix/wmdock.tcl ::msgcat::mcset fr "%s msgs" "%s msgs" ::msgcat::mcset fr "%s is %s" "%s est %s" # Local Variables: # mode: tcl # End: tkabber-0.11.1/msgs/eo.msg0000644000175000017500000005420411014357121014606 0ustar sergeisergei# $Id: eo.msg 1433 2008-05-19 20:08:49Z sergei $ # Esperanto Messages File # Author: Mike Mintz # Modification Date: December 30, 2002 # avatars.tcl ::msgcat::mcset eo "No avatar to store" "Neniu avatar por storiÄi" # browser.tcl ::msgcat::mcset eo "JBrowser" "Jabber Folumilo" ::msgcat::mcset eo "JID:" ::msgcat::mcset eo "Browse" "Folumi" ::msgcat::mcset eo "%s: %s/%s, Description: %s, Version: %s\nNumber of children: %s" "%s: %s/%s, Priskribo: %s, Versio: %s\nNombro da idoj: %s" # chats.tcl ::msgcat::mcset eo ">>> Unable to decipher data: %s <<<" ">>> Malkapabla por malĉifri datumojn: %s <<<" ::msgcat::mcset eo "Error %s: %s" "Eraro %s: %s" ::msgcat::mcset eo "Chat with %s" "Babilu kun %s" ::msgcat::mcset eo "Toggle encryption" "Kapabligi/Malkapabligi ĉifrado" ::msgcat::mcset eo "Subject:" "Subjekto:" ::msgcat::mcset eo "Error %s" "Eraro %s" ::msgcat::mcset eo "Disconnected" "Malkonektita" ::msgcat::mcset eo "Invite %s to conferences" "Invitu %s al konferencoj" ::msgcat::mcset eo "Invite users..." "Invitu uzulojn..." ::msgcat::mcset eo "Invite" "Invitu" ::msgcat::mcset eo "Please join %s" "Bonvolu ĉeesti %s" ::msgcat::mcset eo "Invite users to %s" "Invitu uzulojn al %s" ::msgcat::mcset eo "No conferences in progress..." "Neniu konferencoj progresas" # datagathering.tcl # emoticons.tcl # filetransfer.tcl ::msgcat::mcset eo "Send file to %s" "Sendu dosieron al %s" ::msgcat::mcset eo "File to Send:" "Dosiero por Sendi:" ::msgcat::mcset eo "Browse..." "Folumu..." ::msgcat::mcset eo "Description:" "Priskribo:" ::msgcat::mcset eo "IP address:" "IP adreso:" ::msgcat::mcset eo "File not found or not regular file: %s" "Dosiero ne estas trovita aÅ­ ne estas regula dosiero: %s" ::msgcat::mcset eo "Receive file from %s" "Recevu dosiero de %s" ::msgcat::mcset eo "Save as:" "Surdisku kiel:" ::msgcat::mcset eo "Receive" "Ricevu" ::msgcat::mcset eo "Request failed: %s" "Peto malsukcesis: %s" ::msgcat::mcset eo "Transfering..." "Translokanta..." ::msgcat::mcset eo "Size:" "Grando:" ::msgcat::mcset eo "Connection closed" "Konekto fermiÄis" # filters.tcl ::msgcat::mcset eo "I'm not online" "Mi ne estas enreta" ::msgcat::mcset eo "the message is from" "la mesaÄo estas de" ::msgcat::mcset eo "the message is sent to" "la mesaÄo estas sendita al" ::msgcat::mcset eo "the subject is" "la subjekto estas" ::msgcat::mcset eo "the body is" "la korpo estas" ::msgcat::mcset eo "my status is" "mia retastato estas" ::msgcat::mcset eo "the message type is" "la mesaÄotipo estas" ::msgcat::mcset eo "change message type to" "ÅanÄu mesaÄotipon por esti" ::msgcat::mcset eo "forward message to" "resendu mesaÄon al" ::msgcat::mcset eo "reply with" "respondu kun" ::msgcat::mcset eo "store this message offline" "storu tiun ĉin mesaÄon malenrete" ::msgcat::mcset eo "continue processing rules" "adu trakti regulojn" ::msgcat::mcset eo "Filters" "Filtriloj" ::msgcat::mcset eo "Add" "Aldonu" ::msgcat::mcset eo "Edit" "Redaktu" ::msgcat::mcset eo "Remove" "Elprenu" ::msgcat::mcset eo "Move up" "Transloku suben" ::msgcat::mcset eo "Move down" "Transloku supren" ::msgcat::mcset eo "Edit rule" "Redaktu regulon" ::msgcat::mcset eo "Rule Name:" "Nomo de Regulo:" ::msgcat::mcset eo "Empty rule name" "Malplena nomo de regulo" ::msgcat::mcset eo "Rule name already exists" "Nomo de regulo jam ekzistas" ::msgcat::mcset eo "Condition" "Kondiĉo" ::msgcat::mcset eo "Action" "Agado" # gpgme.tcl ::msgcat::mcset eo "Encrypt traffic" "Ĉifru trafikon" ::msgcat::mcset eo "Change security preferences for %s" "ÅœanÄu sekureco-elektojn por %s" ::msgcat::mcset eo "Select Key for Signing Traffic" "Elektu Åœlosilon por Trafiko-Subskribado" ::msgcat::mcset eo "Select" "Elektu" ::msgcat::mcset eo "Please enter passphrase" "Bonvolu tajpi pasfrazon" ::msgcat::mcset eo "Please try again" "Bonvolu repeni" ::msgcat::mcset eo "Key ID" "Åœlosilo-ID" ::msgcat::mcset eo "User ID" "Uzulo-ID" ::msgcat::mcset eo "Passphrase:" "Pasfrazo:" ::msgcat::mcset eo "Error in signature verification software: %s." "Eraro en subskribo-kontrolanta softvaro: %s." ::msgcat::mcset eo "%s purportedly signed by %s can't be verified.\n\n%s." "%s supozeble subskribiÄis de %s ne povas kontroli\n\n%s." ::msgcat::mcset eo "Unable to sign presence information: %s.\n\nPresence will be sent, but signing traffic is now disabled." "Malkapabla por subskribi ĉeesto-informon: %s.\n\nĈeesto estos sendita, sed trafiko-subskribado nun estas malkapablita." ::msgcat::mcset eo "Unable to sign message body: %s.\n\nSigning traffic is now disabled.\n\nSend it WITHOUT a signature?" "Malkapabla por subskrib mesaÄo-korpon: %s.\n\nTrafiko-subskribado nun estas malkapablita.\n\nCxu sendu SEN subskribo?" ::msgcat::mcset eo "Data purported sent by %s can't be deciphered.\n\n%s." "Datumoj, kiu supozeble sendiÄis de %s, ne povas malĉifriÄi.\n\n%s." ::msgcat::mcset eo "Unable to encipher data for %s: %s.\n\nEncrypting traffic to this user is now disabled.\n\nSend it as PLAINTEXT?" "Malkapabla por ĉifri datumojn por %s: %s.\n\nTrafiko-ĉifrado al tiu ĉi uzulo nun estas malkapablita.\n\nSendu Äin kiel KLARA-TEKSTO?" ::msgcat::mcset eo "" "" # iface.tcl ::msgcat::mcset eo "Presence" "Ĉeesto" ::msgcat::mcset eo "Online" "Enreta" ::msgcat::mcset eo "Free to chat" "Libera por babilado" ::msgcat::mcset eo "Away" "Fora" ::msgcat::mcset eo "Extended Away" "Pli Fora" ::msgcat::mcset eo "Do not disturb" "Ne Äenu" ::msgcat::mcset eo "Invisible" "KaÅita" ::msgcat::mcset eo "Log in..." "Konektu..." ::msgcat::mcset eo "Log out" "Malkonektu" ::msgcat::mcset eo "Log out with reason..." "Malkonektu pro kialo..." ::msgcat::mcset eo "Profile on" "Karakterizo-activigu" ::msgcat::mcset eo "Profile report" "Karakterizo-raporto" ::msgcat::mcset eo "Quit" "Eliru" ::msgcat::mcset eo "Services" "Servoj" ::msgcat::mcset eo "Send message..." "Sendu mesaÄon..." ::msgcat::mcset eo "Roster" "Kontaktulolisto" ::msgcat::mcset eo "Add user..." "Aldonu uzulon..." ::msgcat::mcset eo "Add conference..." "Aldonu konferencon..." ::msgcat::mcset eo "Browser" "Folumilo" ::msgcat::mcset eo "Join group..." "Ĉeesto grupon..." ::msgcat::mcset eo "Chats" "Babilejoj" ::msgcat::mcset eo "Create room..." "Kreu konferencon" ::msgcat::mcset eo "Stop autoscroll" "Haltu aÅ­tomatan scroll" ::msgcat::mcset eo "Sound" "Sono" ::msgcat::mcset eo "Mute" "Muta" ::msgcat::mcset eo "Filters..." "Filtriloj..." ::msgcat::mcset eo "Change password..." "ÅœanÄu pasvorton..." ::msgcat::mcset eo "Show user info..." "Montru informon de uzulo..." ::msgcat::mcset eo "Edit my info..." "Redaktu mian informon..." ::msgcat::mcset eo "Avatar" ::msgcat::mcset eo "Announce" "Anoncu" ::msgcat::mcset eo "Allow downloading" "Permesu elÅutadon" ::msgcat::mcset eo "Send to server" "Sendu al servilo" ::msgcat::mcset eo "Jidlink" ::msgcat::mcset eo "Admin tools" "Administruliloj" ::msgcat::mcset eo "Open raw XML window" "Malfermu krudan XML fenestron" ::msgcat::mcset eo "Send broadcast message..." "Dissendu mesaÄon..." ::msgcat::mcset eo "Send message of the day..." "Sendu mesaÄon de la tago..." ::msgcat::mcset eo "Update message of the day..." "Äœisdatigi mesaÄno de la tago..." ::msgcat::mcset eo "Delete message of the day" "ForviÅu mesaÄon de la tago" ::msgcat::mcset eo "Help" "Helpo" ::msgcat::mcset eo "Quick help" "Rapida helpo" ::msgcat::mcset eo "Quick Help" "Rapida Helpo" ::msgcat::mcset eo "Main window:" "Ĉefa fenestro:" ::msgcat::mcset eo "Tabs:" ::msgcat::mcset eo "Chats:" "Babilejoj:" ::msgcat::mcset eo "Close tab" "Fermu tab" ::msgcat::mcset eo "Previous/Next tab" "AntaÅ­a/Venonta tab" ::msgcat::mcset eo "Hide/Show roster" "KaÅigu/Montru kontaktulolisto" ::msgcat::mcset eo "Complete nickname" "Plena kaÅnomo" ::msgcat::mcset eo "Previous/Next history message" "AntaÅ­a/Venonta mesaÄo de historio" ::msgcat::mcset eo "Show emoticons" "Montru sentikonojn" ::msgcat::mcset eo "Undo" "Malfaru" ::msgcat::mcset eo "Redo" "Refaru" ::msgcat::mcset eo "Scroll chat window up/down" "Transloku babilofenestron supren/suben" ::msgcat::mcset eo "Correct word" "korektu vorton" ::msgcat::mcset eo "About" "Pri" ::msgcat::mcset eo "Authors:" "AÅ­toroj:" ::msgcat::mcset eo "Alexey Shchepin" "Aleksi Åœepin" ::msgcat::mcset eo "Marshall T. Rose" "MarÅal T. Roz" ::msgcat::mcset eo "Sergei Golovan" "Sergej Golovan" ::msgcat::mcset eo "Michail Litvak" "MiÄ¥ejl Litvak" ::msgcat::mcset eo "Add new user..." "Aldonu novan uzulon..." ::msgcat::mcset eo "Jabber Browser" "Jabber Foliumilo" #::msgcat::mcset eo "Join group..." "Ĉeestu grupon..." ::msgcat::mcset eo "Show online & offline users" "Montru enretajn kaj malenretajn uzulojn" ::msgcat::mcset eo "Show online users only" "Montru nur enretajn uzulojn" ::msgcat::mcset eo "Toggle signing" "Kapabligi/Malkapabligi subskribado" ::msgcat::mcset eo "Toggle encryption (when possible)" "Kapabligi/Malkapabligi ĉifrado (kiam eble)" ::msgcat::mcset eo "Cancel" "Nuligu" ::msgcat::mcset eo "Close" "Fermu" ::msgcat::mcset eo "Close other tabs" "Fermu aliajn tabs" ::msgcat::mcset eo "Close all tabs" "Fermu ĉiujn tabs" ::msgcat::mcset eo "Send" "Sendu" # itemedit.tcl ::msgcat::mcset eo "Edit properties for %s" "Redaktu kvalitojn por %s" ::msgcat::mcset eo "Edit nickname for %s" "Redaktu kaÅnomo por %s" ::msgcat::mcset eo "Nickname:" "KaÅnomo:" ::msgcat::mcset eo "Edit groups for %s" "Redaktu grupojn por %s" ::msgcat::mcset eo "Available groups" "Disponeblaj grupoj" ::msgcat::mcset eo "Group:" "Grupo:" ::msgcat::mcset eo "Current groups" "Nunaj grupoj" ::msgcat::mcset eo "Add ->" "Aldonu ->" ::msgcat::mcset eo "<- Remove" "<- Elprenu" # jidlink.tcl ::msgcat::mcset eo "Opening Jidlink connection" "Malfermas Jidlink konekton" ::msgcat::mcset eo "Jidlink connection closed" "Jidlink konekto fermis" # joingrdialog.tcl ::msgcat::mcset eo "Join group" "Ĉeestu grupon" ::msgcat::mcset eo "Nick:" "KaÅnomo:" ::msgcat::mcset eo "Group:" "Grupo:" ::msgcat::mcset eo "Server:" "Servilo:" ::msgcat::mcset eo "use v2 protocol" "Uzu 2an versian retalingvon" ::msgcat::mcset eo "Password (v2 only):" "Pasvorto (por nur versio 2a)" ::msgcat::mcset eo "Join" "Ĉeestu" ::msgcat::mcset eo "Add group" "Aldonu grupon" ::msgcat::mcset eo "Get conference info failed: %s" "Akirado de informo de konferenco malsukcesis %s" ::msgcat::mcset eo "Join failed: %s" "Ĉeestado malsukcesis %s" ::msgcat::mcset eo "Create Room" "Kreu Konferencon" ::msgcat::mcset eo "Address:" "Adreso:" ::msgcat::mcset eo "Nickname:" "KaÅnomo:" ::msgcat::mcset eo "Password:" "Pasvorto:" ::msgcat::mcset eo "Name: " "Nomo:" ::msgcat::mcset eo "Description:" "Priskribu:" ::msgcat::mcset eo "Create" "Kreu" # login.tcl ::msgcat::mcset eo "Login" "Konektu" ::msgcat::mcset eo "Username:" "KaÅnomo:" ::msgcat::mcset eo "Password:" "Pasvorto:" ::msgcat::mcset eo "Server:" "Servilo:" ::msgcat::mcset eo "Resource:" ::msgcat::mcset eo "Port:" ::msgcat::mcset eo "Use hashed password" "Uzu hashed pasvorton" ::msgcat::mcset eo "Connect via alternate server" "Konektu per alia servilo" ::msgcat::mcset eo "Use SSL" "Uzu SSL" ::msgcat::mcset eo "SSL Port:" ::msgcat::mcset eo "Use Proxy" "Uzu Proxy" ::msgcat::mcset eo "Proxy Server:" "Proxy Servilo:" ::msgcat::mcset eo "Proxy Port:" ::msgcat::mcset eo "Proxy Login:" "Proxy KaÅnomo:" ::msgcat::mcset eo "Proxy Password:" "Proxy Pasvorto:" ::msgcat::mcset eo "Profiles" "Karakterizoj" ::msgcat::mcset eo "Profile" "Karakterizo" ::msgcat::mcset eo "Authentication failed: %s\nCreate new account?" "Rajtigado malsukcesis: %s\nKreu novan konton?" ::msgcat::mcset eo "Registration failed: %s" "Enregistrigado malsukcesis: %s" ::msgcat::mcset eo "Change password" "ÅœanÄu pasvorton" ::msgcat::mcset eo "Old password:" "Malnova pasvorto:" ::msgcat::mcset eo "New password:" "Nova pasvorto:" ::msgcat::mcset eo "Repeat new password:" "Ripetu novan pasvorton:" ::msgcat::mcset eo "Old password is incorrect" "Malnova pasvorto malpravas" ::msgcat::mcset eo "New passwords do not match" "Novaj pasvortoj ne estas la samo" ::msgcat::mcset eo "Password is changed" "Pasvorto estas ÅanÄita" ::msgcat::mcset eo "Password change failed: %s" "ÅœanÄo de pasvorto malsukcesis: %s" ::msgcat::mcset eo "Logout with reason" "Malkonektu pro kialo" ::msgcat::mcset eo "Reason:" "Kialo:" ::msgcat::mcset eo "Priority:" # messages.tcl ::msgcat::mcset eo "Message from %s" "MesaÄo de %s" ::msgcat::mcset eo "Message from" "MesaÄo de" ::msgcat::mcset eo "Extras from %s" "Ekstraĵoj de %s" ::msgcat::mcset eo "Extras from" "Ekstraĵoj de" ::msgcat::mcset eo "Reply" "Respondu" ::msgcat::mcset eo "Attached user:" "Afiksita uzulo:" ::msgcat::mcset eo "Attached file:" "Afiksita dosiero:" ::msgcat::mcset eo "Invited to:" "Invitita al:" ::msgcat::mcset eo "Message body" "Korpo de mesaÄo" ::msgcat::mcset eo "Send message to %s" "Sendu mesaÄon al %s" ::msgcat::mcset eo "Send message" "Sendu mesaÄon" ::msgcat::mcset eo "This message is encrypted." "Tiu ĉi mesaÄo estas ĉifrita." ::msgcat::mcset eo "Subscribe request from %s" "Abonopeto de %s" ::msgcat::mcset eo "Subscribe request from" "Abonopeto de" ::msgcat::mcset eo "Subscribe" "Abonu" ::msgcat::mcset eo "Unsubscribe" "Malabonu" ::msgcat::mcset eo "Send subscription" "Sendu abono" ::msgcat::mcset eo "Send subscription to %s" "Sendu abono al %s" ::msgcat::mcset eo "Send subscription to " "Sendu abono al " ::msgcat::mcset eo "Headlines" ::msgcat::mcset eo "Toggle seen" "Kapabligi/Malkapabligi viditado (seen)" ::msgcat::mcset eo "Sort" "Klasi" # muc.tcl ::msgcat::mcset eo "Whois" "Kiu-estas" ::msgcat::mcset eo "Kick" "Piedbatu" ::msgcat::mcset eo "Ban" "Malpermesu" ::msgcat::mcset eo "Grant Voice" "Donu voĉon" ::msgcat::mcset eo "Revoke Voice" "Revoku voĉon" ::msgcat::mcset eo "Grant Membership" "Donu anecon" ::msgcat::mcset eo "Revoke Membership" "Revoku anecon" ::msgcat::mcset eo "Grant Moderator Privilege" "Donu privilegion de moderigado" ::msgcat::mcset eo "Revoke Moderator Privilege" "Revoku privilegion de moderigado" ::msgcat::mcset eo "MUC" ::msgcat::mcset eo "Configure" "decidu opciojn" ::msgcat::mcset eo "Edit admin list" "Redaktu administrulo-listo" ::msgcat::mcset eo "Edit moderator list" "Redaktu moderigulo-listo" ::msgcat::mcset eo "Edit ban list" "Redaktu malpermeso-listo" ::msgcat::mcset eo "Edit member list" "Redaktu ano-listo" ::msgcat::mcset eo "Edit voice list" "Redaktu voĉoliston" ::msgcat::mcset eo "Destroy" "Destruu" # presence.tcl ::msgcat::mcset eo "Not logged in" "Nekonektita" #::msgcat::mcset eo "Online" "Enreta" #::msgcat::mcset eo "Free to chat" "Libera por babilado" #::msgcat::mcset eo "Away" "Fora" #::msgcat::mcset eo "Extended Away" "Pli Fora" #::msgcat::mcset eo "Do not disturb" "Ne Äœenu" #::msgcat::mcset eo "Invisible" "KaÅita" ::msgcat::mcset eo "Offline" "Malenreta" ::msgcat::mcset eo "invalid userstatus value " "malvalida userstatus " # register.tcl ::msgcat::mcset eo "Register in %s" "EnregistriÄu en %s" ::msgcat::mcset eo "Unsubscribed from %s" "Abonita de %s" ::msgcat::mcset eo "We unsubscribed from %s" "Ni abonis %s" # roster.tcl ::msgcat::mcset eo "Undefined" "Nedifinita" ::msgcat::mcset eo "is now" "estas nun" #::msgcat::mcset eo "Show online & offline users" "Montru enretajn kaj malenretajn uzulojn" #::msgcat::mcset eo "Show online users only" "Montru nur enretajn uzulojn" ::msgcat::mcset eo "Are you sure to remove %s from roster?" "Ĉu vi estas certa elpreni %s el kontaktulolisto?" ::msgcat::mcset eo "Start chat" "Eku babilon" #::msgcat::mcset eo "Send message..." "Sendu mesaÄon..." ::msgcat::mcset eo "Invite to conference..." "Invitu al konferenco..." ::msgcat::mcset eo "Resubscribe" "Reabonu" ::msgcat::mcset eo "Send users..." "Sendu uzulojn..." ::msgcat::mcset eo "Send file..." "Sendu dosieron..." ::msgcat::mcset eo "Send file via Jidlink..." "Sendu dosieron per Jidlink..." ::msgcat::mcset eo "Show info" "Montru informon" ::msgcat::mcset eo "Show history" "Montru historion" ::msgcat::mcset eo "Edit item..." "Redaktu eron..." ::msgcat::mcset eo "Edit security..." "Redaktu sekurecon..." ::msgcat::mcset eo "Remove..." "Elprenu..." ::msgcat::mcset eo "Join..." "Ĉeestu..." ::msgcat::mcset eo "Log in" "Konektu" ::msgcat::mcset eo "Log out" "Malkonektu" ::msgcat::mcset eo "Send contacts to" "Sendu kontaktulojn al" ::msgcat::mcset eo "Send" "Sendu" ::msgcat::mcset eo "No users in roster..." "Neniu uzuloj en kontaktulolistoj..." ::msgcat::mcset eo "Contact Information" "Informo de Kontaktulo" ::msgcat::mcset eo "Raw XML input" "Kruda XML enigo" # search.tcl ::msgcat::mcset eo "Search in" "Serĉu en" ::msgcat::mcset eo "Search again" "Reserĉu" ::msgcat::mcset eo "OK" "Bone" # splash.tcl ::msgcat::mcset eo "auto-away" "aÅ­tomata-forado" ::msgcat::mcset eo "avatars" ::msgcat::mcset eo "balloon help" "balona helpo" ::msgcat::mcset eo "browsing" "folumado" ::msgcat::mcset eo "configuration" "decidado de opcioj" ::msgcat::mcset eo "connections" "konektoj" ::msgcat::mcset eo "cryptographics" "ĉifreco" ::msgcat::mcset eo "emoticons" "sentikonoj" ::msgcat::mcset eo "extension management" "administrado de etendaĵoj" ::msgcat::mcset eo "file transfer" "dosiero-translokado" ::msgcat::mcset eo "jabber chat" "babilado" ::msgcat::mcset eo "jabber groupchats" "konferencoj" ::msgcat::mcset eo "jabber iq" "iq" ::msgcat::mcset eo "jabber presence" "ĉeesto" ::msgcat::mcset eo "jabber registration" "enregistrigado" ::msgcat::mcset eo "jabber xml" "xml" ::msgcat::mcset eo "kde" ::msgcat::mcset eo "message filters" "mesaÄofiltriloj" ::msgcat::mcset eo "message/headline" "mesaÄo/headline" ::msgcat::mcset eo "plugin management" "administrado de kromprogramoj" ::msgcat::mcset eo "presence" "ĉeesto" ::msgcat::mcset eo "rosters" "kontaktulolistoj" ::msgcat::mcset eo "searching" "serĉado" ::msgcat::mcset eo "text undo" "malfarado de teksto" ::msgcat::mcset eo "user interface" "uzula interfaco" ::msgcat::mcset eo "utilities" "utilprogramo" ::msgcat::mcset eo "wmaker" # userinfo.tcl ::msgcat::mcset eo "Show user info" "Montru informon de uzulo" ::msgcat::mcset eo "Show" "Montru" ::msgcat::mcset eo "%s info" "Informo de %s" ::msgcat::mcset eo "Personal" "Persona" ::msgcat::mcset eo "Name" "Nomo" ::msgcat::mcset eo "Full Name:" "Plena Nomo:" ::msgcat::mcset eo "Family Name:" "Familia Nomo:" ::msgcat::mcset eo "Name:" "Nomo:" ::msgcat::mcset eo "Middle Name:" "Meza Nomo:" ::msgcat::mcset eo "Prefix:" "Prefikso:" ::msgcat::mcset eo "Suffix:" "Sufikso:" ::msgcat::mcset eo "Nickname:" "KaÅnomo:" ::msgcat::mcset eo "Information" "Informo" ::msgcat::mcset eo "E-mail:" "RetpoÅto:" ::msgcat::mcset eo "Web Site:" "RetpaÄo:" ::msgcat::mcset eo "JID:" ::msgcat::mcset eo "UID:" ::msgcat::mcset eo "Phones" "Telefonoj" ::msgcat::mcset eo "Telephone numbers" "Telefonnumeroj" ::msgcat::mcset eo "Home:" "Hejma:" ::msgcat::mcset eo "Work:" "Labora:" ::msgcat::mcset eo "Voice:" "Voĉo" ::msgcat::mcset eo "Fax:" "Fakso:" ::msgcat::mcset eo "Pager:" ::msgcat::mcset eo "Message Recorder:" "Responda MaÅino:" ::msgcat::mcset eo "Cell:" "PoÅtelefono:" ::msgcat::mcset eo "Video:" "Bildofono:" ::msgcat::mcset eo "BBS:" ::msgcat::mcset eo "Modem:" "Modemo:" ::msgcat::mcset eo "ISDN:" ::msgcat::mcset eo "PCS:" ::msgcat::mcset eo "Preferred:" "Preferita:" ::msgcat::mcset eo "Location" "Loko" ::msgcat::mcset eo "Address" "Adreso" ::msgcat::mcset eo "Address:" "Adreso:" ::msgcat::mcset eo "Address 2:" "Adreso 2a:" ::msgcat::mcset eo "City:" "Urbo:" ::msgcat::mcset eo "State:" "SubÅtato:" ::msgcat::mcset eo "Postal Code:" "PoÅta Kodo:" ::msgcat::mcset eo "Country:" "Lando:" ::msgcat::mcset eo "Geographical position" "Geografia loko" ::msgcat::mcset eo "Latitude:" "Latitudo:" ::msgcat::mcset eo "Longitude:" "Longitudo:" ::msgcat::mcset eo "Organization" "Asocio" ::msgcat::mcset eo "Details" "Detaloj" # Space at the end of the next word is to distinguish it from another "Name:" ::msgcat::mcset eo "Name: " "Nomo:" ::msgcat::mcset eo "Unit:" "Sekcio:" # Space at the end of the next word is to distinguish it from another "Personal" ::msgcat::mcset eo "Personal " "Persona" ::msgcat::mcset eo "Title:" "Titolo:" ::msgcat::mcset eo "Role:" "Rolo:" # Space at the end of the next word is to distinguish it from another "About" ::msgcat::mcset eo "About " "Pri" ::msgcat::mcset eo "Birthday" "Naskotago" ::msgcat::mcset eo "Birthday:" "Naskotago:" ::msgcat::mcset eo "Photo" "Foto" ::msgcat::mcset eo "URL:" ::msgcat::mcset eo "URL" ::msgcat::mcset eo "Image" "Bildo" ::msgcat::mcset eo "None" "Nenio" ::msgcat::mcset eo "Load Image" "Akiru Bildon" ::msgcat::mcset eo "Avatar" ::msgcat::mcset eo "Client Info" "Klienta Informo" ::msgcat::mcset eo "Client" "Kliento" ::msgcat::mcset eo "Client:" "Kliento:" ::msgcat::mcset eo "Version:" "Versio:" ::msgcat::mcset eo "Last Activity or Uptime" "Lasta agado aÅ­ aktivatempo" ::msgcat::mcset eo "Interval:" "Intervalo:" ::msgcat::mcset eo "Description:" "Priskribo:" ::msgcat::mcset eo "Computer" "Komputilo" ::msgcat::mcset eo "OS:" ::msgcat::mcset eo "Time:" "Horo:" ::msgcat::mcset eo "Time Zone:" "Horzono:" ::msgcat::mcset eo "UTC:" ::msgcat::mcset eo "Presence" "Ĉeesto" ::msgcat::mcset eo "Presence id signed" "Ĉeesto estas subskribita" ::msgcat::mcset eo " by " " de " # TODO # utils.tcl ::msgcat::mcset eo "day" ::msgcat::mcset eo "days" ::msgcat::mcset eo "hour" ::msgcat::mcset eo "hours" ::msgcat::mcset eo "minute" ::msgcat::mcset eo "minutes" ::msgcat::mcset eo "second" ::msgcat::mcset eo "seconds" # plugins/jidlink/dtcp.tcl ::msgcat::mcset eo "Opening DTCP active connection" "Malfermas DTCP aktivan konekton" ::msgcat::mcset eo "Opening DTCP passive connection" "Malfermas DTCP malaktivan konekton" # plugins/jidlink/ibb.tcl ::msgcat::mcset eo "Opening IBB connection" "Malfermas IBB konekton" # plugins/clientinfo.tcl ::msgcat::mcset eo "\n\tClient: %s" "\n\tKliento: %s" ::msgcat::mcset eo "\n\tOS: %s" "\n\tOS: %s" # unix/autoaway.tcl # "Automatically away due to idle" goes to textstatus (probably no needs to translate) ::msgcat::mcset eo "Automatically away due to idle" # rest should be translated ::msgcat::mcset eo "Returning from auto-away" "Revenanta de aÅ­tomata fora" ::msgcat::mcset eo "Moving to extended away" "Translokata al pli fora" ::msgcat::mcset eo "Starting auto-away" "Ekanta aÅ­tomatan foran" ::msgcat::mcset eo "Idle for %s" "Senfara dum %s" # unix/dockingtray.tcl ::msgcat::mcset eo "Hide Main Window" "KaÅigu Ĉefan Fenestron" ::msgcat::mcset eo "Show Main Window" "Montru Ĉefan Fenestron" # unix/ispell.tcl ::msgcat::mcset eo "- nothing -" "- nenio -" # unix/wmdock.tcl ::msgcat::mcset eo "%s msgs" "%s mesaÄas" ::msgcat::mcset eo "%s is %s" "%s estas %s" # Local Variables: # mode: tcl # End: tkabber-0.11.1/msgs/ca.msg0000644000175000017500000017352011014357121014571 0ustar sergeisergei#1 Catalan messages file #2 Author: Luis Peralta / jaxp - peralta @ aditel . org #3 Revised by: Carles Bellver - bellverc @ cent . uji . es #4 http://spisa.act.uji.es/~peralta JID: al019409@mi.uji.es #5 Please notify me of errors or incoherencies #6 #7 http://www.softcatala.org/projectes/eines/recull/recull.htm #8 http://www.softcatala.org/projectes/eines/guiaestil/guiaestil.htm ::msgcat::mcset ca "%s administration" "%s administració" ::msgcat::mcset ca "%s want to play chess!" "%s vol jugar a escacs!" ::msgcat::mcset ca "%s whiteboard" "%s Pissarra blanca" ::msgcat::mcset ca "Administrate ejabberd" "Administrar ejabberd" ::msgcat::mcset ca "Administrate" "Administrar" ::msgcat::mcset ca "Allow illegal moves" "Permetre moviments il·legals" ::msgcat::mcset ca "Automatically away due to idle" ::msgcat::mcset ca "Automatically open GeoRoster window." "Obrir finestra de GeoRoster automàticament." ::msgcat::mcset ca "Black" "Negres" ::msgcat::mcset ca "Chess with %s" "Escacs amb %s" ::msgcat::mcset ca "Chess" "Escacs" ::msgcat::mcset ca "Color" "Color" ::msgcat::mcset ca "Default country to use when looking at a vCard." "Pais per defecte a emprar al veure una vCard." ::msgcat::mcset ca "ejabberd server" "servidor ejabberd" ::msgcat::mcset ca "Font" "Font" ::msgcat::mcset ca "GeoRoster options." "Opcions del GeoRoster." ::msgcat::mcset ca "GeoRoster" "GeoRoster" ::msgcat::mcset ca "History" "Historial" ::msgcat::mcset ca "Integral" "Integral" ::msgcat::mcset ca "Latitude: %.2f Longitude: %.2f" "Latitud: %.2f Longitud: %.2f" ::msgcat::mcset ca "Latitude:" "Latitud:" ::msgcat::mcset ca "Let's play chess, %s!" "Juguem a escacs, %s!" ::msgcat::mcset ca "List of ejabberd servers." "Llista de servidors ejabberd." ::msgcat::mcset ca "Move: " "Moure: " ::msgcat::mcset ca "Opponent %s refuse our request: %s" "L'oponent %s rebutja la nostra petició: %s" ::msgcat::mcset ca "Pawn promotion" "Promociò del peò" ::msgcat::mcset ca "Play" "Jugar" ::msgcat::mcset ca "PolyLine" "Multilinea" ::msgcat::mcset ca "Presence Spy" "Espiar presència" ::msgcat::mcset ca "Reload" "Recarregar" ::msgcat::mcset ca "Request only unseen (which aren't displayed in the chat window) messages in the history in MUC compatible conference rooms." "Demanar només els missatges no visualitzats (que no es mostrin a la finestra de xat) en l'historial de les sales de xat" ::msgcat::mcset ca "Show cities" "Mostrar ciutats" ::msgcat::mcset ca "Spy presence" "Espiar presència" ::msgcat::mcset ca "Spy" "Espiar" ::msgcat::mcset ca "Store" "Guardar" ::msgcat::mcset ca "Text Color" "Color del text" ::msgcat::mcset ca "Text" "Text" ::msgcat::mcset ca "Text:" "Text:" ::msgcat::mcset ca "White" "Blanques" ::msgcat::mcset ca "Whiteboard" "Pissarra blanca" ::msgcat::mcset ca " by " " per " ::msgcat::mcset ca " by %s" " per %s" ::msgcat::mcset ca "#" "#" ::msgcat::mcset ca "%s has become available" "%s és ara disponible" ::msgcat::mcset ca "%s has left" "%s s'ha marxat" ::msgcat::mcset ca "%s Headlines" "Titulars de %s" ::msgcat::mcset ca "%s info" "Informació de %s" ::msgcat::mcset ca "%s invites you to conference room %s" "%s et convida a la sala de conversa %s" ::msgcat::mcset ca "%s is %s" "%s està %s" ::msgcat::mcset ca "%s is composing a reply" "%s està escrivint una resposta" ::msgcat::mcset ca "%s is now known as %s" "%s és ara %s" ::msgcat::mcset ca "%s msgs" "%s missatges" ::msgcat::mcset ca "%s purportedly signed by %s can't be verified.\n\n%s." "%s pretesament signat per %s no es pot verificar.\n\n%s." ::msgcat::mcset ca "%s request from %s" "Petició %s de %s" ::msgcat::mcset ca "%s SSL Certificate Info" "Informació de Certificat SSL de %s" ::msgcat::mcset ca "%s: %s/%s, Description: %s, Version: %s\nNumber of children: %s" "%s: %s/%s, Descripció: %s, Versió: %s\nNombre de fills: %s" ::msgcat::mcset ca "- nothing -" "- res -" ::msgcat::mcset ca ". Proceed?\n\n" ". Procedir?\n\n" ::msgcat::mcset ca "/me has changed the subject to: %s" "/me ha canviat el tema a: %s" ::msgcat::mcset ca "<- Remove" "<- Eliminar" ::msgcat::mcset ca ">>> Unable to decipher data: %s <<<" ">>> No ha sigut possible desxifrar les dades: %s <<<" ::msgcat::mcset ca "About " "Més informació" ::msgcat::mcset ca "About" "Referent a" ::msgcat::mcset ca "About..." "Referent a..." ::msgcat::mcset ca "Account" "Compte" ::msgcat::mcset ca "Action" "Acció" ::msgcat::mcset ca "Action:" "Acció:" ::msgcat::mcset ca "Activate lists at startup" "Activar llistes a l'inici" ::msgcat::mcset ca "Activate visible/invisible/ignore lists before sending initial presence." "Activar llistes de visibles/invisibles/ignorats abans d'enviar la presència inicial." ::msgcat::mcset ca "Active Chats" "Sales actives" ::msgcat::mcset ca "Active" "Activa" ::msgcat::mcset ca "Add ->" "Afegir ->" ::msgcat::mcset ca "Add chats group in roster." "Afegir temporalmente grups de xerrada actius a la llista de contactes." ::msgcat::mcset ca "Add conference..." "Afegir xerrada en grup..." ::msgcat::mcset ca "Add group by regexp on JIDs..." "Crear grup per mitjà de regexp sobre JIDs..." ::msgcat::mcset ca "Add group" "Afegir grup" ::msgcat::mcset ca "Add Group..." "Afegir grup..." ::msgcat::mcset ca "Add item" "Afegir ítem" ::msgcat::mcset ca "Add JID" "Afegir JID" ::msgcat::mcset ca "Add list" "Afegir llista" ::msgcat::mcset ca "Add new user..." "Afegir nou usuari..." ::msgcat::mcset ca "Add roster group by JID regexp" "Afegir grup a la llista per mitjà de regexp sobre JID" ::msgcat::mcset ca "Add user..." "Afegir usuari..." ::msgcat::mcset ca "Add" "Afegir" ::msgcat::mcset ca "Address 2:" "Adreça 2:" ::msgcat::mcset ca "Address" "Adreça" ::msgcat::mcset ca "Address:" "Adreça:" ::msgcat::mcset ca "Address:" "Adreça:" ::msgcat::mcset ca "Admin tools" "Eines d'administració" ::msgcat::mcset ca "Affiliation" "Afiliació" ::msgcat::mcset ca "Alexey Shchepin" "Alexey Shchepin" ::msgcat::mcset ca "All Files" "Tots els fitxers" ::msgcat::mcset ca "Allow downloading" "Permetre baixar" ::msgcat::mcset ca "An error is occurred when searching in %s\n\n%s" "S'ha produït un error buscant en %s\n\n%s" ::msgcat::mcset ca "An error occurred when searching in %s\n\n%s" "S'ha produit un error al cercar a %s\n\n%s" ::msgcat::mcset ca "Announce" "Anunciar" ::msgcat::mcset ca "Are you sure to remove %s from roster?" "Estàs segur que vols eliminar %s de la teua llista?" ::msgcat::mcset ca "Are you sure to remove group '%s' from roster?" "Estas segur de que vols eliminar el grup '%s' de la llista de contactes?" ::msgcat::mcset ca "Attached file:" "Fitxer adjunt:" ::msgcat::mcset ca "Attached user:" "Usuari adjunt:" ::msgcat::mcset ca "Authentication failed" "Autenticació fallida" ::msgcat::mcset ca "Authentication failed: %s\nCreate new account?" "L'autenticació ha fallat: %s\nCrear compte nou?" ::msgcat::mcset ca "Authentication successful" "Autenticació correcta" ::msgcat::mcset ca "Authors:" "Autors:" ::msgcat::mcset ca "auto-away" "auto-absència" ::msgcat::mcset ca "Available groups" "Grups disponibles" ::msgcat::mcset ca "Avatar" "Avatar" ::msgcat::mcset ca "Avatar" "Avatar" ::msgcat::mcset ca "avatars" "avatars" ::msgcat::mcset ca "Away" "Absent" ::msgcat::mcset ca "Bad Request" "Petició errònia" ::msgcat::mcset ca "balloon help" "ajuda contextual" ::msgcat::mcset ca "Ban" "Bloquejar" ::msgcat::mcset ca "BBS:" ::msgcat::mcset ca "Begin date" "Data d'inici" ::msgcat::mcset ca "Begin date:" "Data d'inici:" ::msgcat::mcset ca "Birthday" "Data de naixement" ::msgcat::mcset ca "Birthday:" "Data de naixement:" ::msgcat::mcset ca "Blocking communication options." "Opcions de bloqueig de comunicació." ::msgcat::mcset ca "Browse error: %s" "Error al navegar: %s" ::msgcat::mcset ca "Browse" "Explorar" ::msgcat::mcset ca "Browse..." "Explorar..." ::msgcat::mcset ca "Browser" "Explorar" ::msgcat::mcset ca "browsing" "exploració" ::msgcat::mcset ca "bwidget workarounds" "arranjaments de bwidget" ::msgcat::mcset ca "Cache headlines on exit and restore on start." "Guardar les capçaleres al sortir, i carregarles al iniciar." ::msgcat::mcset ca "Can't authenticate: Remote server doesn't support\nplain or digest authentication method" "No es pot autenticar: el servidor remot no suporta\nmètodes d'autenticació simple o per resum" ::msgcat::mcset ca "Cancel" "Cancel·lar" ::msgcat::mcset ca "Cell:" "Mòbil:" ::msgcat::mcset ca "change message type to" "canviar el tipus del missatge a" ::msgcat::mcset ca "Change password" "Canviar contrasenya" ::msgcat::mcset ca "Change password..." "Canviar contrassenya..." ::msgcat::mcset ca "Change Presence Priority" "Canviar la prioritat de la presència" ::msgcat::mcset ca "Change priority..." "Canviar prioritat..." ::msgcat::mcset ca "Change security preferences for %s" "Canviar les preferències de seguretat per a %s" ::msgcat::mcset ca "Chat " "Xat" ::msgcat::mcset ca "Chat options." "Opcions de conversa." ::msgcat::mcset ca "Chat with %s" "Xerrar amb %s" ::msgcat::mcset ca "Chat" "Xerrar" ::msgcat::mcset ca "Chats" "Xats" ::msgcat::mcset ca "Chats:" "Xats:" ::msgcat::mcset ca "Check spell after every entered symbol." "Comprovar l'ortografia després d'introduir cada símbol." ::msgcat::mcset ca "Cipher" "Xifra" ::msgcat::mcset ca "Cipher:" "Xifra:" ::msgcat::mcset ca "City" "Ciutat" ::msgcat::mcset ca "City:" "Població:" ::msgcat::mcset ca "Clear bookmarks" "Borrar marcadors" ::msgcat::mcset ca "Clear chat window" "Buidar finestra de xat" ::msgcat::mcset ca "Clear" "Netejar" ::msgcat::mcset ca "Client Info" "Informació del client" ::msgcat::mcset ca "Client" "Client" ::msgcat::mcset ca "Client:" "Client:" ::msgcat::mcset ca "Close all tabs" "Tancar totes les pestanyes" ::msgcat::mcset ca "Close other tabs" "Tancar altres pestanyes" ::msgcat::mcset ca "Close tab" "Tancar pestanya" ::msgcat::mcset ca "Close Tkabber" "Tancar Tkabber" ::msgcat::mcset ca "Close" "Tancar" ::msgcat::mcset ca "Color message bodies in chat windows." "Color dels missatges en les finestres de xat" ::msgcat::mcset ca "Colors for tab alert levels." "Colors per als nivells d'alerta de les pestanyes." ::msgcat::mcset ca "Complete nickname" "Completar àlies" ::msgcat::mcset ca "Composing a reply" "Escrivint una resposta" ::msgcat::mcset ca "Computer" "Ordinador" ::msgcat::mcset ca "Condition" "Condició" ::msgcat::mcset ca "configuration" "configuració" ::msgcat::mcset ca "Configure room..." "Configurar sala..." ::msgcat::mcset ca "Configure service" "Configurar servei" ::msgcat::mcset ca "Configure" "Configurar" ::msgcat::mcset ca "Conflict" "Conflicte" ::msgcat::mcset ca "Connect via alternate server" "Connectar a través d'un servidor alternatiu" ::msgcat::mcset ca "Connect via HTTP polling" "Connectar per mitjanzant HTTP polling" ::msgcat::mcset ca "Connection closed" "Connexió tancada" ::msgcat::mcset ca "Connection" "Connexió" ::msgcat::mcset ca "Connection:" "Connexió:" ::msgcat::mcset ca "connections" "connexions" ::msgcat::mcset ca "Contact Information" "Informació de contacte" ::msgcat::mcset ca "continue processing rules" "continuar processant regles" ::msgcat::mcset ca "Copy selection to clipboard" "Copiar selecció al portapapers" ::msgcat::mcset ca "Copy URL to clipboard" "Copiar URL al portapapers" ::msgcat::mcset ca "Correct word" "Corregir paraula" ::msgcat::mcset ca "Country" "País" ::msgcat::mcset ca "Country:" "País:" ::msgcat::mcset ca "Create Room" "Crear sala" ::msgcat::mcset ca "Create room..." "Crear sala..." ::msgcat::mcset ca "Create" "Crear" ::msgcat::mcset ca "cryptographics" "criptografia" ::msgcat::mcset ca "Current groups" "Grups actuals" ::msgcat::mcset ca "Customization of the One True Jabber Client." "Personalització del Client Jabber Vertader." ::msgcat::mcset ca "Customize" "Personalitzar" ::msgcat::mcset ca "Data form" "Formulari de dades" ::msgcat::mcset ca "Data purported sent by %s can't be deciphered.\n\n%s." "Les dades pretesament enviades per %s no es poden desxifrar.\n\n%s." ::msgcat::mcset ca "Date:" "Data:" ::msgcat::mcset ca "day" "dia" ::msgcat::mcset ca "Day:" "Dia:" ::msgcat::mcset ca "days" "dies" ::msgcat::mcset ca "Default directory for downloaded files." "Directori per defecte per fitxers descarregats." ::msgcat::mcset ca "Default message type (if not specified explicitly)." "Tipus de missatge per defecte (si no és explicit)." ::msgcat::mcset ca "Default nested roster group delimiter." "Delimitador de grups anidats a la llista de contactes." ::msgcat::mcset ca "Default" "Per defecte" ::msgcat::mcset ca "Delay between getting focus and updating window or tab title in milliseconds." "Retard en milisegons entre la recepció del focus i la actualització de la finestra o pestanya." ::msgcat::mcset ca "Delete all" "Esborrar tots" ::msgcat::mcset ca "Delete message of the day" "Esborrar missatge del dia" ::msgcat::mcset ca "Delete seen" "Esborrar els llegits" ::msgcat::mcset ca "Delete" "Eliminar" ::msgcat::mcset ca "Description:" "Descripció:" ::msgcat::mcset ca "Description:" "Descripció:" ::msgcat::mcset ca "Description:" "Descripció:" ::msgcat::mcset ca "Destroy room" "Destruir sala" ::msgcat::mcset ca "Destroy" "Destruir" ::msgcat::mcset ca "Details" "Detalls" ::msgcat::mcset ca "Dir" "Dir" ::msgcat::mcset ca "Directory to store logs." "Directori on guardar registres." ::msgcat::mcset ca "Disabled\n" "Desactivat\n" ::msgcat::mcset ca "Disconnected" "Desconnectat" ::msgcat::mcset ca "Disconnected\n" "Desconnectat\n" ::msgcat::mcset ca "Discover service" "Descubrir servei" ::msgcat::mcset ca "Discovery" "Descobriment" ::msgcat::mcset ca "Display description of user status in chat windows." "Mostrar descripció de l'estat de l'usuari a les finestres de xat." ::msgcat::mcset ca "Display headlines in single/multiple windows." "Mostrar capçaleres en una única o en multiples finestres." ::msgcat::mcset ca "Display SSL warnings." "Mostrar alertes relatives a SSL." ::msgcat::mcset ca "Do http poll" "Fer enquesta http" ::msgcat::mcset ca "Do not display headline descriptions as tree nodes." "No mostrar descripcions de les capçaleres als nodes de l'arbre." ::msgcat::mcset ca "Do not disturb" "No molesteu" ::msgcat::mcset ca "Do nothing" "No fer res" ::msgcat::mcset ca "Do search" "Buscar" ::msgcat::mcset ca "Down" "Avall" ::msgcat::mcset ca "E-mail" "Correu electrònic" ::msgcat::mcset ca "E-mail:" "Correu electrònic:" ::msgcat::mcset ca "Edit %s color" "Editar color %s" ::msgcat::mcset ca "Edit admin list" "Editar llista d'administradors" ::msgcat::mcset ca "Edit admin list..." "Editar llista d'administradors..." ::msgcat::mcset ca "Edit ban list" "Editar llista de bloquejats" ::msgcat::mcset ca "Edit ban list..." "Editar llista de bloquejats..." ::msgcat::mcset ca "Edit chat user colors" " Editar colors dels usuaris" ::msgcat::mcset ca "Edit groups for %s" "Editar grups de %s" ::msgcat::mcset ca "Edit ignore list..." "Editar llista d'ignorats..." ::msgcat::mcset ca "Edit invisible list..." "Editar llista d'invisibles..." ::msgcat::mcset ca "Edit item..." "Editar ítem..." ::msgcat::mcset ca "Edit list" "Editar llista" ::msgcat::mcset ca "Edit member list" "Editar llista de membres" ::msgcat::mcset ca "Edit member list..." "Editar llista de membres..." ::msgcat::mcset ca "Edit moderator list" "Editar llista de moderadors" ::msgcat::mcset ca "Edit moderator list..." "Editar llista de moderadors..." ::msgcat::mcset ca "Edit my info..." "Editar la meua informació..." ::msgcat::mcset ca "Edit nick color..." "Editar color de l'àlies..." ::msgcat::mcset ca "Edit nick colors..." "Editar colors dels àlies..." ::msgcat::mcset ca "Edit nickname for %s" "Editar àlies de %s" ::msgcat::mcset ca "Edit owner list" "Editar llista de propietaris" ::msgcat::mcset ca "Edit owner list..." "Editar llista de propietaris..." ::msgcat::mcset ca "Edit privacy list" "Editar llista de privacitat" ::msgcat::mcset ca "Edit properties for %s" "Editar propietats de %s" ::msgcat::mcset ca "Edit rule" "Editar regla" ::msgcat::mcset ca "Edit security..." "Editar seguretat..." ::msgcat::mcset ca "Edit voice list" "Editar llista de veus" ::msgcat::mcset ca "Edit voice list..." "Editar llista de veus..." ::msgcat::mcset ca "Edit \$name list" "Editar llista \$name" ::msgcat::mcset ca "Edit \$val list" "Editar llista de \$val" ::msgcat::mcset ca "Edit" "Editar" ::msgcat::mcset ca "Email:" "Correu-e:" ::msgcat::mcset ca "emoticons" "emoticones" ::msgcat::mcset ca "Emphasize" "Enfatitzar" ::msgcat::mcset ca "Empty rule name" "Nom de la regla buit" ::msgcat::mcset ca "Enable chat window autoscroll only when last message is shown." "Activar el desplaçament intel·ligent automàtic una vegada ja s'ha mostrat l'últim missatge." ::msgcat::mcset ca "Enable highlighting plugin." "Activar plugin de resaltat." ::msgcat::mcset ca "Enable Jidlink transport %s." "Activar transport Jidlink %s." ::msgcat::mcset ca "Enable messages emphasize." "Activar l'énfasi als missatges." ::msgcat::mcset ca "Enable nested roster groups." "Activar grups anidats en la llista de contactes." ::msgcat::mcset ca "Enable rendering of XHTML messages." "Mostrar missatges XHTML" ::msgcat::mcset ca "Enabled\n" "Activat\n" ::msgcat::mcset ca "Encrypt traffic" "Xifrar tràfic" ::msgcat::mcset ca "Error %s" "Error %s" ::msgcat::mcset ca "Error %s: %s" "Error %s: %s" ::msgcat::mcset ca "Error displaying %s in browser\n\n%s" "Error mostrant %s en el navegador\n\n%s" ::msgcat::mcset ca "Error getting info: %s" "Error buscant informació: %s" ::msgcat::mcset ca "Error getting items: %s" "Error buscant elements: %s" ::msgcat::mcset ca "Error in signature verification software: %s." "Error en el programari de verificació de signatura: %s." ::msgcat::mcset ca "Error negotiate: %s" "Error negociant: %s" ::msgcat::mcset ca "Error requesting data: %s" "Error demanant dades: %s" ::msgcat::mcset ca "Error submitting data: %s" "Error enviant dades: %s" ::msgcat::mcset ca "Error" "Error" ::msgcat::mcset ca "Expiry date" "Data d'expiració" ::msgcat::mcset ca "Expiry date:" "Data d'expiració:" ::msgcat::mcset ca "Export roster..." "Exportar llista..." ::msgcat::mcset ca "Export to XHTML" "Exportar a XHTML" ::msgcat::mcset ca "Extended Away" "Molt absent" ::msgcat::mcset ca "Extended away" "Molt ausent" ::msgcat::mcset ca "extension management" "gestió d'extensions" ::msgcat::mcset ca "External program, which is to be executed to play sound. If empty, Snack library is required to play sound." "Programa extern que s'executarà per reproduir el so. Si es deixa buit, es requerirà la biblioteca Snack per reproducir so." ::msgcat::mcset ca "Extras from %s" "Extres de %s" ::msgcat::mcset ca "Extras from" "Extres de" ::msgcat::mcset ca "Failed to connect: %s" "No s'ha pogut conectar: %s" ::msgcat::mcset ca "Family Name" "Primer Cognom" ::msgcat::mcset ca "Family Name:" "Cognoms:" ::msgcat::mcset ca "Fax:" "Fax:" ::msgcat::mcset ca "File not found or not regular file: %s" "Fitxer no trobat o no és un fitxer normal" ::msgcat::mcset ca "File to send:" "Fitxer a enviar:" ::msgcat::mcset ca "File to Send:" "Fitxer per enviar:" ::msgcat::mcset ca "File Transfer options." "Opcions de transferència d'fitxers." ::msgcat::mcset ca "file transfer" "transmissió de fitxers" ::msgcat::mcset ca "Filters" "Filtres" ::msgcat::mcset ca "Filters..." "Filtres..." ::msgcat::mcset ca "First Name:" "Nom:" ::msgcat::mcset ca "Font to use in roster, chat windows etc." "Font per usar en les llistes de contactes, finestres de xat, etc." ::msgcat::mcset ca "Forbidden" "Prohibit" ::msgcat::mcset ca "Forward headline" "Reenviar titular" ::msgcat::mcset ca "forward message to" "reenviar el missatge a" ::msgcat::mcset ca "Forward to %s" "Reenviar a %s" ::msgcat::mcset ca "Forward..." "Reenviar... " ::msgcat::mcset ca "Free to chat" "Disponible per xerrar" ::msgcat::mcset ca "FreeHand" "Mà alçada" ::msgcat::mcset ca "From/To" "De/Per a" ::msgcat::mcset ca "From:" "De:" ::msgcat::mcset ca "Full Name" "Nom Complet" ::msgcat::mcset ca "Full Name:" "Nom complet:" ::msgcat::mcset ca "Generate event messages in MUC compatible conference rooms." "Generar missatges d'events en sales de conversa compatibles amb MUC." ::msgcat::mcset ca "Generate event messages" "Generar missatges d'esdeveniments" ::msgcat::mcset ca "Geographical position" "Localització geogràfica" ::msgcat::mcset ca "Get conference info failed: %s" "La petició d'informació de xerrada en grup ha fallat: %s" ::msgcat::mcset ca "Go" "Anar" ::msgcat::mcset ca "Google selection" "Selecció Google" ::msgcat::mcset ca "Got authentication mechanisms" "Obtinguts els mecanismes d'autenticació" ::msgcat::mcset ca "Got roster" "S'ha aconseguit la llista de contactes" ::msgcat::mcset ca "Got stream" "Missatge rebut" ::msgcat::mcset ca "Grant Administrative Privilege" "Concedir privilegis d'administrador" ::msgcat::mcset ca "Grant Administrative Privileges" "Concedir privilegis d'administrador" ::msgcat::mcset ca "Grant Membership" "Concedir pertinença" ::msgcat::mcset ca "Grant Moderator Privilege" "Concedir privilegis de moderador" ::msgcat::mcset ca "Grant Moderator Privileges" "Concedir privilegis de moderador" ::msgcat::mcset ca "Grant Ownership Privilege" "Concedir privilegis de propietari" ::msgcat::mcset ca "Grant Ownership Privileges" "Concedir privilegis de propietari" ::msgcat::mcset ca "Grant Voice" "Concedir veu" ::msgcat::mcset ca "Group:" "Grup:" ::msgcat::mcset ca "Group:" "Grup:" ::msgcat::mcset ca "Groupchat message highlighting plugin options." "Opcions del plugin de resaltat del missatges de sala de xerrada." ::msgcat::mcset ca "Headlines" "Titulars" ::msgcat::mcset ca "Help" "Ajuda" ::msgcat::mcset ca "Hide Main Window" "Amagar finestra principal" ::msgcat::mcset ca "Hide/Show roster" "Amagar/mostrar llista" ::msgcat::mcset ca "Highlight current nickname in messages." "Resaltar el teu àlies actual als missatges." ::msgcat::mcset ca "Highlight only whole words in messages." "Reslatar als missatges només paraules completes" ::msgcat::mcset ca "History for %s" "Historial de %s" ::msgcat::mcset ca "Home:" "Casa:" ::msgcat::mcset ca "hour" "hora" ::msgcat::mcset ca "hours" "hores" ::msgcat::mcset ca "HTTP Poll" "HTTP Poll" ::msgcat::mcset ca "HTTP proxy address." "Adreça del proxy HTTP." ::msgcat::mcset ca "HTTP proxy password." "Contrasenya del proxy HTTP." ::msgcat::mcset ca "HTTP proxy port." "Port del proxy HTTP." ::msgcat::mcset ca "HTTP proxy username." "Usuari del proxy HTTP." ::msgcat::mcset ca "I'm not online" "No estic connectat" ::msgcat::mcset ca "Idle for %s" "Inactiu durant %s" ::msgcat::mcset ca "Idle threshold in milliseconds after that Tkabber marks you as away." "Interval d'inactivitat després del qual Tkabber et marca automàticament com a absent." ::msgcat::mcset ca "Idle threshold in milliseconds after that Tkabber marks you as extended away." "Interval d'inactivitat després del qual Tkabber et marca automàticament com a molt absent." ::msgcat::mcset ca "Image" "Imatge" ::msgcat::mcset ca "Import roster..." "Importar llista..." ::msgcat::mcset ca "Indentation for pretty-printed XML subtags." "Indentar les etiquetes XML en la versió per imprimir." ::msgcat::mcset ca "Info/Query options." "Opcions Info/Query." ::msgcat::mcset ca "Information" "Informació" ::msgcat::mcset ca "Instructions" "Instruccions" ::msgcat::mcset ca "Internal Server Error" "Error intern del servidor" ::msgcat::mcset ca "Interval after error reply on request of participants list" "Interval després que s'haja produït un error en demanar la llista de participants" ::msgcat::mcset ca "Interval between requests of participants list" "Interval entre les peticions de llistes de participants" ::msgcat::mcset ca "Interval:" "Interval:" ::msgcat::mcset ca "invalid userstatus value " "valor d'estat d'usuari no vàlid " ::msgcat::mcset ca "Invisible" "Invisible" ::msgcat::mcset ca "Invite %s to conferences" "Convidar a %s a xerrada en grup" ::msgcat::mcset ca "Invite to conference..." "Convidar a xerrada en grup..." ::msgcat::mcset ca "Invite users to %s" "Convidar usuaris a %s" ::msgcat::mcset ca "Invite users..." "Convidar usuaris..." ::msgcat::mcset ca "Invite" "Convidar" ::msgcat::mcset ca "Invited to:" "Convidat a:" ::msgcat::mcset ca "IP address:" "Adreça IP:" ::msgcat::mcset ca "IQ" "IQ" ::msgcat::mcset ca "is now" "és ara" ::msgcat::mcset ca "ISDN:" "RDSI:" ::msgcat::mcset ca "Ispell dictionary encoding. If it is empty, system encoding is used." "Codificació del diccionari ispell. Si ho deixes buit, s'utilitzarà la codificació per defecte del sistema." ::msgcat::mcset ca "Ispell dictionary. If it is empty, default dictionary is used." "Diccionari ispell. Si ho deixes buit, s'utilitzarà el diccionari per defecte." ::msgcat::mcset ca "Issuer" "Emissor" ::msgcat::mcset ca "Issuer:" "Issuer:" ::msgcat::mcset ca "Jabber Browser" "Explorador Jabber" ::msgcat::mcset ca "jabber chat" "xat jabber" ::msgcat::mcset ca "Jabber Discovery" "Descobriment Jabber" ::msgcat::mcset ca "jabber groupchats" "xats en grup jabber" ::msgcat::mcset ca "jabber iq" "jabber iq" ::msgcat::mcset ca "jabber presence" "presència jabber" ::msgcat::mcset ca "jabber registration" "registre jabber" ::msgcat::mcset ca "jabber xml" ::msgcat::mcset ca "JBrowser" "Explorador Jabber" ::msgcat::mcset ca "JID regexp:" "JID regexp:" ::msgcat::mcset ca "JID" "JID" ::msgcat::mcset ca "JID:" "JID:" ::msgcat::mcset ca "JID:" "JID:" ::msgcat::mcset ca "Jidlink connection closed" "Connexió Jidlink tancada" ::msgcat::mcset ca "Jidlink" "Jidlink" ::msgcat::mcset ca "jidlink" "jidlink" ::msgcat::mcset ca "Join conference" "Unir-se a la conferència" ::msgcat::mcset ca "Join failed: %s" "L'entrada ha fallat: %s" ::msgcat::mcset ca "Join Group Chat..." "Entrar a sala de conversa..." ::msgcat::mcset ca "Join group dialog data (groups)." "Dades del diàleg d'entrada a sala (grups)" ::msgcat::mcset ca "Join group dialog data (nicks)." "Dades del diàleg d'entrada a sala (àlies)" ::msgcat::mcset ca "Join group dialog data (servers)." "Dades del diàleg d'entrada a sala (servidors)" ::msgcat::mcset ca "Join group" "Entrar en grup" ::msgcat::mcset ca "Join group..." "Entrar en grup..." ::msgcat::mcset ca "Join groupchat" "Entrar en sala" ::msgcat::mcset ca "Join" "Entrar" ::msgcat::mcset ca "Join..." "Entrar..." ::msgcat::mcset ca "kde" ::msgcat::mcset ca "Keep trying" "Seguir intentant-ho" ::msgcat::mcset ca "Key ID" "ID de la clau" ::msgcat::mcset ca "Key:" "Clau:" ::msgcat::mcset ca "Kick" "Expulsar" ::msgcat::mcset ca "last %s%s: %s" "últim %s%s: %s" ::msgcat::mcset ca "last %s%s:" "últim %s%s:" ::msgcat::mcset ca "Last Activity or Uptime" "Darrera activitat o temps en marxa" ::msgcat::mcset ca "Last activity" "Darrera activitat" ::msgcat::mcset ca "Last Name:" "Cognom:" ::msgcat::mcset ca "Latitude: %.2f  Longitude: %.2f" "Latitud: %.2f  Longitud: %.2f" ::msgcat::mcset ca "List name" "Llistar nom" ::msgcat::mcset ca "List of browsed JIDs." "Llista de JIDs explorats." ::msgcat::mcset ca "List of discovered JID nodes." "Llista de nodes del JID descoberts." ::msgcat::mcset ca "List of discovered JIDs." "Llista de JIDs descoberts." ::msgcat::mcset ca "List of JIDs to whom headlines have been sent." "Llista de JIDs als que s'ha enviat titulars de la notícia." ::msgcat::mcset ca "List of logout reasons." "Llista de raons de desconnexió." ::msgcat::mcset ca "List of message destination JIDs." "Llista dels JIDs destinataris." ::msgcat::mcset ca "List of users for userinfo." "Llista de usuaris per a userinfo." ::msgcat::mcset ca "Load Image" "Carregar imatge" ::msgcat::mcset ca "Location" "Localització" ::msgcat::mcset ca "Log in" "Iniciar" ::msgcat::mcset ca "Log in..." "Connectar..." ::msgcat::mcset ca "Log out with reason..." "Desconnectar per la raó..." ::msgcat::mcset ca "Log out" "Desconnectar" ::msgcat::mcset ca "Log out" "Tancar sessió" ::msgcat::mcset ca "Logging options." "Opcions d'enregistrament." ::msgcat::mcset ca "Login options." "Opciones d'inici de sessió." ::msgcat::mcset ca "Login" "Iniciar sessió" ::msgcat::mcset ca "Logout with reason" "Tancar sessió per una raó" ::msgcat::mcset ca "Logout" "Tancar sessió" ::msgcat::mcset ca "Longitude:" "Longitud:" ::msgcat::mcset ca "Main window:" "Finestra principal:" ::msgcat::mcset ca "Manually edit rules..." "Editar les regles manualment..." ::msgcat::mcset ca "Mark all seen" "Marcar tots com a llegits" ::msgcat::mcset ca "Mark all unseen" "Marcar tots com a no llegits" ::msgcat::mcset ca "Marshall T. Rose" "Marshall T. Rose" ::msgcat::mcset ca "Match by regexp" "Patró per regexp" ::msgcat::mcset ca "Match case..." "Majúscules/Minúscules..." ::msgcat::mcset ca "Maximum number of characters in the history in MUC compatible conference rooms." "Número màxim de caràcters en l'historial de les sales de xat compatibles amb MUC" ::msgcat::mcset ca "Maximum number of stanzas in the history in MUC compatible conference rooms." "Número màxim de stanzas en l'historial de les sales de xat compatibles amb MUC" ::msgcat::mcset ca "Maximum poll interval." "Interval màxim de Poll." ::msgcat::mcset ca "Maximum Poll Interval." "Interval màxim de Poll." ::msgcat::mcset ca "Maximum Poll Time." "Temps màxim d'enquesta." ::msgcat::mcset ca "Message and Headline options." "Opcions de missatge i de capçalera." ::msgcat::mcset ca "Message archive" "Arxiu de missatges" ::msgcat::mcset ca "Message body" "Cos del missatge" ::msgcat::mcset ca "Message delivered to %s" "Missatge entregat a %s" ::msgcat::mcset ca "Message delivered" "Missatge entregat" ::msgcat::mcset ca "Message displayed to %s" "Missatge mostrat a %s" ::msgcat::mcset ca "Message displayed" "Missatge mostrat" ::msgcat::mcset ca "message filters" "filtres de missatges" ::msgcat::mcset ca "Message filters..." "filtres de missatges..." ::msgcat::mcset ca "Message from %s" "Missatge de %s" ::msgcat::mcset ca "Message from" "Missatge de" ::msgcat::mcset ca "Message Recorder:" "Contestador:" ::msgcat::mcset ca "Message stored on %s's server" "Missatge guardat en el servidor de %s" ::msgcat::mcset ca "Message stored on the server" "Missatge guardat en el servidor" ::msgcat::mcset ca "Message" "Missatge" ::msgcat::mcset ca "message/headline" "missatge/titular" ::msgcat::mcset ca "Messages" "Missatges" ::msgcat::mcset ca "Michail Litvak" "Michail Litvak" ::msgcat::mcset ca "Middle Name" "Segón Nom" ::msgcat::mcset ca "Middle Name:" "Segon nom:" ::msgcat::mcset ca "Minimize" "Minimitzar" ::msgcat::mcset ca "Minimum poll interval." "Interval mínim de Poll" ::msgcat::mcset ca "Minimum Poll Interval." "Interval mínim de Poll." ::msgcat::mcset ca "Minimum Poll Time." "Temps mínim d'enquesta." ::msgcat::mcset ca "minute" "minut" ::msgcat::mcset ca "minutes" "minuts" ::msgcat::mcset ca "Misc:" "Misc:" ::msgcat::mcset ca "Modem:" "Mòdem:" ::msgcat::mcset ca "Moderators" "Moderadors" ::msgcat::mcset ca "Month:" "Mes:" ::msgcat::mcset ca "Move down" "Desplaçar cap avall" ::msgcat::mcset ca "Move up" "Desplaçar cap amunt" ::msgcat::mcset ca "Move" "Moure" ::msgcat::mcset ca "Moving to extended away" "Passant a molt absent" ::msgcat::mcset ca "MUC" "MUC" ::msgcat::mcset ca "multi-user chat" "converses multiusuari" ::msgcat::mcset ca "Mute sound notification." "Enmudir notificació sonora." ::msgcat::mcset ca "Mute sound notifying." "Notificacions de so mudes." ::msgcat::mcset ca "Mute sound when displaying delayed groupchat messages." "So mut al mostrar missatges amb retard de sales de conversa." ::msgcat::mcset ca "Mute sound when displaying delayed personal chat messages." "So mut al mostrar missatges amb retard de converses privades." ::msgcat::mcset ca "Mute" "Mut" ::msgcat::mcset ca "my status is" "el meu estat és" ::msgcat::mcset ca "Name" "Nom" ::msgcat::mcset ca "Name: " "Nom:" ::msgcat::mcset ca "Name: " "Nom:" ::msgcat::mcset ca "Name:" "Nom:" ::msgcat::mcset ca "negotiation" "negociació" ::msgcat::mcset ca "New group name:" "Nou nom del grup:" ::msgcat::mcset ca "New password:" "Contrasenya nova:" ::msgcat::mcset ca "New passwords do not match" "Les contrasenyes noves no coincideixen" ::msgcat::mcset ca "Next bookmark" "Marcador següent" ::msgcat::mcset ca "Next highlighted" "Següent resaltat" ::msgcat::mcset ca "Nick" "Àlies" ::msgcat::mcset ca "Nick:" "Àlies:" ::msgcat::mcset ca "Nickname" "Àlies" ::msgcat::mcset ca "Nickname:" "Àlies:" ::msgcat::mcset ca "Nickname:" "Àlies:" ::msgcat::mcset ca "Nickname:" "Àlies:" ::msgcat::mcset ca "No active list" "No hi ha cap llista activa" ::msgcat::mcset ca "No active" "No activa" ::msgcat::mcset ca "No avatar to store" "No hi ha avatars per guardar" ::msgcat::mcset ca "No conferences in progress..." "No hi ha xerrades en grup ara mateix..." ::msgcat::mcset ca "No default list" "No hi ha llista per defecte" ::msgcat::mcset ca "No users in roster..." "No hi ha usuaris a la llista..." ::msgcat::mcset ca "Node:" "Node:" ::msgcat::mcset ca "None" "Cap" ::msgcat::mcset ca "Normal" "Normal" ::msgcat::mcset ca "Not Acceptable" "No acceptable" ::msgcat::mcset ca "Not Allowed" "No permès" ::msgcat::mcset ca "Not Found" "No trobat" ::msgcat::mcset ca "Not Implemented" "No implementat" ::msgcat::mcset ca "Not logged in" "No connectat" ::msgcat::mcset ca "Number of groupchat messages to expire nick completion according to the last personally addressed message." "Nombre de missatges a la sala de xarra des de que un participant va eixir fins que el seu àlies ja no es completa." ::msgcat::mcset ca "Number of HTTP poll client security keys to send before creating new key sequence." "Número de claus de seguretat del client de HTTP Poll que s'envien abans de crear una nova sequència de clau." ::msgcat::mcset ca "Offline" "Desconnectat" ::msgcat::mcset ca "OK" "OK" ::msgcat::mcset ca "Old password is incorrect" "La contrasenya antiga és incorrecta" ::msgcat::mcset ca "Old password:" "Contrasenya antiga:" ::msgcat::mcset ca "One window per bare JID" "Una finestra per JID simple" ::msgcat::mcset ca "One window per full JID" "Una finestra per JID complet" ::msgcat::mcset ca "One window per JID" "Una finestra per JID" ::msgcat::mcset ca "One window per JID/resource" "Una finestra per JID/recurs" ::msgcat::mcset ca "Online" "Connectat" ::msgcat::mcset ca "Open raw XML window" "Obrir finestra d'XML cru" ::msgcat::mcset ca "Open statistics monitor" "Obrir monitor d'estadístiques" ::msgcat::mcset ca "Open" "Obrir" ::msgcat::mcset ca "Opening DTCP active connection" "Obrint connexió activa DTCP" ::msgcat::mcset ca "Opening DTCP passive connection" "Obrint connexió passiva DTCP" ::msgcat::mcset ca "Opening IBB connection" "Obrint connexió IBB" ::msgcat::mcset ca "Opening Jidlink connection" "Obrint connexió Jidlink" ::msgcat::mcset ca "Opening SI connection" "Obrint conexió SI" ::msgcat::mcset ca "Opening SOCKS5 listening socket" "Obrint socket d'escolta SOCKS5" ::msgcat::mcset ca "Options for Conference Info module, that allows you to see list of participants in roster popup, regardless of whether you are currently joined with the conference." "Opcions del mòdul d'informació sobre xerrades en grup, que permet veure la llista de participants en la finestra desplegable, independenment que hi estigues participant o no." ::msgcat::mcset ca "Options for external play program" "Opcions del programa extern de reproducció" ::msgcat::mcset ca "Options for main interface." "Opcions de la interfície principal." ::msgcat::mcset ca "Options for module that automatically marks you as away after idle threshold." "Opcions del mòdul que et posa automàticament com a absent desprès d'un temps inactiu." ::msgcat::mcset ca "Options for Raw XML Input module, which allows you to monitor incoming/outgoing traffic from connection to server and send custom XML stanzas." "Opcions del módul d'introducció d'XML cru, que permet monitoritzar el tràfic d'entrada i sortida amb el servidor i enviar XML stanzas" ::msgcat::mcset ca "Organization" "Organització" ::msgcat::mcset ca "OS:" "SO:" ::msgcat::mcset ca "Pager:" "Busca:" ::msgcat::mcset ca "Parent group:" "Grup pare:" ::msgcat::mcset ca "Parent groups:" "Grups pare:" ::msgcat::mcset ca "Participants" "Participants" ::msgcat::mcset ca "Passphrase:" "Contrasenya:" ::msgcat::mcset ca "Password (v2 only):" "Contrasenya (només v2)" ::msgcat::mcset ca "Password change failed: %s" "El canvi de contrasenya ha fallat: %s" ::msgcat::mcset ca "Password is changed" "Contrasenya canviada" ::msgcat::mcset ca "Password." "Contrasenya." ::msgcat::mcset ca "Password:" "Contrasenya:" ::msgcat::mcset ca "Password:" "Contrasenya:" ::msgcat::mcset ca "Path to the ispell executable." "Ruta per a l'executable ispell." ::msgcat::mcset ca "Payment Required" "Es requereix pagament" ::msgcat::mcset ca "PCS:" ::msgcat::mcset ca "Periodically browse roster conferences" "Explorar periòrdicament la llista per a xerrades en grup" ::msgcat::mcset ca "Personal " "Personal" ::msgcat::mcset ca "Personal" "Personal" ::msgcat::mcset ca "Phone:" "Telèfon:" ::msgcat::mcset ca "Phones" "Telèfons" ::msgcat::mcset ca "Photo" "Foto" ::msgcat::mcset ca "Please define \$BROWSER" "Per favor, defineix \$BROWSER" ::msgcat::mcset ca "Please enter passphrase" "Per favor, introdueix la contrasenya" ::msgcat::mcset ca "Please join %s" "Per favor, entra en %s" ::msgcat::mcset ca "Please try again" "Per favor, torna a intentar-ho" ::msgcat::mcset ca "plugin management" "gestió de plugins" ::msgcat::mcset ca "Port:" "Port:" ::msgcat::mcset ca "Postal Code:" "Codi postal:" ::msgcat::mcset ca "Preferred:" "Preferent:" ::msgcat::mcset ca "Prefix" "Prefix" ::msgcat::mcset ca "Prefix:" "Prefix:" ::msgcat::mcset ca "Presence id signed" "ID de presència signat" ::msgcat::mcset ca "Presence is signed" "La presència està signada" ::msgcat::mcset ca "Presence" "Presència" ::msgcat::mcset ca "presence" "presència" ::msgcat::mcset ca "Presence-in" "Presència-entra" ::msgcat::mcset ca "Presence-out" "Presència-surt" ::msgcat::mcset ca "Pretty print incoming and outgoing XML stanzas." "Formatar les XML stanzas per imprimir." ::msgcat::mcset ca "Pretty print XML" "XML formatat per imprimir" ::msgcat::mcset ca "Prev bookmark" "Marcador anterior" ::msgcat::mcset ca "Prev highlighted" "Resaltat anterior" ::msgcat::mcset ca "Previous/Next history message" "Missatge anterior/següent" ::msgcat::mcset ca "Previous/Next tab" "Pestanyar anterior/següent" ::msgcat::mcset ca "Priority." "Prioritat." ::msgcat::mcset ca "Priority:" "Prioritat:" ::msgcat::mcset ca "Privacy list is activated" "La llista de privacitat està activada" ::msgcat::mcset ca "Privacy list is not activated" "La llista de privacitat no està activada" ::msgcat::mcset ca "Privacy lists" "Llistes de privacitat" ::msgcat::mcset ca "Privacy rules" "Regles de privacitat" ::msgcat::mcset ca "privacy rules" "regles de privacitat" ::msgcat::mcset ca "Privacy rules..." "Regles de privacitat..." ::msgcat::mcset ca "Profile on" "Perfil" ::msgcat::mcset ca "Profile report" "Informe de perfil" ::msgcat::mcset ca "Profile" "Perfil" ::msgcat::mcset ca "Profiles" "Perfils" ::msgcat::mcset ca "Proxy Login:" "Usuari del proxy:" ::msgcat::mcset ca "Proxy Password:" "Contrasenya del proxy:" ::msgcat::mcset ca "Proxy Port:" "Port del proxy:" ::msgcat::mcset ca "Proxy Server:" "Servidor proxy:" ::msgcat::mcset ca "Proxy" ::msgcat::mcset ca "Question" "Pregunta" ::msgcat::mcset ca "Quick Help" "Ajuda ràpida" ::msgcat::mcset ca "Quick help" "Ajuda ràpida" ::msgcat::mcset ca "Quick help..." "Ajuda ràpida..." ::msgcat::mcset ca "Quit" "Sortir" ::msgcat::mcset ca "Quote" "Citar" ::msgcat::mcset ca "Raise new tab." "Crear nova pestanya." ::msgcat::mcset ca "Raw XML input" "Introducció d'XML cru" ::msgcat::mcset ca "Raw XML" "XML cru" ::msgcat::mcset ca "Reason" "Raó" ::msgcat::mcset ca "Reason:" "Raó:" ::msgcat::mcset ca "Receive file from %s" "Rebre fitxer de %s" ::msgcat::mcset ca "Receive" "Rebre" ::msgcat::mcset ca "Received/Sent" "Rebuts/enviats" ::msgcat::mcset ca "Receiving file failed: %s" "Error recivint el fitxer: %s" ::msgcat::mcset ca "Redirect" "Redirecció" ::msgcat::mcset ca "Redo" "Refer" ::msgcat::mcset ca "Register in %s" "Registrar-se en %s" ::msgcat::mcset ca "Register" "Registrar" ::msgcat::mcset ca "Registration failed: %s" "El registre ha fallat: %s" ::msgcat::mcset ca "Registration is successful!" "El registre s'ha completat amb éxit!" ::msgcat::mcset ca "Registration is successful!" "Registre satisfactori!" ::msgcat::mcset ca "Registration Required" "Es requereix registre" ::msgcat::mcset ca "Registration: %s" "Registre: %s" ::msgcat::mcset ca "Remote Server Error" "Error del servidor remot" ::msgcat::mcset ca "Remote Server Timeout" "Temps d'espera del servidor remot esgotat" ::msgcat::mcset ca "Remove from list" "Eliminar de la llista" ::msgcat::mcset ca "Remove list" "Eliminar llista" ::msgcat::mcset ca "Remove" "Eliminar" ::msgcat::mcset ca "Remove..." "Eliminar..." ::msgcat::mcset ca "Rename roster group" "Reanomenar grup de la llista de contactes" ::msgcat::mcset ca "Rename..." "Canviar el nom..." ::msgcat::mcset ca "Repeat new password:" "Repeteix la contrasenya nova:" ::msgcat::mcset ca "Replace opened connections" "Remplaçar connexions obertes" ::msgcat::mcset ca "Replace opened connections." "Remplaçar connexions obertes." ::msgcat::mcset ca "Reply subject:" "Tema de la resposta:" ::msgcat::mcset ca "Reply to current time (jabber:iq:time) requests." "Respondre les peticions sobre el temps actual (jabber:iq:time)" ::msgcat::mcset ca "Reply to idle time (jabber:iq:last) requests." "Respondre les peticions sobre el temps que portes absent (jabber:iq:last)" ::msgcat::mcset ca "Reply to version (jabber:iq:version) requests." "Respondre les peticions sobre la versió del programa (jabber:iq:version)" ::msgcat::mcset ca "reply with" "contestar amb" ::msgcat::mcset ca "Reply" "Contestar" ::msgcat::mcset ca "Report the list of current MUC rooms on disco#items query." "Informar de les sales MUC actuals al sol·licitar disco#items." ::msgcat::mcset ca "Request failed: %s" "Petició fallida: %s" ::msgcat::mcset ca "Request only unseen (which aren't displayed in the chat window) messages in the history in MUC compatible conference rooms." "Demanar només els missatges no visualitzats (que no es mostrin en la finestra de xat) en l'historial de les sales de xat compaitbles MUC" ::msgcat::mcset ca "Request Timeout" "Temps d'espera de la petició esgotat" ::msgcat::mcset ca "Request" "Sol·licitar" ::msgcat::mcset ca "Requesting filter rules: %s" "Demanant regles de filtres: %s" ::msgcat::mcset ca "Requesting privacy list: %s" "Demanant llista de privacitat: %s" ::msgcat::mcset ca "Requesting privacy rules: %s" "Sol·licitant regles de privacitat: %s" ::msgcat::mcset ca "Requesting \$name list: %s" "Sol·licitant llista \$name: %s" ::msgcat::mcset ca "Reset to Current" "Restablir a Actual" ::msgcat::mcset ca "Reset to Default" "Restablir a Per Defecte" ::msgcat::mcset ca "Reset to Saved" "Restablir a Guardada" ::msgcat::mcset ca "Resource." "Recurs." ::msgcat::mcset ca "Resource:" "Recurs:" ::msgcat::mcset ca "Resubscribe to all users in group..." "Tornar a subscriure's a tots els usuaris del grup..." ::msgcat::mcset ca "Resubscribe" "Tornar a subscriure's" ::msgcat::mcset ca "Retry to connect forever." "Intentar conectar infinitament." ::msgcat::mcset ca "Returning from auto-away" "Tornant d'auto-absència" ::msgcat::mcset ca "Revoke Administrative Privilege" "Revocar privilegis d'administrador" ::msgcat::mcset ca "Revoke Administrative Privileges" "Revocar privilegis d'administrador" ::msgcat::mcset ca "Revoke Membership" "Revocar pertinença" ::msgcat::mcset ca "Revoke Moderator Privilege" "Revocar privilegis de moderador" ::msgcat::mcset ca "Revoke Moderator Privileges" "Revocar privilegis de moderador" ::msgcat::mcset ca "Revoke Ownership Privilege" "Revocar privilegis de propietari" ::msgcat::mcset ca "Revoke Ownership Privileges" "Revocar privilegis de propietari" ::msgcat::mcset ca "Revoke Voice" "Revocar veu" ::msgcat::mcset ca "Role" "Rol" ::msgcat::mcset ca "Role:" "Rol:" ::msgcat::mcset ca "Roster Files" "Arxius de llista de contactes" ::msgcat::mcset ca "Roster of %s" "Llista de contactes de %s" ::msgcat::mcset ca "Roster options." "Opcions de la llista de contactes." ::msgcat::mcset ca "Roster" "Llista" ::msgcat::mcset ca "rosters" "llistes" ::msgcat::mcset ca "Rule name already exists" "El nom de la regla ja existeix" ::msgcat::mcset ca "Rule Name:" "Nom de la regla:" ::msgcat::mcset ca "SASL Certificate:" "Certificat SASL:" ::msgcat::mcset ca "SASL Port:" "Port SASL:" ::msgcat::mcset ca "SASL" ::msgcat::mcset ca "Save as:" "Guardar com:" ::msgcat::mcset ca "Scroll chat window up/down" "Desplaçar finestra de xat amunt/avall" ::msgcat::mcset ca "Search again" "Tornar a buscar" ::msgcat::mcset ca "Search direction" "Direcció de busca" ::msgcat::mcset ca "Search in %s" "Cercar a %s" ::msgcat::mcset ca "Search in %s: No items found" "Cerca a %s: No s'han trobat resultats" ::msgcat::mcset ca "Search in %s: No matching items found" "Cerca en %s: No s'han trobat elements que coincideixin" ::msgcat::mcset ca "Search in" "Buscar en" ::msgcat::mcset ca "Search" "Cercar" ::msgcat::mcset ca "Search: %s" "Cerca: %s" ::msgcat::mcset ca "searching" "buscant" ::msgcat::mcset ca "second" "segon" ::msgcat::mcset ca "seconds" "segons" ::msgcat::mcset ca "Select Key for Signing Traffic" "Seleccionar la clau per a signar el tràfic" ::msgcat::mcset ca "Select" "Sel.leccionar" ::msgcat::mcset ca "Send broadcast message..." "Enviar missatge de difusió..." ::msgcat::mcset ca "Send contacts to %s" "Enviar contactes a %s" ::msgcat::mcset ca "Send contacts to" "Enviar contactes a" ::msgcat::mcset ca "Send custom presence" "Enviar presència personalitzada" ::msgcat::mcset ca "Send file request failed: %s" "Error solicitant l'enviament del fitxer: %s" ::msgcat::mcset ca "Send file to %s" "Enviar fitxer a %s" ::msgcat::mcset ca "Send file via HTTP..." "Enviar fitxer via HTTP..." ::msgcat::mcset ca "Send file via Jidlink..." "Enviar fitxer a través de Jidlink..." ::msgcat::mcset ca "Send file via SI..." "Enviar fitxer via SI..." ::msgcat::mcset ca "Send file..." "Enviar fitxer..." ::msgcat::mcset ca "Send message of the day..." "Enviar missatge del dia..." ::msgcat::mcset ca "Send message to %s" "Enviar missatge a %s" ::msgcat::mcset ca "Send message to all users in group..." "Enviar missatge a tots els usuaris del grup..." ::msgcat::mcset ca "Send message to group %s" "Enviar missatge al grup %s" ::msgcat::mcset ca "Send message to group" "Enviar missatge al grup" ::msgcat::mcset ca "Send message" "Enviar missatge" ::msgcat::mcset ca "Send message..." "Enviar missatge..." ::msgcat::mcset ca "Send subscription to " "Enviar subscripció a " ::msgcat::mcset ca "Send subscription to %s" "Enviar subscripció a %s" ::msgcat::mcset ca "Send subscription" "Enviar subscripció" ::msgcat::mcset ca "Send to server" "Enviar al servidor" ::msgcat::mcset ca "Send users..." "Enviar Usuaris..." ::msgcat::mcset ca "Send" "Enviar" ::msgcat::mcset ca "Send" "Enviar" ::msgcat::mcset ca "Sending \$name list: %s" "Enviant llista \$name: %s" ::msgcat::mcset ca "Sergei Golovan" "Sergei Golovan" ::msgcat::mcset ca "Serial number" "Nombre de sèrie" ::msgcat::mcset ca "Serial number:" "Nombre de sèrie:" ::msgcat::mcset ca "Server name or IP-address." "Nom del servidor o adreça IP." ::msgcat::mcset ca "Server name." "Servidor." ::msgcat::mcset ca "Server port." "Port." ::msgcat::mcset ca "Server Port:" "Port del servidor:" ::msgcat::mcset ca "Server:" "Servidor:" ::msgcat::mcset ca "Server:" "Servidor:" ::msgcat::mcset ca "service discovery" "descobriment de serveis" ::msgcat::mcset ca "Service Discovery" "Descobriment de Servicis" ::msgcat::mcset ca "Service info" "Informació del servei" ::msgcat::mcset ca "Service statistics" "Estadístiques del servei" ::msgcat::mcset ca "Service Unavailable" "Servei no disponible" ::msgcat::mcset ca "Services" "Serveis" ::msgcat::mcset ca "Set bookmark" "Guardar marcador" ::msgcat::mcset ca "Set for Current Session" "Definició per a la sessió actual" ::msgcat::mcset ca "Set for Future Sessions" "Definició per a sessions futures" ::msgcat::mcset ca "Set" "Fixar" ::msgcat::mcset ca "Show console" "Mostrar consola" ::msgcat::mcset ca "Show Console" "Mostrar consola" ::msgcat::mcset ca "Show detailed info on conference room members in roster item tooltips." "Mostrar informació detallada sobre el membres de les sales de xerrada als 'tooltips' de la llista de contactes." ::msgcat::mcset ca "Show emoticons" "Mostrar emoticones" ::msgcat::mcset ca "Show history" "Mostrar historial" ::msgcat::mcset ca "Show info" "Mostrar informació" ::msgcat::mcset ca "Show IQ requests in the status line." "Mostrar peticions IQ en la línia d'estat" ::msgcat::mcset ca "Show Main Window" "Mostrar finestra principal" ::msgcat::mcset ca "Show menu tearoffs when possible." "Mostrar tires en els menús quan sigui possible" ::msgcat::mcset ca "Show native icons for contacts, connected to transports/services in roster." "Mostrar icones natives dels contactes conectats amb un transport a al llista de contactes." ::msgcat::mcset ca "Show native icons for transports/services in roster." "Mostrar icones natives dels transports/servics a la llista de contactes." ::msgcat::mcset ca "Show number of unread messages in tab titles." "Mostrar la quantitat de missatges sense llegir al títol de la pestanya." ::msgcat::mcset ca "Show offline users" "Mostrar contactes desconectats" ::msgcat::mcset ca "Show online users only" "Mostrar només usuaris connectats" ::msgcat::mcset ca "Show only online users in roster." "Mostrar a la llista de contactes només els conectats." ::msgcat::mcset ca "Show presence bar" "Mostrar barra de presència" ::msgcat::mcset ca "Show presence bar." "Mostrar barra de presència." ::msgcat::mcset ca "Show subscription type in roster item tooltips." "Mostrar tipus de subscripció al 'tooltip' a la llista de contactes." ::msgcat::mcset ca "Show toolbar" "Mostrar barra d'eines" ::msgcat::mcset ca "Show Toolbar." "Mostrar barra d'eines." ::msgcat::mcset ca "Show user info" "Mostrar informació d'usuari" ::msgcat::mcset ca "Show user info..." "Mostrar informació d'usuari..." ::msgcat::mcset ca "Show" "Mostrar" ::msgcat::mcset ca "SI connection closed" "Connexió SI tancada" ::msgcat::mcset ca "Single window" "Finestra única" ::msgcat::mcset ca "Size:" "Mida:" ::msgcat::mcset ca "Smart autoscroll" "Desplaçament automàtic intel·ligent" ::msgcat::mcset ca "Sort" "Ordenar" ::msgcat::mcset ca "Sound options." "Opcions de so." ::msgcat::mcset ca "Sound theme. If it starts with \"/\" or \"~\" then it is considered as theme directory. Otherwise theme is loaded from \"sounds\" directory of Tkabber tree." "Tema de so. Si comença per \"/\" o \"~\", es considerarà com a directori de temes. Si no, el tema es carregarà des del directori \"sounds\" de l'arbre de directoris de Tkabber." ::msgcat::mcset ca "Sound" "So" ::msgcat::mcset ca "sound" "so" ::msgcat::mcset ca "Spell check options." "Opcions de correcció ortogràfica." ::msgcat::mcset ca "SSL CA file (optional)." "Fitxer SSL CA (opcional)." ::msgcat::mcset ca "SSL certificate expired" "Certificat SSL expirat" ::msgcat::mcset ca "SSL certificate file (optional)." "Fitxer de certificat SSL (opcional)." ::msgcat::mcset ca "SSL Certificate:" "Certificat SSL:" ::msgcat::mcset ca "SSL disabled" "SSL desactivat" ::msgcat::mcset ca "SSL enabled" "SSL activat" ::msgcat::mcset ca "SSL Info" ::msgcat::mcset ca "SSL port." "Port SSL." ::msgcat::mcset ca "SSL Port:" "Port SSL:" ::msgcat::mcset ca "SSL private key file (optional)." "Fitxer de clau privada SSL (opcional)." ::msgcat::mcset ca "SSL" ::msgcat::mcset ca "Start chat" "Començar xat" ::msgcat::mcset ca "Starting auto-away" "Passant a auto-absència" ::msgcat::mcset ca "State " "Comunitat" ::msgcat::mcset ca "State" "Estat" ::msgcat::mcset ca "State:" "Província/comarca:" ::msgcat::mcset ca "Statistics monitor" "Monitor d'estadístiques" ::msgcat::mcset ca "Statistics" "Estadístiques" ::msgcat::mcset ca "Stop autoscroll" "Parar el desplaçament automàtic" ::msgcat::mcset ca "Stop chat window autoscroll." "Desactivar el desplaçament automàtic en finestres de conversa." ::msgcat::mcset ca "Store group chats logs." "Guardar registres de converses en grup." ::msgcat::mcset ca "Store private chats logs." "Guardar registres de converses privades." ::msgcat::mcset ca "store this message offline" "guardar aquest missatge fora de línia" ::msgcat::mcset ca "Stored collapsed roster groups." "Emmagatzemar l'estat dels grups colapsats en la llista de contactes." ::msgcat::mcset ca "Stored show offline roster groups." "Emmagatzemar si es mostra o no els grups desconnectats en la llista de contactes." ::msgcat::mcset ca "Stream method negotiation failed" "Error negociant el mètode d'enviament" ::msgcat::mcset ca "Strip leading 'http://jabber.org/protocol/' from IQ namespaces in the status line." "Treure 'http://jabber.org/protocol/' de l'espai de nombres IQ en la línia d'estat." ::msgcat::mcset ca "Strip leading \\" "Strip leading \\" ::msgcat::mcset ca "Strip leading \\" "Treure \\" ::msgcat::mcset ca "Subject" "Assumpte" ::msgcat::mcset ca "Subject:" "Assumpte:" ::msgcat::mcset ca "Subscribe request from %s" "Petició de suscripció de %s" ::msgcat::mcset ca "Subscribe request from" "Petició de suscripció de" ::msgcat::mcset ca "Subscribe" "Subscriure's" ::msgcat::mcset ca "Subscription:" "Subscripció:" ::msgcat::mcset ca "Substrings to highlight in messages." "Sil·labes a resaltar als missatges." ::msgcat::mcset ca "Suffix" "Sufix" ::msgcat::mcset ca "Suffix:" "Sufix:" ::msgcat::mcset ca "Tabs:" "Pestanyes:" ::msgcat::mcset ca "Telephone numbers" "Números de telèfon" ::msgcat::mcset ca "Templates" "Plantilles" ::msgcat::mcset ca "Text status, which is set when Tkabber is moving in away state." "Text d'estatus que s'assignarà quan Tkabber et marque com a absent." ::msgcat::mcset ca "text undo" "desfer text" ::msgcat::mcset ca "the body is" "el cos del missatge és" ::msgcat::mcset ca "the message is from" "el missatge és de" ::msgcat::mcset ca "the message is sent to" "el missatge és per a" ::msgcat::mcset ca "the message type is" "el tipus de missatge és" ::msgcat::mcset ca "the subject is" "l'assumpte és" ::msgcat::mcset ca "This message is encrypted." "Aquest missatge està xifrat." ::msgcat::mcset ca "this option has been set and saved." "aquesta opció ha sigut definida i guardada." ::msgcat::mcset ca "this option is unchanged from its standard setting." "la definició estàndard d'aquesta opció no ha sigut canviada." ::msgcat::mcset ca "time %s%s: %s" "temps %s%s: %s" ::msgcat::mcset ca "time %s%s:" "temps %s%s:" ::msgcat::mcset ca "Time interval before playing next sound (in milliseconds)." "Interval de temps entre reproducció de sons (en milisegons)." ::msgcat::mcset ca "Time Zone:" "Zona horària:" ::msgcat::mcset ca "Time" "Hora" ::msgcat::mcset ca "Time:" "Hora:" ::msgcat::mcset ca "Timeout for waiting for HTTP poll responses (if set to zero, Tkabber will wait forever)." "Temps d'espera per a resposta HTTP Poll (si ès cero, Tkabber esperarà per sempre)." ::msgcat::mcset ca "Timer" "Temporitzador" ::msgcat::mcset ca "Title:" "Càrrec:" ::msgcat::mcset ca "Tkabber will set priority to 0 when moving in extended away state." "Tkabber posarà la prioritat a 0 en passar a estat molt absent." ::msgcat::mcset ca "To:" "Per a:" ::msgcat::mcset ca "To:" "Per a:" ::msgcat::mcset ca "Toggle encryption (when possible)" "Activar/desactivar el xifratge (si és possible)" ::msgcat::mcset ca "Toggle encryption" "Activar/desactivar xifratge" ::msgcat::mcset ca "Toggle seen" "Activar/desactivar llegit" ::msgcat::mcset ca "Toggle showing offline users" "Activar/desactivar mostrar usuaris desconnectats" ::msgcat::mcset ca "Toggle signing" "Activar/desactivar la signatura" ::msgcat::mcset ca "Transfering..." "Transferint..." ::msgcat::mcset ca "Transferring..." "Transferint..." ::msgcat::mcset ca "Try again" "Tornar a intentar-ho" ::msgcat::mcset ca "Type" "Tipus" ::msgcat::mcset ca "Type:" "Tipus:" ::msgcat::mcset ca "UID" "UID" ::msgcat::mcset ca "UID:" ::msgcat::mcset ca "Unable to encipher data for %s: %s.\n\nEncrypting traffic to this user is now disabled.\n\nSend it as PLAINTEXT?" "Impossible xifrar dades per a %s: %s.\n\nEl xifratge de dades per a aquest usuari es desactiva a partir d'ara.\n\n¿Enviar com a TEXT NET?" ::msgcat::mcset ca "Unable to sign message body: %s.\n\nSigning traffic is now disabled.\n\nSend it WITHOUT a signature?" "Impossible signar el cos del missatge: %s.\n\nEnviar SENSE signatura?" ::msgcat::mcset ca "Unable to sign presence information: %s.\n\nPresence will be sent, but signing traffic is now disabled." "Impossible signar la informació de presència: %s.\n\nLa presència s'enviarà, pero s'ha desactivat la signatura del tràfic." ::msgcat::mcset ca "Unauthorized" "No autoritzat" ::msgcat::mcset ca "Undefined" "Sense definir" ::msgcat::mcset ca "Undo" "Desfer" ::msgcat::mcset ca "Unit:" "Unitat:" ::msgcat::mcset ca "Unsubscribe" "Cancel·lar subscripció" ::msgcat::mcset ca "Unsubscribed from %s" "Cancel·lada la subscripció a %s" ::msgcat::mcset ca "Up" "Amunt" ::msgcat::mcset ca "Update message of the day..." "Actualitzar missatge del dia..." ::msgcat::mcset ca "Uptime" "Temps actiu" ::msgcat::mcset ca "Url to connect to." "Url a la qual connectar." ::msgcat::mcset ca "URL to connect to." "URL a que connectar." ::msgcat::mcset ca "URL to poll:" "URL per a poll:" ::msgcat::mcset ca "URL" "URL" ::msgcat::mcset ca "Url:" "Url:" ::msgcat::mcset ca "URL:" "URL:" ::msgcat::mcset ca "Use aliases to show multiple users in one roster item." "Usar àlies per a mostrar múltiples usuaris en un sol ítem de la llista de contactes." ::msgcat::mcset ca "Use aliases" "Utilitzar àlies" ::msgcat::mcset ca "Use client security keys" "Usar claus de seguretat del client" ::msgcat::mcset ca "Use colored messages" "Usar missatges colorejats" ::msgcat::mcset ca "Use colored nicks in chat windows." "Usar àlies colorejats en finestres de xat" ::msgcat::mcset ca "Use colored nicks in groupchat rosters." "Usar àlies colorejats en la llista de participants d'una sala de xat" ::msgcat::mcset ca "Use colored nicks" "Usar àlies colorejats" ::msgcat::mcset ca "Use colored roster nicks" "Usar àlies colorejats en la llista de contactes" ::msgcat::mcset ca "Use explicitly-specified server address." "Utilitzar adreça del servidor especificada explícitament." ::msgcat::mcset ca "Use hashed password transmission." "Usar transmissió del resum de la contrasenya." ::msgcat::mcset ca "Use hashed password" "Utilitzar resum de la contrasenya" ::msgcat::mcset ca "Use HTTP poll client security keys (recommended)." "Usar claus de seguretat del client HTTP poll (recomanat)." ::msgcat::mcset ca "Use HTTP poll connection method." "Usar mètode de connexió HTTP poll." ::msgcat::mcset ca "Use HTTP proxy to connect." "Utilitzar proxy HTTP per connectar." ::msgcat::mcset ca "Use Proxy" "Utilitzar proxy" ::msgcat::mcset ca "Use SASL authentification" "Usar autentificació SASL" ::msgcat::mcset ca "Use SASL authentification." "Usar autentificació SASL." ::msgcat::mcset ca "Use sound notification only when being available." "Usar la notificació sonora solament quan s'estiga en estat 'disponible'." ::msgcat::mcset ca "Use SSL to connect to server." "Utilitzar SSL per connectar amb el servidor" ::msgcat::mcset ca "Use SSL" "Utilitzar SSL" ::msgcat::mcset ca "Use this module" "Utilitzar aquest mòdul" ::msgcat::mcset ca "use v2 protocol" "utilitzar protocol v2" ::msgcat::mcset ca "User ID" "ID d'usuari" ::msgcat::mcset ca "User info" "Informació de l'usuari" ::msgcat::mcset ca "user interface" "interfície d'usuari" ::msgcat::mcset ca "User name." "Usuari." ::msgcat::mcset ca "Username Not Available" "El nom d'usuari no està disponible" ::msgcat::mcset ca "Username:" "Usuari:" ::msgcat::mcset ca "Users" "Usuaris" ::msgcat::mcset ca "UTC:" ::msgcat::mcset ca "utilities" "utilitats" ::msgcat::mcset ca "Value" "Valor" ::msgcat::mcset ca "Value:" "Valor:" ::msgcat::mcset ca "vcard %s%s: %s" "vcard %s%s: %s" ::msgcat::mcset ca "vcard %s%s:" "vcard %s%s:" ::msgcat::mcset ca "vCard items to display in chat windows when using /vcard command." "elements vCard a mostrar en les finestres de xarla quan s'usa /vcard" ::msgcat::mcset ca "version %s%s: %s" "versió s%s: %s" ::msgcat::mcset ca "version %s%s:" "versió s%s:" ::msgcat::mcset ca "Version" "Versió" ::msgcat::mcset ca "Version:" "Versió:" ::msgcat::mcset ca "Video:" "Vídeo:" ::msgcat::mcset ca "Visitors" "Visitants" ::msgcat::mcset ca "Voice:" "Veu:" ::msgcat::mcset ca "Waiting for activating privacy list" "Esperant per activar la llista de privacitat" ::msgcat::mcset ca "Waiting for authentication mechanisms" "Esperant mecanismes d'autenticació" ::msgcat::mcset ca "Waiting for authentication results" "Esperant els resultats de l'autenticació" ::msgcat::mcset ca "Waiting for roster" "Esperant la llista de contactes" ::msgcat::mcset ca "Waiting for stream" "Esperant missatge" ::msgcat::mcset ca "Warning display options." "Opcions de mostrar advertències." ::msgcat::mcset ca "Warning" "Advertència" ::msgcat::mcset ca "Warning: Remote server doesn't support\nhashed password authentication.\n\nProceed with PLAINTEXT authentication?" "Advertència: el servidor remot no suporta\nautenticació per resum de clau.\n\n¿Procedir a intentar una identificació per text plà?" ::msgcat::mcset ca "We unsubscribed from %s" "Hem cancel·lat la subscripció a %s" ::msgcat::mcset ca "Web Site" "Lloc Web" ::msgcat::mcset ca "Web Site:" "Lloc web:" ::msgcat::mcset ca "What action does the close button." "Acció realitzada pel butó de Tancar." ::msgcat::mcset ca "When you have unread messages the taskbar icon will start to blink." "Quan tens missatges sense llegir l'icona de la barra de tasques parpadejarà." ::msgcat::mcset ca "Whois" "Qui és?" ::msgcat::mcset ca "wmaker" ::msgcat::mcset ca "Work:" "Treball:" ::msgcat::mcset ca "Year:" "Any:" ::msgcat::mcset ca "you have edited the value, but you have not set the option." "Has editat el valor, però no has definit l'opció." ::msgcat::mcset ca "you have set this option, but not saved it for future sessions." "has activat aquesta opció, però no l'has guardada per a sessions futures." ::msgcat::mcset ca "Zebra list: %s" "Llista Zebra: %s" ::msgcat::mcset ca "Zebra lists" "Llistes Zebra" ::msgcat::mcset ca "Zip:" "Codi Postal:" ::msgcat::mcset ca "\nReason is: %s" "\nLa raó és: %s" ::msgcat::mcset ca "\nRoom is empty at %s" "\nLa sala %s està buida" ::msgcat::mcset ca "\nRoom participants at %s:" "\nParticipants a la sala %s:" ::msgcat::mcset ca "\n\tAffiliation: %s" "\n\tAfiliació: %s" ::msgcat::mcset ca "\n\tCan't browse: %s" "\n\tNo es pot explorar: %s" ::msgcat::mcset ca "\n\tClient: %s" "\n\tClient: %s" ::msgcat::mcset ca "\n\tJID: %s" "\n\tJID: %s" ::msgcat::mcset ca "\n\tName: %s" "\n\tNom: %s" ::msgcat::mcset ca "\n\tOS: %s" "\n\tSO: %s" ::msgcat::mcset ca "\n\tPresence is signed:" "\n\tLa presència està firmada:" tkabber-0.11.1/splash.tcl0000644000175000017500000002035711021767266014537 0ustar sergeisergei# $Id: splash.tcl 1449 2008-06-05 13:48:38Z sergei $ # BWidget's Button overrides this option, so set its priority to # 30 instead of widgetDefault (20) option add *ErrorDialog.function.text [::msgcat::mc "Save To Log"] 30 # Wrapper around bgerror which hides splash window. It's useful when # error window is small auto_load bgerror rename bgerror bgerror_default proc bgerror {msg} { if {[winfo exists .bgerrorDialog]} { # If there's another error message around then don't report the # next error (questionnable). return } if {[winfo exists .splash]} { wm withdraw .splash } bgerror_default $msg if {[winfo exists .splash]} { wm deiconify .splash update } } if {[info exists show_splash_window] && !$show_splash_window} { return } proc splash_start {{aboutP 0}} { global splash_count splash_image splash_info splash_max splash_text global tkabber_version toolkit_version set splash_info "" set splash_count 0 set splash_max 145 array set splash_text [list \ custom [::msgcat::mc "customization"] \ utils [::msgcat::mc "utilities"] \ plugins [::msgcat::mc "plugin management"] \ pixmaps [::msgcat::mc "pixmaps management"] \ balloon [::msgcat::mc "balloon help"] \ presence [::msgcat::mc "jabber presence"] \ iq [::msgcat::mc "jabber iq"] \ plugins:iq [::msgcat::mc "jabber iq"] \ roster [::msgcat::mc "jabber roster"] \ itemedit [::msgcat::mc "jabber roster"] \ messages [::msgcat::mc "jabber messages"] \ chats [::msgcat::mc "jabber chat/muc"] \ plugins:chat [::msgcat::mc "jabber chat/muc"] \ joingrdialog [::msgcat::mc "jabber chat/muc"] \ muc [::msgcat::mc "jabber chat/muc"] \ emoticons [::msgcat::mc "emoticons"] \ aniemoticons [::msgcat::mc "emoticons"] \ login [::msgcat::mc "connections"] \ browser [::msgcat::mc "browsing"] \ disco [::msgcat::mc "service discovery"] \ userinfo [::msgcat::mc "presence"] \ datagathering [::msgcat::mc "utilities"] \ negotiate [::msgcat::mc "negotiation"] \ search [::msgcat::mc "searching"] \ register [::msgcat::mc "jabber registration"] \ si [::msgcat::mc "file transfer"] \ plugins:si [::msgcat::mc "file transfer"] \ filetransfer [::msgcat::mc "file transfer"] \ plugins:filetransfer [::msgcat::mc "file transfer"] \ filters [::msgcat::mc "message filters"] \ privacy [::msgcat::mc "privacy rules"] \ gpgme [::msgcat::mc "cryptographics"] \ ifacetk [::msgcat::mc "user interface"] \ plugins:general [::msgcat::mc "general plugins"] \ plugins:roster [::msgcat::mc "roster plugins"] \ plugins:search [::msgcat::mc "search plugins"] \ plugins:unix [::msgcat::mc "unix plugins"] \ plugins:windows [::msgcat::mc "windows plugins"] \ plugins:macintosh [::msgcat::mc "macintosh plugins"] \ iface [::msgcat::mc "user interface"] \ autoaway [::msgcat::mc "auto-away"] \ avatars [::msgcat::mc "avatars"] \ bwidget_workarounds [::msgcat::mc "bwidget workarounds"] \ config [::msgcat::mc "configuration"] \ dockingtray [::msgcat::mc "kde"] \ hooks [::msgcat::mc "extension management"] \ jabberlib [::msgcat::mc "jabber xml"] \ plugins [::msgcat::mc "plugin management"] \ sound [::msgcat::mc "sound"] \ wmdock [::msgcat::mc "wmaker"] \ ] wm withdraw . set w [toplevel .splash -relief $::tk_relief -borderwidth $::tk_borderwidth] wm withdraw $w wm overrideredirect $w 1 catch { if {[lsearch -exact [wm attributes $w] -topmost] >= 0} { wm attributes $w -topmost 1 } } catch { if {[lsearch -exact [wm attributes $w] -alpha] >= 0} { wm attributes $w -alpha 0.7 } } if {$aboutP} { set h 180 } else { set h 240 } if {![info exists splash_image_$h]} { set splash_image_$h [image create photo -height $h -width 380] } frame $w.frame frame $w.frame.spacer -width 4m image create photo tkabber/logo \ -file [fullpath pixmaps default tkabber tkabber-logo.gif] label $w.frame.image -image tkabber/logo label $w.frame.msg \ -anchor nw \ -justify left \ -text \ "Tkabber $tkabber_version ($toolkit_version) Copyright \u00a9 2002-2008 [::msgcat::mc {Alexey Shchepin}] [::msgcat::mc Authors:] [::msgcat::mc {Alexey Shchepin}] [::msgcat::mc {Marshall T. Rose}] [::msgcat::mc {Sergei Golovan}] [::msgcat::mc {Michail Litvak}] [::msgcat::mc {Konstantin Khomoutov}] http://tkabber.jabber.ru/" grid $w.frame.spacer -row 0 -column 0 -sticky e -pady 4m grid $w.frame.image -row 0 -column 1 -sticky e -pady 4m grid $w.frame.msg -row 0 -column 2 -sticky w -padx 4m -pady 4m if {$aboutP} { bind $w "" bind $w "destroy $w" } else { ProgressBar $w.frame.bar \ -variable splash_count \ -width 100 \ -height 10 \ -maximum $splash_max label $w.frame.info \ -textvariable splash_info grid $w.frame.bar -row 2 -column 0 -sticky s -columnspan 3 grid $w.frame.info -row 3 -column 0 -sticky s -columnspan 3 } pack $w.frame -anchor nw if {(~$aboutP) && (![string compare [info commands splash_source] ""])} { rename source splash_source rename splash_progress source } BWidget::place $w 0 0 center wm deiconify $w } proc splash_progress {args} { global rootdir splash_count splash_info splash_text if {([winfo exists .splash]) && ([llength $args] == 1)} { set lrootdir [string tolower $rootdir] set filepath [string tolower [lindex $args 0]] set homedir [string tolower $::configdir] if {[catch { set globhomedir [file normalize $homedir] }]} { set plugins [lindex [glob -nocomplain [file join $homedir plugins]] 0] set globhomedir \ [file join [lrange [file split $plugins] 0 end-1]] } set globhomedir [string tolower $globhomedir] if {[string first $lrootdir $filepath] == 0} { set log 1 set root $lrootdir } elseif {[string first $homedir $filepath] == 0} { set log 1 set root $homedir } elseif {$globhomedir != "" && [string first $globhomedir $filepath] == 0} { set log 1 set root $globhomedir } else { set log 0 } if {$log} { set srelpath [lrange [file split $filepath] \ [llength [file split $root]] end] if {[llength $srelpath] > 1} { set name [join [lrange $srelpath 0 end-1] :] } else { set name [file rootname [lindex $srelpath 0]] } if {![string equal -nocase [lindex $srelpath end] "pkgIndex.tcl"]} { if {[info exists splash_text($name)]} { set splash_info $splash_text($name) } else { # Process plugins separately set nlist [split $name :] if {[lindex $nlist 0] == "plugins"} { set splash_info \ [::msgcat::mc "%s plugin" [join [lrange $nlist 1 end] :]] } } incr splash_count update } } } uplevel 1 splash_source $args } proc splash_done {} { global splash_count splash_max if {![winfo exists .splash]} { return } set splash_count $splash_max update after 100 destroy .splash rename source splash_progress rename splash_source source } hook::add finload_hook splash_done 99 splash_start # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/xmppmime.tcl0000644000175000017500000000573010512530014015056 0ustar sergeisergei# $Id: xmppmime.tcl 753 2006-10-09 20:24:44Z sergei $ # # Support for XMPP/Jabber MIME Type (XEP-0081) # namespace eval xmppmime { set used 0 set handle 0 set loaded 0 set connected 0 set queue {} } package require jabberlib 0.8.4 proc xmppmime::load {path} { # TODO: catch file errors set f [open $path] set content [read $f] close $f set parser [jlib::wrapper:new "#" "#" xmppmime::parse] jlib::wrapper:parser $parser parse $content jlib::wrapper:parser $parser configure -final 0 jlib::wrapper:free $parser } proc xmppmime::parse {xmldata} { jlib::wrapper:splitxml $xmldata tag vars isempty chdata children set jid [jlib::wrapper:getattr $vars jid] switch -- $tag { message { send_event [list message $jid] } chat { send_event [list chat $jid] } groupchat { send_event [list groupchat $jid] } subscribe { send_event [list subscribe $jid] } vcard { send_event [list vcard $jid] } register { send_event [list register $jid] } disco { send_event [list groupchat $jid] } } } proc xmppmime::send_event {event} { variable handle variable used set used 1 if {!$handle} { if {[tk appname] == "tkabber"} { set handle 1 } } if {$handle} { recv_event $event } else { if {[catch {send tkabber [list xmppmime::recv_event $event]}]} { set handle 1 recv_event $event } } } proc xmppmime::recv_event {event} { variable queue variable loaded if {$loaded} { process_event $event } else { lappend queue $event } } proc xmppmime::process_event {event} { variable queue variable connected set rest [lassign $event type jid] switch -- $type { message { message::send_dialog -to $jid } chat { chat::open_window [chat::chatid [jlib::route $jid] $jid] chat } groupchat { if {$connected} { muc::join $jid } else { lappend queue $event } } subscribe { message::send_subscribe_dialog $jid } vcard { if {$connected} { userinfo::open $jid } else { lappend queue $event } } register { if {$connected} { register::open $jid } else { lappend queue $event } } disco { if {$connected} { disco::browser::open_win $jid } else { lappend queue $event } } } } proc xmppmime::is_done {} { variable handle variable used return [expr {$used && !$handle}] } proc xmppmime::process_queue {} { variable queue variable loaded set loaded 1 set oldqueue $queue set queue {} foreach event $oldqueue { process_event $event } } hook::add finload_hook xmppmime::process_queue proc xmppmime::connected {connid} { variable connected set connected 1 process_queue } hook::add connected_hook xmppmime::connected proc xmppmime::disconnected {connid} { variable connected set connected [expr {[jlib::connections] != {}}] } hook::add disconnected_hook xmppmime::disconnected tkabber-0.11.1/COPYING0000644000175000017500000004311007542422401013554 0ustar sergeisergei GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. tkabber-0.11.1/muc.tcl0000644000175000017500000014257611074122553014031 0ustar sergeisergei# $Id: muc.tcl 1512 2008-10-11 13:08:59Z sergei $ # Multi-User Chat support (XEP-0045) ############################################################################### namespace eval muc { set winid 0 custom::defvar options(gen_enter_exit_msgs) 1 \ [::msgcat::mc "Generate status messages when occupants\ enter/exit MUC compatible conference rooms."] \ -type boolean -group Chat custom::defvar options(gen_muc_status_change_msgs) 0 \ [::msgcat::mc "Generate groupchat messages when occupant\ changes his/her status and/or status message."] \ -type boolean -group Chat custom::defvar options(gen_muc_position_change_msgs) 0 \ [::msgcat::mc "Generate groupchat messages when occupant's\ room position (affiliation and/or role) changes."] \ -type boolean -group Chat custom::defvar options(propose_configure) 0 \ [::msgcat::mc "Propose to configure newly created MUC room.\ If set to false then the default room configuration\ is automatically accepted."] \ -type boolean -group Chat custom::defvar options(history_maxchars) 10000 \ [::msgcat::mc "Maximum number of characters in the history in MUC\ compatible conference rooms."] \ -type integer -group Chat custom::defvar options(history_maxstanzas) 20 \ [::msgcat::mc "Maximum number of stanzas in the history in MUC\ compatible conference rooms."] \ -type integer -group Chat custom::defvar options(request_only_unseen_history) 0 \ [::msgcat::mc "Request only unseen (which aren't displayed in the\ chat window) messages in the history in MUC compatible\ conference rooms."] \ -type boolean -group Chat custom::defvar options(report_muc_rooms) 0 \ [::msgcat::mc "Report the list of current MUC rooms on\ disco#items query."] \ -type boolean -group IQ } # MUC affiliations (for translation): # [::msgcat::mc "owner"] # [::msgcat::mc "admin"] # [::msgcat::mc "member"] # [::msgcat::mc "outcast"] # [::msgcat::mc "none"] # MUC roles (for translation): # [::msgcat::mc "moderator"] # [::msgcat::mc "participant"] # [::msgcat::mc "visitor"] # (yet another "none" omitted) ############################################################################### set ::NS(muc) http://jabber.org/protocol/muc set ::NS(muc#admin) http://jabber.org/protocol/muc#admin set ::NS(muc#owner) http://jabber.org/protocol/muc#owner set ::NS(muc#user) http://jabber.org/protocol/muc#user set ::NS(muc#rooms) http://jabber.org/protocol/muc#rooms ############################################################################### proc muc::add_groupchat_user_menu_items {m connid jid} { set group [node_and_server_from_jid $jid] if {![is_compatible $group]} return set mm [menu $m.muc -tearoff 0] $mm add command -label [::msgcat::mc "Whois"] \ -command [list muc::whois $connid $jid] $mm add command -label [::msgcat::mc "Kick"] \ -command [list muc::change_item_param \ {role none} down $connid $jid ""] $mm add command -label [::msgcat::mc "Ban"] \ -command [list muc::change_item_param \ {affiliation outcast} down $connid $jid ""] $mm add command -label [::msgcat::mc "Grant Voice"] \ -command [list muc::change_item_param \ {role participant} up $connid $jid ""] $mm add command -label [::msgcat::mc "Revoke Voice"] \ -command [list muc::change_item_param \ {role visitor} down $connid $jid ""] $mm add command -label [::msgcat::mc "Grant Membership"] \ -command [list muc::change_item_param \ {affiliation member} up $connid $jid ""] $mm add command -label [::msgcat::mc "Revoke Membership"] \ -command [list muc::change_item_param \ {affiliation none} down $connid $jid ""] $mm add command -label [::msgcat::mc "Grant Moderator Privileges"] \ -command [list muc::change_item_param \ {role moderator} up $connid $jid ""] $mm add command -label [::msgcat::mc "Revoke Moderator Privileges"] \ -command [list muc::change_item_param \ {role participant} down $connid $jid ""] $mm add command -label [::msgcat::mc "Grant Admin Privileges"] \ -command [list muc::change_item_param \ {affiliation admin} up $connid $jid ""] $mm add command -label [::msgcat::mc "Revoke Admin Privileges"] \ -command [list muc::change_item_param \ {affiliation member} down $connid $jid ""] #$mm add command -label [::msgcat::mc "Grant Owner Privileges"] \ # -command [list muc::change_item_param \ # {affiliation owner} up $connid $jid ""] #$mm add command -label [::msgcat::mc "Revoke Owner Privileges"] \ # -command [list muc::change_item_param \ # {affiliation admin} down $connid $jid ""] $m add cascade -label [::msgcat::mc "MUC"] -menu $mm } hook::add roster_create_groupchat_user_menu_hook \ muc::add_groupchat_user_menu_items 39 ############################################################################### proc muc::create_conference_menu_items {m connid jid} { set chatid [chat::chatid $connid $jid] set idx [expr {[$m index end] + 1}] trace variable ::muc::muc_compatible($jid) w \ [list muc::add_conference_menu_items $m $chatid $idx] bind $m [list trace vdelete ::muc::muc_compatible($jid) w \ [list muc::add_conference_menu_items $m $chatid $idx]] } hook::add chat_create_conference_menu_hook muc::create_conference_menu_items 37 proc muc::add_conference_menu_items {m chatid idx args} { set group [chat::get_jid $chatid] if {![is_compatible $group] || ![winfo exists $m]} return trace vdelete ::muc::muc_compatible($group) w \ [list muc::add_conference_menu_items $m $chatid $idx] add_muc_menu_items $m $chatid $idx } proc muc::add_muc_menu_items {m chatid idx} { set mm [menu $m.muc -tearoff 0] $mm add command -label [::msgcat::mc "Configure room"] \ -command [list muc::request_config $chatid] $mm add command -label [::msgcat::mc "Edit voice list"] \ -command [list muc::request_list role participant $chatid] $mm add command -label [::msgcat::mc "Edit ban list"] \ -command [list muc::request_list affiliation outcast $chatid] $mm add command -label [::msgcat::mc "Edit member list"] \ -command [list muc::request_list affiliation member $chatid] $mm add command -label [::msgcat::mc "Edit moderator list"] \ -command [list muc::request_list role moderator $chatid] $mm add command -label [::msgcat::mc "Edit admin list"] \ -command [list muc::request_list affiliation admin $chatid] $mm add command -label [::msgcat::mc "Edit owner list"] \ -command [list muc::request_list affiliation owner $chatid] $mm add separator $mm add command -label [::msgcat::mc "Destroy room"] \ -command [list muc::request_destruction_dialog $chatid "" ""] $m insert $idx cascade -label [::msgcat::mc "MUC"] -menu $mm } proc muc::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] set features [disco::get_jid_features $connid $jid $node] set pfeatures [disco::get_jid_features $pconnid $pjid $pnode] # JID with resource is not a room JID if {[node_and_server_from_jid $jid] != $jid} return # A room must have non-empty node if {[node_from_jid $jid] == ""} return if {[lempty $identities]} { set identities $pidentities } if {[lempty $features]} { set features $pfeatures } foreach id $identities { if {[jlib::wrapper:getattr $id category] == "conference"} { foreach f $features { if {[jlib::wrapper:getattr $f var] == $::NS(muc)} { add_muc_menu_items $m [chat::chatid $connid $jid] end return } } } } } } } hook::add disco_node_menu_hook muc::disco_node_menu_setup 60 ############################################################################### proc muc::handle_commands {chatid user body type} { if {$type != "groupchat"} return set connid [chat::get_connid $chatid] set group [chat::get_jid $chatid] if {[cequal [crange $body 0 5] "/kick "]} { set params {role none} set dir down lassign [parse_nick_reason $body 6] nick reason } elseif {[cequal [crange $body 0 4] "/ban "]} { set params {affiliation outcast} set dir down lassign [parse_nick_reason $body 5] nick reason } elseif {[cequal [crange $body 0 6] "/unban "]} { set jid [parse_nick $body 7] unban $connid $group $jid return stop } elseif {[cequal [crange $body 0 6] "/whois "]} { set nick [parse_nick $body 7] whois $connid $group/$nick return stop } elseif {[cequal [crange $body 0 6] "/voice "]} { set params {role participant} set dir up lassign [parse_nick_reason $body 7] nick reason } elseif {[cequal [crange $body 0 8] "/devoice "]} { set params {role visitor} set dir down lassign [parse_nick_reason $body 9] nick reason } elseif {[cequal [crange $body 0 7] "/member "]} { set params {affiliation member} set dir up lassign [parse_nick_reason $body 8] nick reason } elseif {[cequal [crange $body 0 9] "/demember "]} { set params {affiliation none} set dir down lassign [parse_nick_reason $body 10] nick reason } elseif {[cequal [crange $body 0 10] "/moderator "]} { set params {role moderator} set dir up lassign [parse_nick_reason $body 11] nick reason } elseif {[cequal [crange $body 0 12] "/demoderator "]} { set params {role participant} set dir down lassign [parse_nick_reason $body 13] nick reason } elseif {[cequal [crange $body 0 6] "/admin "]} { set params {affiliation admin} set dir up lassign [parse_nick_reason $body 7] nick reason } elseif {[cequal [crange $body 0 8] "/deadmin "]} { set params {affiliation member} set dir down lassign [parse_nick_reason $body 9] nick reason } else { return } change_item_param $params $dir $connid $group/$nick $reason return stop } hook::add chat_send_message_hook muc::handle_commands 50 proc muc::parse_nick {body n} { return [lindex [parse_nick_reason $body $n] 0] } proc muc::parse_nick_reason {body n} { # Parse nickname and reason # first line is a nick, rest are reason set nick_reason [crange $body $n end] set ne [string first "\n" $nick_reason] if {$ne < 0} { set nick $nick_reason set reason "" } else { set nick [string range $nick_reason 0 [expr {$ne - 1}]] set reason [string range $nick_reason [expr {$ne + 1}] end] } return [list $nick [string trim $reason]] } ############################################################################### proc muc::commands_comps {chatid compsvar wordstart line} { set group [chat::get_jid $chatid] if {![is_compatible $group]} return upvar 0 $compsvar comps if {!$wordstart} { lappend comps {/whois } {/kick } {/ban } {/unban } \ {/voice } {/devoice } \ {/member } {/demember } \ {/moderator } {/demoderator } \ {/admin } {/deadmin } } } hook::add generate_completions_hook muc::commands_comps ############################################################################### proc muc::get_real_jid {connid jid} { variable users if {[info exists users(jid,$connid,$jid)] && \ $users(jid,$connid,$jid) != ""} { return $users(jid,$connid,$jid) } else { return "" } } proc muc::whois {connid user} { set group [node_and_server_from_jid $user] set chatid [chat::chatid $connid $group] set nick [chat::get_nick $connid $user groupchat] set real_jid [get_real_jid $connid $user] if {$real_jid != ""} { chat::add_message $chatid $group info \ [::msgcat::mc "whois %s: %s" $nick $real_jid] {} } else { chat::add_message $chatid $group error \ [::msgcat::mc "whois %s: no info" $nick] {} } } ############################################################################### proc muc::compare_roles {role1 role2} { set roles {none visitor participant moderator} set idx1 [lsearch -exact $roles $role1] set idx2 [lsearch -exact $roles $role2] expr {$idx1 - $idx2} } proc muc::compare_affs {aff1 aff2} { set affs {outcast none member admin owner} set idx1 [lsearch -exact $affs $aff1] set idx2 [lsearch -exact $affs $aff2] expr {$idx1 - $idx2} } proc muc::change_item_param {params dir connid user reason} { variable users set group [node_and_server_from_jid $user] set chatid [chat::chatid $connid $group] set nick [chat::get_nick $connid $user groupchat] lassign $params key val if {![catch { set aff $users(affiliation,$connid,$user) }] && \ ![catch { set role $users(role,$connid,$user) }]} { switch -- $key/$dir { affiliation/up { if {[compare_affs $aff $val] >= 0} { chat::add_message $chatid $group error \ "affiliation $val $nick:\ [::msgcat::mc {User already %s} $aff]" {} return } } affiliation/down { if {[compare_affs $aff $val] <= 0} { chat::add_message $chatid $group error \ "affiliation $val $nick:\ [::msgcat::mc {User already %s} $aff]" {} return } } role/up { if {[compare_roles $role $val] >= 0} { chat::add_message $chatid $group error \ "role $val $nick:\ [::msgcat::mc {User already %s} $role]" {} return } } role/down { if {[compare_roles $role $val] <= 0} { chat::add_message $chatid $group error \ "role $val $nick:\ [::msgcat::mc {User already %s} $role]" {} return } } default { return } } } set itemsubtags {} if {$reason != ""} { lappend itemsubtags [jlib::wrapper:createtag reason \ -chdata $reason] } set vars [list nick $nick] if {$params == {affiliation outcast}} { # For unknown reason banning request MUST be based on # user's bare JID (which may be not known by admin) set real_jid [get_real_jid $connid $user] if {$real_jid != ""} { set vars [list jid [node_and_server_from_jid $real_jid]] } } set item [jlib::wrapper:createtag item \ -vars [concat $vars $params] \ -subtags $itemsubtags] jlib::send_iq set \ [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(muc#admin)] \ -subtags [list $item]] \ -to $group \ -connection $connid \ -command [list muc::test_error_res "$params $nick" $connid $group] } ############################################################################### proc muc::unban {connid group jid} { jlib::send_iq get \ [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(muc#admin)] \ -subtags [list [jlib::wrapper:createtag item \ -vars {affiliation outcast}]]] \ -to $group \ -connection $connid \ -command [list muc::unban_continue $connid $group $jid] } proc muc::unban_continue {connid group jid res child} { if {$res != "OK"} { chat::add_message [chat::chatid $connid $group] $group error \ "affiliation none $jid: [error_to_string $child]" {} return } jlib::wrapper:splitxml $child tag vars isempty chdata children set jid [node_and_server_from_jid $jid] set found 0 foreach item $children { jlib::wrapper:splitxml $item tag1 vars1 isempty1 chdata1 children1 switch -- $tag1 { item { set jid1 [jlib::wrapper:getattr $vars1 jid] if {$jid == $jid1} { set found 1 break } } } } if {!$found} { chat::add_message [chat::chatid $connid $group] $group error \ "affiliation none $jid: User is not banned" {} return } set item [jlib::wrapper:createtag item \ -vars [list jid $jid affiliation none]] jlib::send_iq set \ [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(muc#admin)] \ -subtags [list $item]] \ -to $group \ -connection $connid \ -command [list muc::test_unban_res $connid $group $jid] } proc muc::test_unban_res {connid group jid res child} { if {$res != "OK"} { chat::add_message [chat::chatid $connid $group] $group error \ "affiliation none $jid: [error_to_string $child]" {} return } chat::add_message [chat::chatid $connid $group] $group info \ "affiliation none $jid: User is unbanned" {} } ############################################################################### proc muc::request_destruction_dialog {chatid alt reason} { set connid [chat::get_connid $chatid] set group [chat::get_jid $chatid] set warning \ [::msgcat::mc "Conference room %s will be destroyed\ permanently.\n\nProceed?" $group] set res [MessageDlg .muc_request_destruction -aspect 50000 -icon warning \ -type user -buttons {yes no} -default 1 \ -cancel 1 \ -message $warning] if {!$res} { request_destruction $chatid $alt $reason } } proc muc::request_destruction {chatid alt reason} { set connid [chat::get_connid $chatid] set group [chat::get_jid $chatid] if {$alt != ""} { set vars [list jid $alt] } else { set vars {} } jlib::send_iq set \ [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(muc#owner)] \ -subtags [list \ [jlib::wrapper:createtag destroy \ -vars $vars \ -subtags [list \ [jlib::wrapper:createtag reason \ -chdata $reason]]]]] \ -to $group \ -connection $connid \ -command [list muc::test_error_res "destroy" $connid $group] } ############################################################################### proc muc::request_list {attr val chatid} { set connid [chat::get_connid $chatid] set group [chat::get_jid $chatid] jlib::send_iq get \ [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(muc#admin)] \ -subtags [list [jlib::wrapper:createtag item \ -vars [list $attr $val]]]] \ -to $group \ -connection $connid \ -command [list muc::receive_list $attr $val $chatid] } proc muc::receive_list {attr val chatid res child} { set connid [chat::get_connid $chatid] set group [chat::get_jid $chatid] if {![cequal $res OK]} { chat::add_message $chatid $group error \ "$attr $val list: [error_to_string $child]" {} return } jlib::wrapper:splitxml $child tag vars isempty chdata children #data::draw_window $children [list muc::send_list $role $group] variable winid set w .muc_list$winid incr winid if {[winfo exists $w]} { destroy $w } Dialog $w -title [::msgcat::mc [format "Edit %s list" $val]] \ -modal none -separator 1 -anchor e -default 0 -cancel 1 \ -parent . set wf [$w getframe] set sw [ScrolledWindow $wf.sw -scrollbar vertical] set sf [ScrollableFrame $w.fields -constrainedwidth yes] set f [$sf getframe] $sw setwidget $sf fill_list $sf $f $children $attr $val list_add_item $sf $f $attr $val $w add -text [::msgcat::mc "Send"] \ -command [list muc::send_list $chatid $attr $val $w $f] $w add -text [::msgcat::mc "Cancel"] -command [list destroy $w] bind $w [list after idle [list muc::list_cleanup $w $f]] frame $w.fr pack $w.fr -side bottom -in $wf -fill x button $w.add -text [::msgcat::mc "Add new item"] \ -command [list muc::list_add_item $sf $f $attr $val] pack $w.add -side right -in $w.fr -padx 1m -pady 1m label $w.lall -text [::msgcat::mc "All items:"] pack $w.lall -side left -in $w.fr -padx 1m -pady 1m switch -- $attr { role { ComboBox $w.roleall -text $val \ -values {moderator participant visitor none} \ -editable no \ -width 11 \ -modifycmd [list muc::change_all_items $f $w.roleall $attr] pack $w.roleall -side left -anchor w -in $w.fr -pady 1m } affiliation { ComboBox $w.affiliationall -text $val \ -values {owner admin member none outcast} \ -editable no \ -width 7 \ -modifycmd [list muc::change_all_items $f $w.affiliationall $attr] pack $w.affiliationall -side left -in $w.fr -pady 1m } } pack $sw -side top -expand yes -fill both bindscroll $f $sf set hf [frame $w.hf] pack $hf -side top set vf [frame $w.vf] pack $vf -side left update idletasks $hf configure -width [expr {[winfo reqwidth $f] + [winfo pixels $f 1c]}] set h [winfo reqheight $f] set sh [winfo screenheight $w] if {$h > $sh - 200} { set h [expr {$sh - 200}] } $vf configure -height $h $w draw } ############################################################################### proc muc::change_all_items {f combobox attr} { variable listdata variable origlistdata set value [$combobox get] for {set i 1} {$i <= $listdata($f,rows)} {incr i} { set listdata($f,$attr,$i) $value } } ############################################################################### proc muc::fill_list {sf f items attr val} { variable listdata variable origlistdata grid columnconfigure $f 0 -weight 1 grid columnconfigure $f 1 -weight 1 grid columnconfigure $f 2 -weight 0 grid columnconfigure $f 3 -weight 2 label $f.lnick -text [::msgcat::mc "Nick"] grid $f.lnick -row 0 -column 0 -sticky we -padx 1m bindscroll $f.lnick $sf label $f.ljid -text JID grid $f.ljid -row 0 -column 1 -sticky we -padx 1m bindscroll $f.ljid $sf switch -- $attr { role { label $f.lrole -text [::msgcat::mc "Role"] grid $f.lrole -row 0 -column 2 -sticky we -padx 1m bindscroll $f.lrole $sf } affiliation { label $f.laffiliation -text [::msgcat::mc "Affiliation"] grid $f.laffiliation -row 0 -column 2 -sticky we -padx 1m bindscroll $f.laffiliation $sf } } label $f.lreason -text [::msgcat::mc "Reason"] grid $f.lreason -row 0 -column 3 -sticky we -padx 1m bindscroll $f.lreason $sf set row 1 set items2 {} foreach item $items { jlib::wrapper:splitxml $item tag vars isempty chdata children switch -- $tag { item { set nick [jlib::wrapper:getattr $vars nick] set jid [jlib::wrapper:getattr $vars jid] set role [jlib::wrapper:getattr $vars role] set affiliation [jlib::wrapper:getattr $vars affiliation] set reason "" foreach subitem $children { jlib::wrapper:splitxml $subitem tag1 vars1 isempty1 chdata1 children1 if {$tag1 == "reason"} { set reason $chdata1 } } lappend items2 [list $nick $jid $role $affiliation $reason] } } } foreach item [lsort -dictionary -index 1 $items2] { lassign $item listdata($f,nick,$row) listdata($f,jid,$row) \ role affiliation listdata($f,reason,$row) entry $f.nick$row \ -textvariable muc::listdata($f,nick,$row) \ -takefocus 0 \ -highlightthickness 0 \ -width 20 if {[catch {$f.nick$row configure -state readonly}]} { $f.nick$row configure -state disabled } grid $f.nick$row -row $row -column 0 -sticky we -padx 1m bindscroll $f.nick$row $sf entry $f.jid$row \ -textvariable muc::listdata($f,jid,$row) \ -takefocus 0 \ -highlightthickness 0 \ -width 30 if {[catch {$f.jid$row configure -state readonly}]} { $f.jid$row configure -state disabled } grid $f.jid$row -row $row -column 1 -sticky we -padx 1m bindscroll $f.jid$row $sf switch -- $attr { role { ComboBox $f.role$row -text $role \ -values {moderator participant visitor none} \ -editable no \ -width 11 \ -textvariable muc::listdata($f,role,$row) grid $f.role$row -row $row -column 2 -sticky we -padx 1m bindscroll $f.role$row $sf } affiliation { ComboBox $f.affiliation$row -text $affiliation \ -values {owner admin member none outcast} \ -editable no \ -width 7 \ -textvariable muc::listdata($f,affiliation,$row) grid $f.affiliation$row -row $row -column 2 -sticky we -padx 1m bindscroll $f.affiliation$row $sf } } entry $f.reason$row \ -textvariable muc::listdata($f,reason,$row) \ -width 40 grid $f.reason$row -row $row -column 3 -sticky we -padx 1m bindscroll $f.reason$row $sf incr row } set listdata($f,rows) [incr row -1] array set origlistdata [array get listdata ${f}*] } ############################################################################### proc muc::list_add_item {sf f attr val} { variable listdata set row [incr listdata($f,rows)] entry $f.nick$row \ -textvariable muc::listdata($f,nick,$row) \ -width 20 grid $f.nick$row -row $row -column 0 -sticky we -padx 1m bindscroll $f.nick$row $sf entry $f.jid$row \ -textvariable muc::listdata($f,jid,$row) \ -width 30 grid $f.jid$row -row $row -column 1 -sticky we -padx 1m bindscroll $f.jid$row $sf switch -- $attr { role { ComboBox $f.role$row -text none \ -values {moderator participant visitor none} \ -editable no \ -width 11 \ -textvariable muc::listdata($f,role,$row) grid $f.role$row -row $row -column 2 -sticky we -padx 1m bindscroll $f.role$row $sf } affiliation { ComboBox $f.affiliation$row -text none \ -values {owner admin member none outcast} \ -editable no \ -width 7 \ -textvariable muc::listdata($f,affiliation,$row) grid $f.affiliation$row -row $row -column 2 -sticky we -padx 1m bindscroll $f.affiliation$row $sf } } entry $f.reason$row \ -textvariable muc::listdata($f,reason,$row) \ -width 40 grid $f.reason$row -row $row -column 3 -sticky we -padx 1m bindscroll $f.reason$row $sf set listdata($f,$attr,$row) $val } ############################################################################### proc muc::send_list {chatid attr val w f} { variable origlistdata variable listdata set items {} for {set i 1} {$i <= $origlistdata($f,rows)} {incr i} { set vars {} if {$listdata($f,$attr,$i) != $origlistdata($f,$attr,$i) || \ $listdata($f,reason,$i) != $origlistdata($f,reason,$i)} { lappend vars $attr $listdata($f,$attr,$i) } if {$vars != {}} { if {$origlistdata($f,nick,$i) != ""} { lappend vars nick $origlistdata($f,nick,$i) } if {$origlistdata($f,jid,$i) != ""} { lappend vars jid $origlistdata($f,jid,$i) } set itemsubtags {} set reason $listdata($f,reason,$i) if {$reason != ""} { lappend itemsubtags [jlib::wrapper:createtag reason \ -chdata $reason] } lappend items [jlib::wrapper:createtag item \ -vars $vars \ -subtags $itemsubtags] } } for {} {$i <= $listdata($f,rows)} {incr i} { set vars1 {} set vars2 {} if {$listdata($f,$attr,$i) != ""} { lappend vars1 $attr $listdata($f,$attr,$i) } if {$listdata($f,nick,$i) != ""} { lappend vars2 nick $listdata($f,nick,$i) } if {$listdata($f,jid,$i) != ""} { lappend vars2 jid $listdata($f,jid,$i) } if {$vars1 != {} && $vars2 != {}} { set vars [concat $vars2 $vars1] set itemsubtags {} set reason $listdata($f,reason,$i) if {$reason != ""} { lappend itemsubtags [jlib::wrapper:createtag reason \ -chdata $reason] } lappend items [jlib::wrapper:createtag item \ -vars $vars \ -subtags $itemsubtags] } } set connid [chat::get_connid $chatid] set group [chat::get_jid $chatid] if {$items != {}} { jlib::send_iq set [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(muc#admin)] \ -subtags $items] \ -to $group \ -connection $connid \ -command [list muc::test_error_res \ [::msgcat::mc "Sending %s %s list" $attr $val] \ $connid $group] } destroy $w } ############################################################################### proc muc::list_cleanup {w f} { variable listdata variable origlistdata array unset listdata ${f},* array unset origlistdata ${f},* } proc muc::request_config_dialog {chatid} { variable winid set w .muc_req_config$winid incr winid if {[winfo exists $w]} { destroy $w } Dialog $w -title [::msgcat::mc "Room is created"] \ -modal none -separator 1 -anchor e -default 0 -cancel 1 set wf [$w getframe] message $wf.message -aspect 50000 \ -text [::msgcat::mc "Room %s is successfully created" \ [chat::get_jid $chatid]] pack $wf.message -pady 2m $w add -text [::msgcat::mc "Configure room"] \ -command "[list destroy $w] [list [namespace current]::request_config $chatid]" $w add -text [::msgcat::mc "Accept default config"] \ -command "[list destroy $w] [list [namespace current]::request_instant_room $chatid]" $w draw } proc muc::request_instant_room {chatid} { jlib::send_iq set \ [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(muc#owner)] \ -subtags [list [jlib::wrapper:createtag x \ -vars [list xmlns $::NS(data) \ type submit]]]] \ -to [chat::get_jid $chatid] \ -connection [chat::get_connid $chatid] } proc muc::request_config {chatid} { jlib::send_iq get \ [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(muc#owner)]] \ -to [chat::get_jid $chatid] \ -connection [chat::get_connid $chatid] \ -command [list muc::receive_config $chatid] } proc muc::receive_config {chatid res child} { set group [chat::get_jid $chatid] if {![cequal $res OK]} { chat::add_message $chatid $group error \ [::msgcat::mc "Configure form: %s" [error_to_string $child]] \ {} return } jlib::wrapper:splitxml $child tag vars isempty chdata children data::draw_window $children [list muc::send_config $chatid] \ [list muc::cancel_config $chatid] return } ############################################################################### proc muc::send_config {chatid w restags} { set connid [chat::get_connid $chatid] set group [chat::get_jid $chatid] jlib::send_iq set [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(muc#owner)] \ -subtags $restags] \ -to $group \ -connection $connid \ -command [list muc::test_error_res \ [::msgcat::mc "Sending configure form"] $connid $group] destroy $w } ############################################################################### proc muc::cancel_config {chatid w} { set connid [chat::get_connid $chatid] set group [chat::get_jid $chatid] jlib::send_iq set [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(muc#owner)] \ -subtags [list [jlib::wrapper:createtag x \ -vars [list xmlns jabber:x:data \ type cancel]]]] \ -to $group \ -connection $connid \ -command [list muc::test_error_res \ [::msgcat::mc "Cancelling configure form"] $connid $group] destroy $w } ############################################################################### proc muc::test_error_res {op connid group res child} { if {![cequal $res OK]} { set chatid [chat::chatid $connid $group] chat::add_message $chatid $group error \ [format "%s: %s" $op [error_to_string $child]] {} return } } ############################################################################### proc muc::process_presence {connid from type x args} { switch -- $type { available - unavailable { foreach xs $x { jlib::wrapper:splitxml $xs tag vars isempty chdata children if {[jlib::wrapper:getattr $vars xmlns] == $::NS(muc#user)} { process_muc_user $connid $from $type $children break } } } } } hook::add client_presence_hook muc::process_presence ############################################################################### proc muc::process_muc_user {connid user type childrens} { variable users variable options foreach child $childrens { jlib::wrapper:splitxml $child tag vars isempty chdata children switch -- $tag { item { if {$type != "unavailable"} { set users(jid,$connid,$user) [jlib::wrapper:getattr $vars jid] track_room_position $connid $user \ [jlib::wrapper:getattr $vars role] \ [jlib::wrapper:getattr $vars affiliation] } else { set new_nick [jlib::wrapper:getattr $vars nick] foreach ch $children { jlib::wrapper:splitxml $ch tag1 vars1 isempty1 \ chdata1 children1 switch -- $tag1 { reason { set reason $chdata1 } actor { set actor [jlib::wrapper:getattr $vars1 jid] } } } } } destroy { set group [node_and_server_from_jid $user] set chatid [chat::chatid $connid $group] set msg [::msgcat::mc "Room is destroyed"] foreach ch $children { jlib::wrapper:splitxml $ch tag1 vars1 isempty1 chdata1 children1 if {$tag1 == "reason" && [string trim $chdata1] != ""} { append msg [::msgcat::mc "\nReason: %s" [string trim $chdata1]] } } set altjid [jlib::wrapper:getattr $vars jid] if {$altjid != ""} { append msg [::msgcat::mc "\nAlternative venue: %s" $altjid] } if {$options(gen_enter_exit_msgs)} { chat::add_message \ $chatid $group groupchat $msg {} } } status { set code [jlib::wrapper:getattr $vars code] set group [node_and_server_from_jid $user] set chatid [chat::chatid $connid $group] switch -- $code { 201 { chat::add_message \ $chatid $group groupchat \ [::msgcat::mc "A new room is created"] {} # 201: room creation if {$options(propose_configure)} { request_config_dialog $chatid } else { # requesting "instant" room as specified in XEP-0045 # if the user wants to configure room (s)he can do it later request_instant_room $chatid } } 301 - 307 - 321 - 322 { # 301: ban, 307: kick, 321: loosing membership # 322: room becomes members-only set nick [chat::get_nick $connid $user groupchat] set real_jid [get_real_jid $connid $group/$nick] if {$real_jid != ""} { set real_jid " ($real_jid)" } switch -- $code { 301 {set action \ [::msgcat::mc "%s has been banned" \ $nick$real_jid]} 307 {set action \ [::msgcat::mc "%s has been kicked" \ $nick$real_jid]} 321 {set action \ [::msgcat::mc \ "%s has been kicked because\ of membership loss" \ $nick$real_jid]} 322 {set action \ [::msgcat::mc \ "%s has been kicked because\ room became members-only" \ $nick$real_jid]} } if {[info exists actor] && $actor != ""} { append action [::msgcat::mc " by %s" $actor] } if {[info exists reason] && $reason != ""} { append action ": $reason" } if {$options(gen_enter_exit_msgs)} { variable ignore_unavailable $nick chat::add_message \ $chatid $group groupchat $action {} } } 303 { # 303: nickname change set nick [chat::get_nick $connid $user groupchat] if {[info exists new_nick] && $new_nick != ""} { if {$nick == [get_our_groupchat_nick $chatid]} { set_our_groupchat_nick $chatid $new_nick } # TODO may be this reporting should not be done # if the $nick is being ignored (MUC ignore) if {$options(gen_enter_exit_msgs)} { variable ignore_available $new_nick variable ignore_unavailable $nick set real_jid [get_real_jid $connid $group/$nick] if {$real_jid != ""} { set real_jid " ($real_jid)" } chat::add_message \ $chatid $group groupchat \ [::msgcat::mc "%s is now known as %s" \ $nick$real_jid $new_nick] {} } ::hook::run room_nickname_changed_hook $connid $group $nick $new_nick } } } } } } } proc muc::process_available {chatid nick} { variable pending_nicks set connid [chat::get_connid $chatid] set group [chat::get_jid $chatid] if {![is_compatible $group] && [is_changing_nick $chatid] && \ [string equal $pending_nicks($chatid) $nick]} { set_our_groupchat_nick $chatid $nick unset pending_nicks($chatid) } } proc muc::process_unavailable {chatid nick} { variable options variable ignore_unavailable set group [chat::get_jid $chatid] if {[is_compatible $group] && $options(gen_enter_exit_msgs) && \ (![info exists ignore_unavailable] || \ $ignore_unavailable != $nick)} { set connid [chat::get_connid $chatid] set status [get_jid_presence_info status $connid $group/$nick] if {$status != ""} { set end ": $status" } else { set end "" } chat::add_message $chatid $group groupchat \ [cconcat [::msgcat::mc "%s has left" $nick] $end] {} } catch { unset ignore_unavailable } } proc muc::report_available {chatid nick entered} { variable options variable users variable ignore_available set connid [::chat::get_connid $chatid] set group [::chat::get_jid $chatid] if {![is_compatible $group]} return set jid $group/$nick set msg "" set report_entered [expr {$entered && $options(gen_enter_exit_msgs) \ && (![info exists ignore_available] || $ignore_available != $nick)}] if {$report_entered} { set real_jid [get_real_jid $connid $jid] if {$real_jid != ""} { set occupant "$nick ($real_jid)" } else { set occupant $nick } set msg [format [::msgcat::mc "%s has entered"] $occupant] if {$options(gen_muc_position_change_msgs)} { append msg " " [::msgcat::mc "as %s/%s" \ [::msgcat::mc $users(affiliation,$connid,$jid)] \ [::msgcat::mc $users(role,$connid,$jid)]] } } catch { unset ignore_available } if {$options(gen_muc_status_change_msgs)} { set status [::get_user_status $connid $jid] if {$report_entered} { append msg " " [::msgcat::mc "and"] " " } else { append msg $nick " " } append msg [::get_long_status_desc $status] set desc [::get_user_status_desc $connid $jid] if {$desc != {}} { append msg " ($desc)" } } ::chat::add_message $chatid $group groupchat $msg {} } proc muc::track_room_position {connid jid role affiliation} { variable options variable users upvar 0 users(role,$connid,$jid) _role \ users(affiliation,$connid,$jid) _aff set group [node_and_server_from_jid $jid] if {![is_compatible $group]} return set chatid [chat::chatid $connid $group] if {[chat::is_opened $chatid] && $options(gen_muc_position_change_msgs)} { set nick [chat::get_nick $connid $jid groupchat] set role_changed [expr {![info exists _role] \ || ![string equal $role $_role]}] set aff_changed [expr {![info exists _aff] \ || ![string equal $affiliation $_aff]}] if {$aff_changed} { if {$role_changed} { set msg [::msgcat::mc "%s has been assigned a new room position: %s/%s" \ $nick [::msgcat::mc $affiliation] [::msgcat::mc $role]] } else { set msg [::msgcat::mc "%s has been assigned a new affiliation: %s" \ $nick [::msgcat::mc $affiliation]] } } elseif {$role_changed} { set msg [::msgcat::mc "%s has been assigned a new role: %s" \ $nick [::msgcat::mc $role]] } else { set msg "" } if {$msg != ""} { ::chat::add_message $chatid $group groupchat $msg {} } } set _aff $affiliation set _role $role } ############################################################################### proc muc::change_nick {chatid nick} { global userstatus textstatus global statusdesc set group [chat::get_jid $chatid] if {![is_compatible $group]} { variable pending_nicks set pending_nicks($chatid) $nick } if {$userstatus == "invisible"} { set status available } else { set status $userstatus } if {$textstatus == ""} { set tstatus $statusdesc($status) } else { set tstatus $textstatus } send_custom_presence $group/$nick $status \ -stat $tstatus \ -connection [chat::get_connid $chatid] \ -command [list muc::process_change_nick $chatid] } proc muc::process_change_nick {chatid connid from type x args} { if {![cequal $type error]} { return } # if {![cequal [lindex [jlib::wrapper:getattr $args -error] 1] conflict]} { # return # } if {![is_compatible [chat::get_jid $chatid]] && \ [is_changing_nick $chatid]} { variable pending_nicks unset pending_nicks($chatid) } chat::add_message $chatid [node_and_server_from_jid $from] error \ [::msgcat::mc "Error %s" [jlib::wrapper:getattr $args -status]] {} return break } proc muc::is_changing_nick {chatid} { variable pending_nicks if {[info exists pending_nicks($chatid)]} { return 1 } else { return 0 } } ############################################################################### proc muc::request_negotiation {connid group} { variable muc_compatible set muc_compatible($group) 0 disco::request_info [server_from_jid $group] "" \ -connection $connid \ -cache yes \ -handler [list muc::recv_negotiation1 $connid $group] } proc muc::recv_negotiation1 {connid group res identities features extras} { variable muc_compatible if {[cequal $res OK]} { foreach f $features { set var [jlib::wrapper:getattr $f var] if {$var == $::NS(muc)} { set muc_compatible($group) 1 return } } } disco::request_info $group "" \ -connection $connid \ -cache yes \ -handler [list muc::recv_negotiation2 $group] } proc muc::recv_negotiation2 {group res identities features extras} { variable muc_compatible if {[cequal $res OK]} { foreach f $features { set var [jlib::wrapper:getattr $f var] if {$var == $::NS(muc)} { set muc_compatible($group) 1 return } } } set muc_compatible($group) 0 } proc muc::is_compatible {group} { variable muc_compatible if {[info exists muc_compatible($group)]} { return $muc_compatible($group) } else { return 0 } } ############################################################################### proc muc::add_user_popup_info {infovar connid user} { variable users upvar 0 $infovar info if {[info exists users(jid,$connid,$user)] && \ $users(jid,$connid,$user) != ""} { append info [::msgcat::mc "\n\tJID: %s" $users(jid,$connid,$user)] } if {[info exists users(affiliation,$connid,$user)]} { append info [::msgcat::mc "\n\tAffiliation: %s" \ $users(affiliation,$connid,$user)] } } hook::add roster_user_popup_info_hook muc::add_user_popup_info ############################################################################### proc muc::set_message_timestamp {chatid from type body x} { variable timestamps if {![chat::is_disconnected $chatid]} { set timestamps($chatid) [clock seconds] } } hook::add draw_message_hook muc::set_message_timestamp 15 proc muc::clear_message_timestamp {chatid} { variable timestamps catch { unset timestamps($chatid) } } hook::add close_chat_post_hook muc::clear_message_timestamp ############################################################################### proc muc::join_group {connid group nick {password ""}} { global userstatus textstatus global statusdesc variable options variable timestamps variable muc_password set group [tolower_node_and_domain $group] set chatid [chat::chatid $connid $group] if {[info exists chat::chats(status,$chatid)] && \ ![string equal $chat::chats(status,$chatid) disconnected]} { change_nick $chatid $nick return } privacy::add_to_special_list $connid conference [server_from_jid $group] set_our_groupchat_nick $chatid $nick chat::open_window $chatid groupchat update idletasks request_negotiation $connid $group set x_subtags {} lappend x_subtags [jlib::wrapper:createtag password -chdata $password] set muc_password($chatid) $password set history_vars {} if {$options(history_maxchars) >= 0} { lappend history_vars maxchars $options(history_maxchars) } if {$options(history_maxstanzas) >= 0} { lappend history_vars maxstanzas $options(history_maxstanzas) } if {$options(request_only_unseen_history) && \ [info exists timestamps($chatid)]} { lappend history_vars \ seconds [expr {[clock seconds] - $timestamps($chatid) + 2}] } if {![lempty $history_vars]} { lappend x_subtags [jlib::wrapper:createtag history -vars $history_vars] } if {$userstatus == "invisible"} { set status available } else { set status $userstatus } if {$textstatus == ""} { set tstatus $statusdesc($status) } else { set tstatus $textstatus } send_presence $status \ -to $group/$nick \ -stat $tstatus \ -connection $connid \ -xlist [list [jlib::wrapper:createtag x \ -vars [list xmlns $::NS(muc)] \ -subtags $x_subtags]] } ############################################################################### proc muc::leave_group {connid group nick status} { send_presence unavailable \ -to $group/$nick \ -stat $status \ -connection $connid } ############################################################################### proc muc::invite_muc {connid group jid reason} { # If $jid is a 'real' JID then invite # If $jid is in a conference room try to invite real JID set real_jid [get_real_jid $connid $jid] if {$real_jid == ""} { set real_jid $jid } message::send_msg $group \ -xlist [list \ [jlib::wrapper:createtag x \ -vars [list xmlns $::NS(muc#user)] \ -subtags [list \ [jlib::wrapper:createtag invite \ -vars [list to $real_jid] \ -subtags [list [jlib::wrapper:createtag reason \ -chdata $reason]]]]]] \ -connection $connid } proc muc::invite_xconference {connid group jid reason} { message::send_msg $jid \ -type normal \ -subject "Invitation" \ -body $reason \ -xlist [list [jlib::wrapper:createtag x \ -vars [list xmlns jabber:x:conference \ jid $group]]] \ -connection $connid } ############################################################################### proc muc::process_invitation {rowvar bodyvar f x connid from id type replyP} { upvar 2 $rowvar row upvar 2 $bodyvar body foreach xa $x { jlib::wrapper:splitxml $xa tag vars isempty chdata children set xmlns [jlib::wrapper:getattr $vars xmlns] switch -- $xmlns \ $::NS(xconference) { set xconference_group [jlib::wrapper:getattr $vars jid] set xconference_password "" if {[cequal $body ""] && ![cequal $chdata ""]} { set xconference_body $chdata } else { set xconference_body $body } } \ $::NS(muc#user) { set password "" set inviter "" foreach ch $children { jlib::wrapper:splitxml $ch tag1 vars1 isempty1 \ chdata1 children1 switch -- $tag1 { invite { set inviter [jlib::wrapper:getattr $vars1 from] if {![cequal $inviter ""]} { foreach c [jlib::connections] { set name \ [roster::itemconfig $c \ [roster::find_jid $c $inviter] \ -name] if {$name != ""} break } if {![cequal $name ""]} { set inviter "$name ($inviter)" } set muc_body \ [::msgcat::mc \ "%s invites you to conference\ room %s" \ $inviter $from] foreach ch1 $children1 { jlib::wrapper:splitxml $ch1 tag2 vars2 \ isempty2 chdata2 children2 if {[cequal $tag2 "reason"]} { append muc_body \ [::msgcat::mc "\nReason is: %s" \ $chdata2] } } } # TODO decline } password { set password $chdata1 } } } if {![string equal $inviter ""]} { set muc_group $from set muc_password $password } } } if {[info exists muc_group] && $muc_group != ""} { process_x_conference $f $connid $muc_group $muc_password $row incr row set body $muc_body return } elseif {[info exists xconference_group] && $xconference_group != ""} { process_x_conference $f $connid $xconference_group \ $xconference_password $row incr row set body $xconference_body return } return } hook::add message_process_x_hook muc::process_invitation proc muc::process_x_conference {f connid group password row} { global gr_nick label $f.lgroup$row -text [::msgcat::mc "Invited to:"] button $f.group$row -text $group \ -command [list ::join_group $group \ -nick [get_group_nick $group $gr_nick] \ -password $password \ -connection $connid] grid $f.lgroup$row -row $row -column 0 -sticky e grid $f.group$row -row $row -column 1 -sticky ew } ############################################################################### proc muc::join {jid args} { global gr_nick set category conference set newargs {} foreach {opt val} $args { switch -- $opt { -category { set category $val } -connection { lappend newargs -connection $val } } } if {![cequal $category conference]} { return } if {![cequal [node_from_jid $jid] {}]} { eval {::join_group $jid -nick [get_group_nick $jid $gr_nick]} \ $newargs } else { eval {::join_group_dialog -server [server_from_jid $jid] -group {}} \ $newargs } } hook::add postload_hook \ [list disco::browser::register_feature_handler jabber:iq:conference \ muc::join -desc [list conference [::msgcat::mc "Join conference"]]] hook::add postload_hook \ [list disco::browser::register_feature_handler $::NS(muc) muc::join \ -desc [list conference [::msgcat::mc "Join conference"]]] hook::add postload_hook \ [list disco::browser::register_feature_handler "gc-1.0" muc::join \ -desc [list conference [::msgcat::mc "Join groupchat"]]] ############################################################################### iq::register_handler get query $::NS(muc) muc::iq_reply ############################################################################### proc muc::disco_reply {type connid from lang child} { variable options if {!$options(report_muc_rooms)} { return {error cancel not-allowed} } switch -- $type { info { return {} } items { set res {} foreach chatid [lfilter chat::is_groupchat [chat::opened $connid]] { set group [chat::get_jid $chatid] if {[is_compatible $group]} { lappend res [jlib::wrapper:createtag item \ -vars [list jid $group]] } } return $res } } } hook::add postload_hook \ [list disco::register_node $::NS(muc#rooms) muc::disco_reply \ [::trans::trans "Current rooms"]] ############################################################################### # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/itemedit.tcl0000644000175000017500000001373510573560443015052 0ustar sergeisergei# $Id: itemedit.tcl 1024 2007-03-07 15:58:27Z sergei $ namespace eval itemedit {} proc itemedit::show_dialog {connid jid} { set allowed_name [jid_to_tag $jid] set w .gredit_${connid}_$allowed_name if {[winfo exists $w]} { destroy $w } Dialog $w -title [format [::msgcat::mc "Edit properties for %s"] $jid] \ -separator 1 -anchor e \ -default 0 -cancel 1 set f [$w getframe] hook::run roster_itemedit_setup_hook $f $connid $jid set g [[TitleFrame $f.gr -text [format [::msgcat::mc "Edit groups for %s"] $jid]] getframe] pack $f.gr -side top -expand yes -fill both set ga [frame $g.available] pack $ga -side left -expand yes -fill both label $ga.title -text [::msgcat::mc "Available groups"] pack $ga.title -side top -anchor w frame $ga.gr label $ga.gr.lab -text [::msgcat::mc "Group:"] set gae [entry $ga.gr.oup] pack $ga.gr.lab -side left pack $ga.gr.oup -side left -fill x -expand yes pack $ga.gr -side top -fill x set gasw [ScrolledWindow $ga.grouplist_sw] set gal [listbox $ga.grouplist] $gasw setwidget $gal pack $gasw -side top -expand yes -fill both set gc [frame $g.current] pack $gc -side right -expand yes -fill both label $gc.title -text [::msgcat::mc "Current groups"] pack $gc.title -side top -anchor w set gcsw [ScrolledWindow $gc.grouplist_sw] set gcl [listbox $gc.grouplist] $gcsw setwidget $gcl pack $gcsw -side top -expand yes -fill both frame $g.buttons button $g.buttons.add -text [::msgcat::mc "Add ->"] \ -command "itemedit::add_group $gcl \[$ga.gr.oup get\]" button $g.buttons.remove -text [::msgcat::mc "<- Remove"] \ -command [list itemedit::remove_current_group $gcl] pack $g.buttons.add $g.buttons.remove -side top -fill x -anchor c pack $g.buttons -side left $w add -text [::msgcat::mc "OK"] \ -command [list [namespace current]::commit_changes $gcl $connid $jid] $w add -text [::msgcat::mc "Cancel"] -command [list destroy $w] foreach group [roster::get_groups $connid \ -nested $::ifacetk::roster::options(nested) \ -delimiter $::ifacetk::roster::options(nested_delimiter)] { $gal insert end $group } foreach group [roster::itemconfig $connid $jid -group] { $gcl insert end $group } bindtags $gal [list Listbox $gal . all] bind $gal <1> [list itemedit::select_available_group $gal $gae] $w draw } proc itemedit::edit_item_setup_fallback {f connid jid} { variable gra_name set tf [TitleFrame $f.name -text [format [::msgcat::mc "Edit nickname 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] label $g.lname -text [::msgcat::mc "Nickname:"] set gn [entry $g.name -textvariable [namespace current]::gra_name] set name [roster::itemconfig $connid $jid -name] if {$name == ""} { if {[info exists userinfo::userinfo(nickname,$jid)] && \ ![cequal $userinfo::userinfo(nickname,$jid) ""]} { set name $userinfo::userinfo(nickname,$jid) } else { set name [node_from_jid $jid] jlib::send_iq get \ [jlib::wrapper:createtag vCard \ -vars [list xmlns vcard-temp]] \ -to [node_and_server_from_jid [get_jid_of_user $connid $jid]] \ -connection $connid \ -command [list [namespace current]::fetch_nickname $gn $name $jid] } } $g.name delete 0 end $g.name insert 0 $name pack $g.lname -side left pack $g.name -side left -expand yes -fill x } hook::add roster_itemedit_setup_hook \ [namespace current]::itemedit::edit_item_setup_fallback 100 proc itemedit::prefs_user_menu {m connid jid} { set rjid [roster::find_jid $connid $jid] if {$rjid == ""} { set state disabled } else { set state normal } $m add command -label [::msgcat::mc "Edit item..."] \ -command [list [namespace current]::show_dialog $connid $rjid] \ -state $state } hook::add chat_create_user_menu_hook \ [namespace current]::itemedit::prefs_user_menu 74 hook::add roster_conference_popup_menu_hook \ [namespace current]::itemedit::prefs_user_menu 74 hook::add roster_service_popup_menu_hook \ [namespace current]::itemedit::prefs_user_menu 74 hook::add roster_jid_popup_menu_hook \ [namespace current]::itemedit::prefs_user_menu 74 proc itemedit::add_group {grlist group} { set group [string trim $group] if {![cequal $group ""]} { set groups [$grlist get 0 end] lappend groups $group set groups [lrmdups $groups] $grlist delete 0 end eval $grlist insert end $groups } } proc itemedit::select_available_group {grlist grentry} { if {![lempty [$grlist curselection]]} { set group [$grlist get [$grlist curselection]] $grentry delete 0 end $grentry insert 0 $group } } proc itemedit::remove_current_group {grlist} { if {![lempty [$grlist curselection]]} { $grlist delete [$grlist curselection] } } proc itemedit::commit_changes {grlist connid jid} { hook::run roster_itemedit_commit_hook $connid $jid [$grlist get 0 end] destroy [winfo toplevel $grlist] } proc itemedit::commit_changes_fallback {connid jid groups} { variable gra_name roster::itemconfig $connid $jid \ -name $gra_name \ -group $groups roster::send_item $connid $jid } hook::add roster_itemedit_commit_hook \ [namespace current]::itemedit::commit_changes_fallback 100 proc itemedit::fetch_nickname {name_entry name jid res child} { if {![winfo exists $name_entry] || ![cequal $res OK]} { return } jlib::wrapper:splitxml $child tag vars isempty chdata children foreach item $children { userinfo::parse_vcard_item $jid $item } if {[info exists userinfo::userinfo(nickname,$jid)] && \ ![cequal $userinfo::userinfo(nickname,$jid) ""] && \ [winfo exists $name_entry] && \ [cequal [$name_entry get] $name]} { $name_entry delete 0 end $name_entry insert 0 $userinfo::userinfo(nickname,$jid) } } tkabber-0.11.1/trans/0000755000175000017500000000000011076120366013653 5ustar sergeisergeitkabber-0.11.1/trans/pl.msg0000644000175000017500000000737510667534736015031 0ustar sergeisergei# Polish translation file for replying to other client queries # Author: Irek Chmielowiec # Contact: xmpp:irek@chrome.pl :: mailto:irek.ch@gmail.com # Please notify me of errors or incoherencies # plugins/general/remote.tcl ::trans::trset pl "Change status" "ZmieÅ„ status" ::trans::trset pl "Change Status" "Zmiana statusu" ::trans::trset pl "Choose chats or groupchats from which you want to forward messages" "Wybierz rozmowy i konferencje" ::trans::trset pl "Choose groupchats you want to leave" "Wybierz rozmowy i konferencje, które chcesz zamknąć" ::trans::trset pl "Choose status, priority, and status message" "Wybierz status, priorytet i opis statusu" ::trans::trset pl "Forward all messages" "Przekaż wszystkie wiadomoÅ›ci" ::trans::trset pl "Forward messages from" "Przekaż wiadomoÅ›ci od" ::trans::trset pl "Forward unread messages" "Przekaż nieprzeczytane widomoÅ›ci" ::trans::trset pl "Forward Unread Messages" "Przekazywanie nieprzeczytanych wiadomoÅ›ci" ::trans::trset pl "Groupchats" "Konferencje" ::trans::trset pl "Groupchats were leaved successfully" "Konferencje zostaÅ‚y pomyÅ›lnie zamkniÄ™te" ::trans::trset pl "Leave all groupchats" "Zamknij wszystkie konferencje" ::trans::trset pl "Leave groupchats" "Zamknij konferencje" ::trans::trset pl "Leave Groupchats" "ZamkniÄ™cie konferencji" ::trans::trset pl "Message" "Opis statusu" ::trans::trset pl "No groupchats to leave" "Brak konferencji do zamkniÄ™cia" ::trans::trset pl "Priority" "Priorytet" ::trans::trset pl "Reason" "Powód" ::trans::trset pl "Remote control" "Zdalne sterowanie" ::trans::trset pl "%s at %s" "%s w %s" ::trans::trset pl "%s (%s)" ::trans::trset pl "%s: %s chat message(s)" "%s: %s wiadomość(i) w rozmowie" ::trans::trset pl "%s: %s groupchat message(s)" "%s: %s wiadomość(i) w konferencji" ::trans::trset pl "%s: %s headline message(s)" "%s: %s nagłówek(ów) widomoÅ›ci" ::trans::trset pl "%s: %s normal message(s)" "%s: %s zwykÅ‚a(e) wiadomość(i)" ::trans::trset pl "%s: %s unknown message(s)" "%s: %s wiadomość(i) nieznana(ych)" ::trans::trset pl "Status" "Status" ::trans::trset pl "Status was changed successfully" "Status zostaÅ‚ pomyÅ›lnie zmieniony" ::trans::trset pl "There are no unread messages" "Brak nieprzeczytanych wiadomoÅ›ci" ::trans::trset pl "Unread messages were forwarded successfully" "Nieprzeczytane wiadomoÅ›ci zostaÅ‚y pomyÅ›lnie przekazane" ::trans::trset pl "Available" "DostÄ™pny" ::trans::trset pl "Free to chat" "ChÄ™tny do rozmowy" ::trans::trset pl "Away" "Zaraz wracam" ::trans::trset pl "Extended away" "Nieobecny" ::trans::trset pl "Do not disturb" "Nie przeszkadzać" ::trans::trset pl "Unavailable" "Rozłączony" # muc.tcl ::trans::trset pl "Current rooms" "Aktywne konferencje" # plugins/si/socks5.tcl ::trans::trset pl "Stream ID has not been negotiated" "ID strumienia danych nie zostaÅ‚o wynegocjowane" # plugins/si/iqibb.tcl ::trans::trset pl "Cannot decode recieved data" "Nie można zdekodować odebranych danych" ::trans::trset pl "File transfer is aborted" "Transmisja pliku zostaÅ‚a przerwana" ::trans::trset pl "Unexpected packet sequence number" "Nieoczekiwany numer sekwencyjny pakietu" # plugins/filetransfer/si.tcl ::trans::trset pl "File transfer is refused" "Odmówiono transmisji pliku" ::trans::trset pl "Stream ID is in use" "ID strumienia jest w użyciu" # plugins/filetransfer/http.tcl ::trans::trset pl "File not found" "Nie znaleziono pliku" # plugins/filetransfer/jidlink.tcl ::trans::trset pl "File transfer is failed" "Transmisja pliku nie udaÅ‚a siÄ™" ::trans::trset pl "Invalid file ID" "NieprawidÅ‚owe ID pliku" ::trans::trset pl "Transfer is expired" "Transmisja pliku przedawniÅ‚a siÄ™" # plugins/si/socks5.tcl ::trans::trset pl "Cannot connect to any of the streamhosts" "Nie udaÅ‚o siÄ™ połączyć z żadnym poÅ›rednikiem strumienia danych" tkabber-0.11.1/trans/es.msg0000644000175000017500000000622310570744125015000 0ustar sergeisergei::trans::trset es "%s at %s" "%s en %s" ::trans::trset es "%s: %s chat message(s)" "%s: %s mensajes de charla" ::trans::trset es "%s: %s groupchat message(s)" "%s: %s mensajes de salas de charla" ::trans::trset es "%s: %s headline message(s)" "%s: %s titulares" ::trans::trset es "%s: %s normal message(s)" "%s: %s mensajes normales" ::trans::trset es "%s: %s unknown message(s)" "%s: %s mensajes desconocidos" ::trans::trset es "Available" "Disponible" ::trans::trset es "Away" "Ausente" ::trans::trset es "Cannot decode recieved data" "No se puede decodificar los datos recibidos" ::trans::trset es "Change Status" "Cambiar Estado" ::trans::trset es "Change status" "Cambiar estado" ::trans::trset es "Choose chats or groupchats from which you want to forward messages" "Escoge de qué charlas o salas de charla quieres" ::trans::trset es "Choose groupchats you want to leave" "Escoge de qué salas de charla quieres salir" ::trans::trset es "Choose status, priority, and status message" "Escoge estado, prioridad y mensaje de estado" ::trans::trset es "Current rooms" "Salas actuales" ::trans::trset es "Do not disturb" "No molestar" ::trans::trset es "Extended away" "Muy ausente" ::trans::trset es "File not found" "Fichero no encontado" ::trans::trset es "File transfer is aborted" "Transferencia de ficheros abortada" ::trans::trset es "File transfer is failed" "La transferencia de fichero ha fallado" ::trans::trset es "File transfer is refused" "Transferencia de fichero rechazada" ::trans::trset es "Forward Unread Messages" "Redirigir mensajes no leidos" ::trans::trset es "Forward all messages" "Redirigir todos los mensajes" ::trans::trset es "Forward messages from" "Redirigir mensajes de" ::trans::trset es "Forward unread messages" "Redirigir mensajes no leidos" ::trans::trset es "Free to chat" "Disponible para charlar" ::trans::trset es "Groupchats were leaved successfully" "Has salido correctamente de las salas de charla" ::trans::trset es "Groupchats" "Salas de charla" ::trans::trset es "Invalid file ID" "ID del fichero no es válido" ::trans::trset es "Leave Groupchats" "Salir de las salas de charla" ::trans::trset es "Leave all groupchats" "Salir de todas las salas de charla" ::trans::trset es "Leave groupchats" "Salir de las salas de charla" ::trans::trset es "Message" "Mensaje" ::trans::trset es "No groupchats to leave" "No estás en ninguna sala de charla" ::trans::trset es "Priority" "Prioridad" ::trans::trset es "Reason" "Razón" ::trans::trset es "Remote control" "Control remoto" ::trans::trset es "Status was changed successfully" "El estado se cambió correctamente" ::trans::trset es "Status" "Estado" ::trans::trset es "Stream ID has not been negotiated" "Stream ID no ha sido negociado" ::trans::trset es "Stream ID is in use" "Stream ID está en uso" ::trans::trset es "There are no unread messages" "No hay mensajes sin leer" ::trans::trset es "Transfer is expired" "La transferencia ha expirado" ::trans::trset es "Unavailable" "Desconectado" ::trans::trset es "Unexpected packet sequence number" "Número de secuencia de paquete no esperado" ::trans::trset es "Unread messages were forwarded successfully" "Los mensajes sin leer fueron redireccionados correctamente" tkabber-0.11.1/trans/de.msg0000644000175000017500000001144310670567231014763 0ustar sergeisergei # German messages file # Roger Sondermann 08.09.2007 # .../muc.tcl ::trans::trset de "Current rooms" "Derzeitige Räume" # .../plugins/filetransfer/http.tcl ::trans::trset de "File not found" "Datei nicht gefunden" # .../plugins/filetransfer/jidlink.tcl ::trans::trset de "File transfer is refused" "Datei-Übertragung verweigert" # .../plugins/filetransfer/si.tcl ::trans::trset de "Stream ID is in use" "'Stream'-ID wird benutzt" # .../plugins/general/remote.tcl ::trans::trset de "%s at %s" "%s an %s" ::trans::trset de "%s: %s chat message(s)" "%s: %s Chat-Nachricht(en)" ::trans::trset de "%s: %s groupchat message(s)" "%s: %s Konferenz-Nachricht(en)" ::trans::trset de "%s: %s headline message(s)" "%s: %s Kopfzeilen-Nachricht(en)" ::trans::trset de "%s: %s normal message(s)" "%s: %s normale Nachricht(en)" ::trans::trset de "%s: %s unknown message(s)" "%s: %s unbekannte Nachricht(en)" ::trans::trset de "Available" "Anwesend" ::trans::trset de "Away" "Abwesend" ::trans::trset de "Change Status" "Status ändern" ::trans::trset de "Change status" "Status ändern" ::trans::trset de "Choose chats or groupchats from which you want to forward messages" "Chats oder Konferenzen auswählen, von denen weitergeleitet werden soll" ::trans::trset de "Choose groupchats you want to leave" "Zu verlassene Konferenzen auswählen" ::trans::trset de "Choose status, priority, and status message" "Priorität, Status und Status-Nachricht auswählen" ::trans::trset de "Do not disturb" "Bitte nicht stören" ::trans::trset de "Extended away" "Länger abwesend" ::trans::trset de "Forward all messages" "Alle Nachrichten weiterleiten" ::trans::trset de "Forward messages from" "Nachrichten weiterleiten von" ::trans::trset de "Forward Unread Messages" "Ungelesene Nachrichten weiterleiten" ::trans::trset de "Forward unread messages" "Ungelesene Nachrichten weiterleiten" ::trans::trset de "Free to chat" "Frei zum Chatten" ::trans::trset de "Groupchats" "Konferenzen" ::trans::trset de "Groupchats were leaved successfully" "Konferenzen wurden erfolgreich verlassen" ::trans::trset de "Leave Groupchats" "Konferenzen verlassen" ::trans::trset de "Leave groupchats" "Konferenzen verlassen" ::trans::trset de "Leave all groupchats" "Alle Konferenzen verlassen" ::trans::trset de "Message" "Nachricht" ::trans::trset de "No groupchats to leave" "Keine Konferenzen zu verlassen" ::trans::trset de "Priority" "Priorität" ::trans::trset de "Reason" "Grund" ::trans::trset de "Remote control" "Fernsteuerung" ::trans::trset de "Status" "Status" ::trans::trset de "Status was changed successfully" "Status wurde erfolgreich geändert" ::trans::trset de "There are no unread messages" "Keine ungelesenen Nachrichten vorhanden" ::trans::trset de "Unavailable" "Nicht verfügbar" ::trans::trset de "Unread messages were forwarded successfully" "Ungelesene Nachrichten wurden erfolgreich weitergeleitet" # .../plugins/si/iqibb.tcl ::trans::trset de "Cannot decode recieved data" "Empfangene Daten können nicht dekodiert werden" ::trans::trset de "File transfer is aborted" "Datei-Übertragung abgebrochen" ::trans::trset de "Stream ID has not been negotiated" "'Stream'-ID ist nicht verhandelt worden" ::trans::trset de "Unexpected packet sequence number" "Unerwartete Paket-Sequenz-Nummer" # .../plugins/si/socks5.tcl ::trans::trset de "Cannot connect to any of the streamhosts" "Verbindung zu jedem der 'Streamhosts' misslungen" tkabber-0.11.1/trans/ru.msg0000644000175000017500000001016110570744125015013 0ustar sergeisergei# $Id: ru.msg 985 2007-02-27 05:57:41Z sergei $ # Russian translation file for replying to other client queries ::trans::trset ru "Cannot decode recieved data" "Ðе удалоÑÑŒ декодировать полученные данные" ::trans::trset ru "Change status" "Изменить ÑтатуÑ" ::trans::trset ru "Change Status" "Изменение ÑтатуÑа" ::trans::trset ru "Choose chats or groupchats from which you want to forward messages" \ "Выберите, из каких разговоров или конференций Ð’Ñ‹ хотите переÑлать ÑообщениÑ" ::trans::trset ru "Choose groupchats you want to leave" "Выберите конференции, из которых Ð’Ñ‹ хотите выйти" ::trans::trset ru "Choose status, priority, and status message" "Выберите ÑтатуÑ, приоритет и ÑтатуÑное Ñообщение" ::trans::trset ru "File not found" "Файл не найден" ::trans::trset ru "Forward all messages" "ПереÑлать вÑе ÑообщениÑ" ::trans::trset ru "Forward messages from" "ПереÑлать ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¸Ð·" ::trans::trset ru "File transfer is aborted" "Передача файла прервана" ::trans::trset ru "File transfer is failed" "Передать файл не удалоÑÑŒ" ::trans::trset ru "File transfer is refused" "Ð’ передаче файла отказано" ::trans::trset ru "Forward unread messages" "ПереÑлать непрочитанные ÑообщениÑ" ::trans::trset ru "Forward Unread Messages" "ПереÑылка непрочитанных Ñообщений" ::trans::trset ru "Groupchats" "Конференции" ::trans::trset ru "Groupchats were leaved successfully" "Ð’Ñ‹ уÑпешно вышли из конференций" ::trans::trset ru "Invalid file ID" "Ðеправильный ID файла" ::trans::trset ru "Leave all groupchats" "Выйти из вÑех конференций" ::trans::trset ru "Leave groupchats" "Выйти из конференций" ::trans::trset ru "Leave Groupchats" "Выход из конференций" ::trans::trset ru "Message" "Сообщение" ::trans::trset ru "No groupchats to leave" "Конференций, из которых можно выйти, нет" ::trans::trset ru "Priority" "Приоритет" ::trans::trset ru "Reason" "Причина" ::trans::trset ru "Remote control" "Удалённое управление" ::trans::trset ru "%s at %s" "%s в %s" ::trans::trset ru "%s: %s chat message(s)" "%s: %s Ñообщений в разговоре" ::trans::trset ru "%s: %s groupchat message(s)" "%s: %s Ñообщений в конференции" ::trans::trset ru "%s: %s headline message(s)" "%s: %s новоÑтей" ::trans::trset ru "%s: %s normal message(s)" "%s: %s обычных Ñообщений" ::trans::trset ru "%s: %s unknown message(s)" "%s: %s Ñообщений неизвеÑтного типа" ::trans::trset ru "Status" "СтатуÑ" ::trans::trset ru "Status was changed successfully" "Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½ уÑпешно" ::trans::trset ru "Stream ID has not been negotiated" "ID потока не ÑоглаÑован" ::trans::trset ru "Stream ID is in use" "ID потока уже иÑпользуетÑÑ" ::trans::trset ru "There are no unread messages" "Ðепрочитанных Ñообщений нет" ::trans::trset ru "Transfer is expired" "Срок передачи иÑтёк" ::trans::trset ru "Unexpected packet sequence number" "Ðеожиданный номер поÑледовательноÑти пакетов" ::trans::trset ru "Unread messages were forwarded successfully" "Ðепрочитанные ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¿ÐµÑ€ÐµÑланы уÑпешно" ::trans::trset ru "Available" "ДоÑтупен" ::trans::trset ru "Free to chat" "Свободен Ð´Ð»Ñ Ñ€Ð°Ð·Ð³Ð¾Ð²Ð¾Ñ€Ð°" ::trans::trset ru "Away" "Отошёл" ::trans::trset ru "Extended away" "Отошёл давно" ::trans::trset ru "Do not disturb" "Ðе беÑпокоить" ::trans::trset ru "Unavailable" "ÐедоÑтупен" ::trans::trset ru "Current rooms" "Текущие комнаты" tkabber-0.11.1/trans/uk.msg0000644000175000017500000000612011014607652015001 0ustar sergeisergei# uk.msg / 23.11.06 16:06 / Translated by Fixer (uzver@jabber.kiev.ua) # Ukrainian translation file for replying to other client queries ::trans::trset uk "Change status" "Змінити ÑтатуÑ" ::trans::trset uk "Change Status" "Зміна ÑтатуÑу" ::trans::trset uk "Choose chats or groupchats from which you want to forward messages" "Оберіть, з Ñких размов чи конференцій Ви хочете" ::trans::trset uk "Choose groupchats you want to leave" "Оберіть конференції, з котрих Ви хочете вийти" ::trans::trset uk "Choose status, priority, and status message" "Оберіть ÑтатуÑ, пріоритет чи ÑтатуÑне повідомленнÑ" ::trans::trset uk "Forward all messages" "ПереÑлати вÑÑ– повідомленнÑ" ::trans::trset uk "Forward messages from" "ПереÑлати Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð·" ::trans::trset uk "Forward unread messages" "ПереÑлати непрочитані повідомленнÑ" ::trans::trset uk "Forward Unread Messages" "ПереÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½ÐµÐ¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ð½Ð¸Ñ… повідомлень" ::trans::trset uk "Groupchats" "Конференції" ::trans::trset uk "Groupchats were leaved successfully" "Ви уÑпішно вийшли з конференції" ::trans::trset uk "Leave all groupchats" "Вийти з уÑÑ–Ñ… конференцій" ::trans::trset uk "Leave groupchats" "Вийти з конференцій" ::trans::trset uk "Leave Groupchats" "Вихід з конференцій" ::trans::trset uk "Message" "ПовідомленнÑ" ::trans::trset uk "No groupchats to leave" "Конференцій, з Ñких можна вийти, нема" ::trans::trset uk "Priority" "Пріоритет" ::trans::trset uk "Reason" "Причина" ::trans::trset uk "Remote control" "Віддалене керуваннÑ" ::trans::trset uk "%s at %s" "%s в %s" ::trans::trset uk "%s (%s)" ::trans::trset uk "%s: %s chat message(s)" "%s: %s повідомлень у розмові" ::trans::trset uk "%s: %s groupchat message(s)" "%s: %s повідомлень у конференції" ::trans::trset uk "%s: %s headline message(s)" "%s: %s новин" ::trans::trset uk "%s: %s normal message(s)" "%s: %s звичайних повідомлень" ::trans::trset uk "Status" "СтатуÑ" ::trans::trset uk "Status was changed successfully" "Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð·Ð¼Ñ–Ð½ÐµÐ½Ð¾ уÑпішно" ::trans::trset uk "There are no unread messages" "Ðепрочитаних повідомлень немає" ::trans::trset uk "Unread messages were forwarded successfully" "Ðепрочитані Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð¿ÐµÑ€ÐµÑлані уÑпішно" ::trans::trset uk "Available" "ДоÑтупний" ::trans::trset uk "Free to chat" "Вільний Ð´Ð»Ñ Ñ€Ð¾Ð·Ð¼Ð¾Ð²Ð¸" ::trans::trset uk "Away" "Відійшов" ::trans::trset uk "Extended away" "Давно відійшов" ::trans::trset uk "Do not disturb" "Ðе турбувати" ::trans::trset uk "Unavailable" "ÐедоÑтупний" ::trans::trset uk "Current rooms" "Поточні кімнати" tkabber-0.11.1/contrib/0000755000175000017500000000000011076120366014164 5ustar sergeisergeitkabber-0.11.1/contrib/extract-translations/0000755000175000017500000000000011076120366020355 5ustar sergeisergeitkabber-0.11.1/contrib/extract-translations/extract.tcl0000755000175000017500000001510211015004476022531 0ustar sergeisergei#!/usr/bin/tclsh # # Author: Vincent Ricard # Modified: Sergei Golovan package require fileutil package require cmdline set msgcat_regexp0 \ {::msgcat::mcset [a-zA-Z]+[ \t\r\n]+\"(([^\"]|\\\")*)\"} set msgcat_regexp1 \ {\[::msgcat::mc[ \t\r\n]+\"(([^\"]|\\\")*)\"} set msgcat_regexp2 \ {\[::msgcat::mc[ \t\r\n]+{([^\}]*)}} set msgcat_regexp3 \ {\[::msgcat::mc[ \t\r\n]+([^ \t\r\n\{\"\[\]]*)} set trans_regexp0 \ {::trans::trset [a-zA-Z]+[ \t\r\n]+\"(([^\"]|\\\")*)\"} set trans_regexp1 \ {\[::trans::trans[ \t\r\n]+(\$[^ \t\r\n]+[ \t\r\n]+)?\"(([^\"]|\\\")*)\"} set trans_regexp2 \ {\[::trans::trans[ \t\r\n]+(\$[^ \t\r\n]+[ \t\r\n]+)?{([^\}]*)}} set trans_regexp3 \ {\[::trans::trans[ \t\r\n]+(\$[^ \t\r\n]+[ \t\r\n]+)?([^ \t\r\n\{\"\[\]]*)} set options { {trans "Extract ::trans messages (::msgcat messages by default)"} {unused "Show unused translated messages"} {lang.arg ?? "Prepare messages for specified language, default is"} {showvars.secret "Show translatable strings with variables only"} } set usage ": extract.tcl \[options\] directory \[msgfile\]\noptions:" if {[catch { array set params [::cmdline::getoptions argv $options $usage] } msg]} { puts stderr $msg exit 1 } switch -- [llength $argv] { 1 { set sourceDir [lindex $argv 0] set translationFile "" } 2 { set sourceDir [lindex $argv 0] set translationFile [lindex $argv 1] } default { puts stderr [::cmdline::usage $options $usage] exit 1 } } set sourceDir [lindex $argv 0] set trans $params(trans) set invertMatch $params(unused) set lang $params(lang) if {$lang == "??"} { # take lang from the message file name regexp {([-a-z]+)\.msg$} $translationFile -> lang } set showvars $params(showvars) proc key_with_var {___key} { # The only variable which is defined here is ___key, but # it isn't likely to appear in translatable messages catch [list eval list $___key] } # Read all tcl file from sourceDir set tclFileList [::fileutil::findByPattern $sourceDir -glob -- *tcl] foreach filename $tclFileList { set fd [open $filename] while {[gets $fd line] >= 0} { while {[regexp {(^|[^\B])(\B\B)*\B$} $line] && [gets $fd line1] >= 0} { set line [string replace $line end end " [string trimleft $line1]"] } set line1 $line # Search: [ ::msgcat::mc "translation key" while {[regexp -- $msgcat_regexp1 $line1 whole key] || \ [regexp -- $msgcat_regexp2 $line1 whole key] || \ [regexp -- $msgcat_regexp3 $line1 whole key]} { if {$key != "" && ((![key_with_var $key] && !$showvars) || \ ([key_with_var $key] && $showvars))} { if {![info exists mkeyHash($filename)]} { # Create a new list (with the current key) for this file set mkeyHash($filename) [list $key] } elseif {[lsearch -exact $mkeyHash($filename) $key] < 0} { # key doesn't exist for this file lappend mkeyHash($filename) $key } } set idx [string first $whole $line1] set line1 [string replace $line1 0 [expr {$idx + [string length $whole] - 1}]] } set line1 $line # Search: [ ::trans::trans "translation key" while {[regexp -- $trans_regexp1 $line1 whole _lang key] || \ [regexp -- $trans_regexp2 $line1 whole _lang key] || \ [regexp -- $trans_regexp3 $line1 whole _lang key]} { if {$key != "" && ((![key_with_var $key] && !$showvars) || \ ([key_with_var $key] && $showvars))} { if {![info exists tkeyHash($filename)]} { # Create a new list (with the current key) for this file set tkeyHash($filename) [list $key] } elseif {[lsearch -exact $tkeyHash($filename) $key] < 0} { # key doesn't exist for this file lappend tkeyHash($filename) $key } } set idx [string first $whole $line1] set line1 [string replace $line1 0 [expr {$idx + [string length $whole] - 1}]] } } close $fd } proc remove_duplicate_keys {hashname} { upvar 1 $hashname hash set fileList [array names hash] for {set i 0} {$i < [llength $fileList]} {incr i} { for {set j [expr $i + 1]} {$j < [llength $fileList]} {incr j} { foreach k $hash([lindex $fileList $i]) { set J [lindex $fileList $j] set ix [lsearch -exact $hash($J) $k] if {-1 < $ix} { set hash($J) [lreplace $hash($J) $ix $ix] } } } } } # Remove duplicated keys (through all files) remove_duplicate_keys mkeyHash remove_duplicate_keys tkeyHash proc read_translation_file {filename regexp} { # Read translation file set fd [open $filename] fconfigure $fd -encoding utf-8 set translated [list] while {[gets $fd line] >= 0} { while {[regexp {(^|[^\B])(\B\B)*\B$} $line] && [gets $fd line1] >= 0} { set line [string replace $line end end " [string trimleft $line1]"] } if {[regexp -- $regexp $line whole key]} { lappend translated $key } } close $fd return $translated } proc print_all_results {hashname prefix lang} { upvar 1 $hashname hash foreach f [array names hash] { if {[llength $hash($f)] > 0} { puts "# $f" foreach k [lsort $hash($f)] { puts "$prefix $lang \"$k\"" } puts "" } } } if {$showvars} { print_all_results mkeyHash ::msgcat::mcset $lang print_all_results tkeyHash ::trans::trset $lang exit 0 } if {$trans} { upvar 0 tkeyHash hash set regexp $trans_regexp0 set prefix ::trans::trset } else { upvar 0 mkeyHash hash set regexp $msgcat_regexp0 set prefix ::msgcat::mcset } if {$translationFile != "" && [file readable $translationFile]} { set translated [read_translation_file $translationFile $regexp] if {!$invertMatch} { # Display untranslated keys foreach f [array names hash] { set displayFileName 1 foreach k [lsort $hash($f)] { if {[lsearch -exact $translated $k] < 0} { if {$displayFileName} { set displayFileName 0 puts "# $f" } puts "$prefix $lang \"$k\"" } } if {!$displayFileName} { puts "" } } } else { # Remove useless keys foreach t [lsort $translated] { set found 0 foreach f [array names hash] { if {[lsearch -exact $hash($f) $t] >= 0} { set found 1 } } if {!$found} { puts "\"$t\"" } } } } else { if {!$invertMatch} { # Print result print_all_results hash $prefix $lang } } tkabber-0.11.1/contrib/starkit/0000755000175000017500000000000011076120366015645 5ustar sergeisergeitkabber-0.11.1/contrib/starkit/README0000644000175000017500000001404310603637160016527 0ustar sergeisergei$Id: README 1078 2007-04-01 05:09:04Z sergei $ This file describes a sample startup script for Tkabber starkits/starpacks. I. Purpose. The "main.tcl" file is the "main startup script" for starkits; it is a Tcl script which task is to "bootstrap" the application wrapped in starkit. Although this script is a sample, it's ready, without any modifications, to be used for creation of a working starkit. Note that throughout this text the "starkit" term is used to refer to both Tkabber's starkits and starpacks since there is no difference between them in this context. II. Prerequisites. This scripts expects the starkit's VFS directory to be organised in this way: VFS_root_dir/ -- starkit's VFS root directory; lib/ -- Tcl/Tk extensions (like BWidget); tkabber/ -- Tkabber's code (tkabber.tcl must be placed here); ... main.tcl -- the starkit startup script. III. How it works. Besides the usual starkit initialization which is described in [1], this script performs two major tasks: * Defines the "starkit_init" Tcl procedure; * Sources the main Tkabber script -- "tkabber.tcl". Tkabber checks if the Tcl command named "starkit_init" is present in the global namespace and executes it (without passing any arguments to it) if it exists. At the time of calling "starkit_init" several global Tkabber variables are guaranteed to exist: * "rootdir", which is set to the full pathname of the directory containing the "tkabber.tcl" script; * "configdir", which holds the full pathname of the Tkabber's user configuration directory; * "toolkit_version", which holds the Tcl interpreter version. Also the hooks subsystem is guaranteed to be initialized so that the "starkit_init" procedure could make use of Tkabber hooks. The purpose of the "starkit_init" procedure is to make some preparations before the bulk of the Tkabber code is loaded but after Tkabber managed to initialize some subsystems/variables which might be crucial for the proper initialization of the starkit. The "starkit_init" procedure in the "main.tcl" script discussed here performs the following steps: * Appends the " (starkit)" string to the "toolkit_version" variable. This is done since the toolkit version is reported in response to the XMPP iq:version request, so it helps Tkabber supporters to better know a configuration a particular user runs. * "Forgets" about a Tcl package named "zlib" which is internal to any tclkit and confuses Tkabber forcing it to think that the XMPP stream compression can be used (which, in fact, requires another package -- "ztcl" -- which, in turn, provides another Tcl package named "zlib"). * Looks into two special directories and sources all the files whose names match the "*.kit" pattern. These directories are: * The directory where the running starkit is located; * The Tkabber's user configuration directory (held in the global variable named "configdir"). This allows to bring some Tcl/Tk packages wrapped in starkits in. Two popular starkits known to work with Tkabber's starkit are img.kit (containing the Img package) [2] and the snack.kit (containing the Snack sound kit package) [2]. If one or more of the kit files fail to load, a warning message with collected error messages is shown to the user and the loading process continues after the user dismisses this dialog. * Restores the "::starkit::topdir" variable which could be mangled by external starkits. * Sources the main Tkabber's script "tkabber.tcl". So, the outline of Tkabber bootstrapping process looks like this: * "main.tcl" is sourced by the tclkit reading the Tkabber's starkit. * "main.tcl" creates the global "starkit_init" procedure and sources the main Tkabber script, transferring control to Tkabber's code. * Tkabber performs some initialization steps, then finds the "starkit_init" command and executes it, effectively "calling the starkit code out". * "starkit_init" does its initialization steps, possibly bringing some external Tcl/Tk packages in, then gives control back to Tkabber. * Tkabber then continues with its loading as usually. IV. Differences between 0.10.0 and pre-0.10.0 starkits: Versions of Tkabber earlier that 0.10.0 had more limited support for starkits. Since 0.10.0 Tkabber has received some changes that allow to create fully-functional and customizable starkits without patching the Tkabber's code (as must have been done earlier). In short, the differences include: * The "rootdir" global variable is now initialized based on the actual full pathname of the "tkabber.tcl" script, so that Tkabber's code can now be located in an arbitrary directory in the starkit VFS. Note though that the sample "main.tcl" does make its assumption about where Tkabber's code is located. * Tkabber now "calls out" the starkit code in the course of its initialization process which differs from the old way the things worked when transferring the control to Tkabber's code was the last thing the starkit's initialization code did. * The official Tkabber starkits/starpacks made a Tcl package from the Tkabber's source tree. There were not much point to do so, that's why the discussed "main.tcl" just sources the main Tkabber script now. V. Additional stuff. Ruslan Rakhmanin [3] has created a sample "Windows Tkabber starpack tool" which contains all necessary files to build a Tkabber starpack for Windows in the Windows environment (Windows 2000 and later is required). To build starpack using this tool you only need (recent) Tkabber sources. Also this starpack tool uses a modified tclkit which contains a full set of cp* Windows charsets (which original tclkits lack) thus providing the full support for non-Latin-1 alphabets. There's an article (written in Russian) on the official Tkabber wiki describing this tool [4]. A direct link to the RAR-archive containing this tool is [5]. VI. Reference materials: 1. http://wiki.tcl.tk/8186 2. http://mini.net/sdarchive/ 3. xmpp:archimed@jabber.ru 4. http://ru.tkabber.jabe.ru/index.php/Tkabber_starpack 5. http://ru.tkabber.jabe.ru/images/ru.tkabber.jabe.ru/a/ad/Tkabber_win32_starpack_template.rar tkabber-0.11.1/contrib/starkit/main.tcl0000644000175000017500000000243010607454412017275 0ustar sergeisergei# $Id: main.tcl 1104 2007-04-12 16:06:34Z sergei $ # Sample startup file for the Tkabber starkit. # See README for details. # See: http://wiki.tcl.tk/8186 package require starkit if {[string equal [starkit::startup] sourced]} return # Linux tclkits don't load Tk themselves: package require Tk proc starkit_init {args} { global configdir toolkit_version variable starkit::topdir # Prevent bogus zlib package from confusing Tkabber # (stream compression doesn't work in starkits using vanilla Tkabber): package forget zlib append toolkit_version " (starkit)" set spath $configdir if {[info exists topdir]} { lappend spath [file dirname $topdir] } # Preserve the value of ::starkit::topdir before loading # another starkits, see: http://wiki.tcl.tk/8186 set top $topdir set log "" foreach dir $spath { foreach kit [glob -type f -dir $dir -nocomplain *.kit] { set failed [catch { source $kit } err] if {$failed} { append log "\nFile: $kit\nError: $err" } } } set topdir $top if {$log != ""} { tk_messageBox -icon error -title "Startup problem" \ -message "Failed to load some .kit files:\n$log" } } source [file join [file dirname [info script]] tkabber tkabber.tcl] # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/contrib/gabber-docking-24x24/0000755000175000017500000000000011076120366017603 5ustar sergeisergeitkabber-0.11.1/contrib/gabber-docking-24x24/gabber-docking-24x24.zip0000644000175000017500000000516507644355550023770 0ustar sergeisergeiPKhO.î™Hal available.gifs÷t³°L”``XÊÿ¯gþ¿˜øj§Û“-Žÿï—ü¿÷óDø½uÖ×—›þÿñÿ“êÿWR?ì÷½¸PÿÔl­ÿË_ïr¿¼Øðè4µ[«,¾ ÞÛ§xb¦æ›ÝÛ;eMWÿ>~C“dccã™3gííí8ðŸ6@ñŸ¨sQjbIjŠByfI†BHFª‚»§oƒâOF.{Aže`+80¿ÀCGªÿÄ’¢“9Vó½Dd™˜š¹öŠñ°»4Ýþ¢%ÖÓöØ1މ…ÕE`¢Ï­‹—‡èTx2°ˆKÖ H66qJIswvò óv…:1HÊLÊ šÁ +'+?·‰AAqÁB%ÙåóflÚ¼e«»#ƒ5PKhO.àêylavailable-away.gifs÷t³°L”``XÊ'(oèUš[%:³\xÛdõÍ“TVuÊN*ìÏ῱ÕsÇt… Ý™¼m)<;¦jÌ«ëÎäkNäžT ¸¬Eº6š³5‰§2Šc}bi{ccã™3gííí8ðŸÆ@ñŸ¨sQjbIjŠByfI†BHFª‚»§oƒâOF.Aže`+p˜Pà¡#ÕbIÑÉ«ù^ " ²LLMŒ\{ÅxØ]šnÑct;ìÇÄÂvÔ™¡ÓãÖŃŒÜ3´*<XÄjEøÅ›8…$¸;»ù„xºBÄ%'åÍ`’–’™ÛÄ +·`¡¼Ôòy36mÞ²ÕÝ‘ÁPKhO.2Ö4$available-chat.gifs÷t³°L”``haÓK4O-Ö8±PíüJ½kÍon±9¹Hýê³;;ž :·B÷îNÇÏ7 ~ï[ýrÓ¬{Ëz¯Ík9Ö•¿¯)åܤ’Måá˲|¦ºLŒ´YUØà­÷ŸD øOÔ¹(5±$5E¡<³$C!$#UÁÝÓ7€Añ' #ƒƒ€ÃÀÚ¢ Ò—’9/cÕºœ×û4Îoȹ¥Ý÷j;÷›Í &”1±°41.L0áëÈx.rbÃQ¦† †RWf—2œàc0‘Ü£<›û¹ICB‹wñ/µºÌÛ¬ ø ê ¸ÊUêÊ ØËJÒb­ƒ[8›S˜3¬Ùù,àååáæâàL3t^c°ný†ÚŠ ÖPKhO.tŒÏÂ%*available-xa.gifs÷t³°L”``haoÿÿŸýõï§ÿkýŸsé÷±ÿÅÛ¾e­{7áø¯Ö£–•[ s×h&ÎYóèOýö[3.þÉ[~¡ëÐÃÕÿæ¬IZú̧}OÐÔ³GþØ”o’hþ ÿ‰:¥&–¤¦(”g–d(„d¤*¸{ú0(þdaäbgÐ9äÖ¾ê})™ó2V­Ëy½OSáü†œ[Ú}¯¶s¿Ù¼`B S㾎ÃyxšY,ˆ8!ÑÃöUMA¦_—9Á ç¨u£´PâzÞ{‡ªÜ-> { %W yview scroll -5 units } bind Text <> { %W yview scroll 5 units } bind Listbox <> { %W yview scroll -5 units } bind Listbox <> { %W yview scroll 5 units } bind Text <> { %W xview scroll -10 units } bind Text <> { %W xview scroll 10 units } bind Listbox <> { %W xview scroll -10 units } bind Listbox <> { %W xview scroll 10 units } if {([catch { tk windowingsystem }] && $::tcl_platform(platform) == "unix") || (![catch { tk windowingsystem }] && [tk windowingsystem] == "x11")} { event add <> <4> event add <> <5> event add <> event add <> } if {$::tcl_platform(platform) == "windows"} { # workaround for shortcuts in russian keyboard layout event add <> event add <> event add <> event add <> event add <> event add <> event add <> } tkabber-0.11.1/ifacetk/ilogin.tcl0000644000175000017500000003747710667246012016143 0ustar sergeisergei# $Id: ilogin.tcl 1220 2007-09-04 12:14:02Z sergei $ proc update_login_entries {l {i 0}} { global ltmp if {$i} { array set ltmp [array get ::loginconf$i] array set loginconf [array get ltmp] } foreach ent {username server port password resource priority \ altserver proxyhost proxyport proxyusername proxypassword \ sslcertfile pollurl} { if {[winfo exists $l.$ent]} { catch { $l.$ent icursor end } } } foreach {check enable disable} { \ usehttppoll {lpollurl pollurl usepollkeys} \ {dontusessl usecompress legacyssl encrypted \ sslcertfile lsslcertfile bsslcertfile} \ usealtserver {altserver laltserver port lport} {} \ usesasl {allowgoogletoken} {} \ } { if {![info exists ltmp($check)] || ![winfo exists $l.$check]} { continue } if {$ltmp($check) && ![cequal [$l.$check cget -state] disabled]} { set state1 normal set state2 disabled } else { set state1 disabled set state2 normal } foreach ent $enable { if {[winfo exists $l.$ent]} { $l.$ent configure -state $state1 if {[cequal [focus] $l.$ent] && [cequal $state1 "disabled"]} { focus [Widget::focusPrev $l.$ent] } } } foreach ent $disable { if {[winfo exists $l.$ent]} { $l.$ent configure -state $state2 if {[cequal [focus] $l.$ent] && [cequal $state2 "disabled"]} { focus [Widget::focusPrev $l.$ent] } } } } catch { if {[cequal $ltmp(proxy) none]} { foreach ent {proxyhost proxyport proxyusername proxypassword \ lproxyhost lproxyport lproxyusername lproxypassword} { $l.$ent configure -state disabled if {[cequal [focus] $l.$ent]} { focus [Widget::focusPrev $l.$ent] } } } else { foreach ent {proxyhost proxyport proxyusername proxypassword \ lproxyhost lproxyport lproxyusername lproxypassword} { $l.$ent configure -state normal } } } catch { if {![cequal [$l.dontusessl cget -state] disabled] && \ ($ltmp(stream_options) == "ssl" || \ $ltmp(stream_options) == "encrypted")} { $l.sslcertfile configure -state normal $l.lsslcertfile configure -state normal $l.bsslcertfile configure -state normal } else { $l.sslcertfile configure -state disabled $l.lsslcertfile configure -state disabled $l.bsslcertfile configure -state disabled if {[cequal [focus] $l.sslcertfile] || \ [cequal [focus] $l.bsslcertfile]} { focus [Widget::focusPrev $l.sslcertfile] } } } } proc login_dialog {} { global loginconf global ltmp global use_tls have_compress have_sasl have_http_poll have_proxy if {[winfo exists .login]} { focus -force .login return } array set ltmp [array get loginconf] Dialog .login -title [::msgcat::mc "Login"] \ -separator 1 -anchor e -default 0 -cancel 1 wm resizable .login 0 0 set l [.login getframe] set n 1 while {[info exists ::loginconf$n]} {incr n} incr n -1 if {$n} { menubutton $l.profiles -text [::msgcat::mc "Profiles"] \ -relief $::tk_relief -menu $l.profiles.menu set m [menu $l.profiles.menu -tearoff 0] for {set i 1} {$i <= $n} {incr i} { if {[info exists ::loginconf${i}(profile)]} { set lab [set ::loginconf${i}(profile)] } else { set lab "[::msgcat::mc Profile] $i" } if {$i <= 10} { set j [expr {$i % 10}] $m add command -label $lab -accelerator "$::tk_modify-$j" \ -command [list [namespace current]::update_login_entries $l $i] bind .login \ [list [namespace current]::update_login_entries $l $i] } else { $m add command -label $lab \ -command [list [namespace current]::update_login_entries $l $i] } } grid $l.profiles -row 0 -column 0 -sticky e } set nb [NoteBook $l.nb] set account_page [$nb insert end account_page -text [::msgcat::mc "Account"]] label $l.lusername -text [::msgcat::mc "Username:"] entry $l.username -textvariable ltmp(user) label $l.lserver -text [::msgcat::mc "Server:"] entry $l.server -textvariable ltmp(server) label $l.lpassword -text [::msgcat::mc "Password:"] entry $l.password -show * -textvariable ltmp(password) label $l.lresource -text [::msgcat::mc "Resource:"] entry $l.resource -textvariable ltmp(resource) label $l.lpriority -text [::msgcat::mc "Priority:"] Spinbox $l.priority -1000 1000 1 ltmp(priority) grid $l.lusername -row 0 -column 0 -sticky e -in $account_page grid $l.username -row 0 -column 1 -sticky ew -in $account_page grid $l.lserver -row 0 -column 2 -sticky e -in $account_page grid $l.server -row 0 -column 3 -sticky ew -in $account_page grid $l.lpassword -row 1 -column 0 -sticky e -in $account_page grid $l.password -row 1 -column 1 -sticky ew -in $account_page grid $l.lresource -row 2 -column 0 -sticky e -in $account_page grid $l.resource -row 2 -column 1 -sticky ew -in $account_page grid $l.lpriority -row 2 -column 2 -sticky e -in $account_page grid $l.priority -row 2 -column 3 -sticky ew -in $account_page grid columnconfigure $account_page 1 -weight 3 grid columnconfigure $account_page 2 -weight 1 grid columnconfigure $account_page 3 -weight 3 set connection_page [$nb insert end connection_page -text [::msgcat::mc "Connection"]] checkbutton $l.usealtserver -text [::msgcat::mc "Explicitly specify host and port to connect"] \ -variable ltmp(usealtserver) \ -command [list [namespace current]::update_login_entries $l] label $l.laltserver -text [::msgcat::mc "Host:"] entry $l.altserver -textvariable ltmp(altserver) label $l.lport -text [::msgcat::mc "Port:"] Spinbox $l.port 0 65535 1 ltmp(altport) grid $l.usealtserver -row 0 -column 0 -sticky w -columnspan 4 -in $connection_page grid $l.laltserver -row 1 -column 0 -sticky e -in $connection_page grid $l.altserver -row 1 -column 1 -sticky ew -in $connection_page grid $l.lport -row 1 -column 2 -sticky e -in $connection_page grid $l.port -row 1 -column 3 -sticky we -in $connection_page checkbutton $l.replace -text [::msgcat::mc "Replace opened connections"] \ -variable ltmp(replace_opened) grid $l.replace -row 3 -column 0 -sticky w -columnspan 3 -in $connection_page grid columnconfigure $connection_page 1 -weight 6 grid columnconfigure $connection_page 2 -weight 1 set auth_page [$nb insert end auth_page -text [::msgcat::mc "Authentication"]] checkbutton $l.allowauthplain \ -text [::msgcat::mc "Allow plaintext authentication mechanisms"] \ -variable ltmp(allowauthplain) \ -command [list [namespace current]::update_login_entries $l] grid $l.allowauthplain -row 0 -column 0 -sticky w -in $auth_page if {$have_sasl} { checkbutton $l.usesasl \ -text [::msgcat::mc "Use SASL authentication"] \ -variable ltmp(usesasl) \ -command [list [namespace current]::update_login_entries $l] grid $l.usesasl -row 1 -column 0 -sticky w -in $auth_page checkbutton $l.allowgoogletoken \ -text [::msgcat::mc "Allow X-GOOGLE-TOKEN SASL mechanism"] \ -variable ltmp(allowgoogletoken) \ -command [list [namespace current]::update_login_entries $l] grid $l.allowgoogletoken -row 2 -column 0 -sticky w -in $auth_page } grid columnconfigure $auth_page 0 -weight 1 if {$use_tls || $have_compress} { if {$use_tls && $have_compress} { set page_label [::msgcat::mc "SSL & Compression"] } elseif {$have_compress} { set page_label [::msgcat::mc "Compression"] } else { set page_label [::msgcat::mc "SSL"] } set ssl_page [$nb insert end ssl_page -text $page_label] radiobutton $l.dontusessl -text [::msgcat::mc "Plaintext"] \ -variable ltmp(stream_options) -value plaintext \ -command [list [namespace current]::update_login_entries $l] if {$have_compress} { radiobutton $l.usecompress -text [::msgcat::mc "Compression"] \ -variable ltmp(stream_options) -value compressed \ -command [list [namespace current]::update_login_entries $l] } if {$use_tls} { radiobutton $l.encrypted -text [::msgcat::mc "Encryption (STARTTLS)"] \ -variable ltmp(stream_options) -value encrypted \ -command [list [namespace current]::update_login_entries $l] radiobutton $l.legacyssl -text [::msgcat::mc "Encryption (legacy SSL)"] \ -variable ltmp(stream_options) -value ssl \ -command [list [namespace current]::update_login_entries $l] label $l.lsslcertfile -text [::msgcat::mc "SSL certificate:"] entry $l.sslcertfile -textvariable ltmp(sslcertfile) button $l.bsslcertfile -text [::msgcat::mc "Browse..."] \ -command [list eval set ltmp(sslcertfile) {[tk_getOpenFile]}] } set column 0 grid $l.dontusessl -row 0 -column $column -sticky w -in $ssl_page if {$have_compress} { grid $l.usecompress -row 0 -column [incr column] -sticky w -in $ssl_page } if {$use_tls} { grid $l.encrypted -row 0 -column [incr column] -sticky w -in $ssl_page grid $l.legacyssl -row 0 -column [incr column] -sticky w -in $ssl_page grid $l.lsslcertfile -row 1 -column 0 -sticky e -in $ssl_page grid $l.sslcertfile -row 1 -column 1 -sticky ew -columnspan 2 -in $ssl_page grid $l.bsslcertfile -row 1 -column 3 -sticky w -in $ssl_page } grid columnconfigure $ssl_page 1 -weight 1 grid columnconfigure $ssl_page 2 -weight 1 } if {$have_http_poll} { set httppoll_page [$nb insert end httpoll_page -text [::msgcat::mc "HTTP Poll"]] checkbutton $l.usehttppoll -text [::msgcat::mc "Connect via HTTP polling"] \ -variable ltmp(usehttppoll) \ -command [list [namespace current]::update_login_entries $l] label $l.lpollurl -text [::msgcat::mc "URL to poll:"] entry $l.pollurl -textvariable ltmp(pollurl) checkbutton $l.usepollkeys -text [::msgcat::mc "Use client security keys"] \ -state disabled \ -variable ltmp(usepollkeys) \ -command [list [namespace current]::update_login_entries $l] grid $l.usehttppoll -row 0 -column 0 -sticky w -columnspan 3 -in $httppoll_page grid $l.lpollurl -row 1 -column 0 -sticky e -in $httppoll_page grid $l.pollurl -row 1 -column 1 -sticky ew -in $httppoll_page grid $l.usepollkeys -row 2 -column 0 -sticky w -columnspan 3 -in $httppoll_page grid columnconfigure $httppoll_page 1 -weight 1 } if {$have_proxy} { set proxy_page [$nb insert end proxy_page -text [::msgcat::mc "Proxy"]] label $l.lproxy -text [::msgcat::mc "Proxy type:"] grid $l.lproxy -row 0 -column 0 -sticky e -in $proxy_page frame $l.proxy grid $l.proxy -row 0 -column 1 -columnspan 3 -sticky w -in $proxy_page set col 0 foreach type [jlib::capabilities proxy] { switch -- $type { none { radiobutton $l.proxy.none -text [::msgcat::mc "None"] \ -variable ltmp(proxy) -value none \ -command [list [namespace current]::update_login_entries $l] grid $l.proxy.none -row 0 -column [incr col] -sticky w } socks4 { radiobutton $l.proxy.socks4 -text [::msgcat::mc "SOCKS4a"] \ -variable ltmp(proxy) -value socks4 \ -command [list [namespace current]::update_login_entries $l] grid $l.proxy.socks4 -row 0 -column [incr col] -sticky w } socks5 { radiobutton $l.proxy.socks5 -text [::msgcat::mc "SOCKS5"] \ -variable ltmp(proxy) -value socks5 \ -command [list [namespace current]::update_login_entries $l] grid $l.proxy.socks5 -row 0 -column [incr col] -sticky w } https { radiobutton $l.proxy.https -text [::msgcat::mc "HTTPS"] \ -variable ltmp(proxy) -value https \ -command [list [namespace current]::update_login_entries $l] grid $l.proxy.https -row 0 -column [incr col] -sticky w } } } label $l.lproxyhost -text [::msgcat::mc "Proxy server:"] entry $l.proxyhost -textvariable ltmp(proxyhost) label $l.lproxyport -text [::msgcat::mc "Proxy port:"] Spinbox $l.proxyport 0 65535 1 ltmp(proxyport) grid $l.lproxyhost -row 1 -column 0 -sticky e -in $proxy_page grid $l.proxyhost -row 1 -column 1 -sticky ew -in $proxy_page grid $l.lproxyport -row 1 -column 2 -sticky e -in $proxy_page grid $l.proxyport -row 1 -column 3 -sticky ew -in $proxy_page label $l.lproxyusername -text [::msgcat::mc "Proxy username:"] ecursor_entry [entry $l.proxyusername -textvariable ltmp(proxyusername)] label $l.lproxypassword -text [::msgcat::mc "Proxy password:"] ecursor_entry [entry $l.proxypassword -show * -textvariable ltmp(proxypassword)] grid $l.lproxyusername -row 2 -column 0 -sticky e -in $proxy_page grid $l.proxyusername -row 2 -column 1 -sticky ew -in $proxy_page grid $l.lproxypassword -row 2 -column 2 -sticky e -in $proxy_page grid $l.proxypassword -row 2 -column 3 -sticky ew -in $proxy_page grid columnconfigure $proxy_page 1 -weight 3 grid columnconfigure $proxy_page 2 -weight 1 grid columnconfigure $proxy_page 3 -weight 3 } $nb compute_size $nb raise account_page bind .login [list [namespace current]::tab_move $nb -1] bind .login [list [namespace current]::tab_move $nb 1] grid $nb -row 1 -column 0 .login add -text [::msgcat::mc "Log in"] -command { array set loginconf [array get ltmp] destroy .login if {$loginconf(replace_opened)} { logout } update login [array get loginconf] } .login add -text [::msgcat::mc "Cancel"] -command {destroy .login} update_login_entries $l if {[cequal $ltmp(user) ""]} { .login draw $l.username } elseif {[cequal $ltmp(password) ""]} { .login draw $l.password } else { .login draw $l.resource } } hook::add finload_hook { if {(![info exist ::autologin]) || ($::autologin == 0)} { ifacetk::login_dialog } elseif {$::autologin > 0} { logout update login [array get ::loginconf] } } 9999 proc logout_dialog {} { global logout_conn set w .logout if {[winfo exists $w]} { destroy $w } switch -- [llength [jlib::connections]] { 0 { return } 1 { logout return } } set lnames {} foreach connid [jlib::connections] { lappend lnames $connid [jlib::connection_jid $connid] } if {[CbDialog $w [::msgcat::mc "Logout"] \ [list [::msgcat::mc "Log out"] [list $w enddialog 0] \ [::msgcat::mc "Cancel"] [list $w enddialog 1]] \ logout_conn $lnames {} -modal local] != 0} { return } foreach connid [array names logout_conn] { if {[lcontain [jlib::connections] $connid] && $logout_conn($connid)} { logout $connid } } } # TODO proc change_password_dialog {} { global oldpassword newpassword password set oldpassword "" set newpassword "" set password "" if {[winfo exists .passwordchange]} { destroy .passwordchange } Dialog .passwordchange -title [::msgcat::mc "Change password"] \ -separator 1 -anchor e -default 0 -cancel 1 .passwordchange add -text [::msgcat::mc "OK"] -command { destroy .passwordchange send_change_password } .passwordchange add -text [::msgcat::mc "Cancel"] -command [list destroy .passwordchange] set p [.passwordchange getframe] label $p.loldpass -text [::msgcat::mc "Old password:"] ecursor_entry [entry $p.oldpass -show * -textvariable oldpassword] label $p.lnewpass -text [::msgcat::mc "New password:"] ecursor_entry [entry $p.newpass -show * -textvariable newpassword] label $p.lpassword -text [::msgcat::mc "Repeat new password:"] ecursor_entry [entry $p.password -show * -textvariable password] grid $p.loldpass -row 0 -column 0 -sticky e grid $p.oldpass -row 0 -column 1 -sticky ew grid $p.lnewpass -row 1 -column 0 -sticky e grid $p.newpass -row 1 -column 1 -sticky ew grid $p.lpassword -row 2 -column 0 -sticky e grid $p.password -row 2 -column 1 -sticky ew focus $p.oldpass .passwordchange draw } tkabber-0.11.1/ifacetk/default.xrdb0000644000175000017500000000045610665573256016461 0ustar sergeisergei*Chat.chatgeometry: 400x400 *Chat.groupchatgeometry: 500x500 *Customize.geometry: 600x500 *RawXML.geometry: 500x500 *Stats.geometry: 500x500 *Messages.geometry: 600x500 *JDisco.geometry: 500x500 *Chat.inputheight: 3 *RawXML.inputheight: 4 *font: -*-helvetica-medium-r-*-*-13-*-*-*-*-*-*-* tkabber-0.11.1/ifacetk/bwidget_workarounds.tcl0000644000175000017500000002166611014021262020717 0ustar sergeisergei# $Id: bwidget_workarounds.tcl 1429 2008-05-18 12:36:02Z sergei $ ########################################################################## auto_load Button rename Button::create Button::create_old proc Button::create {path args} { set new_args {} foreach {attr val} $args { switch -- $attr { -background { } default { lappend new_args $attr $val } } } eval [list Button::create_old $path] $new_args } ########################################################################## rename menu menu_old proc menu {path args} { set new_args {} foreach {attr val} $args { switch -- $attr { -background { } default { lappend new_args $attr $val } } } eval [list menu_old $path] $new_args } ########################################################################## if {[info tclversion] >= 8.4} { rename frame frame_old proc frame {path args} { set new_args {} foreach {attr val} $args { switch -- $attr { -class { lappend new_args $attr $val if {$val == "Tree"} { lappend new_args -padx 0 } } default { lappend new_args $attr $val } } } eval [list frame_old $path] $new_args } } ########################################################################## auto_load Tree proc Tree::_see {path idn {side "none"}} { set bbox [$path.c bbox $idn] set scrl [$path.c cget -scrollregion] set ymax [lindex $scrl 3] set dy [$path.c cget -yscrollincrement] set yv [$path yview] set yv0 [expr {round([lindex $yv 0]*$ymax/$dy)}] set yv1 [expr {int([lindex $yv 1]*$ymax/$dy + 0.1)}] set y [expr {int([lindex [$path.c coords $idn] 1]/$dy)}] if { $y < $yv0 } { $path.c yview scroll [expr {$y-$yv0}] units } elseif { $y >= $yv1 } { $path.c yview scroll [expr {$y-$yv1+1}] units } set xmax [lindex $scrl 2] set dx [$path.c cget -xscrollincrement] set xv [$path xview] if { ![string compare $side "none"] } { set x0 [expr {int([lindex $bbox 0]/$dx)}] set xv0 [expr {round([lindex $xv 0]*$xmax/$dx)}] set xv1 [expr {round([lindex $xv 1]*$xmax/$dx)}] if { $x0 >= $xv1 || $x0 < $xv0 } { $path.c xview scroll [expr {$x0-$xv0}] units } } elseif { ![string compare $side "right"] } { set xv1 [expr {round([lindex $xv 1]*$xmax/$dx)}] set x1 [expr {int([lindex $bbox 2]/$dx)}] if { $x1 >= $xv1 } { $path.c xview scroll [expr {$x1-$xv1+1}] units } } else { set xv0 [expr {round([lindex $xv 0]*$xmax/$dx)}] set x0 [expr {int([lindex $bbox 0]/$dx)}] if { $x0 < $xv0 } { $path.c xview scroll [expr {$x0-$xv0}] units } } } rename Tree::create Tree::create:old proc Tree::create {path args} { eval [list Tree::create:old $path] $args Tree::bindText $path [list $path selection set] Tree::bindImage $path [list $path selection set] return $path } ########################################################################## if {0 && [info tclversion] >= 8.5} { proc PanedWin {path args} { set newargs [list -showhandle 0] set pad 0 foreach {key val} $args { switch -- $key { -side { switch -- $val { left - right { lappend newargs -orient vertical } top - bottom { lappend newargs -orient horizontal } } } -pad { set pad [expr {$pad + $val}] } -width { set pad [expr {$pad + ($val >> 2)}] } } } if {$pad > 0} { lappend newargs -sashpad $pad } return [eval [list panedwindow $path] $newargs] } proc PanedWinAdd {path args} { set newargs {} foreach {key val} $args { switch -- $key { -minsize { lappend newargs -minsize $val } -weight { if {$val == 0} { lappend newargs -stretch never } else { lappend newargs -stretch always } } } } set idx [llength [$path panes]] set f [frame $path.frame$idx] eval [list $path add $f] $newargs return $f } proc PanedWinConf {path index args} { lassign $args key val set f [lindex [$path panes] $index] switch -- [llength $args] { 1 { switch -- $key { -width { return [$path panecget $f -width] } default { return -code error "PanedWinConf: Unknown option $key" } } } 2 { switch -- $key { -width { puts "$index $f $val" $path paneconfigure $f -width $val } default { return -code error "PanedWinConf: Unknown option $key" } } } default { return -code error "PanedWinConf: Illegal number of arguments" } } } } else { proc PanedWin {path args} { if {[catch { eval [list PanedWindow $path] $args -activator line } res]} { return [eval [list PanedWindow $path] $args] } else { return $res } } proc PanedWinAdd {path args} { set res [eval [list $path add] $args] catch { set activator [Widget::getoption $path -activator] if {$activator == ""} { if { $::tcl_platform(platform) != "windows" } { set activator button } else { set activator line } } if {$activator == "line"} { set side [Widget::getoption $path -side] set num $PanedWindow::_panedw($path,nbpanes) incr num -1 if {$num > 0} { $path.sash$num.sep configure -relief flat if {$side == "top" || $side == "bottom"} { place configure $path.sash$num.sep -width 4 } else { place configure $path.sash$num.sep -height 4 } } } } return $res } proc PanedWinConf {path index args} { lassign $args key val set f [winfo parent [$path getframe $index]] switch -- [llength $args] { 1 { switch -- $key { -width { return [$f cget -width] } default { return -code error "PanedWinConf: Unknown option $key" } } } 2 { switch -- $key { -width { $f configure -width $val } default { return -code error "PanedWinConf: Unknown option $key" } } } default { return -code error "PanedWinConf: Illegal number of arguments" } } } } ########################################################################## auto_load ComboBox option add *ComboBox.listRelief ridge widgetDefault option add *ComboBox.listBorder 2 widgetDefault rename ComboBox::_create_popup ComboBox::_create_popup_old proc ComboBox::_create_popup {path args} { eval [list ComboBox::_create_popup_old $path] $args $path.shell configure \ -relief [option get $path listRelief ComboBox] \ -border [option get $path listBorder ComboBox] } rename ComboBox::create ComboBox::create_old proc ComboBox::create {path args} { set hlthick $::tk_highlightthickness foreach {opt arg} $args { if {[cequal $opt "-highlightthickness"]} { set hlthick $arg } } eval [list ComboBox::create_old $path] $args -highlightthickness 0 $path:cmd configure -highlightthickness $hlthick return $path } ########################################################################## auto_load NoteBook if {![catch { rename NoteBook::_get_page_name NoteBook::_get_page_name:old }]} { proc NoteBook::_get_page_name { path {item current} {tagindex end-1} } { set pagename [NoteBook::_get_page_name:old $path $item $tagindex] if {[catch { NoteBook::_test_page $path $pagename }]} { return [string range [lindex [$path.c gettags $item] 1] 2 end] } else { return $pagename } } } ########################################################################## if {($::tcl_platform(platform) != "unix") || ($::aquaP)} { auto_load SelectFont rename SelectFont::create SelectFont::create:old proc SelectFont::create {path args} { eval [list SelectFont::create:old $path] $args foreach style {bold italic underline overstrike} { if {![catch { set bd [option get $path.$style \ borderWidth Button] }]} { if {$bd != ""} { $path.$style configure -bd $bd } } } return $path } } ########################################################################## proc BWidget::bindMouseWheel {widget} {} ########################################################################## auto_load Dialog rename Dialog::create Dialog::create:old proc Dialog::create {path args} { toplevel $path wm withdraw $path set parent [winfo parent $path] destroy $path set transient 1 set newargs {} foreach {key val} $args { switch -- $key { -parent { set parent $val ; lappend newargs -parent $val } -transient { set transient $val } default { lappend newargs $key $val } } } # Do not make a dialog window transient if its parent isn't vewable. # Otherwise it leads to hang of a whole application. if {$parent == ""} { set parent . } if {![winfo viewable [winfo toplevel $parent]] } { set transient 0 } eval {Dialog::create:old $path -transient $transient} $newargs } ########################################################################## tkabber-0.11.1/ifacetk/systray.tcl0000644000175000017500000002154111054503013016345 0ustar sergeisergei# $Id: systray.tcl 1488 2008-08-25 10:14:35Z sergei $ # Tray icon support. # See also plugins/unix/systray.tcl, plugins/unix/dokingtray.tcl, # plugins/windows/taskbar.tcl. ########################################################################## namespace eval systray { variable saved_state normal variable saved_geometry variable balloon "" variable s2p array set s2p {} variable icons {} variable options custom::defgroup Systray [::msgcat::mc "Systray icon options."] \ -group IFace custom::defvar options(display_status) 0 \ [::msgcat::mc "Display status tooltip when main window is minimized\ to systray."] \ -group Systray -type boolean custom::defvar options(blink) 0 \ [::msgcat::mc "Systray icon blinks when there are unread messages."] \ -group Systray -type boolean } ########################################################################## proc systray::token {icon} { return [namespace current]::$icon } ########################################################################## proc systray::create {icon args} { global curuserstatus variable icons set token [token $icon] if {[info exists $token]} { return -code error "Systray icon $icon exists" } lappend icons $icon upvar 0 $token state array set state {create "" configure "" destroy "" tray ""} foreach {key val} $args { switch -- $key { -createcommand { set state(create) $val } -configurecommand { set state(configure) $val } -destroycommand { set state(destroy) $val } -locationcommand { set state(location) $val } } } uplevel #0 $state(create) [list $icon] update $icon ::curuserstatus update $icon ::tabcolors foreach var [list curuserstatus tabcolors] { trace variable ::$var w [namespace code [list update $icon]] } } ########################################################################## proc systray::destroy {icon} { variable icons catch { upvar 0 [token $icon] state uplevel #0 $state(destroy) [list $icon] unset state set id [lsearch -exact $icons $icon] if {$id >= 0} { set icons [lreplace $icons $id $id] } } foreach var [list curuserstatus tabcolors] { trace vdelete ::$var w [namespace code [list update $icon]] } } ########################################################################## proc systray::popupmenu {m} { set tearoff [set [namespace parent]::options(show_tearoffs)] menu $m -title [::msgcat::mc "Tkabber Systray"] -tearoff $tearoff $m add command -label [::msgcat::mc "About"] \ -command [list [namespace parent]::about_window] $m add separator menu $m.presence -title [::msgcat::mc "Presence"] -tearoff $tearoff set pm [.mainframe getmenu presence] set id [$pm index [::msgcat::mc "Available"]] for {set i 0} {$i < 7} {incr i} { if {[catch { $pm entryconfigure $id -label }]} { $m.presence add separator } else { $m.presence add command \ -label [lindex [$pm entryconfigure $id -label] 4] \ -command [lindex [$pm entryconfigure $id -command] 4] } incr id } $m add cascade -label [::msgcat::mc "Presence"] -menu $m.presence set tm [.mainframe getmenu tkabber] set id [$tm index [::msgcat::mc "Log in..."]] for {set i 0} {$i < 3} {incr i} { $m add command -label [lindex [$tm entryconfigure $id -label] 4] \ -command [lindex [$tm entryconfigure $id -command] 4] incr id } $m add separator $m add command -label [::msgcat::mc "Show main window"] \ -command [namespace code restore] $m add command -label [::msgcat::mc "Hide main window"] \ -command [namespace code withdraw] $m add separator $m add command -label [::msgcat::mc "Quit"] -command quit return $m } ########################################################################## # Withdraws the main Tkabber window from the screen: proc systray::withdraw {} { variable saved_state variable saved_geometry if {[cequal [wm state .] withdrawn]} return set saved_state [wm state .] set saved_geometry [wm geometry .] wm withdraw . } # Iconifies the main Tkabber window: proc systray::iconify {} { if {[cequal [wm state .] iconic]} return wm iconify . } # De-withdraws the main Tkabber window: proc systray::reshow {} { variable saved_state variable saved_geometry if {![cequal [wm state .] withdrawn]} return if {[info exists saved_state]} { if {$saved_state != "zoomed" && [info exists saved_geometry]} { wm geometry . $saved_geometry } wm state . $saved_state } else { if {[info exists saved_geometry]} { wm geometry . $saved_geometry } wm state . normal } wm deiconify . } # Restores the main Tkabber window from iconic or withdrawn states: proc systray::restore {} { switch -- [wm state .] { iconic { wm deiconify . } withdrawn { reshow } default { wm deiconify . } } raise . } proc systray::toggle_state {} { switch -- [wm state .] { zoomed - normal { withdraw } iconic - withdrawn - default { restore } } } ########################################################################## proc systray::wm_win_iconify {action} { variable icons if {$action == "systray"} { if {![lempty $icons]} { toggle_state } return stop } } hook::add protocol_wm_delete_window_hook \ [namespace current]::systray::wm_win_iconify 40 ########################################################################## proc systray::quit {} { variable icons foreach icon $icons { destroy $icon } } hook::add quit_hook [namespace current]::systray::quit ########################################################################## proc systray::update {icon name1 {name2 ""} {op ""}} { global curuserstatus upvar 0 [token $icon] state if {![info exists state(tray)]} return switch -- [string trimleft $name1 :] { curuserstatus { if {$state(tray) == ""} { uplevel #0 $state(configure) [list $icon $curuserstatus] } } tabcolors { toggle $icon 1 } } } ########################################################################## proc systray::toggle {icon ff} { global curuserstatus tabcolors variable options upvar 0 [token $icon] state if {![info exists state(tray)]} return if {![winfo exists $icon]} return if {![cequal $state(tray) ""]} { after cancel $state(tray) set state(tray) "" } set hitP 0 foreach {k v} [array get tabcolors] { if {[.nb index $k] < 0} { continue } if {(![cequal $v ""]) && ($v > $hitP)} { set hitP $v } } if {$hitP == 0} { update $icon ::curuserstatus return } if {$options(blink)} { set state(tray) \ [after 500 [list [namespace current]::toggle $icon [expr {!$ff}]]] if {$ff} { uplevel #0 $state(configure) [list $icon message$hitP] } else { uplevel #0 $state(configure) [list $icon blank] } } else { set state(tray) message uplevel #0 $state(configure) [list $icon message$hitP] } } ########################################################################## proc systray::set_status {text} { variable options variable icons variable balloon if {!$options(display_status)} return if {[lempty $icons]} return set icon [lindex $icons 0] upvar 0 [token $icon] state switch -- [wm state .] { normal { } default { if {[info exists balloon] && ($balloon != "")} { after cancel $balloon set balloon "" } if {![winfo exists $icon]} { return } balloon::set_text $text if {[info exists state(location)]} { lassign [$state(location) $icon] x y } else { set x [winfo rootx $icon] set y [winfo rooty $icon] } balloon::show $x $y set balloon [after 15000 balloon::destroy] } } } hook::add set_status_hook [namespace current]::systray::set_status ########################################################################## proc systray::clear_status {} { variable options variable icons variable balloon if {!$options(display_status)} return if {[lempty $icons]} return if {[info exists balloon] && ($balloon != "")} { after cancel $balloon set balloon "" } balloon::destroy } hook::add clear_status_hook [namespace current]::systray::clear_status ########################################################################## proc systray::balloon {icon} { return [list $icon [balloon_text]] } ########################################################################## proc systray::balloon_text {} { global userstatusdesc textstatus if {![string equal $textstatus ""]} { set status $textstatus } else { set status $userstatusdesc } return "Tkabber: $status" } ########################################################################## # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/ifacetk/iroster.tcl0000644000175000017500000016423711073733131016337 0ustar sergeisergei# $Id: iroster.tcl 1506 2008-10-10 20:08:57Z sergei $ Tree .faketree foreach {k v} [list background White \ foreground Black] { if {[cequal [set t$k [option get .faketree $k Tree]] ""]} { set t$k $v } } destroy .faketree Button .fakebutton foreach {k v} [list background Gray \ activeBackground LightGray] { if {[cequal [set b$k [option get .fakebutton $k Button]] ""]} { set b$k $v } } destroy .fakebutton option add *Roster.cbackground $tbackground widgetDefault option add *Roster.groupindent 22 widgetDefault option add *Roster.jidindent 24 widgetDefault option add *Roster.jidmultindent 40 widgetDefault option add *Roster.subjidindent 34 widgetDefault option add *Roster.groupiconindent 2 widgetDefault option add *Roster.subgroupiconindent 22 widgetDefault option add *Roster.iconindent 3 widgetDefault option add *Roster.subitemtype 1 widgetDefault option add *Roster.subiconindent 13 widgetDefault option add *Roster.textuppad 1 widgetDefault option add *Roster.textdownpad 1 widgetDefault option add *Roster.linepad 2 widgetDefault option add *Roster.foreground $tforeground widgetDefault option add *Roster.jidfill $tbackground widgetDefault option add *Roster.jidhlfill $bactiveBackground widgetDefault option add *Roster.jidborder $tbackground widgetDefault option add *Roster.groupfill $bbackground widgetDefault option add *Roster.groupcfill $bbackground widgetDefault option add *Roster.grouphlfill $bactiveBackground widgetDefault option add *Roster.groupborder $tforeground widgetDefault option add *Roster.connectionfill $tbackground widgetDefault option add *Roster.connectioncfill $tbackground widgetDefault option add *Roster.connectionhlfill $bactiveBackground widgetDefault option add *Roster.connectionborder $tforeground widgetDefault option add *Roster.unsubscribedforeground #663333 widgetDefault option add *Roster.unavailableforeground #666666 widgetDefault option add *Roster.dndforeground #666633 widgetDefault option add *Roster.xaforeground #004d80 widgetDefault option add *Roster.awayforeground #004d80 widgetDefault option add *Roster.availableforeground #0066cc widgetDefault option add *Roster.chatforeground #0099cc widgetDefault unset tbackground tforeground bbackground bactiveBackground namespace eval roster { custom::defgroup Roster [::msgcat::mc "Roster options."] -group Tkabber custom::defvar use_aliases 1 \ [::msgcat::mc "Use aliases to show multiple users in one roster item."] \ -type boolean -group Roster \ -command [namespace current]::redraw_after_idle custom::defvar show_only_online 0 \ [::msgcat::mc "Show only online users in roster."] \ -type boolean -group Roster \ -command [namespace current]::redraw_after_idle custom::defvar show_transport_icons 0 \ [::msgcat::mc "Show native icons for transports/services in roster."] \ -type boolean -group Roster \ -command [namespace current]::redraw_after_idle custom::defvar show_transport_user_icons 0 \ [::msgcat::mc "Show native icons for contacts, connected to transports/services in roster."] \ -type boolean -group Roster \ -command [namespace current]::redraw_after_idle custom::defvar options(nested) 0 \ [::msgcat::mc "Enable nested roster groups."] \ -type boolean -group Roster \ -command [namespace current]::redraw_after_idle custom::defvar options(nested_delimiter) "::" \ [::msgcat::mc "Default nested roster group delimiter."] \ -type string -group Roster \ -command [namespace current]::redraw_after_idle custom::defvar options(show_own_resources) 0 \ [::msgcat::mc "Show my own resources in the roster."] \ -type boolean -group Roster \ -command [namespace current]::redraw_after_idle custom::defvar options(chats_group) 0 \ [::msgcat::mc "Add chats group in roster."] \ -type boolean -group Roster \ -command [namespace current]::redraw_after_idle custom::defvar options(use_filter) 0 \ [::msgcat::mc "Use roster filter."] \ -type boolean -group Roster \ -command [namespace current]::pack_filter_entry custom::defvar options(match_jids) 0 \ [::msgcat::mc "Match contact JIDs in addition to nicknames in roster filter."] \ -type boolean -group Roster \ -command [namespace current]::redraw_after_idle custom::defvar options(free_drop) 1 \ [::msgcat::mc "Roster item may be dropped not only over group name\ but also over any item in group."] \ -type boolean -group Roster custom::defvar options(show_subscription) 0 \ [::msgcat::mc "Show subscription type in roster item tooltips."] \ -type boolean -group Roster custom::defvar options(show_conference_user_info) 0 \ [::msgcat::mc "Show detailed info on conference room members in roster item tooltips."] \ -type boolean -group Roster custom::defvar options(chat_on_doubleclick) 1 \ [::msgcat::mc "If set then open chat window/tab when user doubleclicks roster item.\ Otherwise open normal message window."] \ -type boolean -group Roster # {jid1 {group1 1 group2 0} jid2 {group3 0 group4 0}} custom::defvar collapsed_group_list {} \ [::msgcat::mc "Stored collapsed roster groups."] \ -type string -group Hidden # {jid1 {group1 1 group2 0} jid2 {group3 0 group4 0}} custom::defvar show_offline_group_list {} \ [::msgcat::mc "Stored show offline roster groups."] \ -type string -group Hidden custom::defvar options(filter) "" \ [::msgcat::mc "Roster filter."] \ -type string -group Hidden \ -command [namespace current]::redraw_after_idle variable menu_item_idx 0 variable undef_group_name $::roster::undef_group_name variable chats_group_name $::roster::chats_group_name variable own_resources_group_name $roster::own_resources_group_name } proc roster::get_group_lists {} { variable collapsed_group_list variable show_offline_group_list variable collapsed variable show_offline foreach {jid grlist} $collapsed_group_list { foreach {group val} $grlist { set collapsed($jid,$group) $val } } foreach {jid grlist} $show_offline_group_list { foreach {group val} $grlist { set show_offline($jid,$group) $val } } } hook::add finload_hook [namespace current]::roster::get_group_lists proc roster::set_group_lists {connid} { variable collapsed_group_list variable show_offline_group_list variable collapsed variable show_offline variable roster variable options variable undef_group_name variable chats_group_name set _collapsed_group_list $collapsed_group_list set _show_offline_group_list $show_offline_group_list if {$connid == {}} { set connidlist [jlib::connections] } else { set connidlist [list $connid] } foreach connid $connidlist { if {[catch { set bare_jid [jlib::connection_bare_jid $connid] }]} { continue } if {[catch { set groups [roster::get_groups $connid -raw 1] }]} { continue } if {$options(nested)} { set tmp {} foreach group $groups { set tmp1 [msplit $group $options(nested_delimiter)] for {set i 0} {$i < [llength $tmp1]} {incr i} { lappend tmp [lrange $tmp1 0 $i] } } set groups [lrmdups $tmp] } lappend groups $undef_group_name $chats_group_name set tmpc {} set tmps {} foreach group $groups { if {$options(nested)} { set grname [join $group $options(nested_delimiter)] set gid [list $connid $group] } else { set grname [list $group] set gid [list $connid $grname] } if {[info exists roster(collapsed,$gid)]} { set collapsed($bare_jid,$grname) $roster(collapsed,$gid) lappend tmpc $grname $roster(collapsed,$gid) } if {[info exists roster(show_offline,$gid)]} { set show_offline($bare_jid,$grname) $roster(show_offline,$gid) lappend tmps $grname $roster(show_offline,$gid) } } if {![lempty $tmpc]} { while {[set idx [lsearch -exact $_collapsed_group_list $bare_jid]] >= 0} { set _collapsed_group_list \ [lreplace $_collapsed_group_list $idx [expr {$idx + 1}]] } lappend _collapsed_group_list $bare_jid $tmpc } if {![lempty $tmps]} { while {[set idx [lsearch -exact $_show_offline_group_list $bare_jid]] >= 0} { set _show_offline_group_list \ [lreplace $_show_offline_group_list $idx [expr {$idx + 1}]] } lappend _show_offline_group_list $bare_jid $tmps } } set collapsed_group_list $_collapsed_group_list set show_offline_group_list $_show_offline_group_list } hook::add predisconnected_hook [namespace current]::roster::set_group_lists proc roster::process_item {connid jid name groups subsc ask} { after cancel [namespace parent]::update_chat_titles after idle [namespace parent]::update_chat_titles } hook::add roster_item_hook [namespace current]::roster::process_item 90 hook::add roster_push_hook [namespace current]::roster::process_item 90 proc roster::create_filter_entry {} { entry .roster_filter -textvariable [namespace current]::options(filter) \ -width 1 bind .roster_filter \ [list set [namespace current]::options(filter) ""] pack_filter_entry } hook::add finload_hook [namespace current]::roster::create_filter_entry proc roster::pack_filter_entry {args} { global usetabbar variable options if {$options(use_filter)} { if {$usetabbar} { pack .roster_filter -before .roster \ -anchor w \ -side bottom \ -fill x \ -expand no \ -in $::ifacetk::rw } else { grid .roster_filter -row 2 \ -column 1 \ -sticky we \ -in [$::ifacetk::mf getframe] } focus .roster_filter } else { if {$usetabbar} { pack forget .roster_filter } else { grid forget .roster_filter } } redraw_after_idle } # TODO: get rid of roster::roster proc roster::redraw {} { upvar #0 roster::aliases aliases variable roster variable options variable config variable show_only_online variable use_aliases variable show_transport_user_icons variable undef_group_name variable chats_group_name variable own_resources_group_name variable collapsed variable show_offline clear .roster 0 set connections [jlib::connections] switch -- [llength $connections] { 0 { update_scrollregion .roster return } 1 { set draw_connection 0 set gindent 0 } default { set draw_connection 1 set gindent 0 } } foreach connid $connections { # Suppress display of aliases, but not if "main" JID is unavailable. # If main JID is unavailable, perform reordering of aliases. # Suppression means that aliases wont get a line in the roster for # themselves, but will be places as children under "main" JID element if {$use_aliases} { foreach jid [array names aliases] { set status [get_user_status $connid $jid] if {$status == "unavailable"} { # Need to look an alternative for main JID, # which is offline. set jidstatus [get_user_aliases_status_and_jid $connid $jid] switch -- [lindex $jidstatus 1] { unavailable { # Main JID and all aliases are unavailable. # Will skip them all } default { # Make "most available" JID the main JID, # put main JID into list of aliases set new_jid [lindex $jidstatus 0] set idx [lsearch -exact $aliases($jid) $new_jid] set new_aliases [lreplace $aliases($jid) $idx $idx] # If this already have some aliases defined, # merge them in if {[info exists aliases($new_jid)]} { set new_aliases \ [lsort -unique -dictionary -index 0 \ [lappend new_aliases \ $aliases($new_jid)]] } set aliases($new_jid) $new_aliases # Remove aliases of old "main" JID set aliases($jid) {} } } } # Main JID is online, suppress alternatives foreach alias $aliases($jid) { set ignore_jid($alias) "" } } } if {$draw_connection} { if {![info exists roster(collapsed,[list connid $connid])]} { set roster(collapsed,[list connid $connid]) 0 } addline .roster connection \ [jlib::connection_jid $connid] \ [list connid $connid] [list connid $connid] 0 if {$roster(collapsed,[list connid $connid])} { continue } } if {[lempty [::roster::get_jids $connid]]} { continue } set bare_jid [jlib::connection_bare_jid $connid] set groups {} array unset jidsingroup array unset jidsundergroup array unset groupsundergroup foreach jid [::roster::get_jids $connid] { if {$options(use_filter) && $options(filter) != ""} { if {[string first [string tolower $options(filter)] \ [string tolower [::roster::get_label $connid $jid]]] < 0} { if {!$options(match_jids) || \ [string first [string tolower $options(filter)] \ [string tolower $jid]] < 0} { continue } } } if {[info exists ignore_jid($jid)]} continue set jid_groups [::roster::itemconfig $connid $jid -group] if {![lempty $jid_groups]} { foreach group $jid_groups { if {$options(nested)} { set sgroup [msplit $group $options(nested_delimiter)] } else { set sgroup [list $group] } lappend groups [list [join $sgroup "\u0000"] $sgroup] lappend jidsingroup($sgroup) $jid set deep [expr {[llength $sgroup] - 1}] for {set i 0} {$i < $deep} {incr i} { set sgr [lrange $sgroup 0 $i] lappend groups [list [join $sgr "\u0000"] $sgr] lappend jidsundergroup($sgr) $jid lappend groupsundergroup($sgr) $sgroup if {![info exists jidsingroup($sgr)]} { set jidsingroup($sgr) {} } } if {![info exists jidsundergroup($sgroup)]} { set jidsundergroup($sgroup) {} } if {![info exists groupsundergroup($sgroup)]} { set groupsundergroup($sgroup) {} } } } else { set sgroup [list $undef_group_name] lappend jidsingroup($sgroup) $jid set groupsundergroup($sgroup) {} if {![info exists jidsundergroup($sgroup)]} { set jidsundergroup($sgroup) {} } } } set groups [lsort -unique -dictionary -index 0 $groups] set ugroup [list $undef_group_name] if {[info exists jidsingroup($ugroup)]} { lappend groups [list [join $ugroup "\u0000"] $ugroup] } if {$options(chats_group)} { set cgroup [list $chats_group_name] foreach chatid [chat::opened $connid] { set jid [chat::get_jid $chatid] lappend jidsingroup($cgroup) $jid if {[cequal [roster::itemconfig $connid $jid -isuser] ""]} { roster::itemconfig $connid $jid \ -name [chat::get_nick $connid $jid chat] roster::itemconfig $connid $jid -subsc none } } if {[info exists jidsingroup($cgroup)]} { set groups [linsert $groups 0 [list [join $cgroup "\u0000"] $cgroup]] } set groupsundergroup($cgroup) {} set jidsundergroup($cgroup) {} } if {$options(show_own_resources)} { set cgroup [list $own_resources_group_name] set jid [tolower_node_and_domain [::jlib::connection_bare_jid $connid]] set jidsingroup($cgroup) [list $jid] set groups [linsert $groups 0 [list [join $cgroup "\u0000"] $cgroup]] roster::itemconfig $connid $jid -subsc both set groupsundergroup($cgroup) {} set jidsundergroup($cgroup) {} } foreach group $groups { set group [lindex $group 1] set gid [list $connid $group] if {![info exists roster(show_offline,$gid)]} { if {$options(nested)} { set gname [join $group $options(nested_delimiter)] } else { set gname $group } if {[info exists show_offline($bare_jid,$gname)]} { set roster(show_offline,$gid) $show_offline($bare_jid,$gname) } else { set roster(show_offline,$gid) 0 } } } foreach group $groups { set group [lindex $group 1] set jidsingroup($group) [lrmdups $jidsingroup($group)] set groupsundergroup($group) [lrmdups $groupsundergroup($group)] set gid [list $connid $group] if {![info exists roster(collapsed,$gid)]} { if {$options(nested)} { set gname [join $group $options(nested_delimiter)] } else { set gname $group } if {[info exists collapsed($bare_jid,$gname)]} { set roster(collapsed,$gid) $collapsed($bare_jid,$gname) } else { set roster(collapsed,$gid) 0 } } set indent [expr {[llength $group] - 1}] set collapse 0 set show_offline_users 0 set show_offline_group 0 foreach undergroup $groupsundergroup($group) { if {$roster(show_offline,[list $connid $undergroup])} { set show_offline_group 1 break } } for {set i 0} {$i < $indent} {incr i} { set sgr [list $connid [lrange $group 0 $i]] if {$roster(collapsed,$sgr)} { set collapse 1 break } if {$roster(show_offline,$sgr)} { set show_offline_users 1 set show_offline_group 1 } } incr indent $gindent if {$collapse} continue set group_name "[lindex $group end]" set online 0 set users 0 set not_users 0 set sub_jids 0 foreach jid [concat $jidsingroup($group) $jidsundergroup($group)] { if {[::roster::itemconfig $connid $jid -isuser]} { incr users set status [get_user_aliases_status $connid $jid] set jstat($jid) $status if {$status != "unavailable"} { incr online set useronline($jid) 1 } else { set useronline($jid) 0 } } else { incr not_users } } if {!$show_only_online || $show_offline_group || \ $roster(show_offline,$gid) || \ ($options(use_filter) && $options(filter) != "") || \ $online + $not_users + $sub_jids > 0} { if {$users} { addline .roster group "$group_name ($online/$users)" \ $gid $gid $indent } else { addline .roster group $group_name \ $gid $gid $indent } } if {!$roster(collapsed,$gid)} { set jid_names {} foreach jid $jidsingroup($group) { lappend jid_names [list $jid [::roster::get_label $connid $jid]] } set jid_names [lsort -index 1 -dictionary $jid_names] foreach jid_name $jid_names { lassign $jid_name jid name if {$options(chats_group)} { set chatid [chat::chatid $connid $jid] if {[info exists chat::chats(messages,$chatid)] && \ $chat::chats(messages,$chatid) > 0} { append name " \[$chat::chats(messages,$chatid)\]" } } set cjid [list $connid $jid] if {!$show_only_online || $show_offline_users || $roster(show_offline,$gid) || \ ($options(use_filter) && $options(filter) != "") || \ ![info exists useronline($jid)] || $useronline($jid)} { lassign [::roster::get_category_and_subtype $connid $jid] category type set jids [get_jids_of_user $connid $jid] set numjids [llength $jids] if {($numjids > 1) && ($config(subitemtype) > 0) && \ $category == "user"} { if {$config(subitemtype) & 1} { if {$category == "conference"} { set numjids [expr {$numjids - 1}] } set label "$name ($numjids)" } else { set label "$name" } addline .roster jid $label $cjid $gid $indent $jids changeicon .roster $cjid [get_jid_icon $connid $jid] changeforeground .roster $cjid [get_jid_foreground $connid $jid] if {!$roster(collapsed,$cjid)} { foreach subjid $jids { set subjid_resource [resource_from_jid $subjid] if {$subjid_resource != ""} { addline .roster jid2 \ $subjid_resource [list $connid $subjid] \ $gid $indent \ [list $subjid] changeicon .roster \ [list $connid $subjid] [get_jid_icon $connid $subjid] changeforeground .roster \ [list $connid $subjid] [get_jid_foreground $connid $subjid] } } } } else { if {$numjids <= 1 && $category == "user" && \ !$show_transport_user_icons} { if {[info exists jstat($jid)]} { set status $jstat($jid) } else { set status [get_user_aliases_status $connid $jid] } set subsc [::roster::itemconfig $connid $jid -subsc] if {([cequal $subsc from] || [cequal $subsc none]) && \ $status == "unavailable"} { set status unsubscribed } addline .roster jid $name $cjid $gid $indent \ $jids \ roster/user/$status \ $config(${status}foreground) } else { addline .roster jid $name $cjid $gid $indent $jids changeicon .roster $cjid [get_jid_icon $connid $jid] changeforeground .roster $cjid [get_jid_foreground $connid $jid] } } } } } } } update_scrollregion .roster } proc roster::redraw_after_idle {args} { variable redraw_afterid if {[info exists redraw_afterid]} return if {![winfo exists .roster.canvas]} return set redraw_afterid \ [after idle "[namespace current]::redraw unset [namespace current]::redraw_afterid"] } # Callback proc ::redraw_roster {args} { ifacetk::roster::redraw_after_idle } proc roster::get_jids_of_user {connid user} { upvar #0 roster::aliases aliases variable use_aliases if {$use_aliases && [info exists aliases($user)]} { set jids [::get_jids_of_user $connid $user] foreach alias $aliases($user) { set jids [concat $jids [::get_jids_of_user $connid $alias]] } return $jids } else { return [::get_jids_of_user $connid $user] } } proc roster::get_user_aliases_status {connid user} { set jidstatus [get_user_aliases_status_and_jid $connid $user] return [lindex $jidstatus 1] } proc roster::get_user_aliases_status_and_jid {connid user} { upvar #0 roster::aliases aliases variable use_aliases if {$use_aliases && [info exists aliases($user)]} { set status [get_user_status $connid $user] set jid $user foreach alias $aliases($user) { set new_status [max_status $status [get_user_status $connid $alias]] if {$status != $new_status} { set status $new_status set jid $alias } } return [list $jid $status] } else { return [list $user [get_user_status $connid $user]] } } proc roster::get_jid_foreground {connid jid} { lassign [::roster::get_category_and_subtype $connid $jid] category type switch -- $category { "" - user { return [get_user_foreground $connid $jid] } conference { if {[get_jid_status $connid $jid] != "unavailable"} { return available } else { return unavailable } } server - gateway - service { return [get_service_foreground $connid $jid $type] } default { return "" } } } proc roster::get_service_foreground {connid service type} { switch -- $type { jud {return ""} } if {![cequal [::roster::itemconfig $connid $service -subsc] none]} { return [get_user_status $connid $service] } else { return unsubscribed } } proc roster::get_user_foreground {connid user} { set status [get_user_aliases_status $connid $user] set subsc [::roster::itemconfig $connid $user -subsc] if {[cequal $subsc ""]} { set subsc [::roster::itemconfig $connid \ [::roster::find_jid $connid $user] -subsc] } if {([cequal $subsc from] || [cequal $subsc none]) && \ $status == "unavailable"} { return unsubscribed } else { return $status } } proc roster::get_jid_icon {connid jid {status ""}} { lassign [::roster::get_category_and_subtype $connid $jid] category type switch -- $category { "" - user { if {$status == ""} { set status [get_user_aliases_status $connid $jid] } return [get_user_icon $connid $jid $status] } conference { if {$status == ""} { set status [get_jid_status $connid $jid] } if {$status != "unavailable"} { return roster/conference/available } return roster/conference/unavailable } server - gateway - service { if {$status == ""} { set status [get_user_status $connid $jid] } return [get_service_icon $connid $jid $type $status] } default { if {$status == ""} { set status [get_jid_status $connid $jid] } return [get_user_icon $connid $jid $status] } } } proc roster::get_service_icon {connid service type status} { variable show_transport_icons if {$show_transport_icons} { switch -- $type { jud {return services/jud} sms {return services/sms} } if {![cequal [::roster::itemconfig $connid $service -subsc] none]} { if {![catch { image type services/$type/$status }]} { return services/$type/$status } else { return roster/user/$status } } else { return roster/user/unsubscribed } } else { if {![cequal [::roster::itemconfig $connid $service -subsc] none]} { return roster/user/$status } else { return roster/user/unsubscribed } } } proc roster::get_user_icon {connid user status} { variable show_transport_user_icons set subsc [::roster::itemconfig $connid $user -subsc] if {[cequal $subsc ""]} { set subsc [::roster::itemconfig $connid \ [::roster::find_jid $connid $user] -subsc] } if {!([cequal $subsc from] || [cequal $subsc none]) || \ $status != "unavailable"} { if {$show_transport_user_icons} { set service [server_from_jid $user] lassign [::roster::get_category_and_subtype $connid $service] category type switch -glob -- $category/$type { directory/* - */jud { return services/jud } */sms { return services/sms } } if {![catch { image type services/$type/$status }]} { return services/$type/$status } else { return roster/user/$status } } else { return roster/user/$status } } else { return roster/user/unsubscribed } } proc roster::changeicon {w jid icon} { set c $w.canvas set tag [jid_to_tag $jid] $c itemconfigure jid$tag&&icon -image $icon } proc roster::changeforeground {w jid fg {color ""}} { variable config set c $w.canvas set tag [jid_to_tag $jid] if {$color == ""} { set color $config(${fg}foreground) } $c itemconfigure jid$tag&&text -fill $color } proc roster::create {w args} { variable iroster variable config set c $w.canvas set width 150 set height 100 set popupproc {} set grouppopupproc {} set singleclickproc {} set doubleclickproc {} foreach {attr val} $args { switch -- $attr { -width {set width $val} -height {set height $val} -popup {set popupproc $val} -grouppopup {set grouppopupproc $val} -singleclick {set singleclickproc $val} -doubleclick {set doubleclickproc $val} -draginitcmd {set draginitcmd $val} -dropovercmd {set dropovercmd $val} -dropcmd {set dropcmd $val} } } frame $w -relief sunken -borderwidth $::tk_borderwidth -class Roster set sw [ScrolledWindow $w.sw] pack $sw -fill both -expand yes set config(groupindent) [option get $w groupindent Roster] set config(jidindent) [option get $w jidindent Roster] set config(jidmultindent) [option get $w jidmultindent Roster] set config(jid2indent) [option get $w subjidindent Roster] set config(groupiconindent) [option get $w groupiconindent Roster] set config(subgroupiconindent) [option get $w subgroupiconindent Roster] set config(iconindent) [option get $w iconindent Roster] set config(subitemtype) [option get $w subitemtype Roster] set config(subiconindent) [option get $w subiconindent Roster] set config(textuppad) [option get $w textuppad Roster] set config(textdownpad) [option get $w textdownpad Roster] set config(linepad) [option get $w linepad Roster] set config(background) [option get $w cbackground Roster] set config(jidfill) [option get $w jidfill Roster] set config(jidhlfill) [option get $w jidhlfill Roster] set config(jidborder) [option get $w jidborder Roster] set config(jid2fill) $config(jidfill) set config(jid2hlfill) $config(jidhlfill) set config(jid2border) $config(jidborder) set config(groupfill) [option get $w groupfill Roster] set config(groupcfill) [option get $w groupcfill Roster] set config(grouphlfill) [option get $w grouphlfill Roster] set config(groupborder) [option get $w groupborder Roster] set config(connectionfill) [option get $w connectionfill Roster] set config(connectioncfill) [option get $w connectioncfill Roster] set config(connectionhlfill) [option get $w connectionhlfill Roster] set config(connectionborder) [option get $w connectionborder Roster] set config(foreground) [option get $w foreground Roster] set config(unsubscribedforeground) [option get $w unsubscribedforeground Roster] set config(unavailableforeground) [option get $w unavailableforeground Roster] set config(dndforeground) [option get $w dndforeground Roster] set config(xaforeground) [option get $w xaforeground Roster] set config(awayforeground) [option get $w awayforeground Roster] set config(availableforeground) [option get $w availableforeground Roster] set config(chatforeground) [option get $w chatforeground Roster] canvas $c -bg $config(background) \ -highlightthickness $::tk_highlightthickness \ -scrollregion {0 0 0 0} \ -width $width -height $height $sw setwidget $c set iroster($w,ypos) 1 set iroster($w,width) 0 set iroster($w,popup) $popupproc set iroster($w,grouppopup) $grouppopupproc set iroster($w,singleclick) $singleclickproc set iroster($w,doubleclick) $doubleclickproc bindscroll $c if {[info exists draginitcmd]} { DragSite::register $c -draginitcmd $draginitcmd } set args {} if {[info exists dropovercmd]} { lappend args -dropovercmd $dropovercmd } if {[info exists dropcmd]} { lappend args -dropcmd $dropcmd } if {![lempty $args]} { eval [list DropSite::register $c -droptypes {JID}] $args } } proc roster::addline {w type text jid group indent {jids {}} {icon ""} {foreground ""}} { upvar #0 roster::aliases aliases variable roster variable iroster variable config variable use_aliases set c $w.canvas set tag [jid_to_tag $jid] set grouptag [jid_to_tag $group] set ypad 1 set linespace [font metric $::RosterFont -linespace] set lineheight [expr {$linespace + $ypad}] set uy $iroster($w,ypos) set ly [expr {$uy + $lineheight + $config(textuppad) + \ $config(textdownpad)}] set levindent [expr $config(groupindent)*$indent] set border $config(${type}border) set hlfill $config(${type}hlfill) if {($type == "group" || $type == "connection") && \ [info exists roster(collapsed,$jid)] && \ $roster(collapsed,$jid)} { set rfill $config(${type}cfill) } else { set rfill $config(${type}fill) } if {$type == "connection"} { set type group } $c create rectangle [expr {1 + $levindent}] $uy 10000 $ly -fill $rfill \ -outline $border -tags [list jid$tag group$grouptag $type rect] if {[cequal $type jid]} { lassign $jid connid jjid set isuser [::roster::itemconfig $connid $jjid -isuser] if {[cequal $isuser ""]} { set isuser 1 } set y [expr {($uy + $ly)/2}] set x [expr {$config(iconindent) + $levindent}] if {$icon == ""} { $c create image $x $y -image roster/user/unavailable \ -anchor w \ -tags [list jid$tag group$grouptag $type icon] } else { $c create image $x $y -image $icon \ -anchor w \ -tags [list jid$tag group$grouptag $type icon] } if {[llength $jids] > 1} { if {[info exists roster(collapsed,$jid)] && !$roster(collapsed,$jid)} { set jid_state opened } else { set roster(collapsed,$jid) 1 set jid_state closed } if {$config(subitemtype) > 0} { if {($config(subitemtype) & 2) && $isuser} { set y [expr {($uy + $ly)/2}] set x [expr {$config(subgroupiconindent) + $levindent}] $c create image $x $y -image roster/group/$jid_state -anchor w \ -tags [list jid$tag group$grouptag $type group] } } } else { set roster(collapsed,$jid) 1 } } elseif {[cequal $type jid2]} { #set jids [get_jids_of_user $jid] set y [expr {($uy + $ly)/2}] set x [expr {$config(subiconindent) + $levindent}] $c create image $x $y -image roster/user/unavailable -anchor w \ -tags [list jid$tag group$grouptag $type icon] } elseif {[cequal $type group]} { set y [expr {($uy + $ly)/2}] set x [expr {$config(groupiconindent) + $levindent}] if {[info exists roster(collapsed,$jid)] && $roster(collapsed,$jid)} { set group_state closed } else { set group_state opened } $c create image $x $y -image roster/group/$group_state -anchor w \ -tags [list jid$tag group$grouptag $type icon] } if {([cequal $type jid]) && ($config(subitemtype) > 0) && ($config(subitemtype) & 2)} { #set jids [get_jids_of_user $jid] if {$isuser && ([llength $jids] > 1)} { set x [expr {$config(jidmultindent) + $levindent}] } else { set x [expr {$config(jidindent) + $levindent}] } } else { set x [expr {$config(${type}indent) + $levindent}] } incr uy $config(textuppad) if {$foreground == ""} { if {[cequal $type jid] || [cequal $type jid2]} { set foreground $config(unavailableforeground) } else { set foreground $config(foreground) } } $c create text $x $uy -text $text -anchor nw -font $::RosterFont \ -fill $foreground -tags [list jid$tag group$grouptag $type text] set iroster($w,width) [max $iroster($w,width) \ [expr {$x + [font measure $::RosterFont $text]}]] $c bind jid$tag \ [list $c itemconfig jid$tag&&rect -fill $hlfill] $c bind jid$tag \ [list $c itemconfig jid$tag&&rect -fill $rfill] set doubledjid [double% $jid] set doubledjids [double% $jids] set iroster($w,ypos) [expr {$ly + $config(linepad)}] if {[cequal $type jid] || [cequal $type jid2]} { $c bind jid$tag \ [list [namespace current]::on_singleclick \ [double% $iroster($w,singleclick)] $doubledjid] $c bind jid$tag \ [list [namespace current]::on_doubleclick \ [double% $iroster($w,doubleclick)] $doubledjid] $c bind jid$tag \ +[list eval balloon::set_text \ \[[namespace current]::jids_popup_info \ [list $doubledjid] [list $doubledjids]\]] $c bind jid$tag \ [list eval balloon::on_mouse_move \ \[[namespace current]::jids_popup_info \ [list $doubledjid] [list $doubledjids]\] %X %Y] $c bind jid$tag {+ balloon::destroy} if {![cequal $iroster($w,popup) {}]} { $c bind jid$tag <3> [list [double% $iroster($w,popup)] $doubledjid] } } else { if {$w == ".roster"} { $c bind jid$tag&&group \ [list [namespace current]::group_click $doubledjid] } if {![cequal $iroster($w,grouppopup) {}]} { $c bind jid$tag&&group <3> \ [list $iroster($w,grouppopup) $doubledjid] } } } proc roster::clear {w {updatescroll 1}} { variable iroster $w.canvas delete rect||icon||text||group set iroster($w,ypos) 1 set iroster($w,width) 0 if {$updatescroll} { update_scrollregion $w } } proc roster::update_scrollregion {w} { variable iroster $w.canvas configure \ -scrollregion [list 0 0 $iroster($w,width) $iroster($w,ypos)] } ############################################################################### proc roster::on_singleclick {command cjid} { variable click_afterid if {$command == ""} return if {![info exists click_afterid]} { set click_afterid \ [after 300 [list [namespace current]::singleclick_run $command $cjid]] } else { after cancel $click_afterid unset click_afterid } } proc roster::singleclick_run {command cjid} { variable click_afterid if {[info exists click_afterid]} { unset click_afterid } eval $command {$cjid} } proc roster::on_doubleclick {command cjid} { variable click_afterid if {[info exists click_afterid]} { after cancel $click_afterid unset click_afterid } if {$command == ""} return eval $command {$cjid} } ############################################################################### proc roster::jid_doubleclick {id} { lassign $id connid jid lassign [::roster::get_category_and_subtype $connid $jid] category subtype hook::run roster_jid_doubleclick $connid $jid $category $subtype } ############################################################################### proc roster::doubleclick_fallback {connid jid category subtype} { variable options if {$options(chat_on_doubleclick)} { chat::open_to_user $connid $jid } else { message::send_dialog -to $jid } } hook::add roster_jid_doubleclick \ [namespace current]::roster::doubleclick_fallback 100 ############################################################################### proc roster::group_click {gid} { variable roster set roster(collapsed,$gid) [expr {!$roster(collapsed,$gid)}] redraw_after_idle } proc roster::jids_popup_info {id jids} { variable use_aliases lassign $id connid jid if {$jids == {}} { if {$use_aliases && [info exists aliases($jid)]} { set jids [concat [list $jid] $aliases($jid)] } else { set jids [list $jid] } } set text {} set i 0 foreach j $jids { append text "\n[[namespace current]::user_popup_info $connid $j $i]" incr i } set text [string trimleft $text "\n"] return $text } proc roster::user_popup_info {connid user i} { variable options variable user_popup_info global statusdesc lassign [::roster::get_category_and_subtype $connid $user] category subtype set bare_user [::roster::find_jid $connid $user] lassign [::roster::get_category_and_subtype $connid $bare_user] \ category1 subtype1 set name $user switch -- $category { conference { set status $statusdesc([get_jid_status $connid $user]) set desc "" } user - default { set status $statusdesc([get_user_status $connid $user]) set desc [get_user_status_desc $connid $user] if {[cequal $category1 conference] && $i > 0} { if {$options(show_conference_user_info)} { set name " [resource_from_jid $user]" } else { set name "\t[resource_from_jid $user]" } } } } if {(![string equal -nocase $status $desc]) && (![cequal $desc ""])} { append status " ($desc)" } set subsc [::roster::itemconfig $connid $bare_user -subsc] if {($options(show_subscription) && ![cequal $subsc ""]) && !([cequal $category1 conference] && [cequal $category user])} { set subsc [format "\n\t[::msgcat::mc {Subscription:}] %s" $subsc] set ask [::roster::itemconfig $connid $bare_user -ask] if {![cequal $ask ""]} { set ask [format " [::msgcat::mc {Ask:}] %s" $ask] } } else { set subsc "" set ask "" } set user_popup_info "$name: $status$subsc$ask" if {!([cequal $category1 conference] && $i > 0) || \ $options(show_conference_user_info)} { hook::run roster_user_popup_info_hook \ [namespace which -variable user_popup_info] $connid $user } return $user_popup_info } proc roster::switch_only_online {args} { variable show_only_online set show_only_online [expr {!$show_only_online}] } proc roster::is_online {connid jid} { if {[::roster::itemconfig $connid $jid -isuser]} { switch -- [get_user_aliases_status $connid $jid] { unavailable {return 0} default {return 1} } } else { return 1 } } ############################################################################### proc roster::add_remove_item_menu_item {m connid jid} { set rjid [roster::find_jid $connid $jid] if {$rjid == ""} { set state disabled } else { set state normal } $m add command -label [::msgcat::mc "Remove from roster..."] \ -command [list ifacetk::roster::remove_item_dialog $connid $rjid] \ -state $state } hook::add chat_create_user_menu_hook \ [namespace current]::roster::add_remove_item_menu_item 90 hook::add roster_conference_popup_menu_hook \ [namespace current]::roster::add_remove_item_menu_item 90 hook::add roster_service_popup_menu_hook \ [namespace current]::roster::add_remove_item_menu_item 90 hook::add roster_jid_popup_menu_hook \ [namespace current]::roster::add_remove_item_menu_item 90 ############################################################################### proc roster::remove_item_dialog {connid jid} { set res [MessageDlg .remove_item -aspect 50000 -icon question -type user \ -buttons {yes no} -default 0 -cancel 1 \ -message [format [::msgcat::mc "Are you sure to remove %s from roster?"] $jid]] if {$res == 0} { ::roster::remove_item $connid $jid } } proc roster::update_chat_activity {args} { variable options if {$options(chats_group)} { redraw_after_idle } } hook::add open_chat_post_hook [namespace current]::roster::redraw_after_idle hook::add close_chat_post_hook [namespace current]::roster::redraw_after_idle hook::add draw_message_hook [namespace current]::roster::update_chat_activity hook::add raise_chat_tab_hook [namespace current]::roster::update_chat_activity ############################################################################### proc roster::dropcmd {target source X Y op type data} { variable options debugmsg roster "$target $source $X $Y $op $type $data" set c .roster.canvas set x [expr {$X-[winfo rootx $c]}] set y [expr {$Y-[winfo rooty $c]}] set xc [$c canvasx $x] set yc [$c canvasy $y] set tags [$c gettags [lindex [$c find closest $xc $yc] 0]] if {$options(free_drop) && ![cequal $tags ""]} { lassign [tag_to_jid [crange [lindex $tags 1] 5 end]] connid gr if {$connid == "connid"} { set connid $gr set gr {} } } elseif {[lcontain $tags group]} { lassign [tag_to_jid [crange [lindex $tags 0] 3 end]] connid gr if {$connid == "connid"} { set connid $gr set gr {} } } elseif {![cequal $tags ""]} { lassign [tag_to_jid [crange [lindex $tags 1] 5 end]] connid set gr {} } else { set connid [lindex [jlib::connections] 0] set gr {} } if {$options(nested)} { set gr [join $gr $options(nested_delimiter)] } else { set gr [lindex $gr 0] } debugmsg roster "GG: $gr; $tags" lassign $data _connid jid category type name version fromgid set subsc "" if {[info exists fromgid]} { lassign $fromgid fromconnid fromgr if {$options(nested)} { set fromgr [join $fromgr $options(nested_delimiter)] } else { set fromgr [lindex $fromgr 0] } } if {![lcontain [::roster::get_jids $connid] $jid]} { if {$gr != {}} { set groups [list $gr] } else { set groups {} } ::roster::itemconfig $connid $jid -category $category -subtype $type \ -name $name -group $groups lassign [::roster::get_category_and_subtype $connid $jid] ccategory ctype switch -- $ccategory { conference { ::roster::itemconfig $connid $jid -subsc bookmark } user { jlib::send_presence -to $jid -type subscribe -connection $connid } } } else { set groups [::roster::itemconfig $connid $jid -group] if {[info exists fromgid] && ($fromconnid == $connid)} { set idx [lsearch -exact $groups $fromgr] if {$idx >= 0} { set groups [lreplace $groups $idx $idx] } } if {$gr != ""} { lappend groups $gr set groups [lrmdups $groups] debugmsg roster $groups } ::roster::itemconfig $connid $jid -category $category -subtype $type \ -name $name -group $groups } ::roster::send_item $connid $jid } proc roster::draginitcmd {target x y top} { debugmsg roster "$target $x $y $top" balloon::destroy set c .roster.canvas set tags [$c gettags current] if {[lcontain $tags jid]} { set grouptag [crange [lindex $tags 1] 5 end] set gid [tag_to_jid $grouptag] set tag [crange [lindex $tags 0] 3 end] set cjid [tag_to_jid $tag] lassign $cjid connid jid set data [list $connid $jid \ [::roster::itemconfig $connid $jid -category] \ [::roster::itemconfig $connid $jid -subtype] \ [::roster::itemconfig $connid $jid -name] {} \ $gid] debugmsg roster $data return [list JID {move} $data] } else { return {} } } ############################################################################### proc roster::user_singleclick {cjid} { variable roster lassign $cjid connid jid if {[roster::itemconfig $connid $jid -isuser] && \ [llength [get_jids_of_user $connid $jid]] > 1} { set roster(collapsed,$cjid) [expr {!$roster(collapsed,$cjid)}] redraw_after_idle } } ############################################################################### proc roster::popup_menu {id} { global curuser lassign $id connid jid set curuser $jid lassign [::roster::get_category_and_subtype $connid $jid] category subtype switch -- $category { user {set menu [create_user_menu $connid $jid]} conference {set menu [conference_popup_menu $connid $jid]} server - gateway - service {set menu [service_popup_menu $connid $jid]} default {set menu [jid_popup_menu $connid $jid]} } tk_popup $menu [winfo pointerx .] [winfo pointery .] } ############################################################################### proc roster::group_popup_menu {id} { variable options lassign $id connid name if {$options(nested)} { set name [join $name $options(nested_delimiter)] } else { set name [lindex $name 0] } if {$connid != "connid"} { tk_popup [create_group_popup_menu $connid $name] \ [winfo pointerx .] [winfo pointery .] } } ############################################################################### proc roster::groupchat_popup_menu {id} { lassign $id connid jid tk_popup [create_groupchat_user_menu $connid $jid] \ [winfo pointerx .] [winfo pointery .] } ############################################################################### proc roster::create_user_menu {connid user} { set m .jidpopupmenu if {[winfo exists $m]} { destroy $m } menu $m -tearoff 0 set jids [get_jids_of_user $connid $user] switch -- [llength $jids] { 0 { hook::run roster_jid_popup_menu_hook $m $connid $user return $m } 1 { hook::run roster_jid_popup_menu_hook $m $connid [lindex $jids 0] return $m } default { foreach jid $jids { set m1 .jidpopupmenu[jid_to_tag $jid] if {[winfo exists $m1]} { destroy $m1 } menu $m1 -tearoff 0 hook::run roster_jid_popup_menu_hook $m1 $connid $jid } add_menu_submenu $m .jidpopupmenu "" $jids foreach jid $jids { set m1 .jidpopupmenu[jid_to_tag $jid] if {[winfo exists $m1]} { destroy $m1 } } return $m } } } ############################################################################### proc roster::add_menu_submenu {m prefix suffix jids} { set m1 $prefix[jid_to_tag [lindex $jids 0]]$suffix for {set i 0} {[$m1 index $i] == $i} {incr i} { if {[catch { $m1 entrycget $i -label } label]} { $m add separator } elseif {![catch { $m1 entrycget $i -menu } menu]} { set suffix2 [join [lrange [split $menu .] 2 end] .] set suffix3 [lindex [split $menu .] end] set m2 [menu $m.$suffix3 -tearoff 0] $m add cascade -label $label -menu $m2 add_menu_submenu $m2 $prefix .$suffix2 $jids } elseif {![catch { $m1 entrycget $i -variable } var]} { # Can't distinguish checkbuttons and radiobuttons # Works only for checkbuttons add_checkbutton_submenu $m $prefix $suffix $i $label $jids } else { add_command_submenu $m $prefix $suffix $i $label $jids } } } ############################################################################### proc roster::add_command_submenu {m prefix suffix i label jids} { set command_list {} foreach jid $jids { set m1 $prefix[jid_to_tag $jid]$suffix set idx [$m1 index $label] if {$idx != "none"} { set command [$m1 entrycget $idx -command] if {![lcontain $command_list $command]} { lappend command_list $command } } } if {[llength $command_list] > 1} { set m2 [menu $m.$i -tearoff 0] $m add cascade -label $label -menu $m2 foreach jid $jids { set m1 $prefix[jid_to_tag $jid]$suffix set idx [$m1 index $label] if {$idx != "none"} { set command [$m1 entrycget $idx -command] $m2 add command -label $jid \ -command [string map [list $m1 $m2] $command] } } } else { $m add command -label $label -command [lindex $command_list 0] } } ############################################################################### proc roster::add_checkbutton_submenu {m prefix suffix i label jids} { set command_list {} foreach jid $jids { set m1 $prefix[jid_to_tag $jid]$suffix set idx [$m1 index $label] if {$idx != "none"} { set var [$m1 entrycget $idx -variable] set command [$m1 entrycget $idx -command] if {![lcontain $command_list [list $var $command]]} { lappend command_list [list $var $command] } } } if {[llength $command_list] > 1} { set m2 [menu $m.$i -tearoff 0] $m add cascade -label $label -menu $m2 foreach jid $jids { set m1 $prefix[jid_to_tag $jid]$suffix set idx [$m1 index $label] if {$idx != "none"} { set var [$m1 entrycget $idx -variable] set command [$m1 entrycget $idx -command] $m2 add checkbutton -label $jid -variable $var -command $command } } } else { lassign [lindex $command_list 0] var command $m add checkbutton -label $label -variable $var -command $command } } ############################################################################### proc roster::add_separator {m connid jid} { $m add separator } ############################################################################### proc roster::jid_popup_menu {connid jid} { if {[winfo exists [set m .jidpopupmenu]]} { destroy $m } menu $m -tearoff 0 hook::run roster_jid_popup_menu_hook $m $connid $jid return $m } hook::add roster_jid_popup_menu_hook \ [namespace current]::roster::add_separator 40 hook::add roster_jid_popup_menu_hook \ [namespace current]::roster::add_separator 50 hook::add roster_jid_popup_menu_hook \ [namespace current]::roster::add_separator 70 hook::add roster_jid_popup_menu_hook \ [namespace current]::roster::add_separator 85 ############################################################################### proc roster::conference_popup_menu {connid jid} { if {[winfo exists [set m .confpopupmenu]]} { destroy $m } menu $m -tearoff 0 hook::run roster_conference_popup_menu_hook $m $connid $jid return $m } hook::add roster_conference_popup_menu_hook \ [namespace current]::roster::add_separator 50 hook::add roster_conference_popup_menu_hook \ [namespace current]::roster::add_separator 70 hook::add roster_conference_popup_menu_hook \ [namespace current]::roster::add_separator 85 ############################################################################### proc roster::service_popup_menu {connid jid} { if {[winfo exists [set m .servicepopupmenu]]} { destroy $m } menu $m -tearoff 0 hook::run roster_service_popup_menu_hook $m $connid $jid return $m } hook::add roster_service_popup_menu_hook \ [namespace current]::roster::add_separator 50 hook::add roster_service_popup_menu_hook \ [namespace current]::roster::add_separator 70 hook::add roster_service_popup_menu_hook \ [namespace current]::roster::add_separator 85 ############################################################################### proc roster::create_groupchat_user_menu {connid jid} { if {[winfo exists [set m .groupchatpopupmenu]]} { destroy $m } menu $m -tearoff 0 hook::run roster_create_groupchat_user_menu_hook $m $connid $jid return $m } hook::add roster_create_groupchat_user_menu_hook \ [namespace current]::roster::add_separator 40 hook::add roster_create_groupchat_user_menu_hook \ [namespace current]::roster::add_separator 50 ############################################################################### proc roster::create_group_popup_menu {connid name} { variable options variable chats_group_name if {$name == $chats_group_name} { set state disabled } else { set state normal } if {[winfo exists [set m .grouppopupmenu]]} { destroy $m } if {$options(nested)} { set oname [msplit $name $options(nested_delimiter)] } else { set oname $name } menu $m -tearoff 0 $m add command \ -label [::msgcat::mc "Send message to all users in group..."] \ -command [list ::message::send_dialog \ -to $name -group 1 -connection $connid] $m add command \ -label [::msgcat::mc "Resubscribe to all users in group..."] \ -command [list ::roster::resubscribe_group $connid $name] add_group_custom_presence_menu $m $connid $name $m add checkbutton -label [::msgcat::mc "Show offline users"] \ -variable [namespace current]::roster(show_offline,[list $connid $oname]) \ -command [list [namespace current]::redraw_after_idle] $m add command -label [::msgcat::mc "Rename group..."] \ -command [list [namespace current]::rename_group_dialog $connid $name] \ -state $state $m add command -label [::msgcat::mc "Remove group..."] \ -command [list [namespace current]::remove_group_dialog $connid $name] \ -state $state $m add command -label [::msgcat::mc "Remove all users in group..."] \ -command [list [namespace current]::remove_users_group_dialog $connid $name] set last [$m index end] ::hook::run roster_group_popup_menu_hook $m $connid $name if {[$m index end] > $last} { $m insert [expr $last + 1] separator } return $m } ############################################################################### proc roster::remove_group_dialog {connid name} { set res [MessageDlg .remove_item -aspect 50000 -icon question -type user \ -buttons {yes no} -default 0 -cancel 1 \ -message [format [::msgcat::mc "Are you sure to remove group '%s' from roster?\ \n(Users which are in this group only, will be in undefined group.)"] $name]] if {$res == 0} { roster::send_rename_group $connid $name "" } } proc roster::remove_users_group_dialog {connid name} { set res [MessageDlg .remove_item -aspect 50000 -icon question -type user \ -buttons {yes no} -default 0 -cancel 1 \ -message [format [::msgcat::mc "Are you sure to remove all users in group '%s' from roster?\ \n(Users which are in another groups too, will not be removed from the roster.)"] $name]] if {$res == 0} { roster::send_remove_users_group $connid $name } } proc roster::rename_group_dialog {connid name} { global new_roster_group_name set new_roster_group_name $name set w .roster_group_rename if {[winfo exists $w]} { destroy $w } Dialog $w -title [::msgcat::mc "Rename roster group"] \ -separator 1 -anchor e -default 0 -cancel 1 $w add -text [::msgcat::mc "OK"] -command \ [list [namespace current]::confirm_rename_group $w $connid $name] $w add -text [::msgcat::mc "Cancel"] -command [list destroy $w] set p [$w getframe] label $p.lgroupname -text [::msgcat::mc "New group name:"] ecursor_entry [entry $p.groupname -textvariable new_roster_group_name] grid $p.lgroupname -row 0 -column 0 -sticky e grid $p.groupname -row 0 -column 1 -sticky ew focus $p.groupname $w draw } proc roster::confirm_rename_group {w connid name} { global new_roster_group_name variable roster destroy $w ::roster::send_rename_group $connid $name $new_roster_group_name set gid [list $connid $name] set newgid [list $connid $new_roster_group_name] if {[info exists roster(collapsed,$gid)]} { set roster(collapsed,$newgid) $roster(collapsed,$gid) unset roster(collapsed,$gid) } if {[info exists roster(show_offline,$gid)]} { set roster(show_offline,$newgid) $roster(show_offline,$gid) unset roster(show_offline,$gid) } } proc roster::add_group_by_jid_regexp_dialog {} { global new_roster_group_rname global new_roster_group_regexp set w .roster_group_add_by_jid_regexp if {[winfo exists $w]} { destroy $w } Dialog $w -title [::msgcat::mc "Add roster group by JID regexp"] \ -separator 1 -anchor e -default 0 -cancel 1 $w add -text [::msgcat::mc "OK"] -command " destroy [list $w] roster::add_group_by_jid_regexp \ \$new_roster_group_rname \$new_roster_group_regexp " $w add -text [::msgcat::mc "Cancel"] -command [list destroy $w] set p [$w getframe] label $p.lgroupname -text [::msgcat::mc "New group name:"] ecursor_entry [entry $p.groupname -textvariable new_roster_group_rname] label $p.lregexp -text [::msgcat::mc "JID regexp:"] ecursor_entry [entry $p.regexp -textvariable new_roster_group_regexp] grid $p.lgroupname -row 0 -column 0 -sticky e grid $p.groupname -row 0 -column 1 -sticky ew grid $p.lregexp -row 1 -column 0 -sticky e grid $p.regexp -row 1 -column 1 -sticky ew focus $p.groupname $w draw } ############################################################################### proc roster::add_group_custom_presence_menu {m connid name} { set mm [menu $m.custom_presence -tearoff 0] $mm add command -label [::msgcat::mc "Available"] \ -command [list roster::send_custom_presence_group $connid $name available] $mm add command -label [::msgcat::mc "Free to chat"] \ -command [list roster::send_custom_presence_group $connid $name chat] $mm add command -label [::msgcat::mc "Away"] \ -command [list roster::send_custom_presence_group $connid $name away] $mm add command -label [::msgcat::mc "Extended away"] \ -command [list roster::send_custom_presence_group $connid $name xa] $mm add command -label [::msgcat::mc "Do not disturb"] \ -command [list roster::send_custom_presence_group $connid $name dnd] $mm add command -label [::msgcat::mc "Unavailable"] \ -command [list roster::send_custom_presence_group $connid $name unavailable] $m add cascade -label [::msgcat::mc "Send custom presence"] -menu $mm } ############################################################################### # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/ifacetk/iface.tcl0000644000175000017500000013620411074113462015710 0ustar sergeisergei# $Id: iface.tcl 1511 2008-10-11 12:08:18Z sergei $ namespace eval ifacetk { variable options custom::defgroup IFace \ [::msgcat::mc "Options for main interface."] \ -group Tkabber -tag "Main Interface" custom::defvar options(use_tabbar) 1 \ [::msgcat::mc \ "Use Tabbed Interface (you need to restart)."] \ -group IFace -type boolean custom::defvar options(tabs_side) top \ [::msgcat::mc "Side where to place tabs in tabbed mode."] \ -group IFace -type options \ -values [list top [::msgcat::mc "Top"] \ bottom [::msgcat::mc "Bottom"] \ left [::msgcat::mc "Left"] \ right [::msgcat::mc "Right"]] \ -command [namespace current]::configure_tabs custom::defvar options(tab_minwidth) 90 \ [::msgcat::mc "Minimum width of tab buttons in tabbed mode."] \ -group IFace -type integer \ -command [namespace current]::configure_tabs custom::defvar options(tab_maxwidth) 120 \ [::msgcat::mc "Maximum width of tab buttons in tabbed mode."] \ -group IFace -type integer \ -command [namespace current]::configure_tabs custom::defvar options(show_toolbar) 1 \ [::msgcat::mc "Show Toolbar."] \ -group IFace -type boolean \ -command [namespace current]::switch_toolbar custom::defvar options(show_presencebar) 1 \ [::msgcat::mc "Show presence bar."] \ -group IFace -type boolean \ -command [namespace current]::switch_presencebar custom::defvar options(show_statusbar) 1 \ [::msgcat::mc "Show status bar."] \ -group IFace -type boolean \ -command [namespace current]::switch_statusbar if {!$XLFDFonts} { custom::defvar options(font) $::default_Chat_font \ [::msgcat::mc "Font to use in chat windows."] \ -group IFace -type font \ -command [list [namespace current]::switch_font font Chat] custom::defvar options(roster_font) $::default_Roster_font \ [::msgcat::mc "Font to use in roster windows."] \ -group IFace -type font \ -command [list [namespace current]::switch_font roster_font Roster] } custom::defvar options(raise_new_tab) 1 \ [::msgcat::mc "Raise new tab."] \ -group IFace -type boolean custom::defvar options(message_numbers_in_tabs) 1 \ [::msgcat::mc "Show number of unread messages in tab titles."] \ -group IFace -type boolean custom::defvar options(only_personal_messages_in_window_title) 0 \ [::msgcat::mc "Show only the number of personal unread messages\ in window title."] \ -group IFace -type boolean custom::defvar options(update_title_delay) 600 \ [::msgcat::mc "Delay between getting focus and updating window or\ tab title in milliseconds."] \ -group IFace -type integer custom::defvar options(show_tearoffs) 1 \ [::msgcat::mc "Show menu tearoffs when possible."] \ -group IFace -type boolean custom::defvar options(closebuttonaction) close \ [::msgcat::mc "What action does the close button."] \ -group IFace -type options \ -values [list \ close [::msgcat::mc "Close Tkabber"] \ nothing [::msgcat::mc "Do nothing"] \ minimize [::msgcat::mc "Minimize"] \ iconize [::msgcat::mc "Iconize"] \ systray [::msgcat::mc "Minimize to systray (if systray\ icon is enabled, otherwise do nothing)"] \ ] custom::defvar mainwindowstate normal \ [::msgcat::mc "Stored main window state (normal or zoomed)"] \ -type string -group Hidden custom::defvar status_history [list] \ [::msgcat::mc "History of availability status messages"] \ -type list \ -group Hidden custom::defvar options(max_status_history) 10 \ [::msgcat::mc "Maximum number of status messages to keep.\ If the history size reaches this threshold,\ the oldest message will be deleted automatically\ when a new one is recorded."] \ -type integer -group IFace proc isource {file} { set dir [file dirname [info script]] source [file join $dir $file] } isource ilogin.tcl isource iroster.tcl isource systray.tcl variable after_focused_id "" variable number_msg variable personal_msg namespace export raise_win add_win tab_set_updated } source [file join [file dirname [info script]] buttonbar.tcl] proc ifacetk::configure_tabs {args} { variable options global usetabbar variable tabs if {$usetabbar} { if {[string is integer -strict $options(tab_minwidth)] && \ $options(tab_minwidth) >= 0} { set minwidth $options(tab_minwidth) } else { set minwidth 90 } if {[string is integer -strict $options(tab_maxwidth)] && \ $options(tab_maxwidth) >= 0} { set maxwidth $options(tab_maxwidth) } else { set maxwidth 90 } switch -- $options(tabs_side) { bottom { set row 2 set col 1 set orient horizontal } left { set row 1 set col 0 set orient vertical } right { set row 1 set col 2 set orient vertical } default { set row 0 set col 1 set orient horizontal } } grid .nb -row $row -column $col -sticky nswe -in $tabs .nb configure -minwidth $minwidth -maxwidth $maxwidth -orient $orient } } proc ifacetk::save_mainwindowstate {w} { variable mainwindowstate if {![cequal $w .]} return set state [wm state .] if {$state != $mainwindowstate} { set mainwindowstate $state } } hook::add map_window_hook [namespace current]::ifacetk::save_mainwindowstate option add *errorForeground red widgetDefault wm protocol . WM_SAVE_YOURSELF session_checkpoint wm protocol . WM_DELETE_WINDOW \ [list [namespace current]::ifacetk::wm_delete_window] proc ifacetk::wm_delete_window {} { variable options hook::run protocol_wm_delete_window_hook $options(closebuttonaction) } proc ifacetk::closebuttonproc {action} { variable options switch -- $action { nothing {} minimize { wm iconify . } iconize { wm iconify . wm state . withdrawn } close - default { quit } } } hook::add protocol_wm_delete_window_hook \ [namespace current]::ifacetk::closebuttonproc set xselection "" proc EncodeTextSelection {txt offset len} { set elided "" if {[lcontain [$txt tag names] emphasized] && [$txt tag cget emphasized -elide]} { set elided emphasized } elseif {[lcontain [$txt tag names] nonemphasized] && [$txt tag cget nonemphasized -elide]} { set elided nonemphasized } if {[cequal $elided ""]} { set ::xselection [eval $txt get [$txt tag ranges sel]] } else { lassign [$txt tag ranges sel] selstart selstop set sel $selstart set ::xselection "" while {![cequal [set range [$txt tag nextrange $elided $sel $selstop]] ""]} { append ::xselection [$txt get $sel [lindex $range 0]] set sel [lindex $range 1] } append ::xselection [$txt get $sel $selstop] } encoding convertto [crange $::xselection $offset [expr $offset + $len - 1]] } proc EncodeEntrySelection {txt offset len} { if [$txt selection present] { set idx1 [$txt index sel.first] set idx2 [$txt index sel.last] set ::xselection [string range [$txt get] $idx1 $idx2] encoding convertto \ [crange $::xselection $offset [expr $offset + $len - 1]] } else { set ::xselection "" } } if {[cequal $tcl_platform(platform) unix]} { proc ::tk::GetSelection {w {sel PRIMARY}} { if {![catch {selection get -displayof $w \ -selection $sel -type UTF8_STRING} txt]} { return $txt } elseif {![catch {selection get -displayof $w -selection $sel} txt]} { if {[selection own] == ""} { return [encoding convertfrom $txt] } else { return $::xselection } } else { return -code error "could not find default selection" } } bind Text { selection handle %W "EncodeTextSelection %W" } bind Entry { selection handle %W "EncodeEntrySelection %W" } if {[info tclversion] < 8.4} { bind Text { if {![catch {::tk::GetSelection %W} sel]} { %W insert current $sel } } bind Entry { if {![catch {::tk::GetSelection %W} sel]} { %W insert insert $sel } } } } ############################################################################### proc ifacetk::load_descmenu {} { global descmenu set descmenu \ [list "&Tkabber" {} tkabber $ifacetk::options(show_tearoffs) \ [list \ [list cascad [::msgcat::mc "Presence"] {} presence $ifacetk::options(show_tearoffs) \ [list \ [list command [::msgcat::mc "Available"] {} {} {} \ -command {set userstatus available}] \ [list command [::msgcat::mc "Free to chat"] {} {} {} \ -command {set userstatus chat}] \ [list command [::msgcat::mc "Away"] {} {} {} \ -command {set userstatus away}] \ [list command [::msgcat::mc "Extended away"] {} {} {} \ -command {set userstatus xa}] \ [list command [::msgcat::mc "Do not disturb"] {} {} {} \ -command {set userstatus dnd}] \ {separator} \ [list command [::msgcat::mc "Change priority..."] {} {} {} \ -command {change_priority_dialog}]]] \ [list command [::msgcat::mc "Log in..."] {} {} {Ctrl l} \ -command [list [namespace current]::login_dialog]] \ [list command [::msgcat::mc "Log out"] {} {} {Ctrl j} \ -command [list [namespace current]::logout_dialog]] \ [list command [::msgcat::mc "Log out with reason..."] {} {} {} \ -command {show_logout_dialog}] \ {separator} \ [list command [::msgcat::mc "Change password..."] {} {} {} \ -command {change_password_dialog}] \ [list command [::msgcat::mc "Edit my info..."] {} {} {} \ -command { if {[llength [jlib::connections]] > 0} { set connid [lindex [jlib::connections] 0] userinfo::open [jlib::connection_bare_jid $connid] \ -editable 1 -connection $connid }}] \ [list cascad [::msgcat::mc "Privacy rules"] {} privacy $ifacetk::options(show_tearoffs) \ [list \ [list checkbutton [::msgcat::mc "Activate lists at startup"] {} {} {} \ -variable privacy::options(activate_at_startup)] \ [list command [string trim [::msgcat::mc "Edit invisible list "]] {} {} {} \ -command {privacy::edit_special_list invisible}] \ [list command [string trim [::msgcat::mc "Edit ignore list "]] {} {} {} \ -command {privacy::edit_special_list ignore}] \ [list command [string trim [::msgcat::mc "Edit conference list "]] {} {} {} \ -command {privacy::edit_special_list conference}] \ [list checkbutton [::msgcat::mc "Accept messages from roster users only"] {} {} {} \ -variable privacy::accept_from_roster_only \ -command privacy::on_accept_from_roster_only_change] \ {separator} \ [list command [::msgcat::mc "Manually edit rules"] {} {} {} \ -command {privacy::request_lists}]]] \ {separator} \ [list cascad [::msgcat::mc "View"] {} {} $ifacetk::options(show_tearoffs) \ [list \ [list checkbutton [::msgcat::mc "Toolbar"] \ {} {} {} \ -variable [namespace current]::options(show_toolbar)] \ [list checkbutton [::msgcat::mc "Presence bar"] \ {} {} {} \ -variable [namespace current]::options(show_presencebar)] \ [list checkbutton [::msgcat::mc "Status bar"] \ {} {} {} \ -variable [namespace current]::options(show_statusbar)] \ ]] \ [list cascad [::msgcat::mc "Roster"] {} roster $ifacetk::options(show_tearoffs) \ [list \ [list checkbutton [::msgcat::mc "Show online users only"] \ {} {} {} \ -variable [namespace current]::roster::show_only_online] \ [list checkbutton [::msgcat::mc "Show own resources"] {} {} {} \ -variable [namespace current]::roster::options(show_own_resources)] \ [list checkbutton [::msgcat::mc "Use roster filter"] {} {} {} \ -variable [namespace current]::roster::options(use_filter)] \ [list cascad [::msgcat::mc "Export roster..."] \ export_roster export_roster 0 {}] \ [list cascad [::msgcat::mc "Import roster..."] \ import_roster import_roster 0 {}] \ [list command [::msgcat::mc "Add group by regexp on JIDs..."] {} {} {} \ -command [namespace current]::roster::add_group_by_jid_regexp_dialog] \ ]] \ [list cascad [::msgcat::mc "Chats"] {} chats $ifacetk::options(show_tearoffs) \ [list \ [list checkbutton [::msgcat::mc "Generate enter/exit messages"] {} {} {} \ -variable muc::options(gen_enter_exit_msgs)] \ [list checkbutton [::msgcat::mc "Smart autoscroll"] {} {} {} \ -variable chat::options(smart_scroll)] \ [list checkbutton [::msgcat::mc "Stop autoscroll"] {} {} {} \ -variable chat::options(stop_scroll)] \ [list checkbutton [::msgcat::mc "Emphasize"] {} {} {} \ -variable plugins::stylecodes::options(emphasize)] \ [list checkbutton [::msgcat::mc "Show emoticons"] {} {} {} \ -variable plugins::emoticons::options(show_emoticons)] \ {separator} \ ]] \ {separator} \ [list command [::msgcat::mc "Customize"] {} {} {} \ -command {custom::open_window Tkabber}] \ {separator} \ [list command [::msgcat::mc "Profile on"] {} {} {} -command { profile -commands -eval on }] \ [list command [::msgcat::mc "Profile report"] {} {} {} -command { profile off profil profrep profil real profresults }] \ {separator} \ [list command [::msgcat::mc "Quit"] {} {} {} \ -command {quit}] \ ] \ [::msgcat::mc "&Services"] {} services $ifacetk::options(show_tearoffs) \ [list \ [list command [::msgcat::mc "Add user to roster..."] {} {} {} \ -command {message::send_subscribe_dialog ""}] \ {separator} \ [list command [::msgcat::mc "Send message..."] {} {} {} \ -command {message::send_dialog}] \ [list command [::msgcat::mc "Open chat..."] {} {} {} \ -command {chat::open_chat_dialog}] \ [list command [::msgcat::mc "Join group..."] {} {} {}\ -command {join_group_dialog}] \ [list command [::msgcat::mc "Show user or service info..."] {} {} {} \ -command {userinfo::show_info_dialog}] \ {separator} \ [list command [::msgcat::mc "Service Discovery"] {} {} {} \ -command {disco::browser::open_win ""}] \ {separator} \ [list command [::msgcat::mc "Message archive"] {} {} {} \ -command {message_archive::show_archive}] \ [list cascad [::msgcat::mc "Plugins"] {} plugins $ifacetk::options(show_tearoffs) \ ] \ {separator} \ [list cascad [::msgcat::mc "Admin tools"] {} admin $ifacetk::options(show_tearoffs) \ [list \ [list command [::msgcat::mc "Send broadcast message..."] {} {} {} \ -command {ifacetk::send_announce_message announce/online}] \ [list command [::msgcat::mc "Send message of the day..."] {} {} {} \ -command {ifacetk::send_announce_message announce/motd}] \ [list command [::msgcat::mc "Update message of the day..."] {} {} {} \ -command {ifacetk::send_announce_message announce/motd/update}] \ [list command [::msgcat::mc "Delete message of the day"] {} {} {} \ -command {ifacetk::send_announce_message announce/motd/delete}] \ {separator} \ ]] \ ] \ [::msgcat::mc "&Help"] {} {} $ifacetk::options(show_tearoffs) \ [list \ [list command [::msgcat::mc "Quick help"] {} {} {} \ -command ifacetk::quick_help_window] \ [list command [::msgcat::mc "About"] {} {} {} \ -command ifacetk::about_window] \ ] \ ] if {![info exists ::enable_profiling] || !$::enable_profiling || \ ([clength [info commands profile]] == 0)} { set tmpmenu {} set eatP 0 foreach menu [lindex $descmenu 4] { if {[::msgcat::mc "Profile on"] == [lindex $menu 1] || \ [::msgcat::mc "Profile report"] == [lindex $menu 1]} { set eatP 1 } elseif {$eatP} { set eatP 0 } else { lappend tmpmenu $menu } } set descmenu [lreplace $descmenu 4 4 $tmpmenu] } set descmenu [menuload $descmenu] } ############################################################################### proc ifacetk::send_announce_message {resource} { if {[llength [jlib::connections]] == 0} return set server [jlib::connection_server [lindex [jlib::connections] 0]] if {$resource == "announce/motd/delete"} { message::send_msg "$server/$resource" -type normal } else { message::send_dialog -to "$server/$resource" } } ############################################################################### proc ifacetk::quick_help_window {} { set w .quick_help if {[winfo exists $w]} { destroy $w } Dialog $w -anchor e \ -separator yes \ -title [::msgcat::mc "Quick Help"] \ -side bottom \ -modal none \ -default 0 \ -cancel 0 $w add -text [::msgcat::mc "Close"] -command [list destroy $w] set frame [$w getframe] set sw [ScrolledWindow $frame.sw] pack $sw -fill both -expand yes set t [text $frame.help -wrap none] set tabstop [font measure [get_conf $t -font] \ " [::msgcat::mc {Middle mouse button}] "] $t configure -tabs $tabstop $sw setwidget $t $t insert 0.0 \ "[::msgcat::mc {Main window:}] $::tk_modify-L\t[::msgcat::mc {Log in}] $::tk_modify-J\t[::msgcat::mc {Log out}] [::msgcat::mc Tabs:] $::tk_modify-F4, [::msgcat::mc {Middle mouse button}]\t[::msgcat::mc {Close tab}] $::tk_modify-PgUp/Down\t[::msgcat::mc {Previous/Next tab}] $::tk_modify-Alt-PgUp/Down\t[::msgcat::mc {Move tab left/right}] Alt-\[1-9,0\]\t[::msgcat::mc {Switch to tab number 1-9,10}] $::tk_modify-R\t[::msgcat::mc {Hide/Show roster}] [::msgcat::mc Common:] $::tk_modify-S\t[::msgcat::mc {Activate search panel}] [::msgcat::mc Chats:] TAB\t[::msgcat::mc {Complete nickname or command}] $::tk_modify-Up/Down\t[::msgcat::mc {Previous/Next history message}] Alt-E\t[::msgcat::mc {Show palette of emoticons}] $::tk_modify-Z\t[::msgcat::mc {Undo}] $::tk_modify-Shift-Z\t[::msgcat::mc {Redo}] Alt-PgUp/Down\t[::msgcat::mc {Scroll chat window up/down}] [::msgcat::mc {Right mouse button}]\t[::msgcat::mc {Correct word}] [::msgcat::mc Systray:] [::msgcat::mc {Left mouse button}]\t[::msgcat::mc {Show main window}] [::msgcat::mc {Middle mouse button}]\t[::msgcat::mc {Hide main window}] [::msgcat::mc {Right mouse button}]\t[::msgcat::mc {Popup menu}]" $t configure -state disabled $w draw } proc ifacetk::about_window {} { global tkabber_version toolkit_version set w .about if {[winfo exists $w]} { destroy $w } Dialog $w -anchor e \ -separator yes \ -title [::msgcat::mc "About"] \ -image tkabber/logo \ -side bottom \ -modal none \ -default 0 \ -cancel 0 $w add -text [::msgcat::mc "Close"] -command [list destroy $w] set frame [$w getframe] set m [message $frame.msg -text " Tkabber $tkabber_version ($toolkit_version) Copyright \u00a9 2002-2008 [::msgcat::mc {Alexey Shchepin}] \n[::msgcat::mc Authors:] [::msgcat::mc {Alexey Shchepin}] [::msgcat::mc {Marshall T. Rose}] [::msgcat::mc {Sergei Golovan}] [::msgcat::mc {Michail Litvak}] [::msgcat::mc {Konstantin Khomoutov}] "] pack $m -side top -anchor w set t [text $frame.url -cursor [get_conf $frame.msg -cursor] \ -bg [get_conf $frame.msg -bg] \ -height 1 \ -width 25 \ -bd 0 \ -highlightthickness 0 \ -takefocus 0] ::richtext::config $t -using url ::richtext::render_message $t " http://tkabber.jabber.ru/" "" $t delete {end - 1 char} $t configure -state disabled pack $t -side top -anchor w -fill x $w draw } proc ifacetk::switch_font {font class args} { variable options set opts [lassign $options($font) family size] set args [list -family $family -size $size] set bold 0 set italic 0 set underline 0 set overstrike 0 foreach opt $opts { switch -- $opt { bold { lappend args -weight bold set bold 1 } italic { lappend args -slant italic set italic 1 } underline { lappend args -underline 1 set underline 1 } overstrike { lappend args -overstrike 1 set overstrike 1 } } } if {!$bold} { lappend args -weight normal } if {!$italic} { lappend args -slant roman } if {!$underline} { lappend args -underline 0 } if {!$overstrike} { lappend args -overstrike 0 } eval redefine_fonts $class $args if {$class == "Roster"} { roster::redraw_after_idle foreach chatid [chat::opened] { if {[chat::is_groupchat $chatid]} { chat::redraw_roster_after_idle $chatid } } } } proc ifacetk::show_ssl_info {} { global ssl_certificate_fields if {[winfo exists .ssl_info]} { destroy .ssl_info } if {[lempty [set msg_list [ssl_info]]]} return Dialog .ssl_info -title [::msgcat::mc "SSL Info"] -separator 1 -anchor e \ -default 0 -cancel 0 -modal none .ssl_info add -text [::msgcat::mc "Close"] -command "destroy .ssl_info" set fr [.ssl_info getframe] if {[llength $msg_list] == 2} { lassign $msg_list server msg set page [frame $fr.page] set title [format [::msgcat::mc "%s SSL Certificate Info"] $server] grid [label $page.title -text $title] -row 0 -column 0 -sticky ew grid [message $page.info -aspect 50000 -text $msg] \ -row 1 -column 0 -sticky ew pack $page -expand yes -fill both -padx 1m -pady 1m } else { set nb [NoteBook $fr.nb] pack $nb -expand yes -fill both -padx 0m -pady 0m set i 0 foreach {server msg} $msg_list { set page [$nb insert end page$i -text $server] set title [format [::msgcat::mc "%s SSL Certificate Info"] $server] grid [label $page.title -text $title] -row 0 -column 0 -sticky ew grid [message $page.info -aspect 50000 -text $msg] \ -row 1 -column 0 -sticky ew incr i } $nb compute_size $nb raise page0 } .ssl_info draw } proc ifacetk::update_ssl_ind {args} { global use_tls variable ssl_ind if {!$use_tls} return lassign [update_ssl_info] state fg balloon if {![cequal $fg warning]} { label .fake_label set fg [.fake_label cget -foreground] destroy .fake_label } else { set fg [option get $ssl_ind errorForeground Label] } $ssl_ind configure -state $state if {[cequal $state normal]} { $ssl_ind configure -foreground $fg } DynamicHelp::register $ssl_ind balloon $balloon } hook::add connected_hook [namespace current]::ifacetk::update_ssl_ind hook::add disconnected_hook [namespace current]::ifacetk::update_ssl_ind ############################################################################### proc ifacetk::add_toolbar_button {icon command helptext} { if {[catch {set bbox [.mainframe gettoolbar 0].bbox}] || \ ![winfo exists $bbox]} { return 0 } $bbox add -image $icon \ -highlightthickness 0 \ -takefocus 0 \ -relief link \ -bd $::tk_borderwidth \ -padx 1 \ -pady 1 \ -command $command \ -helptext $helptext return [$bbox index end] } ############################################################################### proc ifacetk::set_toolbar_icon {index script args} { if {[catch {set bbox [.mainframe gettoolbar 0].bbox}] || \ ![winfo exists $bbox]} { return } set image [eval $script] $bbox itemconfigure $index -image $image } ############################################################################### proc ifacetk::online_icon {args} { if {$roster::show_only_online} { return toolbar/show-online } else { return toolbar/show-offline } } proc ifacetk::create_main_window {} { global usetabbar global user_status_list global use_tls global descmenu variable mf variable rw variable rosterwidth variable ssl_ind variable main_window_title variable options variable status_history set main_window_title "Tkabber" wm title . $main_window_title wm iconname . $main_window_title wm group . . bind all <> {focus [Widget::focusPrev %W]} load_descmenu set mf [MainFrame .mainframe -menu $descmenu -textvariable status] unset descmenu if {$use_tls} { set ssl_ind [$mf addindicator -text "SSL" -state disabled] $ssl_ind configure -relief flat DynamicHelp::register $ssl_ind balloon [::msgcat::mc "Disconnected"] bind $ssl_ind <1> [namespace current]::show_ssl_info } pack $mf -expand yes -fill both bind $mf quit set bbox [ButtonBox [$mf addtoolbar].bbox -spacing 0 -padx 1 -pady 1] add_toolbar_button toolbar/add-user {message::send_subscribe_dialog ""} \ [::msgcat::mc "Add new user..."] add_toolbar_button toolbar/disco {disco::browser::open_win ""} \ [::msgcat::mc "Service Discovery"] add_toolbar_button toolbar/join-conference join_group_dialog \ [::msgcat::mc "Join group..."] set idx [add_toolbar_button [ifacetk::online_icon] \ [namespace current]::roster::switch_only_online \ [::msgcat::mc "Toggle showing offline users"]] trace variable [namespace current]::roster::show_only_online w \ [list [namespace current]::set_toolbar_icon $idx \ [namespace current]::online_icon] pack $bbox -side left -anchor w switch_toolbar if {$options(use_tabbar)} { set usetabbar 1 } else { set usetabbar 0 } set ww 0 foreach {status str} $user_status_list { if {[string length $str] > $ww} { set ww [string length $str] } } frame .presence menubutton .presence.button -menu .presence.button.menu -relief $::tk_relief \ -textvariable userstatusdesc -direction above -width $ww disallow_presence_change "" set w .presence.status ComboBox $w -textvariable textstatus -values $status_history $w bind {set userstatus $userstatus} trace add variable ::userstatus write \ [list [namespace current]::save_availability_status $w] $w bind [list [namespace current]::show_status_context_menu $w] if {$usetabbar} { pack .presence.button -side left pack .presence.status -side left -fill x -expand yes } else { pack .presence.button -side top -anchor w pack .presence.status -side top -fill x -expand yes -anchor w } grid .presence -row 3 -column 1 -sticky nswe -in [$mf getframe] if {[winfo exists [set m .presence.button.menu]]} { destroy $m } menu $m -tearoff $ifacetk::options(show_tearoffs) foreach {status str} $user_status_list { switch -- $status { invisible - unavailable {} default { $m add command \ -label $str \ -command [list set userstatus $status] } } } switch_presencebar switch_statusbar set rosterwidth [option get . mainRosterWidth [winfo class .]] if {$rosterwidth == ""} { set rosterwidth [winfo pixels . 3c] } grid columnconfigure [$mf getframe] 1 -weight 1 grid rowconfigure [$mf getframe] 1 -weight 1 if {$usetabbar} { set pw [PanedWin [$mf getframe].pw -side bottom -pad 1 -width 4] grid $pw -row 1 -column 1 -sticky nswe set rw [PanedWinAdd $pw -minsize 0 -weight 0] set nw [PanedWinAdd $pw -minsize 32 -weight 1] variable tabs set tabs $nw roster::create .roster -width $rosterwidth -height 300 \ -popup [namespace current]::roster::popup_menu \ -grouppopup [namespace current]::roster::group_popup_menu \ -singleclick [namespace current]::roster::user_singleclick \ -doubleclick [namespace current]::roster::jid_doubleclick \ -draginitcmd [namespace current]::roster::draginitcmd \ -dropcmd [namespace current]::roster::dropcmd pack .roster -expand yes -fill both -side top -in $rw -anchor w grid columnconfigure $nw 1 -weight 1 grid rowconfigure $nw 1 -weight 1 ButtonBar .nb -orient horizontal \ -pady 1 \ -padx 4 \ -pages .pages configure_tabs frame $nw.fr -relief raised -bd 1 grid $nw.fr -row 1 -column 1 -sticky nsew grid columnconfigure $nw.fr 0 -weight 1 grid rowconfigure $nw.fr 0 -weight 1 PagesManager .pages -width 400 grid .pages -row 0 -column 0 -padx 2m -pady 2m -in $nw.fr -sticky nsew PanedWinConf $pw 0 -width $rosterwidth event add <> bind . <> [list [namespace current]::collapse_roster] bind . [list [namespace current]::tab_move .nb -1] bind . [list [namespace current]::tab_move .nb 1] bind . [list [namespace current]::current_tab_move .nb -1] bind . [list [namespace current]::current_tab_move .nb -1] bind . [list [namespace current]::current_tab_move .nb 1] bind . [list [namespace current]::current_tab_move .nb 1] bind . { if {[.nb raise] != ""} { eval destroy [pack slaves [.nb getframe [.nb raise]]] .nb delete [.nb raise] 1 ifacetk::tab_move .nb 0 } } for {set i 1} {$i < 10} {incr i} { bind . [list [namespace current]::tab_raise_by_number .nb $i] bind . [list [namespace current]::tab_raise_by_number .nb $i] } bind . [list [namespace current]::tab_raise_by_number .nb 10] bind . [list [namespace current]::tab_raise_by_number .nb 10] set m [menu .tabsmenu -tearoff 0] $m add command -label [::msgcat::mc "Close"] -accelerator $::tk_close \ -command { if {[.nb raise] != ""} { eval destroy [pack slaves [.nb getframe $curmenutab]] .nb delete $curmenutab 1 ifacetk::tab_move .nb 0 } } $m add separator $m add command -label [::msgcat::mc "Close other tabs"] \ -command { foreach tab [.nb pages] { if {$tab != $curmenutab} { eval destroy [pack slaves [.nb getframe $tab]] .nb delete $tab 1 } } ifacetk::tab_move .nb 0 } $m add command -label [::msgcat::mc "Close all tabs"] \ -command { foreach tab [.nb pages] { eval destroy [pack slaves [.nb getframe $tab]] .nb delete $tab 1 } } .nb bindtabs <3> [list [namespace current]::tab_menu %X %Y] .nb bindtabs <2> [list [namespace current]::destroy_tab] .nb bindtabs <> [list [namespace current]::tab_move .nb -1] .nb bindtabs <> [list [namespace current]::tab_move .nb 1] #DragSite::register .nb.c -draginitcmd [namespace current]::draginitcmd #DropSite::register .nb.c -dropovercmd [namespace current]::dropovercmd \ # -dropcmd [namespace current]::dropcmd -droptypes {NoteBookPage} set geometry [option get . geometry [winfo class .]] if {$geometry == ""} { set geometry 788x550 } } else { roster::create .roster -width $rosterwidth -height 300 \ -popup [namespace current]::roster::popup_menu \ -grouppopup [namespace current]::roster::group_popup_menu \ -singleclick [namespace current]::roster::user_singleclick \ -doubleclick [namespace current]::roster::jid_doubleclick \ -draginitcmd [namespace current]::roster::draginitcmd \ -dropcmd [namespace current]::roster::dropcmd grid .roster -row 1 -column 1 -sticky nswe -in [$mf getframe] set geometry [option get . geometry [winfo class .]] if {$geometry == ""} { set geometry 200x350 } } bind . [list [namespace current]::map_dot %W] wm geometry . $geometry define_alert_colors update idletasks } proc ifacetk::map_dot {w} { if {$w != "."} return hook::run map_window_hook $w } proc ifacetk::destroy_tab {page} { if {[.nb raise] != ""} { eval destroy [pack slaves [.nb getframe $page]] .nb delete $page 1 ifacetk::tab_move .nb 0 } } proc ifacetk::draginitcmd {target x y top} { set c .nb.c set tags [$c gettags current] if {[lcontain $tags page]} { # page name set data [string range [lindex $tags 1] 2 end] return [list NoteBookPage {move} $data] } else { return {} } } proc ifacetk::dropovercmd {target source event X Y op type data} { set c .nb.c set x [expr {$X-[winfo rootx $c]}] set y [expr {$Y-[winfo rooty $c]}] set xc [$c canvasx $x] set yc [$c canvasy $y] set tags [$c gettags [lindex [$c find closest $xc $yc] 0]] if {[lcontain $tags page]} { DropSite::setcursor based_arrow_down return 3 } else { DropSite::setcursor dot return 2 } } proc ifacetk::dropcmd {target source X Y op type data} { set c .nb.c set x [expr {$X-[winfo rootx $c]}] set y [expr {$Y-[winfo rooty $c]}] set xc [$c canvasx $x] set yc [$c canvasy $y] set tags [$c gettags [lindex [$c find closest $xc $yc] 0]] if {[lcontain $tags page]} { # page name set data1 [string range [lindex $tags 1] 2 end] .nb move $data [.nb index $data1] } } proc ifacetk::destroy_win {path} { global usetabbar if {$usetabbar} { if {[winfo exists $path]} { set page [ifacetk::nbpage $path] eval destroy [pack slaves [.nb getframe $page]] .nb delete $page 1 ifacetk::tab_move .nb 0 } } else { destroy $path } } hook::add finload_hook [namespace current]::ifacetk::create_main_window 1 proc ifacetk::allow_presence_change {connid} { .presence.button configure -state normal set m [.mainframe getmenu tkabber] $m entryconfigure [$m index [::msgcat::mc "Presence"]] -state normal } proc ifacetk::disallow_presence_change {connid} { if {[llength [jlib::connections]] == 0} { .presence.button configure -state disabled set m [.mainframe getmenu tkabber] $m entryconfigure [$m index [::msgcat::mc "Presence"]] -state disabled } } hook::add connected_hook [namespace current]::ifacetk::allow_presence_change hook::add disconnected_hook [namespace current]::ifacetk::disallow_presence_change proc ifacetk::on_open_chat_window {chatid type} { variable number_msg variable personal_msg set number_msg($chatid) 0 set personal_msg($chatid) 0 } proc ifacetk::on_close_chat_window {chatid} { variable number_msg variable personal_msg unset number_msg($chatid) unset personal_msg($chatid) } hook::add open_chat_pre_hook [namespace current]::ifacetk::on_open_chat_window hook::add close_chat_post_hook [namespace current]::ifacetk::on_close_chat_window proc ifacetk::nbpage {path} { return [crange [win_id tab $path] 1 end] } proc ifacetk::nbpath {page} { return [lindex [pack slaves [.nb getframe $page]] 0] } proc ifacetk::update_chat_title {chatid} { global usetabbar variable options variable number_msg variable personal_msg set cw [chat::winid $chatid] if {$usetabbar} { set tabtitle $chat::chats(tabtitlename,$chatid) if {$options(message_numbers_in_tabs) && ($number_msg($chatid) > 0)} { append tabtitle " ($number_msg($chatid))" } .nb itemconfigure [nbpage $cw] -text $tabtitle } else { if {$personal_msg($chatid) > 0} { set star "*" } else { set star "" } if {$options(only_personal_messages_in_window_title)} { set messages $personal_msg($chatid) } else { set messages $number_msg($chatid) } if {$messages > 0} { set title "($messages$star) $chat::chats(titlename,$chatid)" } else { set title $chat::chats(titlename,$chatid) } wm title $cw $title wm iconname $cw $title } } proc ifacetk::update_chat_titles {} { foreach chatid [chat::opened] { lassign [chat::window_titles $chatid] \ ::chat::chats(tabtitlename,$chatid) \ ::chat::chats(titlename,$chatid) ifacetk::update_chat_title $chatid } } proc ifacetk::update_main_window_title {} { global usetabbar variable options variable main_window_title variable number_msg variable personal_msg if {!$usetabbar} return set star "" set messages 0 if {$options(only_personal_messages_in_window_title)} { set star "*" foreach chatid [chat::opened] { incr messages $personal_msg($chatid) } } else { foreach chatid [chat::opened] { incr messages $number_msg($chatid) if {$personal_msg($chatid) > 0} { set star "*" } } } if {$messages} { set title "($messages$star) $main_window_title" } else { set title $main_window_title } wm title . $title wm iconname . $title } proc ifacetk::chat_window_is_active {chatid} { global usetabbar set cw [chat::winid $chatid] set w [winfo toplevel $cw] set f [focus] if {($f != "") && ($w == [winfo toplevel $f]) && \ (!$usetabbar || ([.nb raise] == [nbpage $cw]))} { return 1 } else { return 0 } } proc ifacetk::add_number_of_messages_to_title {chatid from type body extras} { global usetabbar variable number_msg variable personal_msg if {![catch {::plugins::mucignore::is_ignored $connid $from $type} ignore] && \ $ignore != ""} { return } foreach xelem $extras { jlib::wrapper:splitxml $xelem tag vars isempty chdata children # Don't add number to title if this 'empty' tag is present. It indicates # messages history in chat window. if {[cequal $tag ""] && \ [cequal [jlib::wrapper:getattr $vars xmlns] tkabber:x:nolog]} { return } } if {[chat_window_is_active $chatid]} return if {$from == ""} return if {$type == "chat"} { incr number_msg($chatid) incr personal_msg($chatid) } elseif {$type == "groupchat"} { set jid [chat::get_jid $chatid] set myjid [chat::our_jid $chatid] set mynick [chat::get_nick [chat::get_connid $chatid] $myjid $type] if {![cequal $jid $from] && ![cequal $myjid $from]} { incr number_msg($chatid) } if {![cequal $jid $from] && ![cequal $myjid $from] && \ [check_message $mynick $body]} { incr personal_msg($chatid) } } update_chat_title $chatid update_main_window_title } hook::add draw_message_hook [namespace current]::ifacetk::add_number_of_messages_to_title 18 proc ifacetk::set_main_window_title_on_connect {connid} { variable main_window_title set main_window_title "[jlib::connection_jid $connid] - Tkabber" wm title . $main_window_title wm iconname . $main_window_title } proc ifacetk::set_main_window_title_on_disconnect {connid} { variable main_window_title if {[llength [jlib::connections]] == 0} { set main_window_title "Tkabber" } else { set main_window_title \ "[jlib::connection_jid [lindex [jlib::connections] end]] - Tkabber" } wm title . $main_window_title wm iconname . $main_window_title } hook::add connected_hook \ [namespace current]::ifacetk::set_main_window_title_on_connect hook::add disconnected_hook \ [namespace current]::ifacetk::set_main_window_title_on_disconnect proc ifacetk::raise_win {path} { global usetabbar if {[winfo exists $path]} { if {$usetabbar} { .nb raise [nbpage $path] } } } proc ifacetk::add_win {path args} { global usetabbar variable options set title "" set tabtitle "" set class "" set raisecmd "" set type "" set raise 0 foreach {attr val} $args { switch -- $attr { -title {set title $val} -tabtitle {set tabtitle $val} -class {set class $val} -raisecmd {set raisecmd $val} -raise {set raise $val} -type {set type $val} default {error "Unknown option $attr"} } } if {$usetabbar} { set page [nbpage $path] set f [.nb insert end $page \ -text $tabtitle \ -raisecmd [list [namespace current]::tab_raise \ $path $raisecmd]] frame $path -class $class pack $path -expand yes -fill both -in $f #tkwait visibility $path set ::tabcolors($page) "" if {$raise || $options(raise_new_tab) || [llength [.nb pages]] == 1} { after idle [list catch [list .nb raise $page]] } } else { toplevel $path -class $class -relief flat -bd 2m wm group $path . wm title $path $title wm iconname $path $title set geometry [option get $path ${type}geometry $class] if {$geometry != ""} { wm geometry $path $geometry } } } bind Chat [list [namespace current]::ifacetk::get_focus %W] bind Chat [list [namespace current]::ifacetk::loose_focus %W] proc ifacetk::tab_raise {path command} { tab_set_updated $path if {$command != ""} { eval $command } } proc ifacetk::get_focus {path} { if {![winfo exists $path]} return hook::run got_focus_hook $path } proc ifacetk::on_focus_got {path} { variable options variable after_focused_id if {$after_focused_id != ""} { after cancel $after_focused_id } set after_focused_id \ [after $options(update_title_delay) \ [list [namespace current]::set_title $path]] } hook::add got_focus_hook [namespace current]::ifacetk::on_focus_got proc ifacetk::set_title {path} { global usetabbar variable number_msg variable personal_msg if {![winfo exists $path]} return if {$usetabbar} { if {[set p [.nb raise]] != ""} { tab_set_updated $p } update_main_window_title } else { if {[info exists chat::chat_id($path)]} { set chatid $chat::chat_id($path) set number_msg($chatid) 0 set personal_msg($chatid) 0 update_chat_title $chatid } } } proc ifacetk::loose_focus {path} { if {![winfo exists $path]} return hook::run lost_focus_hook $path } proc ifacetk::on_focus_lost {path} { variable after_focused_id if {$after_focused_id != ""} { after cancel $after_focused_id set after_focused_id "" } balloon::destroy } hook::add lost_focus_hook [namespace current]::ifacetk::on_focus_lost proc ifacetk::tab_move {nb shift args} { set len [llength [$nb pages]] if {$len > 0} { set newidx [expr [$nb index [$nb raise]] + $shift] if {$newidx < 0} { set newidx [expr $len - 1] } elseif {$newidx >= $len} { set newidx 0 } $nb see [lindex [$nb pages] $newidx] $nb raise [lindex [$nb pages] $newidx] } } proc ifacetk::current_tab_move {nb shift} { set len [llength [$nb pages]] if {$len > 0} { set newidx [expr [$nb index [$nb raise]] + $shift] if {$newidx < 0} { set newidx [expr $len - 1] } elseif {$newidx >= $len} { set newidx 0 } $nb move [$nb raise] $newidx $nb see [$nb raise] } } proc ifacetk::tab_raise_by_number {nb num} { set pages [$nb pages] incr num -1 set page [lindex $pages $num] if {$page != ""} { $nb raise $page } } proc ifacetk::define_alert_colors {} { global usetabbar global alert_colors if {$usetabbar} { option add *alertColor0 Black widgetDefault option add *alertColor1 DarkBlue widgetDefault option add *alertColor2 Blue widgetDefault option add *alertColor3 Red widgetDefault set alert_colors [list \ [option get .nb alertColor0 ButtonBar] \ [option get .nb alertColor1 ButtonBar] \ [option get .nb alertColor2 ButtonBar] \ [option get .nb alertColor3 ButtonBar]] } } array set ::alert_lvls {info 1 error 1 server 1 message 2 mesg_to_user 3} proc ifacetk::tab_set_updated {path {updated 0} {level ""}} { global usetabbar global tabcolors global alert_lvls alert_colors variable number_msg variable personal_msg if {!$usetabbar} return set page [nbpage $path] if {[.nb index $page] < 0} { set page $path if {[.nb index $page] < 0} return set path [nbpath $page] } set st [wm state .] if {(![cequal $st normal] && ![cequal $st zoomed]) || \ ([cequal [focus -displayof .] ""])} { set backgroundP 1 } else { set backgroundP 0 } if {(!$updated) && $backgroundP} { return } if {$updated && \ (($page != [.nb raise]) && \ [info exists alert_lvls($level)] || \ $backgroundP)} { set lvlnum $alert_lvls($level) } else { set lvlnum 0 } if {!$updated || $tabcolors($page) < $lvlnum} { set color [lindex $alert_colors $lvlnum] .nb itemconfigure $page -foreground $color -activeforeground $color set tabcolors($page) $lvlnum hook::run tab_set_updated $path $updated $level } if {[info exists chat::chat_id($path)]} { if {!$updated || ($lvlnum == 0)} { set chatid $chat::chat_id($path) set number_msg($chatid) 0 set personal_msg($chatid) 0 update_chat_title $chatid update_main_window_title } } } proc ifacetk::tab_menu {x y page} { global curmenutab set curmenutab $page tk_popup .tabsmenu $x $y } ############################################################################### proc ifacetk::collapse_roster {} { variable mf variable rosterwidth set pw [$mf getframe].pw set r [PanedWinConf $pw 0 -width] set n [PanedWinConf $pw 1 -width] if {$r > 0} { set rosterwidth $r PanedWinConf $pw 0 -width 0 PanedWinConf $pw 1 -width [expr {$r + $n}] } else { PanedWinConf $pw 0 -width $rosterwidth PanedWinConf $pw 1 -width [expr {$r + $n - $rosterwidth}] } } ############################################################################### proc ifacetk::switch_toolbar {args} { variable options variable mf $mf showtoolbar 0 $options(show_toolbar) } proc ifacetk::switch_presencebar {args} { global usetabbar variable options variable mf if {[winfo exists .presence]} { if {$options(show_presencebar)} { catch { grid .presence -row 3 -column 1 \ -sticky nswe -in [.mainframe getframe] .presence.status configure -takefocus 1 } } else { grid forget .presence .presence.status configure -takefocus 0 if {[focus] == ".presence.status"} { focus [Widget::focusPrev .presence.status] } } } } proc ifacetk::switch_statusbar {args} { variable options variable mf catch { if {$options(show_statusbar)} { pack $mf.botf -side bottom -fill x -before [$mf getframe] } else { pack forget $mf.botf } } } proc ifacetk::deiconify {} { global tcl_platform variable mainwindowstate if {[cequal $tcl_platform(platform) windows]} { if {[cequal $mainwindowstate zoomed]} { wm state . zoomed } } update wm deiconify . } hook::add finload_hook [namespace current]::ifacetk::deiconify 100 proc ifacetk::save_availability_status {w args} { variable status_history variable options set avstatus [$w cget -text] if {$avstatus == ""} return set ix [$w getvalue] if {$ix >= 0} { set status_history [linsert [lreplace $status_history $ix $ix] end $avstatus] } elseif {[llength $status_history] < $options(max_status_history)} { lappend status_history $avstatus } else { set status_history [linsert [lrange $status_history 1 end] end $avstatus] } $w configure -values $status_history } proc ifacetk::show_status_context_menu w { set m $w.menu if {![winfo exists $m]} { menu $m -tearoff 0 $m add command \ -label [::msgcat::mc "Clear history"] \ -command [list [namespace current]::clear_status_history $w] } tk_popup $m [winfo pointerx $w] [winfo pointery $w] } proc ifacetk::clear_status_history w { variable status_history set status_history [list] $w configure -values $status_history } proc client:errormsg {message} { if {[winfo exists .client_error]} { destroy .client_error } MessageDlg .client_error -aspect 50000 -icon error \ -message $message -type user -buttons ok -default 0 -cancel 0 } # This proc should be called by WM_SAVE_YOURSELF protocol callback. # On Windows (and Tk >= 8.4.13) this means WM_QUERYENDSESSION (so we should quit), # on Unix, an X session manager may call this repeatedly. proc session_checkpoint {} { global tcl_platform ::hook::run save_yourself_hook if {$tcl_platform(platform) == "windows"} quit } # Trap SIGTERM to quit gracefully on Unix when Tclx is available: if {$tcl_platform(platform) == "unix" && ![catch {package require Tclx}]} { signal trap SIGTERM quit } # Import add_win tab_set_updated to the root namespace: namespace import ::ifacetk::raise_win ::ifacetk::add_win ::ifacetk::tab_set_updated # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/ifacetk/buttonbar.tcl0000644000175000017500000004043711061044512016636 0ustar sergeisergei# ---------------------------------------------------------------------------- # ButtonBar.tcl # ---------------------------------------------------------------------------- # Index of commands: # - ButtonBar::create # - ButtonBar::configure # - ButtonBar::cget # - ButtonBar::insert # - ButtonBar::delete # - ButtonBar::move # - ButtonBar::itemconfigure # - ButtonBar::itemcget # - ButtonBar::setfocus # - ButtonBar::index # ---------------------------------------------------------------------------- namespace eval ButtonBar { Widget::define ButtonBar ButtonBar Button Widget::declare ButtonBar { {-background TkResource "" 0 frame} {-orient Enum horizontal 0 {horizontal vertical}} {-minwidth Int 0 0 "%d >= 0"} {-maxwidth Int 200 0 "%d >= 0"} {-padx TkResource "" 0 button} {-pady TkResource "" 0 button} {-command String "" 0} {-bg Synonym -background} {-pages String "" 0} } Widget::addmap ButtonBar "" :cmd {-background {}} bind ButtonBar [list [namespace current]::_destroy %W] } # ---------------------------------------------------------------------------- # Command ButtonBar::create # ---------------------------------------------------------------------------- proc ButtonBar::create {path args} { Widget::init ButtonBar $path $args variable $path upvar 0 $path data eval [list frame $path] [Widget::subcget $path :cmd] \ [list -class ButtonBar -takefocus 0 -highlightthickness 0] # For 8.4+ we don't want to inherit the padding catch {$path configure -padx 0 -pady 0} frame $path.spacer -width [winfo screenwidth $path] bind $path [list [namespace current]::_configure $path] set data(buttons) [list] set data(active) "" set data(bindtabs) [list] return [Widget::create ButtonBar $path] } # ---------------------------------------------------------------------------- # Command ButtonBar::configure # ---------------------------------------------------------------------------- proc ButtonBar::configure {path args} { variable $path upvar 0 $path data set res [Widget::configure $path $args] if {[Widget::hasChanged $path -orient val] || \ [Widget::hasChanged $path -minwidth val] || \ [Widget::hasChanged $path -maxwidth val]} { _redraw $path } return $res } # ---------------------------------------------------------------------------- # Command ButtonBar::cget # ---------------------------------------------------------------------------- proc ButtonBar::cget {path option} { return [Widget::cget $path $option] } # ---------------------------------------------------------------------------- # Command ButtonBar::_option # ---------------------------------------------------------------------------- proc ButtonBar::_itemoption {path name option} { return [lindex [Button::configure [_but $path $name] $option] 4] } # ---------------------------------------------------------------------------- # Command ButtonBar::insert # ---------------------------------------------------------------------------- proc ButtonBar::insert {path idx name args} { variable $path upvar 0 $path data set but [_but $path $name] set data(buttons) [linsert $data(buttons) $idx $name] set newargs {} foreach {key val} $args { switch -- $key { -raisecmd { set data(raisecmd,$name) $val } default { lappend newargs $key $val } } } eval [list Button::create $but \ -padx [Widget::getoption $path -padx] \ -pady [Widget::getoption $path -pady] \ -anchor w \ -command [list [namespace current]::activate $path $name]] \ $newargs _calc_text $path $name bind $but [list [namespace current]::_itemconfigure $path $name] foreach {event script} $data(bindtabs) { bind $but $event [linsert $script end $name] } DragSite::register $but \ -draginitcmd [list [namespace current]::_draginitcmd $path $name] DropSite::register $but \ -dropcmd [list [namespace current]::_dropcmd $path $name] \ -droptypes [list ButtonBar:$path] _redraw $path if {![string equal [Widget::getoption $path -pages] ""]} { set res [[Widget::getoption $path -pages] add $name] } else { set res $but } if {[llength $data(buttons)] == 1} { activate $path $name -nocmd } return $res } proc ButtonBar::_draginitcmd {path name target x y top} { activate $path $name return [list ButtonBar:$path {move} $name] } proc ButtonBar::_dropcmd {path tname target source X Y op type name} { move $path $name [index $path $tname] } # ---------------------------------------------------------------------------- # Command ButtonBar::move # ---------------------------------------------------------------------------- proc ButtonBar::move {path name idx} { variable $path upvar 0 $path data set i [lsearch -exact $data(buttons) $name] if {$i >= 0} { set data(buttons) [linsert [lreplace $data(buttons) $i $i] $idx $name] _redraw $path } } # ---------------------------------------------------------------------------- # Command ButtonBar::delete # ---------------------------------------------------------------------------- proc ButtonBar::delete {path name {destroyframe 1}} { variable $path upvar 0 $path data set i [lsearch -exact $data(buttons) $name] if {$i >= 0} { set data(buttons) [lreplace $data(buttons) $i $i] destroy [_but $path $name] if {![string equal [Widget::getoption $path -pages] ""]} { [Widget::getoption $path -pages] delete $name } if {[llength $data(buttons)] == 0} { set data(active) "" } catch {unset data(raisecmd,$name)} catch {unset data(text,$name)} catch {unset data(width,$name)} catch {unset data(height,$name)} _redraw $path } } # ---------------------------------------------------------------------------- # Command ButtonBar::activate # ---------------------------------------------------------------------------- proc ButtonBar::activate {path name {nocmd ""}} { variable $path upvar 0 $path data set active "" foreach n $data(buttons) { set but [_but $path $n] if {[string equal $n $name]} { Button::configure $but -relief sunken -state active set active $n } else { Button::configure $but -relief raised -state normal } } if {![string equal [Widget::getoption $path -pages] ""]} { [Widget::getoption $path -pages] raise $active } if {$nocmd != "-nocmd" && $active != $data(active)} { if {[info exists data(raisecmd,$name)]} { uplevel #0 $data(raisecmd,$name) } set cmd [Widget::getoption $path -command] if {$cmd != ""} { uplevel #0 $cmd [list $active] } } set data(active) $active } # ---------------------------------------------------------------------------- # Command ButtonBar::itemconfigure # ---------------------------------------------------------------------------- proc ButtonBar::itemconfigure {path name args} { variable $path upvar 0 $path data set but [_but $path $name] set res [eval [list Button::configure $but] $args] if {[llength $args] == 1} { switch -- [lindex $args 0] { -text { set res $data(text,$name) } } } else { set tf 0 foreach {key val} $args { switch -- $key { -text - -font { set tf 1 } } } if {$tf} { _calc_text $path $name _reconfigure_text $path $name } } return $res } # ---------------------------------------------------------------------------- # Command ButtonBar::itemcget # ---------------------------------------------------------------------------- proc ButtonBar::itemcget {path name option} { variable $path upvar 0 $path data set res [Button::cget [_but $path $name] $option] switch -- $option { -text { set res $data(text,$name) } } return $res } # ---------------------------------------------------------------------------- # Command ButtonBar::setfocus # ---------------------------------------------------------------------------- proc ButtonBar::setfocus {path name} { set but [_but $path $name] if { [winfo exists $but] } { focus $but } } # ---------------------------------------------------------------------------- # Command ButtonBar::index # ---------------------------------------------------------------------------- proc ButtonBar::index {path name} { variable $path upvar 0 $path data return [lsearch -exact $data(buttons) $name] } # ---------------------------------------------------------------------------- # Command ButtonBar::_configure # ---------------------------------------------------------------------------- proc ButtonBar::_configure {path} { variable $path upvar 0 $path data set w [winfo width $path] set h [winfo height $path] if {![info exists data(width)] || $data(width) != $w || \ ![info exists data(height)] || $data(height) != $h} { set data(width) $w set data(height) $h _redraw $path } } # ---------------------------------------------------------------------------- # Command ButtonBar::_redraw # ---------------------------------------------------------------------------- proc ButtonBar::_redraw {path} { variable $path upvar 0 $path data array unset data configured,* $path:cmd configure -width 0 grid forget $path.spacer set cols [lindex [grid size $path] 0] set rows [lindex [grid size $path] 1] for {set c 0} {$c < $cols} {incr c} { grid columnconfigure $path $c -weight 0 -minsize 0 catch {grid columnconfigure $path $c -uniform {}} } for {set r 0} {$r < $rows} {incr r} { grid rowconfigure $path $r -weight 0 -minsize 0 catch {grid rowconfigure $path $r -uniform {}} } set num [llength $data(buttons)] if {$num == 0} return # Change buttons stacking order foreach name $data(buttons) { ::raise [_but $path $name] } set min [Widget::getoption $path -minwidth] set max [Widget::getoption $path -maxwidth] if {$min > $max} { set max $min } if {[string equal [Widget::getoption $path -orient] "horizontal"]} { set w [winfo width $path] if {$min == 0} { set cols $num } else { set cols [expr {int($w / $min)}] if {$cols > $num} { set cols $num } } if {[expr {$max * $cols}] < $w} { set weight 2 set minsize $max grid $path.spacer -column $cols -row 0 grid columnconfigure $path $cols -weight 1 -minsize 0 } else { set weight 1 set minsize $min } set c 0 set r 0 foreach name $data(buttons) { grid [_but $path $name] -column $c -row $r -sticky nsew grid columnconfigure $path $c -weight $weight -minsize $minsize catch {grid columnconfigure $path $c -uniform 1} incr c if {$c >= $cols} { set c 0 incr r } } } else { set h [winfo height $path] set c 0 set r 0 set th 0 set num 0 foreach name $data(buttons) { _reconfigure_text $path $name } foreach name $data(buttons) { set but [_but $path $name] if {[info exists data(height,$name)]} { incr th $data(height,$name) } else { incr th [winfo reqheight $but] } if {($c > 0 && $r >= $num) || ($c == 0 && $th > $h)} { set r 0 incr c } elseif {$c == 0} { incr num } grid $but -column $c -row $r -sticky nsew grid rowconfigure $path $r -weight 0 -minsize 0 grid columnconfigure $path $c -weight 0 -minsize $max incr r } grid rowconfigure $path $num -weight 10000000 -minsize 0 } } # ---------------------------------------------------------------------------- # Command ButtonBar::_destroy # ---------------------------------------------------------------------------- proc ButtonBar::_destroy {path} { variable $path upvar 0 $path data Widget::destroy $path unset data } # ---------------------------------------------------------------------------- # Command ButtonBar::_but # ---------------------------------------------------------------------------- proc ButtonBar::_but {path name} { return $path.b:$name } # ---------------------------------------------------------------------------- # Command ButtonBar::pages # ---------------------------------------------------------------------------- proc ButtonBar::pages {path {first ""} {last ""}} { variable $path upvar 0 $path data if {[string equal $first ""]} { return $data(buttons) } elseif {[string equal $last ""]} { return [lindex $data(buttons) $first] } else { return [lrange $data(buttons) $first $last] } } # ---------------------------------------------------------------------------- # Command ButtonBar::raise # ---------------------------------------------------------------------------- proc ButtonBar::raise {path {name ""}} { variable $path upvar 0 $path data if {[string equal $name ""]} { return $data(active) } else { activate $path $name } } # ---------------------------------------------------------------------------- # Command ButtonBar::getframe # ---------------------------------------------------------------------------- proc ButtonBar::getframe {path name} { if {![string equal [Widget::getoption $path -pages] ""]} { return [[Widget::getoption $path -pages] getframe $name] } else { return "" } } # ---------------------------------------------------------------------------- # Command ButtonBar::bindtabs # ---------------------------------------------------------------------------- proc ButtonBar::bindtabs {path event script} { variable $path upvar 0 $path data lappend data(bindtabs) $event $script foreach name $data(buttons) { bind [_but $path $name] $event [linsert $script end $name] } } # ---------------------------------------------------------------------------- # Command ButtonBar::see # ---------------------------------------------------------------------------- proc ButtonBar::see {path name} { return "" } # ---------------------------------------------------------------------------- # Command ButtonBar::_itemconfigure # ---------------------------------------------------------------------------- proc ButtonBar::_itemconfigure {path name} { variable $path upvar 0 $path data if {[info exists data(configured,$name)]} return set data(configured,$name) 1 set but [_but $path $name] set w [winfo width $but] if {![info exists data(text,$name)] || ![info exists data(width,$name)] || $data(width,$name) != $w} { set data(width,$name) $w _reconfigure_text $path $name } set data(height,$name) [winfo height $but] } # ---------------------------------------------------------------------------- # Command ButtonBar::_calc_text # ---------------------------------------------------------------------------- proc ButtonBar::_calc_text {path name} { variable $path upvar 0 $path data set text [_itemoption $path $name -text] set font [_itemoption $path $name -font] set data(text,$name) [list $text [font measure $font $text]] set len [string length $text] for {set ind 0} {$ind < $len} {incr ind} { lappend data(text,$name) \ [font measure $font [string range $text 0 $ind]\u2026] } } # ---------------------------------------------------------------------------- # Command ButtonBar::_reconfigure_text # ---------------------------------------------------------------------------- proc ButtonBar::_reconfigure_text {path name} { variable $path upvar 0 $path data if {![info exists data(text,$name)]} return set but [_but $path $name] set padx [_itemoption $path $name -padx] set bd [_itemoption $path $name -bd] set hl [_itemoption $path $name -highlightthickness] set w [winfo width $but] set min [Widget::getoption $path -minwidth] set max [Widget::getoption $path -maxwidth] if {$min > $max} { set max $min } set tw [expr {$w - 2*($padx + $bd + $hl + 1)}] set mw [expr {$max - 2*($padx + $bd + $hl + 1)}] set text [lindex $data(text,$name) 0] set textw [lindex $data(text,$name) 1] Button::configure $but -text $text -helptext "" if {$textw <= $tw && $textw <= $mw} { return } set i -1 foreach textw [lrange $data(text,$name) 2 end] { if {$textw > $tw || $textw > $mw} { Button::configure $but -text [string range $text 0 $i]\u2026 \ -helptext $text return } incr i } } tkabber-0.11.1/utils.tcl0000644000175000017500000003434111037425055014375 0ustar sergeisergei# $Id: utils.tcl 1477 2008-07-16 17:04:45Z sergei $ proc rand {num} { return [expr round(rand()*$num)] } proc user_from_jid {jid} { set user $jid regexp {(.*@.*)/.*} $jid temp user return $user } proc node_and_server_from_jid {jid} { set nas $jid regexp {([^/]*)/.*} $jid temp nas return $nas } proc server_from_jid {jid} { set serv $jid regexp {([^/]*)/.*} $jid temp serv regexp {[^@]*@(.*)} $serv temp serv return $serv } proc resource_from_jid {jid} { set resource "" regexp {[^/]*/(.*)} $jid temp resource return $resource } proc node_from_jid {jid} { set node "" regexp {^([^@/]*)@.*} $jid temp node return $node } proc tolower_node_and_domain {jid} { set nas [string tolower [node_and_server_from_jid $jid]] set resource [resource_from_jid $jid] if {![cequal $resource ""]} { return $nas/$resource } else { return $nas } } # my_jid - returns JID for inclusion in queries. If the recipient # is from some conference room then JID is a room JID. proc my_jid {connid recipient} { set bare_recipient [node_and_server_from_jid $recipient] set chatid [chat::chatid $connid $bare_recipient] if {[chat::is_groupchat $chatid]} { set myjid [chat::our_jid $chatid] } else { set myjid [jlib::connection_jid $connid] } } proc win_id {prefix key} { global wins if {![info exists wins(seq,$prefix)]} { set wins(seq,$prefix) 0 } if {![info exists wins(key,$prefix,$key)]} { set idx $wins(seq,$prefix) set wins(key,$prefix,$key) ".${prefix}_$idx" incr wins(seq,$prefix) } return $wins(key,$prefix,$key) } proc jid_to_tag {jid} { variable jidtag variable tagjid if {[info exists jidtag($jid)]} { return $jidtag($jid) } else { regsub -all {[^[:alnum:]]+} $jid {} prefix set tag $prefix[rand 1000000000] while {[info exists tagjid($tag)]} { set tag $prefix[rand 1000000000] } set jidtag($jid) $tag set tagjid($tag) $jid return $tag } } proc tag_to_jid {tag} { variable tagjid if {[info exists tagjid($tag)]} { return $tagjid($tag) } else { error "Unknown tag $tag" } } proc double% {str} { return [string map {% %%} $str] } proc error_type_condition {errmsg} { return [lrange [stanzaerror::error_to_list $errmsg] 0 1] } proc error_to_string {errmsg} { return [lindex [stanzaerror::error_to_list $errmsg] 2] } proc get_group_nick {jid fallback} { global defaultnick set nick $fallback set tmp_pattern * foreach pattern [array names defaultnick] { if {[string equal $pattern $jid]} { return $defaultnick($pattern) } elseif {([string match $pattern $jid]) && ([string match $tmp_pattern $pattern])} { set nick $defaultnick($pattern) set tmp_pattern $pattern } } return $nick } proc check_message {nick body} { set personal 0 hook::run check_personal_message_hook personal $nick $body return $personal } proc personal_message_fallback {vpersonal nick body} { upvar 2 $vpersonal personal set prefixes {"" "2"} set suffixes {":" any " " any "" end} foreach pref $prefixes { foreach {suff pos} $suffixes { set str "$pref$nick$suff" if {[cequal $body $str] || \ ([cequal [crange $body 0 [expr {[clength $str] - 1}]] $str] && \ [cequal $pos any])} { set l [clength $pref] set personal 1 return } } } } hook::add check_personal_message_hook personal_message_fallback 100 proc format_time {t} { if {[cequal $t ""]} { return } set sec [expr {$t % 60}] set secs [expr {($sec==1)?"[::msgcat::mc second]":"[::msgcat::mc seconds]"}] set t [expr {$t / 60}] set min [expr {$t % 60}] set mins [expr {($min==1)?"[::msgcat::mc minute]":"[::msgcat::mc minutes]"}] set t [expr {$t / 60}] set hour [expr {$t % 24}] set hours [expr {($hour==1)?"[::msgcat::mc hour]":"[::msgcat::mc hours]"}] set day [expr {$t / 24}] set days [expr {($day==1)?"[::msgcat::mc day]":"[::msgcat::mc days]"}] set flag 0 set message "" if {$day != 0} { set flag 1 set message "$day $days" } if {$flag || ($hour != 0)} { set flag 1 set message [concat $message "$hour $hours"] } if {$flag || ($min != 0)} { set message [concat $message "$min $mins"] } return [concat $message "$sec $secs"] } proc NonmodalMessageDlg {path args} { set icon "none" set title "" set message "" set opts {} set mopts {} foreach {option value} $args { switch -- $option { -icon { set icon $value } -title { set title $value } -aspect { lappend mopts $option $value } -message { lappend mopts -text $value } default { lappend opts $option $value } } } if {$icon == "none"} { set image "" } else { set image [Bitmap::get $icon] } if {$title == ""} { set frame [frame $path -class MessageDlg] set title [option get $frame "${icon}Title" MessageDlg] destroy $frame if { $title == "" } { set title "Message" } } eval [list Dialog::create $path -image $image -modal none -title $title \ -side bottom -anchor c -default 0 -cancel 0] $opts Dialog::add $path -text [::msgcat::mc "OK"] -name ok -command "destroy $path" set frame [Dialog::getframe $path] eval [list message $frame.msg -relief flat \ -borderwidth 0 -highlightthickness 0] \ $mopts pack $frame.msg -side left -padx 3m -pady 1m -fill x -expand yes Dialog::draw $path } proc bindscroll {w {w1 ""}} { if {[cequal $w1 ""]} { set w1 $w } bind $w <> \ "if {\[lindex \[$w1 yview\] 0\] > 0} { $w1 yview scroll -5 units }" bind $w <> \ "if {\[lindex \[$w1 yview\] 1\] < 1} { $w1 yview scroll 5 units }" bind $w <> \ "if {\[lindex \[$w1 xview\] 0\] > 0} { $w1 xview scroll -10 units }" bind $w <> \ "if {\[lindex \[$w1 xview\] 1\] < 1} { $w1 xview scroll 10 units }" } ########################################################################### if {[info tclversion] >= 8.4} { # Tk 8.4 or newer proc Spinbox {path from to incr textvar args} { return [eval [list spinbox $path \ -from $from \ -to $to \ -increment $incr \ -buttoncursor left_ptr \ -textvariable $textvar] \ $args] } proc textUndoable {path args} { eval {text $path -undo 1} $args bind $path +[list %W edit separator] hook::run text_on_create_hook $path return $path } # There is an evil bug in Tk, which does not allow inserting symbols # using XIM if more than one bound script uses %A. # See http://sourceforge.net/tracker/index.php?func=detail&aid=1373712&group_id=12997&atid=112997 # Workaround overwrites existiong binding and uses hook to # simulate event with %A substituted. # Usage example see in plugins/unix/ispell.tcl. proc text_on_keypress {path sym} { tk::TextInsert $path $sym hook::run text_on_keypress_hook $path $sym } bind Text {text_on_keypress %W %A} } else { # Tk 8.3 proc Spinbox {path from to incr textvar args} { return [eval [list SpinBox $path \ -range [list $from $to $incr] \ -textvariable $textvar] \ $args] } proc textUndoable {path args} { eval {text $path} $args hook::run text_on_create_hook $path return $path } proc text_on_keypress {path sym} { tkTextInsert $path $sym hook::run text_on_keypress_hook $path $sym } bind Text {text_on_keypress %W %A} } ########################################################################### proc focus_next {path fr} { focus [Widget::focusNext $path] set widget [focus] if {[string first $fr $widget] == 0} { $fr see $widget } } proc focus_prev {path fr} { focus [Widget::focusPrev $path] $fr see [focus] } proc CbDialog {path title buttons var lnames lballoons args} { upvar #0 $var result array set names $lnames array set balloons $lballoons set modal none set radio 0 foreach {opt val} $args { switch -- $opt { -type { set radio [cequal $val radio] } -modal { set modal $val } } } set len [llength $buttons] Dialog $path -title $title \ -modal $modal -separator 1 -anchor e -default 0 \ -cancel [expr {[llength $buttons]/2 - 1}] foreach {but com} $buttons { $path add -text $but -command $com } set sw [ScrolledWindow [$path getframe].sw] set sf [ScrollableFrame $sw.sf -constrainedwidth yes] pack $sw -expand yes -fill both $sw setwidget $sf set sff [$sf getframe] bind $path [list focus_prev %W $sf] bind $path [list focus_next %W $sf] bind $path [list focus_next %W $sf] bind $path [list focus_prev %W $sf] bind $path <> [list focus_prev %W $sf] bindscroll $sff $sf if {!$radio} { catch { array unset result } } set temp {} foreach idx [array names names] { lappend temp [list $idx $names($idx)] } set i 0 foreach idxt [lsort -dictionary -index 1 $temp] { set idx [lindex $idxt 0] if {$radio} { set cb [radiobutton $sff.cb$i -variable $var \ -text $names($idx) -value $idx] if {$i == 0} { set result $idx } } else { set result($idx) 0 set cb [checkbutton $sff.cb$i -variable ${var}($idx) \ -text $names($idx)] } bind $cb [list $path invoke 0] bind $cb +break bind $cb <1> [list focus %W] bindscroll $cb $sf if {[info exists balloons($idx)]} { balloon::setup $cb -text $balloons($idx) } pack $cb -anchor w incr i } $path draw $sff.cb0 } proc OptionMenu {path args} { set m [eval [list ::tk_optionMenu $path] $args] set bd [option get $path borderWidth ""] if {$bd != ""} { $path configure -bd $bd } return $m } # Forces (string) $x to be interpreted as integer. # Useful to deal with strings representing decimal interegs and # containing leading zeroes (so, normaly they would be interpreted # by Tcl as octal integers). # Contributed on c.l.t. by Kevin Kenny, see http://wiki.tcl.tk/498 proc force_integer {x} { set count [scan $x %d%s n rest] if { $count <= 0 || ( $count == 2 && ![string is space $rest] ) } { return -code error "not an integer: $x" } return $n } # Excludes element $what from the list named $listVar: proc lexclude {listVar what} { upvar 1 $listVar list set at [lsearch $list $what] if {$at >= 0} { set list [lreplace $list $at $at] } } # Takes one or more lists and returns one list with only unique # members from all of the passed lists: proc lfuse {args} { lsort -unique [lconcat $args] } # Takes a list of lists and flattens them into one list. # NOTE that it takes ONE argument, which should be a list. proc lconcat {L} { foreach S $L { foreach E $S { lappend out $E } } set out } # List intersection. # For a number of lists, return only those elements # that are present in all lists. # (Richard Suchenwirth, from http://wiki.tcl.tk/43) proc lintersect {args} { set res {} foreach element [lindex $args 0] { set found 1 foreach list [lrange $args 1 end] { if {[lsearch -exact $list $element] < 0} { set found 0 break } } if {$found} {lappend res $element} } set res } proc lmap {command list} { set newlist {} foreach elem $list { lappend newlist [eval $command [list $elem]] } return $newlist } proc lfilter {command list} { set newlist {} foreach elem $list { if {[eval $command [list $elem]]} { lappend newlist $elem } } return $newlist } # Removes $nth element from the list contained in a # variable named $listVar in the caller's scope, # then returns the value of the removed element. proc lpop {listVar {nth 0}} { upvar 1 $listVar L set v [lindex $L $nth] set L [lreplace $L $nth $nth] set v } # Returns a fully-qualified name of the command that has invoked # the caller of this procedure. # To put is simple: if ::one::bar has invoked ::two::foo, the # ::two::foo proc can use [caller] to know that its caller # is ::one::bar # If the caller of this proc has no caller (i.e. it was called # on level 0), this proc returns empty string. # You can specify 2, 3, etc as the argument to get info about # the caller of the caller and so on (think of [uplevel]). proc caller {{level 1}} { incr level if {[catch {info level -$level} prc]} { return "" } else { return [namespace which -command [lindex $prc 0]] } } # Splits a string given in $s at each occurence of # substring given in $by. # $sep contains a Unicode character used to replace # found substrings before actual splitting; # this character MUST NOT occur in $s. proc msplit {s by {sep \u001F}} { split [string map [list $by $sep] $s] $sep } ################################################################## proc reverse_scroll {w} { set command [$w cget -yscrollcommand] $w configure -yscrollcommand [list store_scroll $w $command] bind $w {move_scroll %W} bind $w {+clean_scroll %W} } proc store_scroll {w command lo hi} { set ::lo($w) $lo set ::hi($w) $hi eval $command {$lo $hi} } proc move_scroll {w} { if {![info exists ::lo($w)] || ![info exists ::hi($w)]} return foreach {lo hi} [$w yview] break if {$hi < 1.0} { $w yview moveto [expr {$lo + ($::hi($w) - $::lo($w)) - ($hi - $lo)}] } else { $w see end } } proc clean_scroll {w} { catch {unset ::lo($w)} catch {unset ::hi($w)} } ################################################################## proc epath {} { global EPathNum if {![info exists EPathNum]} { set EPathNum 0 } else { incr EPathNum } return .errorpath$EPathNum } ################################################################## proc get_conf {w option} { return [lindex [$w configure $option] 4] } ################################################################## proc render_url {path url title args} { set t [eval [list text $path \ -cursor left_ptr \ -height 1 \ -width 10 \ -bd 0 \ -highlightthickness 0 \ -takefocus 0 \ -wrap none] $args] ::richtext::config $t -using url ::plugins::urls::render_url $t text $url {} -title $title $t delete {end - 1 char} $t configure -state disabled return $t } # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/filetransfer.tcl0000644000175000017500000002117710532142434015720 0ustar sergeisergei# $Id: filetransfer.tcl 810 2006-11-25 22:35:08Z sergei $ ############################################################################### namespace eval ft { custom::defgroup {File Transfer} [::msgcat::mc "File Transfer options."] \ -group Tkabber switch -- $::tcl_platform(platform) { windows { if {[info exists $::env(TEMP)]} { set default_dir $::env(TEMP) } else { set default_dir "C:\\TEMP" } } default { set default_dir "/tmp" } } # TODO macintosh? custom::defvar options(download_dir) $default_dir \ [::msgcat::mc "Default directory for downloaded files."] \ -type string -group {File Transfer} variable winid 0 } ############################################################################### proc ft::register_protocol {name args} { variable protocols set priority 50 set label $name foreach {key val} $args { switch -- $key { -priority { set priority $val } -label { set label $val } -options { set options $val } -send { set send $val } -receive { set receive $val } -close { set close $val } -closed { set closed $val } default { return -code error "[namespace current]::register_protocol:\ Illegal option $key" } } } lappend protocols(names) [list $name $priority] set protocols(names) [lsort -integer -index 1 $protocols(names)] set protocols(label,$name) $label foreach option {options send receive close closed} { if {[info exists $option]} { set protocols($option,$name) [set $option] } } } plugins::load [file join plugins filetransfer] ############################################################################### namespace eval ft { variable protocols set values {} foreach name_prio $protocols(names) { lassign $name_prio name priority lappend values $name $protocols(label,$name) } custom::defvar options(default_proto) [lindex $values 0] \ [::msgcat::mc "Default protocol for sending files."] \ -type options \ -values $values \ -group {File Transfer} } ############################################################################### proc ft::get_POSIX_error_desc {} { global errorCode set class [lindex $errorCode 0] if {$class != "POSIX"} { return [::msgcat::mc "unknown"] } else { return [::msgcat::mc [lindex $errorCode 2]] } } proc ft::report_cannot_open_file {f filename error} { report_error $f [::msgcat::mc "Can't open file \"%s\": %s" \ $filename $error] } proc ft::report_error {f errormsg} { set m $f.errormsg catch {destroy $m} message $m -aspect 50000 \ -text $errormsg \ -pady 1m $m configure -foreground [option get $m errorForeground Message] grid $m -row 0 -column 0 -sticky ewns -columnspan 4 } proc ft::hide_error_msg {f} { catch {destroy $f.errormsg} } ############################################################################### proc ft::create_menu {m connid jid} { variable protocols if {![lempty $protocols(names)]} { $m add command -label [::msgcat::mc "Send file..."] \ -command [list [namespace current]::send_file_dialog \ $jid \ -connection $connid] } } hook::add chat_create_user_menu_hook \ [namespace current]::ft::create_menu 46 hook::add roster_create_groupchat_user_menu_hook \ [namespace current]::ft::create_menu 46 hook::add roster_jid_popup_menu_hook \ [namespace current]::ft::create_menu 46 hook::add message_dialog_menu_hook \ [namespace current]::ft::create_menu 46 hook::add search_popup_menu_hook \ [namespace current]::ft::create_menu 46 ############################################################################### # # Draw a send file dialog # proc ft::send_file_dialog {jid args} { variable winid variable options variable protocols foreach {opt val} $args { switch -- $opt { -connection { set connid $val } } } if {![info exists connid]} { error "[namespace current]::send_file_dialog: -connection option\ is mandatory" } set token [namespace current]::[incr winid] upvar #0 $token state set w .sfd$winid set state(w) $w set state(jid) $jid set state(connid) $connid Dialog $w -title [format [::msgcat::mc "Send file to %s"] $jid] \ -separator 1 -anchor e -modal none \ -default 0 -cancel 1 $w add -text [::msgcat::mc "Send"] \ -command [list [namespace current]::send_file_negotiate $token] $w add -text [::msgcat::mc "Cancel"] -command [list destroy $w] bind $w [list [namespace current]::send_file_close $token %W] set f [$w getframe] set state(f) $f label $f.lfile -text [::msgcat::mc "File path:"] entry $f.file -textvariable ${token}(filename) button $f.browsefile -text [::msgcat::mc "Browse..."] \ -command [list [namespace current]::set_send_file_name $token] label $f.ldesc -text [::msgcat::mc "Description:"] set sw [ScrolledWindow $f.sw -scrollbar vertical] textUndoable $f.desc -width 55 -height 4 -wrap word $sw setwidget $f.desc set values {} foreach name_prio $protocols(names) { lassign $name_prio name priority lappend values $protocols(label,$name) if {$options(default_proto) == $name} { set state(protocol) $protocols(label,$name) } } if {![info exists state(protocol)]} { set state(protocol) [lindex $values 0] } label $f.lproto -text [::msgcat::mc "Protocol:"] eval [list OptionMenu $f.proto ${token}(protocol)] $values ProgressBar $f.pb -variable ${token}(progress) set state(pb) $f.pb set state(progress) 0 # Grid row 0 is used for displaying error messages grid $f.lfile -row 1 -column 0 -sticky e grid $f.file -row 1 -column 1 -sticky ew grid $f.browsefile -row 1 -column 2 -sticky ew grid $f.ldesc -row 2 -column 0 -sticky en grid $f.sw -row 2 -column 1 -sticky ewns -columnspan 2 grid $f.lproto -row 3 -column 0 -sticky e grid $f.proto -row 3 -column 1 -sticky ew -columnspan 2 -pady 1m # Grid row 4 vill be used for displaying protocol options grid $f.pb -row 5 -column 0 -sticky ew -columnspan 3 grid columnconfigure $f 1 -weight 1 grid rowconfigure $f 2 -weight 1 $w draw $f.file } proc ft::set_send_file_name {token} { variable $token upvar 0 $token state set file [tk_getOpenFile] if {$file != ""} { set state(filename) $file } } ############################################################################### proc ft::send_file_negotiate {token} { upvar #0 $token state variable chunk_size variable protocols hide_error_msg $state(f) $state(w) itemconfigure 0 -state disabled set state(desc) [$state(f).desc get 0.0 "end -1c"] if {[catch {open $state(filename)} fd]} { report_cannot_open_file $state(f) $state(filename) [get_POSIX_error_desc] $state(w) itemconfigure 0 -state normal return } debugmsg filetransfer "SENDFILE: $state(filename)" set state(fd) $fd fconfigure $fd -translation binary set state(name) [file tail $state(filename)] set size [file size $state(filename)] set state(size) $size if {$size == 0} { $state(pb) configure -maximum 1 set state(progress) -1 } else { $state(pb) configure -maximum $size } foreach name_prio $protocols(names) { lassign $name_prio proto priority if {$state(protocol) == $protocols(label,$proto)} { break } } set state(proto) $proto set state(command) [list [namespace current]::send_file_callback $token] # Use $token as filetransfer ID and state array variable eval $protocols(send,$proto) [list $token] } ############################################################################### proc ft::send_file_close {token w} { upvar #0 $token state variable protocols if {[winfo toplevel $w] != $w} return catch {eval $protocols(close,$state(proto)) $token} catch {close $state(fd)} catch {unset $token} } ############################################################################### proc ft::send_file_callback {token res {msg ""}} { upvar #0 $token state # Peer's reply may arrive after window is closed. if {![info exists state(w)] || ![winfo exists $state(w)]} return switch -- $res { ERR { if {$state(size) > 0} { set state(progress) 0 } report_error $state(f) $msg catch {eval $protocols(close,$state(proto)) $token} catch {close $state(fd)} $state(w) itemconfigure 0 -state normal } PROGRESS { if {$state(size) > 0} { set state(progress) $msg } } default { destroy $state(w) } } } ############################################################################### tkabber-0.11.1/mclistbox/0000755000175000017500000000000011076120366014530 5ustar sergeisergeitkabber-0.11.1/mclistbox/mclistbox.tcl0000644000175000017500000023231110762611355017246 0ustar sergeisergei# Copyright (c) 1999, Bryan Oakley # All Rights Reservered # # Bryan Oakley # oakley@channelpoint.com # # mclistbox v1.02 March 30, 1999 # # a multicolumn listbox written in pure tcl # # this code is freely distributable without restriction, but is # provided as-is with no waranty expressed or implied. # # basic usage: # # mclistbox::mclistbox .listbox # .listbox column add col1 -label "Column 1" # .listbox column add col2 -label "Column 2" # .listbox insert end [list "some stuff" "some more stuff"] # .listbox insert end [list "a second row of stuff" "blah blah blah"] # # see the documentation for more, uh, documentation. # # Something to think about: implement a "-optimize" option, with two # values: speed and memory. If set to speed, keep a copy of the data # in our hidden listbox so retrieval of data doesn't require us to # do all the getting and splitting and so forth. If set to "memory", # bag saving a duplicate copy of the data, which means data retrieval # will be slower, but memory requirements will be reduced. package require Tk 8.0 package provide mclistbox 1.02 namespace eval ::mclistbox { # this is the public interface namespace export mclistbox # these contain references to available options variable widgetOptions variable columnOptions # these contain references to available commands and subcommands variable widgetCommands variable columnCommands variable labelCommands } # ::mclistbox::Init -- # # Initialize the global (well, namespace) variables. This should # only be called once, immediately prior to creating the first # instance of the widget # # Results: # # All state variables are set to their default values; all of # the option database entries will exist. # # Returns: # # empty string proc ::mclistbox::Init {} { variable widgetOptions variable columnOptions variable widgetCommands variable columnCommands variable labelCommands # here we match up command line options with option database names # and classes. As it turns out, this is a handy reference of all of the # available options. Note that if an item has a value with only one # item (like -bd, for example) it is a synonym and the value is the # actual item. array set widgetOptions [list \ -background {background Background} \ -bd -borderwidth \ -bg -background \ -borderwidth {borderWidth BorderWidth} \ -columnbd -columnborderwidth \ -columnborderwidth {columnBorderWidth BorderWidth} \ -columnrelief {columnRelief Relief} \ -cursor {cursor Cursor} \ -exportselection {exportSelection ExportSelection} \ -fg -foreground \ -fillcolumn {fillColumn FillColumn} \ -font {font Font} \ -foreground {foreground Foreground} \ -height {height Height} \ -highlightbackground {highlightBackground HighlightBackground} \ -highlightcolor {highlightColor HighlightColor} \ -highlightthickness {highlightThickness HighlightThickness} \ -labelanchor {labelAnchor Anchor} \ -labelactivebackground {labelActiveBackground ActiveBackground} \ -labelactiveforeground {labelActiveForeground ActiveForeground} \ -labelbackground {labelBackground Background} \ -labelbd -labelborderwidth \ -labelbg -labelbackground \ -labelborderwidth {labelBorderWidth BorderWidth} \ -labelfg -labelforeground \ -labelfont {labelFont Font} \ -labelforeground {labelForeground Foreground} \ -labelheight {labelHeight Height} \ -labelimage {labelImage Image} \ -labelrelief {labelRelief Relief} \ -labels {labels Labels} \ -relief {relief Relief} \ -resizablecolumns {resizableColumns ResizableColumns} \ -resizeonecolumn {resizeOneColumn ResizeOneColumn} \ -selectbackground {selectBackground Foreground} \ -selectborderwidth {selectBorderWidth BorderWidth} \ -selectcommand {selectCommand Command} \ -selectforeground {selectForeground Background} \ -selectmode {selectMode SelectMode} \ -setgrid {setGrid SetGrid} \ -state {state State} \ -takefocus {takeFocus TakeFocus} \ -width {width Width} \ -xscrollcommand {xScrollCommand ScrollCommand} \ -yscrollcommand {yScrollCommand ScrollCommand} \ ] # and likewise for column-specific stuff. array set columnOptions [list \ -background {background Background} \ -bitmap {bitmap Bitmap} \ -font {font Font} \ -foreground {foreground Foreground} \ -image {image Image} \ -label {label Label} \ -position {position Position} \ -resizable {resizable Resizable} \ -visible {visible Visible} \ -width {width Width} \ ] # this defines the valid widget commands. It's important to # list them here; we use this list to validate commands and # expand abbreviations. set widgetCommands [list \ activate bbox cget column configure \ curselection delete get index insert \ label nearest scan see selection \ size xview yview ] set columnCommands [list add cget configure delete names nearest] set labelCommands [list bind] ###################################################################### #- this initializes the option database. Kinda gross, but it works #- (I think). ###################################################################### set packages [package names] # why check for the Tk package? This lets us be sourced into # an interpreter that doesn't have Tk loaded, such as the slave # interpreter used by pkg_mkIndex. In theory it should have no # side effects when run if {[lsearch -exact [package names] "Tk"] != -1} { # compute a widget name we can use to create a temporary widget set tmpWidget ".__tmp__" set count 0 while {[winfo exists $tmpWidget] == 1} { set tmpWidget ".__tmp__$count" incr count } # steal options from the listbox # we want darn near all options, so we'll go ahead and do # them all. No harm done in adding the one or two that we # don't use. listbox $tmpWidget foreach foo [$tmpWidget configure] { if {[llength $foo] == 5} { set option [lindex $foo 1] set value [lindex $foo 4] option add *Mclistbox.$option $value widgetDefault # these options also apply to the individual columns... if {[string compare $option "foreground"] == 0 \ || [string compare $option "background"] == 0 \ || [string compare $option "font"] == 0} { option add *Mclistbox*MclistboxColumn.$option $value \ widgetDefault } } } destroy $tmpWidget # steal some options from label widgets; we only want a subset # so we'll use a slightly different method. No harm in *not* # adding in the one or two that we don't use... :-) label $tmpWidget foreach option [list Anchor Background Font \ Foreground Height Image ] { set values [$tmpWidget configure -[string tolower $option]] option add *Mclistbox.label$option [lindex $values 4] widgetDefault } set values [$tmpWidget configure -foreground] option add *Mclistbox.labelActiveForeground [lindex $values 4] widgetDefault set values [$tmpWidget configure -background] option add *Mclistbox.labelActiveBackground [lindex $values 4] widgetDefault destroy $tmpWidget # these are unique to us... option add *Mclistbox.columnBorderWidth 0 widgetDefault option add *Mclistbox.columnRelief flat widgetDefault option add *Mclistbox.labelBorderWidth 1 widgetDefault option add *Mclistbox.labelRelief $::tk_relief \ widgetDefault option add *Mclistbox.labels 1 widgetDefault option add *Mclistbox.resizableColumns 1 widgetDefault option add *Mclistbox.resizeOneColumn 0 widgetDefault option add *Mclistbox.selectcommand {} widgetDefault option add *Mclistbox.fillcolumn {} widgetDefault # column options option add *Mclistbox*MclistboxColumn.visible 1 widgetDefault option add *Mclistbox*MclistboxColumn.resizable 1 widgetDefault option add *Mclistbox*MclistboxColumn.position end widgetDefault option add *Mclistbox*MclistboxColumn.label "" widgetDefault option add *Mclistbox*MclistboxColumn.width 0 widgetDefault option add *Mclistbox*MclistboxColumn.bitmap "" widgetDefault option add *Mclistbox*MclistboxColumn.image "" widgetDefault } ###################################################################### # define the class bindings ###################################################################### SetClassBindings } # ::mclistbox::mclistbox -- # # This is the command that gets exported. It creates a new # mclistbox widget. # # Arguments: # # w path of new widget to create # args additional option/value pairs (eg: -background white, etc.) # # Results: # # It creates the widget and sets up all of the default bindings # # Returns: # # The name of the newly create widget proc ::mclistbox::mclistbox {args} { variable widgetOptions # perform a one time initialization if {![info exists widgetOptions]} { Init } # make sure we at least have a widget name if {[llength $args] == 0} { error "wrong # args: should be \"mclistbox pathName ?options?\"" } # ... and make sure a widget doesn't already exist by that name if {[winfo exists [lindex $args 0]]} { error "window name \"[lindex $args 0]\" already exists" } # and check that all of the args are valid foreach {name value} [lrange $args 1 end] { Canonize [lindex $args 0] option $name } # build it... set w [eval Build $args] # set some bindings... SetBindings $w # and we are done! return $w } # ::mclistbox::Build -- # # This does all of the work necessary to create the basic # mclistbox. # # Arguments: # # w widget name # args additional option/value pairs # # Results: # # Creates a new widget with the given name. Also creates a new # namespace patterened after the widget name, as a child namespace # to ::mclistbox # # Returns: # # the name of the widget proc ::mclistbox::Build {w args} { variable widgetOptions # create the namespace for this instance, and define a few # variables namespace eval ::mclistbox::$w { variable options variable widgets variable misc } # this gives us access to the namespace variables within # this proc upvar ::mclistbox::${w}::widgets widgets upvar ::mclistbox::${w}::options options upvar ::mclistbox::${w}::misc misc # initially we start out with no columns set misc(columns) {} # this is our widget -- a frame of class Mclistbox. Naturally, # it will contain other widgets. We create it here because # we need it to be able to set our default options. set widgets(this) [frame $w -class Mclistbox -takefocus 1] # this defines all of the default options. We get the # values from the option database. Note that if an array # value is a list of length one it is an alias to another # option, so we just ignore it foreach name [array names widgetOptions] { if {[llength $widgetOptions($name)] == 1} continue set optName [lindex $widgetOptions($name) 0] set optClass [lindex $widgetOptions($name) 1] set options($name) [option get $w $optName $optClass] } # now apply any of the options supplied on the command # line. This may overwrite our defaults, which is OK if {[llength $args] > 0} { array set options $args } # the columns all go into a text widget since it has the # ability to scroll. set widgets(text) [text $w.text \ -width 0 \ -height 0 \ -padx 0 \ -pady 0 \ -wrap none \ -borderwidth 0 \ -highlightthickness 0 \ -takefocus 0 \ -cursor {} \ ] $widgets(text) configure -state disabled # here's the tricky part (shhhh... don't tell anybody!) # we are going to create column that completely fills # the base frame. We will use it to control the sizing # of the widget. The trick is, we'll pack it in the frame # and then place the text widget over it so it is never # seen. set columnWidgets [NewColumn $w {__hidden__}] set widgets(hiddenFrame) [lindex $columnWidgets 0] set widgets(hiddenListbox) [lindex $columnWidgets 1] set widgets(hiddenLabel) [lindex $columnWidgets 2] # by default geometry propagation is turned off, but for this # super-secret widget we want it turned on. The idea is, we # resize the listbox which resizes the frame which resizes the # whole shibang. pack propagate $widgets(hiddenFrame) on pack $widgets(hiddenFrame) -side top -fill both -expand y place $widgets(text) -x 0 -y 0 -relwidth 1.0 -relheight 1.0 raise $widgets(text) # we will later rename the frame's widget proc to be our # own custom widget proc. We need to keep track of this # new name, so we'll define and store it here... set widgets(frame) ::mclistbox::${w}::$w # this moves the original frame widget proc into our # namespace and gives it a handy name rename ::$w $widgets(frame) # now, create our widget proc. Obviously (?) it goes in # the global namespace. All mclistbox widgets will actually # share the same widget proc to cut down on the amount of # bloat. proc ::$w {command args} \ "eval ::mclistbox::WidgetProc {$w} \$command \$args" # ok, the thing exists... let's do a bit more configuration. if {[catch "Configure $widgets(this) [array get options]" error]} { catch {destroy $w} } # and be prepared to handle selections.. (this, for -exportselection # support) selection handle $w [list ::mclistbox::SelectionHandler $w get] return $w } # ::mclistbox::SelectionHandler -- # # handle reqests to set or retrieve the primary selection. This is # the "guts" of the implementation of the -exportselection option. # What a pain! Note that this command is *not* called as a result # of the widget's "selection" command, but rather as a result of # the global selection being set or cleared. # # If I read the ICCCM correctly (which is doubtful; who has time to # read that thing thoroughly?), this should return each row as a tab # separated list of values, and the whole as a newline separated # list of rows. # # Arguments: # # w pathname of the widget # type one of "own", "lose" or "get" # offset only used if type is "get"; offset into the selection # buffer where the returned data should begin # length number of bytes to return # proc ::mclistbox::SelectionHandler {w type {offset ""} {length ""}} { upvar ::mclistbox::${w}::options options upvar ::mclistbox::${w}::misc misc upvar ::mclistbox::${w}::widgets widgets switch -exact -- $type { own { selection own \ -command [list ::mclistbox::SelectionHandler $w lose] \ -selection PRIMARY \ $w } lose { if {$options(-exportselection)} { foreach id $misc(columns) { $widgets(listbox$id) selection clear 0 end } } } get { set end [expr {$length + $offset - 1}] set column [lindex $misc(columns) 0] set curselection [$widgets(listbox$column) curselection] # this is really, really slow (relatively speaking). # but the only way I can think of to speed this up # is to duplicate all the data in our hidden listbox, # which I really don't want to do because of memory # considerations. set data "" foreach index $curselection { set rowdata [join [::mclistbox::WidgetProc-get $w $index] "\t"] lappend data $rowdata } set data [join $data "\n"] return [string range $data $offset $end] } } } # ::mclistbox::convert -- # # public routine to convert %x, %y and %W binding substitutions. # Given an x, y and or %W value relative to a given widget, this # routine will convert the values to be relative to the mclistbox # widget. For example, it could be used in a binding like this: # # bind .mclistbox {doSomething [::mclistbox::convert %W -x %x]} # # Note that this procedure is *not* exported, but is indented for # public use. It is not exported because the name could easily # clash with existing commands. # # Arguments: # # w a widget path; typically the actual result of a %W # substitution in a binding. It should be either a # mclistbox widget or one of its subwidgets # # args should one or more of the following arguments or # pairs of arguments: # # -x will convert the value ; typically will # be the result of a %x substitution # -y will convert the value ; typically will # be the result of a %y substitution # -W (or -w) will return the name of the mclistbox widget # which is the parent of $w # # Returns: # # a list of the requested values. For example, a single -w will # result in a list of one items, the name of the mclistbox widget. # Supplying "-x 10 -y 20 -W" (in any order) will return a list of # three values: the converted x and y values, and the name of # the mclistbox widget. proc ::mclistbox::convert {w args} { set result {} if {![winfo exists $w]} { error "window \"$w\" doesn't exist" } while {[llength $args] > 0} { set option [lindex $args 0] set args [lrange $args 1 end] switch -exact -- $option { -x { set value [lindex $args 0] set args [lrange $args 1 end] set win $w while {[winfo class $win] != "Mclistbox"} { incr value [winfo x $win] set win [winfo parent $win] if {$win == "."} break } lappend result $value } -y { set value [lindex $args 0] set args [lrange $args 1 end] set win $w while {[winfo class $win] != "Mclistbox"} { incr value [winfo y $win] set win [winfo parent $win] if {$win == "."} break } lappend result $value } -w - -W { set win $w while {[winfo class $win] != "Mclistbox"} { set win [winfo parent $win] if {$win == "."} break; } lappend result $win } } } return $result } # ::mclistbox::SetBindings -- # # Sets up the default bindings for the named widget # # Arguments: # # w the widget pathname for which the bindings should be assigned # # Results: # # The named widget will inheirit all of the default Mclistbox # bindings. proc ::mclistbox::SetBindings {w} { upvar ::mclistbox::${w}::widgets widgets upvar ::mclistbox::${w}::options options upvar ::mclistbox::${w}::misc misc # we must do this so that the columns fill the text widget in # the y direction bind $widgets(text) \ [list ::mclistbox::AdjustColumns $w %h] } # ::mclistbox::SetClassBindings -- # # Sets up the default bindings for the widget class # # Arguments: # # none # proc ::mclistbox::SetClassBindings {} { # this allows us to clean up some things when we go away bind Mclistbox [list ::mclistbox::DestroyHandler %W] # steal all of the standard listbox bindings. Note that if a user # clicks in a column, %W will return that column. This is bad, # so we have to make a substitution in all of the bindings to # compute the real widget name (ie: the name of the topmost # frame) foreach event [bind Listbox] { set binding [bind Listbox $event] regsub -all {%W} $binding {[::mclistbox::convert %W -W]} binding regsub -all {%x} $binding {[::mclistbox::convert %W -x %x]} binding regsub -all {%y} $binding {[::mclistbox::convert %W -y %y]} binding bind Mclistbox $event $binding } # these define bindings for the column labels for resizing. Note # that we need both the name of this widget (calculated by $this) # as well as the specific widget that the event occured over. # Also note that $this is a constant string that gets evaluated # when the binding fires. # What a pain. set this {[::mclistbox::convert %W -W]} bind MclistboxMouseBindings \ "::mclistbox::ResizeEvent $this buttonpress %W %x %X %Y" bind MclistboxMouseBindings \ "::mclistbox::ResizeEvent $this buttonrelease %W %x %X %Y" bind MclistboxMouseBindings \ "::mclistbox::ResizeEvent $this leave %W %x %X %Y" bind MclistboxMouseBindings \ "::mclistbox::ResizeEvent $this motion %W %x %X %Y" bind MclistboxMouseBindings \ "::mclistbox::ResizeEvent $this motion %W %x %X %Y" bind MclistboxMouseBindings \ "::mclistbox::ResizeEvent $this drag %W %x %X %Y" } # ::mclistbox::NewColumn -- # # Adds a new column to the mclistbox widget # # Arguments: # # w the widget pathname # id the id for the new column # # Results: # # Creates a set of widgets which defines the column. Adds # appropriate entries to the global array widgets for the # new column. # # Note that this column is not added to the listbox by # this proc. # # Returns: # # A list of three elements: the path to the column frame, # the path to the column listbox, and the path to the column # label, in that order. proc ::mclistbox::NewColumn {w id} { upvar ::mclistbox::${w}::widgets widgets upvar ::mclistbox::${w}::options options upvar ::mclistbox::${w}::misc misc upvar ::mclistbox::${w}::columnID columnID # the columns are all children of the text widget we created... set frame \ [frame $w.frame$id \ -takefocus 0 \ -highlightthickness 0 \ -class MclistboxColumn \ -background $options(-background) \ ] set listbox \ [listbox $frame.listbox \ -takefocus 0 \ -bd 0 \ -setgrid $options(-setgrid) \ -exportselection false \ -selectmode $options(-selectmode) \ -highlightthickness 0 \ ] set label \ [label $frame.label \ -takefocus 0 \ -relief $::tk_relief \ -bd $::tk_borderwidth \ -highlightthickness 0 \ ] # define mappings from widgets to columns set columnID($label) $id set columnID($frame) $id set columnID($listbox) $id # we're going to associate a new bindtag for the label to # handle our resize bindings. Why? We want the bindings to # be specific to this widget but we don't want to use the # widget name. If we use the widget name then the bindings # could get mixed up with user-supplied bindigs (via the # "label bind" command). set tag MclistboxLabel bindtags $label [list MclistboxMouseBindings $label] # reconfigure the label based on global options foreach option [list bd image height relief font anchor \ background foreground borderwidth] { if {[info exists options(-label$option)] \ && $options(-label$option) != ""} { $label configure -$option $options(-label$option) } } # reconfigure the column based on global options foreach option [list borderwidth relief] { if {[info exists options(-column$option)] \ && $options(-column$option) != ""} { $frame configure -$option $options(-column$option) } } # geometry propagation must be off so we can control the size # of the listbox by setting the size of the containing frame pack propagate $frame off pack $label -side top -fill x -expand n pack $listbox -side top -fill both -expand y -pady 2 # any events that happen in the listbox gets handled by the class # bindings. This has the unfortunate side effect bindtags $listbox [list $w Mclistbox all] # return a list of the widgets we created. return [list $frame $listbox $label] } # ::mclistbox::Column-add -- # # Implements the "column add" widget command # # Arguments: # # w the widget pathname # args additional option/value pairs which define the column # # Results: # # A column gets created and added to the listbox proc ::mclistbox::Column-add {w args} { upvar ::mclistbox::${w}::widgets widgets upvar ::mclistbox::${w}::options options upvar ::mclistbox::${w}::misc misc variable widgetOptions set id "column-[llength $misc(columns)]" ;# a suitable default # if the first argument doesn't have a "-" as the first # character, it is an id to associate with this column if {![string match {-*} [lindex $args 0]]} { # the first arg must be an id. set id [lindex $args 0] set args [lrange $args 1 end] if {[lsearch -exact $misc(columns) $id] != -1} { error "column \"$id\" already exists" } } # define some reasonable defaults, then add any specific # values supplied by the user set opts(-bitmap) {} set opts(-image) {} set opts(-visible) 1 set opts(-resizable) 1 set opts(-position) "end" set opts(-width) 20 set opts(-background) $options(-background) set opts(-foreground) $options(-foreground) set opts(-font) $options(-font) set opts(-label) $id if {[expr {[llength $args]%2}] == 1} { # hmmm. An odd number of elements in args # if the last item is a valid option we'll give a different # error than if its not set option [::mclistbox::Canonize $w "column option" [lindex $args end]] error "value for \"[lindex $args end]\" missing" } array set opts $args # figure out if we have any data in the listbox yet; we'll need # this information in a minute... if {[llength $misc(columns)] > 0} { set col0 [lindex $misc(columns) 0] set existingRows [$widgets(listbox$col0) size] } else { set existingRows 0 } # create the widget and assign the associated paths to our array set widgetlist [NewColumn $w $id] set widgets(frame$id) [lindex $widgetlist 0] set widgets(listbox$id) [lindex $widgetlist 1] set widgets(label$id) [lindex $widgetlist 2] # add this column to the list of known columns lappend misc(columns) $id # configure the options. As a side effect, it will be inserted # in the text widget eval ::mclistbox::Column-configure {$w} {$id} [array get opts] # now, if there is any data already in the listbox, we need to # add a corresponding number of blank items. At least, I *think* # that's the right thing to do. if {$existingRows > 0} { set blanks {} for {set i 0} {$i < $existingRows} {incr i} { lappend blanks {} } eval {$widgets(listbox$id)} insert end $blanks } InvalidateScrollbars $w return $id } # ::mclistbox::Column-configure -- # # Implements the "column configure" widget command # # Arguments: # # w widget pathname # id column identifier # args list of option/value pairs proc ::mclistbox::Column-configure {w id args} { variable widgetOptions variable columnOptions upvar ::mclistbox::${w}::widgets widgets upvar ::mclistbox::${w}::options options upvar ::mclistbox::${w}::misc misc # bail if they gave us a bogus id set index [CheckColumnID $w $id] # define some shorthand set listbox $widgets(listbox$id) set frame $widgets(frame$id) set label $widgets(label$id) if {[llength $args] == 0} { # hmmm. User must be wanting all configuration information # note that if the value of an array element is of length # one it is an alias, which needs to be handled slightly # differently set results {} foreach opt [lsort [array names columnOptions]] { if {[llength $columnOptions($opt)] == 1} { set alias $columnOptions($opt) set optName $columnOptions($alias) lappend results [list $opt $optName] } else { set optName [lindex $columnOptions($opt) 0] set optClass [lindex $columnOptions($opt) 1] set default [option get $frame $optName $optClass] lappend results [list $opt $optName $optClass \ $default $options($id:$opt)] } } return $results } elseif {[llength $args] == 1} { # the user must be querying something... I need to get this # to return a bona fide list like the "real" configure # command, but it's not a priority at the moment. I still # have to work on the option database support foo. set option [::mclistbox::Canonize $w "column option" [lindex $args 0]] set value $options($id:$option) set optName [lindex $columnOptions($option) 0] set optClass [lindex $columnOptions($option) 1] set default [option get $frame $optName $optClass] set results [list $option $optName $optClass $default $value] return $results } # if we have an odd number of values, bail. if {[expr {[llength $args]%2}] == 1} { # hmmm. An odd number of elements in args error "value for \"[lindex $args end]\" missing" } # Great. An even number of options. Let's make sure they # are all valid before we do anything. Note that Canonize # will generate an error if it finds a bogus option; otherwise # it returns the canonical option name foreach {name value} $args { set name [::mclistbox::Canonize $w "column option" $name] set opts($name) $value } # if we get to here, the user is wanting to set some options foreach option [array names opts] { set value $opts($option) set options($id:$option) $value switch -- $option { -label { $label configure -text $value } -image - -bitmap { $label configure $option $value } -width { set font [$listbox cget -font] set factor [font measure $options(-font) "0"] set width [expr {$value * $factor}] $widgets(frame$id) configure -width $width set misc(min-$widgets(frame$id)) $width AdjustColumns $w } -font - -foreground - -background { if {[string length $value] == 0} {set value $options($option)} $listbox configure $option $value } -resizable { if {[catch { if {$value} { set options($id:-resizable) 1 } else { set options($id:-resizable) 0 } } msg]} { error "expected boolean but got \"$value\"" } } -visible { if {[catch { if {$value} { set options($id:-visible) 1 $widgets(text) configure -state normal $widgets(text) window configure 1.$index -window $frame $widgets(text) configure -state disabled } else { set options($id:-visible) 0 $widgets(text) configure -state normal $widgets(text) window configure 1.$index -window {} $widgets(text) configure -state disabled } InvalidateScrollbars $w } msg]} { error "expected boolean but got \"$value\"" } } -position { if {[string compare $value "start"] == 0} { set position 0 } elseif {[string compare $value "end"] == 0} { set position [expr {[llength $misc(columns)] -1}] } else { # ought to check for a legal value here, but I'm # lazy set position $value } if {$position >= [llength $misc(columns)]} { set max [expr {[llength $misc(columns)] -1}] error "bad position; must be in the range of 0-$max" } # rearrange misc(columns) to reflect the new ordering set current [lsearch -exact $misc(columns) $id] set misc(columns) [lreplace $misc(columns) $current $current] set misc(columns) [linsert $misc(columns) $position $id] set frame $widgets(frame$id) $widgets(text) configure -state normal $widgets(text) window create 1.$position \ -window $frame -stretch 1 $widgets(text) configure -state disabled } } } } # ::mclistbox::DestroyHandler {w} -- # # Cleans up after a mclistbox widget is destroyed # # Arguments: # # w widget pathname # # Results: # # The namespace that was created for the widget is deleted, # and the widget proc is removed. proc ::mclistbox::DestroyHandler {w} { # kill off any idle event we might have pending if {[info exists ::mclistbox::${w}::misc(afterid)]} { catch { after cancel $::mclistbox::${w}::misc(afterid) unset ::mclistbox::${w}::misc(afterid) } } # if the widget actually being destroyed is of class Mclistbox, # crush the namespace and kill the proc. Get it? Crush. Kill. # Destroy. Heh. Danger Will Robinson! Oh, man! I'm so funny it # brings tears to my eyes. if {[string compare [winfo class $w] "Mclistbox"] == 0} { namespace delete ::mclistbox::$w rename $w {} } } # ::mclistbox::MassageIndex -- # # this proc massages indicies of the form @x,y such that # the coordinates are relative to the first listbox rather # than relative to the topmost frame. # # Arguments: # # w widget pathname # index an index of the form @x,y # # Results: # # Returns a new index with translated coordinates. This index # may be used directly by an internal listbox. proc ::mclistbox::MassageIndex {w index} { upvar ::mclistbox::${w}::widgets widgets upvar ::mclistbox::${w}::misc misc if {[regexp {@([0-9]+),([0-9]+)} $index matchvar x y]} { set id [lindex $misc(columns) 0] incr y -[winfo y $widgets(listbox$id)] incr y -[winfo y $widgets(frame$id)] incr x [winfo x $widgets(listbox$id)] incr x [winfo x $widgets(frame$id)] set index @${x},${y} } return $index } # ::mclistbox::WidgetProc -- # # This gets uses as the widgetproc for an mclistbox widget. # Notice where the widget is created and you'll see that the # actual widget proc merely evals this proc with all of the # arguments intact. # # Note that some widget commands are defined "inline" (ie: # within this proc), and some do most of their work in # separate procs. This is merely because sometimes it was # easier to do it one way or the other. # # Arguments: # # w widget pathname # command widget subcommand # args additional arguments; varies with the subcommand # # Results: # # Performs the requested widget command proc ::mclistbox::WidgetProc {w command args} { variable widgetOptions upvar ::mclistbox::${w}::widgets widgets upvar ::mclistbox::${w}::options options upvar ::mclistbox::${w}::misc misc upvar ::mclistbox::${w}::columnID columnID set command [::mclistbox::Canonize $w command $command] # some commands have subcommands. We'll check for that here # and mung the command and args so that we can treat them as # distinct commands in the following switch statement if {[string compare $command "column"] == 0} { set subcommand [::mclistbox::Canonize $w "column command" \ [lindex $args 0]] set command "$command-$subcommand" set args [lrange $args 1 end] } elseif {[string compare $command "label"] == 0} { set subcommand [::mclistbox::Canonize $w "label command" \ [lindex $args 0]] set command "$command-$subcommand" set args [lrange $args 1 end] } set result "" catch {unset priorSelection} # here we go. Error checking be damned! switch -- $command { xview { # note that at present, "xview " is broken. I'm # not even sure how to do it. Unless I attach our hidden # listbox to the scrollbar and use it. Hmmm..... I'll # try that later. (FIXME) set result [eval {$widgets(text)} xview $args] set frame $widgets(frame$options(-fillcolumn)) set minwidth $misc(min-$frame) if {([lindex [$widgets(text) xview] 1] == 1) || ([$frame cget -width] <= $minwidth)} { InvalidateScrollbars $w } else { AdjustColumns $w } } yview { if {[llength $args] == 0} { # length of zero means to fetch the yview; we can # get this from a single listbox set result [$widgets(hiddenListbox) yview] } else { # if it's one argument, it's an index. We'll pass that # index through the index command to properly translate # @x,y indicies, and place the value back in args if {[llength $args] == 1} { set index [::mclistbox::MassageIndex $w [lindex $args 0]] set args [list $index] } # run the yview command on every column. foreach id $misc(columns) { eval {$widgets(listbox$id)} yview $args } eval {$widgets(hiddenListbox)} yview $args InvalidateScrollbars $w set result "" } } activate { if {[llength $args] != 1} { error "wrong \# of args: should be $w activate index" } set index [::mclistbox::MassageIndex $w [lindex $args 0]] foreach id $misc(columns) { $widgets(listbox$id) activate $index } set result "" } bbox { if {[llength $args] != 1} { error "wrong \# of args: should be $w bbox index" } # get a real index. This will adjust @x,y indicies # to account for the label, if any. set index [::mclistbox::MassageIndex $w [lindex $args 0]] set id [lindex $misc(columns) 0] # we can get the x, y, and height from the first # column. set bbox [$widgets(listbox$id) bbox $index] if {[string length $bbox] == 0} {return ""} foreach {x y w h} $bbox {} # the x and y coordinates have to be adjusted for the # fact that the listbox is inside a frame, and the # frame is inside a text widget. All of those add tiny # offsets. Feh. incr y [winfo y $widgets(listbox$id)] incr y [winfo y $widgets(frame$id)] incr x [winfo x $widgets(listbox$id)] incr x [winfo x $widgets(frame$id)] # we can get the width by looking at the relative x # coordinate of the right edge of the last column set id [lindex $misc(columns) end] set w [expr {[winfo width $widgets(frame$id)] + \ [winfo x $widgets(frame$id)]}] set bbox [list $x $y [expr {$x + $w}] $h] set result $bbox } label-bind { # we are just too clever for our own good. (that's a # polite way of saying this is more complex than it # needs to be) set id [lindex $args 0] set index [CheckColumnID $w $id] set args [lrange $args 1 end] if {[llength $args] == 0} { set result [bind $widgets(label$id)] } else { # when we create a binding, we'll actually have the # binding run our own command with the user's command # as an argument. This way we can do some sanity checks # before running the command. So, when querying a binding # we need to only return the user's code set sequence [lindex $args 0] if {[llength $args] == 1} { set result [lindex [bind $widgets(label$id) $sequence] end] } else { # replace %W with our toplevel frame, then # do the binding set code [lindex $args 1] regsub -all {%W} $code $w code set result [bind $widgets(label$id) $sequence \ [list ::mclistbox::LabelEvent $w $id $code]] } } } column-add { eval ::mclistbox::Column-add {$w} $args AdjustColumns $w set result "" } column-delete { foreach id $args { set index [CheckColumnID $w $id] # remove the reference from our list of columns set misc(columns) [lreplace $misc(columns) $index $index] # whack the widget destroy $widgets(frame$id) # clear out references to the individual widgets unset widgets(frame$id) unset widgets(listbox$id) unset widgets(label$id) } InvalidateScrollbars $w set result "" } column-cget { if {[llength $args] != 2} { error "wrong # of args: should be \"$w column cget name option\"" } set id [::mclistbox::Canonize $w column [lindex $args 0]] set option [lindex $args 1] set data [::mclistbox::Column-configure $w $id $option] set result [lindex $data 4] } column-configure { set id [::mclistbox::Canonize $w column [lindex $args 0]] set args [lrange $args 1 end] set result [eval ::mclistbox::Column-configure {$w} {$id} $args] } column-names { if {[llength $args] != 0} { error "wrong # of args: should be \"$w column names\"" } set result $misc(columns) } column-nearest { if {[llength $args] != 1} { error "wrong # of args: should be \"$w column nearest x\"" } set x [lindex $args 0] set tmp [$widgets(text) index @$x,0] set tmp [split $tmp "."] set index [lindex $tmp 1] set result [lindex $misc(columns) $index] } cget { if {[llength $args] != 1} { error "wrong # args: should be $w cget option" } set opt [::mclistbox::Canonize $w option [lindex $args 0]] set result $options($opt) } configure { set result [eval ::mclistbox::Configure {$w} $args] } curselection { set id [lindex $misc(columns) 0] set result [$widgets(listbox$id) curselection] } delete { if {[llength $args] < 1 || [llength $args] > 2} { error "wrong \# of args: should be $w delete first ?last?" } # it's possible that the selection will change because # of something we do. So, grab the current selection before # we do anything. Just before returning we'll see if the # selection has changed. If so, we'll call our selectcommand if {$options(-selectcommand) != ""} { set col0 [lindex $misc(columns) 0] set priorSelection [$widgets(listbox$col0) curselection] } set index1 [::mclistbox::MassageIndex $w [lindex $args 0]] if {[llength $args] == 2} { set index2 [::mclistbox::MassageIndex $w [lindex $args 1]] } else { set index2 "" } # note we do an eval here to make index2 "disappear" if it # is set to an empty string. foreach id $misc(columns) { eval {$widgets(listbox$id)} delete $index1 $index2 } eval {$widgets(hiddenListbox)} delete $index1 $index2 InvalidateScrollbars $w set result "" } get { if {[llength $args] < 1 || [llength $args] > 2} { error "wrong \# of args: should be $w get first ?last?" } set index1 [::mclistbox::MassageIndex $w [lindex $args 0]] if {[llength $args] == 2} { set index2 [::mclistbox::MassageIndex $w [lindex $args 1]] } else { set index2 "" } set result [eval ::mclistbox::WidgetProc-get {$w} $index1 $index2] } index { if {[llength $args] != 1} { error "wrong \# of args: should be $w index index" } set index [::mclistbox::MassageIndex $w [lindex $args 0]] set id [lindex $misc(columns) 0] set result [$widgets(listbox$id) index $index] } insert { if {[llength $args] < 1} { error "wrong \# of args: should be $w insert ?element \ element...?" } # it's possible that the selection will change because # of something we do. So, grab the current selection before # we do anything. Just before returning we'll see if the # selection has changed. If so, we'll call our selectcommand if {$options(-selectcommand) != ""} { set col0 [lindex $misc(columns) 0] set priorSelection [$widgets(listbox$col0) curselection] } set index [::mclistbox::MassageIndex $w [lindex $args 0]] ::mclistbox::Insert $w $index [lrange $args 1 end] InvalidateScrollbars $w set result "" } nearest { if {[llength $args] != 1} { error "wrong \# of args: should be $w nearest y" } # translate the y coordinate into listbox space set id [lindex $misc(columns) 0] set y [lindex $args 0] incr y -[winfo y $widgets(listbox$id)] incr y -[winfo y $widgets(frame$id)] set col0 [lindex $misc(columns) 0] set result [$widgets(listbox$col0) nearest $y] } scan { foreach {subcommand x y} $args {} switch -- $subcommand { mark { # we have to treat scrolling in x and y differently; # scrolling in the y direction affects listboxes and # scrolling in the x direction affects the text widget. # to facilitate that, we need to keep a local copy # of the scan mark. set misc(scanmarkx) $x set misc(scanmarky) $y # set the scan mark for each column foreach id $misc(columns) { $widgets(listbox$id) scan mark $x $y } # we can't use the x coordinate given us, since it # is relative to whatever column we are over. So, # we'll just usr the results of [winfo pointerx]. $widgets(text) scan mark [winfo pointerx $w] $y } dragto { # we want the columns to only scan in the y direction, # so we'll force the x componant to remain constant foreach id $misc(columns) { $widgets(listbox$id) scan dragto $misc(scanmarkx) $y } # since the scan mark of the text widget was based # on the pointer location, so must be the x # coordinate to the dragto command. And since we # want the text widget to only scan in the x # direction, the y componant will remain constant $widgets(text) scan dragto \ [winfo pointerx $w] $misc(scanmarky) # make sure the scrollbars reflect the changes. InvalidateScrollbars $w } } set result "" } see { if {[llength $args] != 1} { error "wrong \# of args: should be $w see index" } set index [::mclistbox::MassageIndex $w [lindex $args 0]] foreach id $misc(columns) { $widgets(listbox$id) see $index } InvalidateScrollbars $w set result {} } selection { # it's possible that the selection will change because # of something we do. So, grab the current selection before # we do anything. Just before returning we'll see if the # selection has changed. If so, we'll call our selectcommand if {$options(-selectcommand) != ""} { set col0 [lindex $misc(columns) 0] set priorSelection [$widgets(listbox$col0) curselection] } set subcommand [lindex $args 0] set args [lrange $args 1 end] set prefix "wrong \# of args: should be $w" switch -- $subcommand { includes { if {[llength $args] != 1} { error "$prefix selection $subcommand index" } set index [::mclistbox::MassageIndex $w [lindex $args 0]] set id [lindex $misc(columns) 0] set result [$widgets(listbox$id) selection includes $index] } set { switch -- [llength $args] { 1 { set index1 [::mclistbox::MassageIndex $w \ [lindex $args 0]] set index2 "" } 2 { set index1 [::mclistbox::MassageIndex $w \ [lindex $args 0]] set index2 [::mclistbox::MassageIndex $w \ [lindex $args 1]] } default { error "$prefix selection clear first ?last?" } } if {$options(-exportselection)} { SelectionHandler $w own } if {$index1 != ""} { foreach id $misc(columns) { eval {$widgets(listbox$id)} selection set \ $index1 $index2 } } set result "" } anchor { if {[llength $args] != 1} { error "$prefix selection $subcommand index" } set index [::mclistbox::MassageIndex $w [lindex $args 0]] if {$options(-exportselection)} { SelectionHandler $w own } foreach id $misc(columns) { $widgets(listbox$id) selection anchor $index } set result "" } clear { switch -- [llength $args] { 1 { set index1 [::mclistbox::MassageIndex $w \ [lindex $args 0]] set index2 "" } 2 { set index1 [::mclistbox::MassageIndex $w \ [lindex $args 0]] set index2 [::mclistbox::MassageIndex $w \ [lindex $args 1]] } default { error "$prefix selection clear first ?last?" } } if {$options(-exportselection)} { SelectionHandler $w own } foreach id $misc(columns) { eval {$widgets(listbox$id)} selection clear \ $index1 $index2 } set result "" } } } size { set id [lindex $misc(columns) 0] set result [$widgets(listbox$id) size] } } # if the user has a selectcommand defined and the selection changed, # run the selectcommand if {[info exists priorSelection] && $options(-selectcommand) != ""} { set column [lindex $misc(columns) 0] set currentSelection [$widgets(listbox$column) curselection] if {[string compare $priorSelection $currentSelection] != 0} { # this logic keeps us from getting into some sort of # infinite loop of the selectcommand changes the selection # (not particularly well tested, but it seems like the # right thing to do...) if {![info exists misc(skipRecursiveCall)]} { set misc(skipRecursiveCall) 1 uplevel \#0 $options(-selectcommand) $currentSelection catch {unset misc(skipRecursiveCall)} } } } return $result } # ::mclistbox::WidgetProc-get -- # # Implements the "get" widget command # # Arguments: # # w widget path # args additional arguments to the get command proc ::mclistbox::WidgetProc-get {w args} { upvar ::mclistbox::${w}::widgets widgets upvar ::mclistbox::${w}::options options upvar ::mclistbox::${w}::misc misc set returnType "list" # the listbox "get" command returns different things # depending on whether it has one or two args. Internally # we *always* want a valid list, so we'll force a second # arg which in turn forces the listbox to return a list, # even if its a list of one element if {[llength $args] == 1} { lappend args [lindex $args 0] set returnType "listOfLists" } # get all the data from each column foreach id $misc(columns) { set data($id) [eval {$widgets(listbox$id)} get $args] } # now join the data together one row at a time. Ugh. set result {} set rows [llength $data($id)] for {set i 0} {$i < $rows} {incr i} { set this {} foreach column $misc(columns) { lappend this [lindex $data($column) $i] } lappend result $this } # now to unroll the list if necessary. If the user gave # us only one indicie we want to return a single list # of values. If they gave use two indicies we want to return # a list of lists. if {[string compare $returnType "list"] == 0} { return $result } else { return [lindex $result 0] } } # ::mclistbox::CheckColumnID -- # # returns the index of the id within our list of columns, or # reports an error if the id is invalid # # Arguments: # # w widget pathname # id a column id # # Results: # # Will compute and return the index of the column within the # list of columns (which happens to be it's -position, as it # turns out) or returns an error if the named column doesn't # exist. proc ::mclistbox::CheckColumnID {w id} { upvar ::mclistbox::${w}::misc misc set id [::mclistbox::Canonize $w column $id] set index [lsearch -exact $misc(columns) $id] return $index } # ::mclistbox::LabelEvent -- # # Handle user events on the column labels for the Mclistbox # class. # # Arguments: # # w widget pathname # id a column identifier # code tcl code to be evaluated. # # Results: # # Executes the code associate with an event, but only if the # event wouldn't otherwise potentially trigger a resize event. # # We use the cursor of the label to let us know whether the # code should be executed. If it is set to the cursor of the # mclistbox widget, the code will be executed. It is assumed # that if it is not the same cursor, it is the resize cursor # which should only be set if the cursor is very near a border # of a label and the column is resizable. proc ::mclistbox::LabelEvent {w id code} { upvar ::mclistbox::${w}::widgets widgets upvar ::mclistbox::${w}::options options # only fire the binding if the cursor is our default cursor # (ie: if we aren't in a "resize zone") set cursor [$widgets(label$id) cget -cursor] if {[string compare $cursor $options(-cursor)] == 0} { uplevel \#0 $code } } # ::mclistbox::HumanizeList -- # # Returns a human-readable form of a list by separating items # by columns, but separating the last two elements with "or" # (eg: foo, bar or baz) # # Arguments: # # list a valid tcl list # # Results: # # A string which as all of the elements joined with ", " or # the word " or " proc ::mclistbox::HumanizeList {list} { if {[llength $list] == 1} { return [lindex $list 0] } else { set list [lsort $list] set secondToLast [expr {[llength $list] -2}] set most [lrange $list 0 $secondToLast] set last [lindex $list end] return "[join $most {, }] or $last" } } # ::mclistbox::Canonize -- # # takes a (possibly abbreviated) option or command name and either # returns the canonical name or an error # # Arguments: # # w widget pathname # object type of object to canonize; must be one of "command", # "option", "column" or "column option". # opt the option (or command) to be canonized # # Returns: # # Returns either the canonical form of an option or command, # or raises an error if the option or command is unknown or # ambiguous. proc ::mclistbox::Canonize {w object opt} { variable widgetOptions variable columnOptions variable widgetCommands variable columnCommands variable labelCommands switch -- $object { command { if {[lsearch -exact $widgetCommands $opt] >= 0} { return $opt } # command names aren't stored in an array, and there # isn't a way to get all the matches in a list, so # we'll stuff the columns in a temporary array so # we can use [array names] set list $widgetCommands foreach element $list { set tmp($element) "" } set matches [array names tmp ${opt}*] } {label command} { if {[lsearch -exact $labelCommands $opt] >= 0} { return $opt } # command names aren't stored in an array, and there # isn't a way to get all the matches in a list, so # we'll stuff the columns in a temporary array so # we can use [array names] set list $labelCommands foreach element $list { set tmp($element) "" } set matches [array names tmp ${opt}*] } {column command} { if {[lsearch -exact $columnCommands $opt] >= 0} { return $opt } # command names aren't stored in an array, and there # isn't a way to get all the matches in a list, so # we'll stuff the columns in a temporary array so # we can use [array names] set list $columnCommands foreach element $list { set tmp($element) "" } set matches [array names tmp ${opt}*] } option { if {[info exists widgetOptions($opt)] \ && [llength $widgetOptions($opt)] == 3} { return $opt } set list [array names widgetOptions] set matches [array names widgetOptions ${opt}*] } {column option} { if {[info exists columnOptions($opt)]} { return $opt } set list [array names columnOptions] set matches [array names columnOptions ${opt}*] } column { upvar ::mclistbox::${w}::misc misc if {[lsearch -exact $misc(columns) $opt] != -1} { return $opt } # column names aren't stored in an array, and there # isn't a way to get all the matches in a list, so # we'll stuff the columns in a temporary array so # we can use [array names] set list $misc(columns) foreach element $misc(columns) { set tmp($element) "" } set matches [array names tmp ${opt}*] } } if {[llength $matches] == 0} { set choices [HumanizeList $list] error "unknown $object \"$opt\"; must be one of $choices" } elseif {[llength $matches] == 1} { # deal with option aliases set opt [lindex $matches 0] switch -- $object { option { if {[llength $widgetOptions($opt)] == 1} { set opt $widgetOptions($opt) } } {column option} { if {[llength $columnOptions($opt)] == 1} { set opt $columnOptions($opt) } } } return $opt } else { set choices [HumanizeList $list] error "ambiguous $object \"$opt\"; must be one of $choices" } } # ::mclistbox::Configure -- # # Implements the "configure" widget subcommand # # Arguments: # # w widget pathname # args zero or more option/value pairs (or a single option) # # Results: # # Performs typcial "configure" type requests on the widget proc ::mclistbox::Configure {w args} { variable widgetOptions upvar ::mclistbox::${w}::widgets widgets upvar ::mclistbox::${w}::options options upvar ::mclistbox::${w}::misc misc if {[llength $args] == 0} { # hmmm. User must be wanting all configuration information # note that if the value of an array element is of length # one it is an alias, which needs to be handled slightly # differently set results {} foreach opt [lsort [array names widgetOptions]] { if {[llength $widgetOptions($opt)] == 1} { set alias $widgetOptions($opt) set optName $widgetOptions($alias) lappend results [list $opt $optName] } else { set optName [lindex $widgetOptions($opt) 0] set optClass [lindex $widgetOptions($opt) 1] set default [option get $w $optName $optClass] lappend results [list $opt $optName $optClass \ $default $options($opt)] } } return $results } # one argument means we are looking for configuration # information on a single option if {[llength $args] == 1} { set opt [::mclistbox::Canonize $w option [lindex $args 0]] set optName [lindex $widgetOptions($opt) 0] set optClass [lindex $widgetOptions($opt) 1] set default [option get $w $optName $optClass] set results [list $opt $optName $optClass \ $default $options($opt)] return $results } # if we have an odd number of values, bail. if {[expr {[llength $args]%2}] == 1} { # hmmm. An odd number of elements in args error "value for \"[lindex $args end]\" missing" } # Great. An even number of options. Let's make sure they # are all valid before we do anything. Note that Canonize # will generate an error if it finds a bogus option; otherwise # it returns the canonical option name foreach {name value} $args { set name [::mclistbox::Canonize $w option $name] set opts($name) $value } # process all of the configuration options foreach option [array names opts] { set newValue $opts($option) if {[info exists options($option)]} { set oldValue $options($option) # set options($option) $newValue } switch -- $option { -exportselection { if {$newValue} { SelectionHandler $w own set options($option) 1 } else { set options($option) 0 } } -fillcolumn { # if the fill column changed, we need to adjust # the columns. AdjustColumns $w set options($option) $newValue } -takefocus { $widgets(frame) configure -takefocus $newValue set options($option) [$widgets(frame) cget $option] } -background { foreach id $misc(columns) { $widgets(listbox$id) configure -background $newValue $widgets(frame$id) configure -background $newValue } $widgets(frame) configure -background $newValue $widgets(text) configure -background $newValue set options($option) [$widgets(frame) cget $option] } # { the following all must be applied to each listbox } -foreground - -font - -selectborderwidth - -selectforeground - -selectbackground - -setgrid { foreach id $misc(columns) { $widgets(listbox$id) configure $option $newValue } $widgets(hiddenListbox) configure $option $newValue set options($option) [$widgets(hiddenListbox) cget $option] } # { the following all must be applied to each listbox and frame } -cursor { foreach id $misc(columns) { $widgets(listbox$id) configure $option $newValue $widgets(frame$id) configure -cursor $newValue } # -cursor also needs to be applied to the # frames of each column foreach id $misc(columns) { $widgets(frame$id) configure -cursor $newValue } $widgets(hiddenListbox) configure $option $newValue set options($option) [$widgets(hiddenListbox) cget $option] } # { this just requires to pack or unpack the labels } -labels { if {$newValue} { set newValue 1 foreach id $misc(columns) { pack $widgets(label$id) \ -side top -fill x -expand n \ -before $widgets(listbox$id) } pack $widgets(hiddenLabel) \ -side top -fill x -expand n \ -before $widgets(hiddenListbox) } else { set newValue foreach id $misc(columns) { pack forget $widgets(label$id) } pack forget $widgets(hiddenLabel) } set options($option) $newValue } -height { $widgets(hiddenListbox) configure -height $newValue InvalidateScrollbars $w set options($option) [$widgets(hiddenListbox) cget $option] } -width { if {$newValue == 0} { error "a -width of zero is not supported. " } $widgets(hiddenListbox) configure -width $newValue InvalidateScrollbars $w set options($option) [$widgets(hiddenListbox) cget $option] } # { the following all must be applied to each column frame } -columnborderwidth - -columnrelief { regsub {column} $option {} listboxoption foreach id $misc(columns) { $widgets(listbox$id) configure $listboxoption $newValue } $widgets(hiddenListbox) configure $listboxoption $newValue set options($option) [$widgets(hiddenListbox) cget \ $listboxoption] } -resizeonecolumn - -resizablecolumns { if {$newValue} { set options($option) 1 } else { set options($option) 0 } } # { the following all must be applied to each column header } -labelimage - -labelheight - -labelrelief - -labelfont - -labelanchor - -labelbackground - -labelforeground - -labelborderwidth { regsub {label} $option {} labeloption foreach id $misc(columns) { $widgets(label$id) configure $labeloption $newValue } $widgets(hiddenLabel) configure $labeloption $newValue set options($option) [$widgets(hiddenLabel) cget $labeloption] } -labelactiveforeground { set options($option) $newValue } -labelactivebackground { set options($option) $newValue } # { the following apply only to the topmost frame} -borderwidth - -highlightthickness - -highlightcolor - -highlightbackground - -relief { $widgets(frame) configure $option $newValue set options($option) [$widgets(frame) cget $option] } -selectmode { set options($option) $newValue } -selectcommand { set options($option) $newValue } -xscrollcommand { InvalidateScrollbars $w set options($option) $newValue } -yscrollcommand { InvalidateScrollbars $w set options($option) $newValue } } } } # ::mclistbox::UpdateScrollbars -- # # This proc does the work of actually update the scrollbars to # reflect the current view # # Arguments: # # w widget pathname # # Results: # # Potentially changes the size or placement of the scrollbars # (if any) based on changes to the widget proc ::mclistbox::UpdateScrollbars {w} { upvar ::mclistbox::${w}::widgets widgets upvar ::mclistbox::${w}::options options upvar ::mclistbox::${w}::misc misc if {![winfo ismapped $w]} { catch {unset misc(afterid)} return } update idletasks if {[llength $misc(columns)] > 0} { if {[string length $options(-yscrollcommand)] != 0} { set col0 [lindex $misc(columns) 0] set yview [$widgets(listbox$col0) yview] eval $options(-yscrollcommand) $yview } if {[string length $options(-xscrollcommand)] != 0} { set col0 [lindex $misc(columns) 0] set xview [$widgets(text) xview] eval $options(-xscrollcommand) $xview } } catch {unset misc(afterid)} } # ::mclistbox::InvalidateScrollbars -- # # Schedules the scrollbars to be updated the next time # we are idle. # # Arguments: # # w widget pathname # # Results: # # sets up a proc to be run in the idle event handler proc ::mclistbox::InvalidateScrollbars {w} { upvar ::mclistbox::${w}::widgets widgets upvar ::mclistbox::${w}::options options upvar ::mclistbox::${w}::misc misc if {![info exists misc(afterid)]} { set misc(afterid) \ [after idle "catch {::mclistbox::UpdateScrollbars $w}"] } } # ::mclistbox::Insert -- # # This implements the "insert" widget command; it arranges for # one or more elements to be inserted into the listbox. # # Arguments: # # w widget pathname # index a valid listbox index to designate where the data is # to be inserted # arglist A list of values to be inserted. Each element of the # list will itself be treated as a list, one element for # each column. # # Results: # # Inserts the data into the list and updates the scrollbars proc ::mclistbox::Insert {w index arglist} { upvar ::mclistbox::${w}::widgets widgets upvar ::mclistbox::${w}::options options upvar ::mclistbox::${w}::misc misc foreach list $arglist { # make sure we have enough elements for each column for {set i [llength $list]} {$i < [llength $misc(columns)]} {incr i} { lappend list {} } set column 0 foreach id $misc(columns) { $widgets(listbox$id) insert $index [lindex $list $column] incr column } # we also want to add a bogus item to the hidden listbox. Why? # For standard listboxes, if you specify a height of zero the # listbox will resize to be just big enough to hold all the lines. # Since we use a hidden listbox to regulate the size of the widget # and we want this same behavior, this listbox needs the same number # of elements as the visible listboxes # # (NB: we might want to make this listbox contain the contents # of all columns as a properly formatted list; then the get # command can query this listbox instead of having to query # each individual listbox. The disadvantage is that it doubles # the memory required to hold all the data) $widgets(hiddenListbox) insert $index "x" } return "" } # ::mclistbox::ColumnIsHidden -- # # Returns a boolean representing whether a column is visible or # not # # Arguments: # # w widget pathname # id a column identifier # # Results: # # returns 1 if the column is visible (ie: not hidden), or 0 # if invisible. Note that the result doesn't consider whether # the column is actually viewable. Even if it has been scrolled # off screen, 1 will be returned as long as the column hasn't # been hidden by turning the visibility off. proc ::mclistbox::ColumnIsHidden {w id} { upvar ::mclistbox::${w}::widgets widgets upvar ::mclistbox::${w}::misc misc set retval 1 set col [lsearch -exact $misc(columns) $id] if {$col != ""} { set index "1.$col" catch { set window [$widgets(text) window cget $index -window] if {[string length $window] > 0 && [winfo exists $window]} { set retval 0 } } } return $retval } # ::mclistbox::AdjustColumns -- # # Adjusts the height and width of the individual columns. # # Arguments: # # w widget pathname # height height, in pixels, that the columns should be adjusted # to. If null, the height will be the height of the text # widget that underlies our columns. # # Results: # # All columns will be adjusted to fill the text widget in the y # direction. Also, if a -fillcolumn is defined, that column will # be grown, if necessary, to fill the widget in the x direction. proc ::mclistbox::AdjustColumns {w {height ""}} { upvar ::mclistbox::${w}::widgets widgets upvar ::mclistbox::${w}::options options upvar ::mclistbox::${w}::misc misc if {[string length $height] == 0} { set height [winfo height $widgets(text)] } # resize the height of each column so it matches the height # of the text widget, minus a few pixels. incr height -4 foreach id $misc(columns) { $widgets(frame$id) configure -height $height } # if we have a fillcolumn, change its width accordingly if {$options(-fillcolumn) != ""} { # make sure the column has been defined. If not, bail (?) if {![info exists widgets(frame$options(-fillcolumn))]} { return } set frame $widgets(frame$options(-fillcolumn)) set minwidth $misc(min-$frame) # compute current width of all columns set colwidth 0 set col 0 foreach id $misc(columns) { if {![ColumnIsHidden $w $id] && $id != $options(-fillcolumn)} { incr colwidth [winfo reqwidth $widgets(frame$id)] } } # this is just shorthand for later use... set id $options(-fillcolumn) # compute optimal width set optwidth [expr {[winfo width $widgets(text)] - \ (2 * [$widgets(text) cget -padx])}] # compute the width of our fill column set newwidth [expr {$optwidth - $colwidth}] if {$newwidth < $minwidth} { # adjust the width of our fill column frame if {$options(-resizeonecolumn)} { set fullwidth [expr {$colwidth + [winfo reqwidth $frame]}] lassign [$widgets(text) xview] lb rb set h [expr {int(($rb * $fullwidth) - $colwidth)}] if {$h < $minwidth} { set newwidth $minwidth } else { set newwidth $h } } else { set newwidth $minwidth } } $widgets(frame$id) configure -width $newwidth } InvalidateScrollbars $w } # ::mclistbox::FindResizableNeighbor -- # # Returns the nearest resizable column to the left or right # of the named column. # # Arguments: # # w widget pathname # id column identifier # direction should be one of "right" or "left". Actually, anything # that doesn't match "right" will be treated as "left" # # Results: # # Will return the column identifier of the nearest resizable # column, or an empty string if none exists. proc ::mclistbox::FindResizableNeighbor {w id {direction right}} { upvar ::mclistbox::${w}::widgets widgets upvar ::mclistbox::${w}::options options upvar ::mclistbox::${w}::misc misc if {$direction == "right"} { set incr 1 set stop [llength $misc(columns)] set start [expr {[lsearch -exact $misc(columns) $id] + 1}] } else { set incr -1 set stop -1 set start [expr {[lsearch -exact $misc(columns) $id] - 1}] } for {set i $start} {$i != $stop} {incr i $incr} { set col [lindex $misc(columns) $i] if {![ColumnIsHidden $w $col] && $options($col:-resizable)} { return $col } } return "" } # ::mclistbox::ResizeEvent -- # # Handles the events which implement interactive column resizing # using the mouse. # # Arguments: # # w widget pathname # type type of event; must be one of "buttonpress", "drag", # "motion", or "buttonrelease" # widget the actual widget that the event occured over # x the x coordinate of the mouse, relative to $widget # X the root x coordinate of the mouse # Y the root y coordinate of the mouse # # The basic idea is this: # # whenever the cursor moves over the label, we examine it's x # coordinate to determine if its within a fixed amount of # pixels from the left or right edge. If it is, we reconfigure # the cursor to be a suitable "this thing is resizable" cursor. # # On a buttonclick, if the cursor is not the default cursor # (and thus, presumably the resize cursor), we set up some # state for an eventual resize. We figure out which columns # are to the left and right and base a maximum resize amount # for each direction. We also define the absolute X coordinate # of the buttonpress as a reference point for the drag. # # on a b1-motion, if the drag state exists, we look at the # absolute X value and use it to compute a delta value from # the reference (the X of the button press). We then resize the # left and right column frames by the delta amount. # # on a button release, we unset the state and the cursor, which # cancels all of the above. proc ::mclistbox::ResizeEvent {w type widget x X Y} { upvar ::mclistbox::${w}::widgets widgets upvar ::mclistbox::${w}::options options upvar ::mclistbox::${w}::misc misc upvar ::mclistbox::${w}::columnID columnID # if the widget doesn't allow resizable cursors, there's # nothing here to do... if {!$options(-resizablecolumns)} { return } # this lets us keep track of some internal state while # the user is dragging the mouse variable drag # this lets us define a small window around the edges of # the column. set threshold [expr {$options(-labelborderwidth) + 4}] # this is what we use for the "this is resizable" cursor set resizeCursor sb_h_double_arrow # if we aren't over an area that we care about, bail. if {![info exists columnID($widget)]} { return } # id refers to the column name set id $columnID($widget) switch -- $type { buttonpress { # we will do all the work of initiating a drag only if # the cursor is not the defined cursor. In theory this # will only be the case if the mouse moves over the area # in which a drag can happen. if {[$widgets(label$id) cget -cursor] == $resizeCursor} { if {$x <= $threshold} { set lid [::mclistbox::FindResizableNeighbor $w $id left] if {$lid == ""} return set drag(leftFrame) $widgets(frame$lid) set drag(rightFrame) $widgets(frame$id) set drag(leftListbox) $widgets(listbox$lid) set drag(rightListbox) $widgets(listbox$id) set rrid [lsearch -exact $misc(columns) $id] } else { set rid [::mclistbox::FindResizableNeighbor $w $id right] if {$rid == ""} return set drag(leftFrame) $widgets(frame$id) set drag(rightFrame) $widgets(frame$rid) set drag(leftListbox) $widgets(listbox$id) set drag(rightListbox) $widgets(listbox$rid) set rrid [lsearch -exact $misc(columns) $rid] } if {$options(-resizeonecolumn)} { for {set lastid [expr [llength $misc(columns)] - 1]} \ {$lastid >= $rrid} {incr $lastid -1} { set col [lindex $misc(columns) $lastid] if {![ColumnIsHidden $w $col] && $options($col:-resizable)} { break } } set drag(rightFrame) $widgets(frame$col) set drag(rightListbox) $widgets(listbox$col) } set drag(leftWidth) [winfo width $drag(leftFrame)] set drag(rightWidth) [winfo width $drag(rightFrame)] # it seems to be a fact that windows can never be # less than one pixel wide. So subtract that one pixel # from our max deltas... set drag(maxDelta) [expr {$drag(rightWidth) - 1}] set drag(minDelta) -[expr {$drag(leftWidth) - 1}] set drag(x) $X } } motion { if {[info exists drag(x)]} {return} # this is just waaaaay too much work for a motion # event, IMO. set resizable 0 # is the column the user is over resizable? if {!$options($id:-resizable)} {return} # did the user click on the left of a column? if {$x < $threshold} { set leftColumn [::mclistbox::FindResizableNeighbor $w $id left] if {$leftColumn != ""} { set resizable 1 } } elseif {$x > [winfo width $widget] - $threshold} { set rightColumn [::mclistbox::FindResizableNeighbor $w $id \ right] if {$rightColumn != ""} { set resizable 1 } } # if it's resizable, change the cursor set cursor [$widgets(label$id) cget -cursor] if {$resizable && $cursor != $resizeCursor} { $widgets(label$id) configure -cursor $resizeCursor $widgets(label$id) configure \ -background $options(-labelbackground) \ -foreground $options(-labelforeground) } elseif {!$resizable} { $widgets(label$id) configure \ -background $options(-labelactivebackground) \ -foreground $options(-labelactiveforeground) if {$cursor == $resizeCursor} { $widgets(label$id) configure -cursor $options(-cursor) } } } leave { $widgets(label$id) configure \ -background $options(-labelbackground) \ -foreground $options(-labelforeground) } drag { # if the state is set up, do the drag... if {[info exists drag(x)]} { if {$options(-resizeonecolumn)} { set delta [expr {$X - $drag(x)}] if {$delta <= $drag(minDelta)} { set delta $drag(minDelta) } set lwidth [expr {$drag(leftWidth) + $delta}] set rwidth [expr {$drag(rightWidth) - $delta}] $drag(leftFrame) configure -width $lwidth if {$misc(min-$drag(rightFrame)) < $rwidth} { $drag(rightFrame) configure -width $rwidth } set misc(min-$drag(leftFrame)) $lwidth AdjustColumns $w } else { set delta [expr {$X - $drag(x)}] if {$delta >= $drag(maxDelta)} { set delta $drag(maxDelta) } elseif {$delta <= $drag(minDelta)} { set delta $drag(minDelta) } set lwidth [expr {$drag(leftWidth) + $delta}] set rwidth [expr {$drag(rightWidth) - $delta}] $drag(leftFrame) configure -width $lwidth $drag(rightFrame) configure -width $rwidth } } } buttonrelease { set fillColumnID $options(-fillcolumn) if {[info exists drag(x)] && $fillColumnID != {}} { set fillColumnFrame $widgets(frame$fillColumnID) if {[string compare $drag(leftFrame) $fillColumnFrame] == 0 \ || [string compare $drag(rightFrame) $fillColumnFrame] == 0} { set width [$fillColumnFrame cget -width] set misc(minFillColumnSize) $width } set misc(min-$drag(leftFrame)) [$drag(leftFrame) cget -width] if {!$options(-resizeonecolumn)} { set misc(min-$drag(rightFrame)) [$drag(rightFrame) cget -width] } } # reset the state and the cursor catch {unset drag} $widgets(label$id) configure -cursor $options(-cursor) } } } # end of mclistbox.tcl tkabber-0.11.1/roster.tcl0000644000175000017500000004661711037425055014564 0ustar sergeisergei# $Id: roster.tcl 1477 2008-07-16 17:04:45Z sergei $ namespace eval roster { variable undef_group_name [::msgcat::mc "Undefined"] variable chats_group_name [::msgcat::mc "Active Chats"] variable own_resources_group_name [::msgcat::mc "My Resources"] } proc roster::process_item {connid jid name groups subsc ask} { variable roster variable undef_group_name variable chats_group_name variable own_resources_group_name debugmsg roster "ROSTER_ITEM: $connid; $jid; $name; $groups; $subsc; $ask" set jid [tolower_node_and_domain $jid] if {$subsc != "remove"} { if {![lcontain $roster(jids,$connid) $jid]} { lappend roster(jids,$connid) $jid } set groups [lrmdups $groups] foreach group [list "" $undef_group_name $chats_group_name $own_resources_group_name] { set ind [lsearch -exact $groups $group] if {$ind >= 0} { set groups [lreplace $groups $ind $ind] } } set roster(group,$connid,$jid) $groups set roster(name,$connid,$jid) $name set roster(subsc,$connid,$jid) $subsc set roster(ask,$connid,$jid) $ask catch {unset roster(cached_category_and_subtype,$connid,$jid)} get_category_and_subtype $connid $jid } else { lvarpop roster(jids,$connid) [lsearch -exact $roster(jids,$connid) $jid] catch {unset roster(group,$connid,$jid)} catch {unset roster(name,$connid,$jid)} catch {unset roster(subsc,$connid,$jid)} catch {unset roster(ask,$connid,$jid)} catch {unset roster(cached_category_and_subtype,$connid,$jid)} } } hook::add roster_item_hook [namespace current]::roster::process_item hook::add roster_push_hook [namespace current]::roster::process_item proc client:roster_item {connid jid name groups subsc ask} { hook::run roster_item_hook $connid $jid $name $groups $subsc $ask } proc client:roster_push {connid jid name groups subsc ask} { hook::run roster_push_hook $connid $jid $name $groups $subsc $ask ::redraw_roster } proc client:roster_cmd {connid status} { debugmsg roster "ROSTER_CMD: $status" if {[cequal $status END_ROSTER]} { hook::run roster_end_hook $connid ::redraw_roster } } proc roster::request_roster {connid} { variable roster set roster(jids,$connid) {} jlib::roster_get -command client:roster_cmd -connection $connid } hook::add connected_hook [namespace current]::roster::request_roster 15 proc roster::get_group_jids {connid group args} { variable roster variable undef_group_name if {![info exists roster(jids,$connid)]} { return {} } set nested 0 set delim "::" foreach {opt val} $args { switch -- $opt { -nested { set nested $val } -delimiter { set delim $val } } } set jids {} if {[cequal $group $undef_group_name]} { foreach jid $roster(jids,$connid) { if {[lempty [::roster::itemconfig $connid $jid -group]]} { lappend jids $jid } } } else { foreach jid $roster(jids,$connid) { foreach jgroup [::roster::itemconfig $connid $jid -group] { if {($nested && \ [string first "$group$delim" "$jgroup$delim"] == 0) || \ [cequal $group $jgroup]} { lappend jids $jid break } } } } return $jids } proc roster::get_jids {connid} { variable roster if {[info exists roster(jids,$connid)]} { return [lsort -dictionary $roster(jids,$connid)] } else { return {} } } proc roster::get_groups {connid args} { variable roster variable undef_group_name if {![info exists roster(jids,$connid)]} { return {} } set nested 0 set delimiter "::" set undefined 0 set groups {} foreach {opt val} $args { switch -- $opt { -nested { set nested $val } -delimiter { set delimiter $val } -raw { if {$val} { foreach jid $roster(jids,$connid) { set groups [concat $groups $roster(group,$connid,$jid)] } return [lrmdups $groups] } } -undefined { set undefined $val } } } set empty 0 foreach jid $roster(jids,$connid) { set jid_groups [::roster::itemconfig $connid $jid -group] if {![lempty $jid_groups]} { foreach group $jid_groups { if {$nested} { set sgroup [msplit $group $delimiter] } else { set sgroup [list $group] } set deep [llength $sgroup] for {set i 0} {$i < $deep} {incr i} { set sgr [lrange $sgroup 0 $i] lappend groups [join $sgr "\u0000"] } } } else { set empty 1 } } set res {} foreach sgroup [lsort -unique -dictionary $groups] { lappend res [join [split $sgroup "\u0000"] $delimiter] } if {$empty && $undefined} { lappend res $undef_group_name } return $res } proc roster::itemconfig {connid jid args} { variable roster if {[llength $args] == 1} { lassign $args attr switch -- $attr { -group {set param group} -name {set param name} -subsc {set param subsc} -ask {set param ask} -category { return [lindex [get_category_and_subtype $connid $jid] 0] } -subtype { return [lindex [get_category_and_subtype $connid $jid] 1] } -isuser { return [cequal [lindex [get_category_and_subtype $connid $jid] 0] "user"] } default { return -code error "Bad option \"$attr\":\ must be one of: -group, -name, -subsc, -ask,\ -category, -subtype or -isuser" } } if {[info exists roster($param,$connid,$jid)]} { return $roster($param,$connid,$jid) } else { return "" } } else { foreach {attr val} $args { switch -- $attr { -group {set param group} -name {set param name} -subsc {set param subsc} -ask {set param ask} -category { override_category $connid $jid $val continue } -subtype { override_subtype $connid $jid $val continue } default {return -code error "Illegal option"} } set roster($param,$connid,$jid) $val } } } # Returns true if $jid is allowed to receive our presence information, # false otherwise. proc roster::is_trusted {connid jid} { set subsc [itemconfig $connid [find_jid $connid $jid] -subsc] if {[node_and_server_from_jid $jid] == [jlib::connection_bare_jid $connid]} { return 1 } elseif {$subsc == "both" || $subsc == "from"} { return 1 } else { return 0 } } proc roster::on_change_jid_presence {connid jid type x args} { variable roster switch -- $type { error - unavailable - available {} default { return } } set rjid [find_jid $connid $jid] debugmsg roster "$jid $rjid" if {$rjid != ""} { lassign [get_category_and_subtype $connid $rjid] category subtype if {$category == "user"} { set status [get_user_status $connid $rjid] set label [get_label $connid $rjid] if {![catch {set desc [::get_long_status_desc $status]}]} { set_status [format "%s $desc" $label] } hook::run on_change_user_presence_hook $label $status } } ::redraw_roster } hook::add client_presence_hook roster::on_change_jid_presence 60 proc roster::find_jid {connid jid} { variable roster if {![info exists roster(jids,$connid)]} { return "" } if {[lsearch -exact $roster(jids,$connid) $jid] >= 0} { return $jid } lassign [get_category_and_subtype $connid $jid] category subtype if {$category == "user"} { set rjid [node_and_server_from_jid $jid] if {[lsearch -exact $roster(jids,$connid) $rjid] >= 0} { lassign [get_category_and_subtype $connid $rjid] rcategory rsubtype if {$category == $rcategory} { return $rjid } } } return "" } proc roster::get_label {connid jid} { set name [itemconfig $connid $jid -name] if {[string equal $name ""]} { return $jid } else { return $name } } proc roster::override_category_and_subtype {connid jid category subtype} { variable roster set roster(overridden_category_and_subtype,$connid,$jid) \ [list $category $subtype] } proc roster::override_category {connid jid category} { variable roster if {![info exists roster(overridden_category_and_subtype,$connid,$jid)]} { lassign [get_category_and_subtype $connid $jid] category1 subtype set roster(overridden_category_and_subtype,$connid,$jid) \ [list $category $subtype] } else { set roster(overridden_category_and_subtype,$connid,$jid) \ [list $category \ [lindex \ $roster(overridden_category_and_subtype,$connid,$jid) 1]] } } proc roster::override_subtype {connid jid subtype} { variable roster if {![info exists roster(overridden_category_and_subtype,$connid,$jid)]} { lassign [get_category_and_subtype $connid $jid] category subtype1 set roster(overridden_category_and_subtype,$connid,$jid) \ [list $category $subtype] } else { set roster(overridden_category_and_subtype,$connid,$jid) \ [list [lindex \ $roster(overridden_category_and_subtype,$connid,$jid) 0] \ $subtype] } } proc roster::get_category_and_subtype {connid jid} { variable roster if {[info exists roster(overridden_category_and_subtype,$connid,$jid)]} { return $roster(overridden_category_and_subtype,$connid,$jid) } set server [server_from_jid $jid] if {[info exists roster(overridden_category_and_subtype,$connid,$server)]} { catch { unset roster(cached_category_and_subtype,$connid,$jid) } set cs [heuristically_get_category_and_subtype $connid $jid] set roster(overridden_category_and_subtype,$connid,$jid) $cs return $cs } if {[info exists roster(cached_category_and_subtype,$connid,$jid)]} { return $roster(cached_category_and_subtype,$connid,$jid) } catch { plugins::cache_categories::request_category_and_subtype $connid $jid } set cs [heuristically_get_category_and_subtype $connid $jid] set roster(cached_category_and_subtype,$connid,$jid) $cs return $cs } proc roster::heuristically_get_category_and_subtype {connid jid} { variable roster set node [node_from_jid $jid] set server [server_from_jid $jid] set resource [resource_from_jid $jid] if {$node == "" && $resource == ""} { set updomain [lindex [split $server .] 0] set category service switch -- $updomain { aim - icq - irc - jabber - jud - msn - mrim - pager - rss - serverlist - sms - smtp - yahoo { set subtype $updomain } gg { set subtype gadu-gadu } pogoda - weather { set subtype x-weather } default { set subtype "" } } return [list $category $subtype] } if {$node == ""} { return [get_category_and_subtype $connid $server] } if {[resource_from_jid $jid] == ""} { lassign [get_category_and_subtype $connid $server] scategory ssubtype switch -glob -- $scategory/$ssubtype { conference/irc { if {[string first "%" $node] >= 0} { set category conference set subtype irc } else { set category user set subtype "" } } conference/* { set category conference set subtype "" } default { set category user set subtype "" } } return [list $category $subtype] } return {user client} } proc roster::clean {} { variable roster array unset roster jids,* array unset roster group,* array unset roster name,* array unset roster subsc,* array unset roster ask,* array unset roster subtype,* array unset roster cached_category_and_subtype,* array unset roster overridden_category_and_subtype,* ::redraw_roster } proc roster::clean_connection {connid} { variable roster array unset roster jids,$connid array unset roster group,$connid,* array unset roster name,$connid,* array unset roster subsc,$connid,* array unset roster ask,$connid,* array unset roster subtype,$connid,* array unset roster cached_category_and_subtype,$connid,* array unset roster overridden_category_and_subtype,$connid,* ::redraw_roster } ############################################################################### proc roster::item_to_xml {connid jid} { variable roster variable undef_group_name variable chats_group_name variable own_resources_group_name set grtags {} foreach group $roster(group,$connid,$jid) { if {![cequal $group ""] && \ ![cequal $group $undef_group_name] && \ ![cequal $group $chats_group_name] && \ ![cequal $group $own_resources_group_name]} { lappend grtags [jlib::wrapper:createtag group -chdata $group] } } set vars [list jid $jid] if {$roster(name,$connid,$jid) != ""} { lappend vars name $roster(name,$connid,$jid) } return [jlib::wrapper:createtag item -vars $vars -subtags $grtags] } ############################################################################### proc roster::send_item {connid jid} { hook::run roster_send_item_hook $connid $jid } proc roster::send_item_fallback {connid jid} { jlib::send_iq set \ [jlib::wrapper:createtag query \ -vars {xmlns jabber:iq:roster} \ -subtags [list [roster::item_to_xml $connid $jid]]] \ -connection $connid } hook::add roster_send_item_hook roster::send_item_fallback 100 ############################################################################### proc roster::remove_item {connid jid} { hook::run roster_remove_item_hook $connid $jid } proc roster::remove_item_fallback {connid jid} { jlib::send_iq set \ [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(roster)] \ -subtags [list [jlib::wrapper:createtag item \ -vars [list jid $jid \ subscription remove]]]] \ -connection $connid jlib::send_presence -to $jid -type unsubscribe -connection $connid jlib::send_presence -to $jid -type unsubscribed -connection $connid lassign [get_category_and_subtype $connid $jid] category subtype if {(($category == "service") || \ ($category == "server") || \ ($category == "gateway")) && \ [string compare -nocase [node_and_server_from_jid $jid] \ [jlib::connection_server $connid]]} { jlib::send_iq set \ [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(register)] \ -subtags [list [jlib::wrapper:createtag remove]]] \ -to $jid \ -connection $connid } } hook::add roster_remove_item_hook roster::remove_item_fallback 100 ############################################################################### proc roster::send_rename_group {connid name new_name} { variable roster variable undef_group_name if {[string equal $new_name $name]} return hook::run roster_rename_group_hook $connid $name $new_name set items {} foreach jid $roster(jids,$connid) { switch -- [itemconfig $connid $jid -subsc] { none - from - to - both { } default { continue } } if {[lcontain $roster(group,$connid,$jid) $name] || \ ($name == $undef_group_name && \ $roster(group,$connid,$jid) == {})} { set idx [lsearch -exact $roster(group,$connid,$jid) $name] if {$new_name != ""} { set roster(group,$connid,$jid) \ [lreplace $roster(group,$connid,$jid) $idx $idx $new_name] } else { set roster(group,$connid,$jid) \ [lreplace $roster(group,$connid,$jid) $idx $idx] } set roster(group,$connid,$jid) [lrmdups $roster(group,$connid,$jid)] lappend items [item_to_xml $connid $jid] } } if {$items != {}} { jlib::send_iq set \ [jlib::wrapper:createtag query \ -vars {xmlns jabber:iq:roster} \ -subtags $items] \ -connection $connid } } ############################################################################### proc roster::send_remove_users_group {connid name} { variable roster variable undef_group_name hook::run roster_remove_users_group_hook $connid $name set items {} foreach jid $roster(jids,$connid) { switch -- [itemconfig $connid $jid -subsc] { none - from - to - both { } default { continue } } set groups $roster(group,$connid,$jid) if {(([llength $groups] == 1) && [lcontain $groups $name]) || \ (($name == $undef_group_name) && ($groups == {}))} { remove_item $connid $jid } elseif {[lcontain $groups $name]} { set idx [lsearch -exact $groups $name] set roster(group,$connid,$jid) [lreplace $groups $idx $idx] lappend items [item_to_xml $connid $jid] } } if {$items != {}} { jlib::send_iq set \ [jlib::wrapper:createtag query \ -vars {xmlns jabber:iq:roster} \ -subtags $items] \ -connection $connid } } ############################################################################### proc roster::resubscribe_group {connid name} { variable roster variable undef_group_name foreach jid $roster(jids,$connid) { if {[lcontain $roster(group,$connid,$jid) $name] || \ ($name == $undef_group_name && \ $roster(group,$connid,$jid) == {})} { lassign [get_category_and_subtype $connid $jid] category type if {$category == "user"} { jlib::send_presence \ -to $jid \ -connection $connid \ -type subscribe } } } } ############################################################################### proc roster::send_custom_presence_group {connid name status} { variable roster variable undef_group_name foreach jid $roster(jids,$connid) { if {[lcontain $roster(group,$connid,$jid) $name] || \ ($name == $undef_group_name && \ $roster(group,$connid,$jid) == {})} { lassign [get_category_and_subtype $connid $jid] category type if {$category == "user"} { send_custom_presence $jid $status -connection $connid } } } } ############################################################################### proc roster::add_group_by_jid_regexp {name regexp} { variable roster # TODO: connid if {$name == ""} return foreach connid [jlib::connections] { set items {} foreach jid $roster(jids,$connid) { if {[regexp -- $regexp $jid]} { set idx [lsearch -exact $roster(group,$connid,$jid) $name] lappend roster(group,$connid,$jid) $name set roster(group,$connid,$jid) \ [lrmdups $roster(group,$connid,$jid)] lappend items [item_to_xml $connid $jid] } } if {$items != {}} { jlib::send_iq set \ [jlib::wrapper:createtag query \ -vars {xmlns jabber:iq:roster} \ -subtags $items] \ -connection $connid } } } ############################################################################### proc roster::export_to_file {connid} { variable roster set filename [tk_getSaveFile \ -initialdir $::configdir \ -initialfile [jlib::connection_user $connid].roster \ -filetypes [list \ [list [::msgcat::mc "Roster Files"] \ .roster] \ [list [::msgcat::mc "All Files"] *]]] if {$filename != ""} { set items {} foreach jid $roster(jids,$connid) { lappend items [item_to_xml $connid $jid] } set fd [open $filename w] fconfigure $fd -encoding utf-8 puts $fd $items close $fd } } proc roster::import_from_file {connid} { variable roster set filename [tk_getOpenFile \ -initialdir $::configdir \ -initialfile [jlib::connection_user $connid].roster \ -filetypes [list \ [list [::msgcat::mc "Roster Files"] \ .roster] \ [list [::msgcat::mc "All Files"] *]]] if {$filename != ""} { set fd [open $filename r] fconfigure $fd -encoding utf-8 set items [read $fd] close $fd if {$items != {}} { jlib::send_iq set \ [jlib::wrapper:createtag query \ -vars [list xmlns "jabber:iq:roster"] \ -subtags $items] \ -connection $connid } } } ############################################################################### # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/doc/0000755000175000017500000000000011076120366013271 5ustar sergeisergeitkabber-0.11.1/doc/tkabber.html0000644000175000017500000040010511076045704015573 0ustar sergeisergei Tkabber 0.11.1
 TOC 
A. Shchepin
 Process-One
 M. Rose
 Dover Beach Consulting, Inc.
 S. Golovan
 New Economic School
 M. Litvak
 Colocall Ltd.
 K. Khomoutov
 Service 007
 June 2008

Tkabber 0.11.1

Abstract

Tkabber is an open source Jabber client, written in Tcl/Tk. This memo describes the installation, configuration, and extension of Tkabber.



Table of Contents

1.  Features
2.  Requirements
3.  Download, install and run
4.  Upgrading from version 0.10.0
    4.1.  Configuration options
        4.1.1.  Proxy servers
        4.1.2.  Resources to control fonts
        4.1.3.  Keep-alives and dead link detection
        4.1.4.  Resources to control appearance of balloon windows
        4.1.5.  Support for external XML parser
    4.2.  User interface
        4.2.1.  System tray icon mouse gestures
        4.2.2.  New tab management widget
        4.2.3.  Window splitters
5.  Upgrading from version 0.9.9
6.  Configuration
    6.1.  Pre-load
        6.1.1.  Tabbed Interface
        6.1.2.  Fonts and colors
        6.1.3.  Cryptography by default
        6.1.4.  Using of external XML parser from tDOM
        6.1.5.  Debugging Output
        6.1.6.  Splash window
        6.1.7.  I18n/L10n
        6.1.8.  Searching
    6.2.  Post-load
        6.2.1.  Look-and-Feel
        6.2.2.  The Autoaway Module
        6.2.3.  The Avatar Module
        6.2.4.  The Chat Module
        6.2.5.  The Clientinfo Module
        6.2.6.  The Conferenceinfo Module
        6.2.7.  The Cryptographic Module
        6.2.8.  The Emoticons Module
        6.2.9.  The File Transfer Module
        6.2.10.  The Groupchat Module
        6.2.11.  The Ispell Module
        6.2.12.  The Stream Initiation Module
        6.2.13.  The Logger Module
        6.2.14.  The Login Module
        6.2.15.  The Message Module
        6.2.16.  The Raw XML Input Module
        6.2.17.  The Roster Module
        6.2.18.  The Sound Module
    6.3.  Menu-load
        6.3.1.  The Avatar Module
        6.3.2.  The Browser Module
        6.3.3.  The Groupchat Module
        6.3.4.  The Login Module
        6.3.5.  The Message Module
        6.3.6.  The Presence Module
        6.3.7.  Miscellany
    6.4.  Final-Load
7.  Extensibility
    7.1.  Chat Hooks
    7.2.  Login Hooks
    7.3.  Presence Hooks
    7.4.  Roster Hooks
    7.5.  Miscellaneous Hooks
8.  User Interface basics
    8.1.  Searching
Appendix A.  Releases History
    A.1.  Main changes in 0.11.1
    A.2.  Main changes in 0.11.0
    A.3.  Main changes in 0.10.0
    A.4.  Main changes in 0.9.9
    A.5.  Main changes in 0.9.8
    A.6.  Main changes in 0.9.7beta
    A.7.  Main changes in 0.9.6beta
    A.8.  Main changes in 0.9.5beta
Appendix B.  Tk option database resources
Appendix C.  Documentation TODO
Appendix D.  Acknowledgements
Appendix E.  Copyrights
§  Authors' Addresses




 TOC 

1. Features

Tkabber provides a Tcl/Tk interface to the Jabber/XMPP instant messaging and presence service.

Tcl/Tk is a graphical scripting language that runs on the Unix, Windows, and Macintosh platforms. The choice of Tcl/Tk for a Jabber client is three-fold:

  • it is portable: once you install a Tcl/Tk interpreter on your system, the Tkabber script "just runs" — without having to compile anything;
  • it is customizable: Tkabber reads a configuration file when it starts that tells it the settings of various parameters; and,
  • it is extensible: the configuration file is actually a Tcl script, so you can replace or augment entire portions of Tkabber (if you're so inclined).

Tkabber is fully-featured:

sessions:
  • TCP and HTTP-polling session transports
  • XMPP SRV and TXT DNS-records handling
  • hashed passwords
  • SASL authentication
  • encrypted sessions (if you install an optional extension)
  • compressed sessions (if you install an optional extension)
  • login via SOCKS4a, SOCKS5 or HTTPS proxy
  • user-defined hooks for connection establishment and release
  • XMPP/Jabber MIME type
messages:
  • privacy rules
  • signed/encrypted messages (if you install an optional extension)
  • file transfers (HTTP, SOCKS bytestream, DTCP and IBB transports)
  • groupchat (GroupChat-1.0 and Multi-User Chat conferencing protocols)
  • headline messages
  • message events
  • completions of nick and commands
  • hyperlinks
  • emoticons
  • user-defined hooks for chat window events
presence:
  • signed presence (if you install an optional extension)
  • avatars
  • browsing
  • groupchat and roster invitations
  • conference room bookmarks
  • annotations about roster items
  • vCards
  • user-defined hooks for presence changes
windowing:
  • configurable look-and-feel via a resources database
  • unicode
  • tabbed/non-tabbed interface
  • sound notifications
  • nested roster groups
  • for Unix: auto-away, spell checking, KDE or freedesktop docking, and WMaker icons
  • for Windows: auto-away, and taskbar icons



 TOC 

2. Requirements

You should already have installed:

Most systems already come with these packages pre-installed. If not, various Unix systems have them available as ready-made packages. Otherwise, go to the URLs above and click on the appropriate download link for your system. Both tcllib and BWidget are script libraries — no compiling is necessary. In the case of Tcl/Tk, there are many ready-made binary packages available on the download site.

The ActiveTcl distribution contains all three packages (along with the Img package mentioned next); so, you may want to use that instead of three separate downloads.

At your discretion, there are several optional packages that you may also install. Tkabber will run just fine without them, but if they're available Tkabber will make additional features available to you. So, here's the list:

  • Tcl/Tk supports only a small number of image formats (i.e., bitmaps, GIFs and portable pixmaps). If presence information contains avatars, these may be in other formats (e.g., PNGs or JPGs).
    Accordingly, you may want to install Img version 1.2 (or later). This package works on both Unix and Windows.


  • By default, Tkabber uses pure-Tcl XML parser. If its performance is insufficient, you may want to install tDOM version 0.8.0 (or later) and use expat based XML parser.
  • By default, communications between the server and client take place over a plaintext connection. While this may not be a problem in some local, wired environments, if your server is distant or your client is wireless, then you may want to encrypt all the client/server traffic.
    Accordingly, you may to install tls version 1.4.1 (or later). This package works on both Unix and Windows. Note that if you're using Unix, then you'll also need to have OpenSSL installed. Fortunately, this comes preinstalled on many Unix systems. If it's not on your system, check OpenSSL source page. (The Windows distribution of tls comes with all the necessary DLLs.)


  • Another option in Unix is to compress connection between client and server (it currently disables encryption).
    If you want to compress traffic you should install ZTcl version 1.0b4 (or later) and Tclmore version 0.7b1 (or later).
    (At the time of 0.11.0 release ZTcl and Tclmore home page were unavailable, so you may grab them from a mirror.)


  • By default, end-to-end communications between two or more Jabber clients is plaintext. Depending on your environment, this may not be a problem for you. Alternatively, you may want to digitally-sign all of your outgoing messages, and allow others to encrypt their messages to you.
    Accordingly, you may want to install the gpgme package, which, at present, works only on Unix. Depending on what's already installed on your system, you may have to download upto three files:


  • If you're running Unix or Windows, then you may want Tkabber to automatically mark you as away after a priod of inactivity.
    Accordingly (if you're using Tcl/Tk 8.3 or 8.4), on Unix, you may want to install Tk Xwin version 1.0 (or later), whilst on WIndows, you may want to install Tcl Winidle version 0.1 (or later).
  • Users of Tcl/Tk 8.5 don't have to use external packages to measure their idle time.


  • If you're running Unix, then you may want Tkabber to use the docking tray.
    Accordingly, you may want to install Tk Theme version 1.20 (or later) for KDE icon, or tktray version 1.1 (or later) for freedesktop icon (supported by modern KDE and GNOME).


  • If you're running Windows, then you may want Tkabber to use the system tray.
    Accordingly, you may want to install Winico version 0.6 (or later).


  • If you're a Tcl/Tk guru, then you may want to access the Tk console to debug things.
    Accordingly, you may want to install tkcon version 2.3 (or later).

Please keep in mind that these are all "optional extras" — if they're not right for you or your environment, don't bother with them!



 TOC 

3. Download, install and run

Latest stable version is 0.11.1 and available at http://tkabber.jabber.ru/download.

Older versions can be found at http://files.jabber.ru/tkabber/.

You can always find the latest development version via SVN. Execute the following command:

svn co https://svn.xmpp.ru/repos/tkabber/trunk/tkabber

And if you want to test some plugins, then do

svn co https://svn.xmpp.ru/repos/tkabber/trunk/tkabber-plugins

If you use the Debian GNU/Linux distribution, you may want to get all required packages by using apt. Just execute

apt-get install tk tcllib bwidget

or

apt-get install tkabber

to get the version included into Debian repository.

No real installation is required, simply copy the tkabber/ directory to a commonly-available area, and then either:

  • put this directory in your search-path; or,
  • make a calling script/shortcut to the file tkabber.tcl in that directory.

Although Tkabber comes with a Makefile, there's really not much to do — most folks prefer to simply copy the distribution directory to somewhere in their home directory.

From the shell, you can invoke Tkabber as:

% tkabber.tcl

whilst on a windowing system, simply double-click on that file or a short-cut to it.

If you're a Tcl/Tk guru and have installed tkcon, then you may want to invoke Tkabber as:

% tkcon.tcl -exec "" -root .tkconn -main "source tkabber.tcl"

Tkabber will automatically know that it's running under tkcon and will start by hiding the Tk console window. Look under the Help menu to find the checkbutton to show the console.

Also you can setup Tkabber as handler for XMPP/Jabber MIME Type. For this you need to set hanler for application/xmpp+xml MIME type in your browser to something like this:

tkabber -mime %s


 TOC 

4. Upgrading from version 0.10.0

When upgrading Tkabber from version 0.10.0 or earlier note that several configuration options and user interface elements have been changed.



 TOC 

4.1. Configuration options

There are notable changes in handling connection through proxy servers, managing fonts and balloon colors, and detecting breaks in underlying TCP connection to a server.



 TOC 

4.1.1. Proxy servers

Since SOCKS4 and SOCKS5 proxy types were implemented in addition to HTTP proxy type, the whole set of connection options regarding proxy servers has been changed. This means that after upgrade the old values stored using the Customize mechanism will be lost and the same values in loginconf arrays will not be recognized any longer.

If you do not use HTTP proxy, you can skip this section because these changes will not affect you.

If your options are set using the Customize interface, write down values for options relevant to proxy server from the "Login" group of Customize settings, then after upgrade visit this group of settings, select "HTTPS" for the option ::loginconf(proxy) and then fill in the rest of relevant settings with recorded values. As usual, save each setting after you change them. Do not be surprised with the word "HTTPS" (which stands for "HTTP over SSL"). It just means that Tkabber will use CONNECT method to tunnel TCP connection through a proxy.

If you maintain loginconf arrays in config.tcl, you have to modify each array using this scheme:

  • Rename variable "useproxy", if present, to just "proxy" and change its value to either "https" if "useproxy" was set to true or to "none" (yes, the word "none", do not leave it empty) if it was set to false.
  • Modify existing variables in these arrays using this map:
    • Rename "httpproxy" to "proxyhost".
    • Rename "httpport" to "proxyport".
    • Rename "httplogin" to "proxyusername".
    • Rename "httppassword" to "proxypassword".



 TOC 

4.1.2. Resources to control fonts

Fonts handling has been partially reworked: the global variable font that controls chat and roster fonts has been removed and now Tkabber relies on Tk option database to manage these settings. You can override roster and chat fonts independently of each other. To do that on systems not based on X Window use Customize options described below.

The main consequence of this change is that now the fonts are taken from Tk option database and if it contains sane values you don't need to touch anything (until the update you had to tweak the font variable because it was set to font "fixed" by default). The variable font does not have any special meaning starting from 0.11.0 release.

The second consequence is that you are now able to set fonts for chat and roster windows separately from each other using this list as a reference:

  • *font Tk option database resource sets default font for all widgets used in Tkabber.
  • *Chat*Text.font Tk option database resource can be used to override font used for chat windows. This resource can be overridden by the ::ifacetk::options(font) option from the "Main Interface" group of Customize settings.
  • *Roster*font Tk option database resource can be used to override font used for roster windows. This resource can be overridden by the ::ifacetk::options(roster_font) option from the "Main Interface" group of Customize settings.



 TOC 

4.1.3. Keep-alives and dead link detection

Keep-alive mechanism that was used to keep NATP devices from disconnecting idle XMPP sessions was accompanied in 0.10.0 with "XMPP ping" mechanism which also implemented dead link detection with support for disconnecting upon detection of network outage.

In version 0.11.0, the old keep-alive mechanism has been dropped, so the following two global options have no effect now:

  • keep_alive
  • keep_alive_interval

In order to get the same functionality, enable XMPP ping using these options in the "IQ" group of Customize settings:

  • Enabling ::plugins::ping::options(ping) will make Tkabber periodically send xmpp:ping IQ request to the server.
  • Set ::plugins::ping::options(timeout) option to a number of seconds Tkabber should wait for either a xmpp:ping reply or an error to arrive from the server; if there is no answer from the server during this timeout, the socket for this connection will be forcibly disconnected.



 TOC 

4.1.4. Resources to control appearance of balloon windows

Resources controlling the appearance of balloon windows have been made more generic. If you use custom Tk option database settings for balloon windows, change the relevant resources using this map:

  • Change references to *Balloon.background and *Balloon.foreground resources to *Balloon*background and *Balloon*foreground, respectively.
  • Change references to *Balloon*padX and *Balloon*padY resources to *Balloon.text.padX and *Balloon.text.padY, respectively.



 TOC 

4.1.5. Support for external XML parser

Support for TclXML as an external XML parser has been removed (since TclXML has anyway been unable to support partial XML processing) along with the global variable use_external_tclxml which controlled the loading of TclXML.

Now expat-based Tcl package tDOM is supported as an external XML parser. It can be enabled by loading it manually in config.tcl using the Tcl package command, for example:

package require tdom


 TOC 

4.2. User interface

There are notable changes in systray mouse gestures, appearance of a main tabbed window, and in behavior of paned window splitters.



 TOC 

4.2.1. System tray icon mouse gestures

Mouse gestures bound to system tray (system notification area) icon have been reworked:

  • Single click on it with the left mouse button now unconditionally brings the main Tkabber window to front, possibly deiconifying it first.
  • Single click with the middle mouse button now unconditionally iconifies the main Tkabber window.

This differs from the previois behaviour where single click with the left mouse button on Tkabber's system tray icon toggled the iconified/visible state of the main Tkabber window.



 TOC 

4.2.2. New tab management widget

The notebook widget which was used to render tabs in tabbed interface mode has been replaced with a new custom widget providing the ability for multi-row placement of tabs and docking them to the left or right sides of the chat window (in addition to top or bottom docking available in 0.10.0 version and earlier).

If you adjusted any specific Tk option database resources pertaining to that notebook widget, you have to change them keeping in mind that the new widget is just a bunch of Tk buttons (class Button) placed in a frame (called .nb as before). The class name for the new widget is ButtonBar.

So if you explicitly set, say *Notebook*font option, you have to change it to *ButtonBar*font and so on.



 TOC 

4.2.3. Window splitters

Window splitters (thin vertical and horizontal windows used to change relative sizes of windows between which a splitter is placed) have been changed to "Windows" style. This differs from previous "Motif" style which implemented explicit "grip box" on each splitter which was the only "active point" of a splitter.



 TOC 

5. Upgrading from version 0.9.9

When upgrading Tkabber from version 0.9.9 or earlier note the following:

  • On Macintosh or Microsoft Windows Tkabber will copy it's configuration directory to a new location (see the next section (Configuration) for details). If the transfer of the config directory goes smoothly you may delete old "~/.tkabber" directory and replace its name in your config file by $::configdir.
  • Also, Tkabber will convert chatlogs directory to a new format.
  • Also, Tkabber changed the way it works with emoticons. Instead of loading them in config file you may put you faivorite emoticons directory into $::configdir/plugins directory, restart Tkabber and then choose emoticons set using Customize GUI.



 TOC 

6. Configuration

Tkabber maintains its configuration using a set of files placed in a special configuration directory which location depends on the operating system Tkabber runs on. These locations are:

  • Unix systems: "~/.tkabber";
  • Macintosh: "~/Library/Application Support/Tkabber";
  • Under Microsoft Windows this location is governed by the policy of the particular flavor of this OS, but the general rule is that the Tkabber configuration directory is named "Tkabber" and is located in the special system folder for storing application-specific data. For example, under Windows XP this will be something like "C:\Documents and Settings\USERNAME\Application Data\Tkabber", where "USERNAME" is the login name of a particular operating system's user.

Tkabber also honors the value of the "TKABBER_HOME" environment variable — if it exists the whole OS-based guessing of the configuration directory location is cancelled and the value of this environment variable is used instead.

Once the pathname of the Tkabber configuration directory is known, its value is assigned to the "configdir" global Tcl variable which can be accessed from within the main Tkabber configuration file (see below).

One of the first things that Tkabber does when it's starting up is reading a file located in its configuration directory under the name "config.tcl". This is a Tcl source file, so obviously, it's a lot easier to maintain this file if you know the Tcl programming language. If you're not familiar with it, that's okay — most things you'll need to do are pretty simple! (In fact, if you don't have your own configuration file, you'll get the vanilla Tkabber, which hopefully you'll find quite usable.)

Note that almost all Tkabber options can be cofigured using graphical interface (menu Tkabber->Customize), so editing configuration file is not strictly necessary.

Tkabber is configured in four stages:

  • in the pre-load stage, configuration options which guide the loading process are set;
  • in the post-load stage, configuration options for each module are set;
  • in the menu-load stage, the user is given an option to re-arrange Tkabber's menu bar; and,
  • the final-load stage allows any last changes to be made before the "login" dialog window is displayed to the user.

Let's look at each, in turn.



 TOC 

6.1. Pre-load

There are a few things that you may let Tkabber know immediately. These are:

# tabbed interface

set ifacetk::options(use_tabbar) 1


# primary look-and-feel

set load_default_xrdb 1

option add *font \
       "-monotype-arial-medium-r-normal-*-13-*-*-*-*-*-iso10646-1" \
       userDefault


# cryptography by default

set ssj::options(sign-traffic)    0
set ssj::options(encrypt-traffic) 0


# using of external XML parser

package require tdom 0.8


# debugging output

set debug_lvls {jlib warning}


# splash window

set show_splash_window 0


# force english labels instead of native language

::msgcat::mclocale en


 TOC 

6.1.1. Tabbed Interface

The first of these options, ifacetk::options(use_tabbar), tells Tkabber whether you want a tabbed interface or not. If not, here's what to put in your configuration file:

set ifacetk::options(use_tabbar) 0

Although Tkabber immediately applies most of its configuration changes, in order to apply changed option ifacetk::options(use_tabbar) you have to restart Tkabber. So, basically you have two options: set ifacetk::options(use_tabbar) at the beginning of your configuration file, or using graphical interface save the option and restart Tkabber.



 TOC 

6.1.2. Fonts and colors

Many aspects of the Tkabber's visual appearance such as fonts, colors and geometry of windows can be configured using the Tk option database.

The corresponding Tk's option command can be used in the Tkabber's configuration file in any acceptable way: from small tweaks to reading files containing elaborate sets of configuration commands; ready-to-use examples of such files are included in the distribution and are located under the "examples/xrdb" directory.

The Tk toolkit is able to initialize its option database from the XRDB (X Resource Database) if its availability is detected at run time. This means that any settings described here can be tuned via the standard XRDB mechanism (see man xrdb).

Beware though that the Tk's semantics of matching option specifications against the option database differ in some subtle details from that of the Xt toolkit. The most notable one is the priority of options: Tk prefers the latest option it sees, while Xt prefers "the most specific" one.

When specifying Tkabber-specific options in your XRDB file use the "Tkabber" class as the root element of the options.

See Appendix B (Tk option database resources) for a list of all the resources that you can set to control Tkabber's look-and-feel.

Probably the most commonly used way to configure Tkabber's visual appearance (especially on Windows platforms which lack XRDB mechanism) is to put all the necessary settings in some file and then ask Tk to update its option database from it, like this:

    set load_default_xrdb 0
    option readfile $::configdir/newlook.xrdb userDefault

The first line tells Tkabber not to load its default "xrdb" file, whilst the second line tells Tkabber which file to load instead. Look at the provided example "xrdb" files to get the idea about how they are organised. Of course, you can use any of that files as a template. And of course, you can simply specify any of the example files instead of your own to the option readfile command to get the provided "theme".

Alternatively, if you're a Tcl "old timer", you can always do:

    set load_default_xrdb 0
    tk_bisque

to set the palette to a pleasing color scheme. Read more about this in man palette.

You can also customize the fonts Tkabber uses to render its user interface:

    option add *font \
           "-monotype-arial-medium-r-normal-*-13-*-*-*-*-*-iso10646-1" \
           userDefault

The above setting (operating on the Tk option database) selects the font used for all UI elements like buttons and labels and roster and conversation windows. Obviously, you should choose fonts that suit your taste.

If you want to specify another font for roster labels use the following option:

    option add *Roster*font \
           "-misc-fixed-medium-r-normal-*-12-*-*-*-*-*-iso10646-1" \
           userDefault

When picking fonts, observe these rules:

  • Under X, encoding (charset) of fonts must match that of your locale.
  • Ensure that the specified font exists, since if it's not, Tk will try hard to pick the most suitable one which often yields not what you want. (The best bet is to first pick the font using some tool like xfontsel.)

Note that when specifying settings using the Tkabber's configuration files (i.e. not using XRDB directly) you are not forced to use "X-style" (XLFD) font descriptions and may instead specify fonts using sometimes more convenient Tk features described in Tk font manual page.



 TOC 

6.1.3. Cryptography by default

Next, you may want to Tkabber to use cryptography by default. There are two options:

  • whether the traffic you send should be digitally-signed; and,
  • if you have cryptographic information for someone, should the default action be to encipher your traffic for them.

(By defining these options early on, Tkabber will complain immediately if it isn't able to load its cryptographic module; otherwise, the default behavior is to proceed without any cryptographic buttons, menus, and so on.)



 TOC 

6.1.4. Using of external XML parser from tDOM

By default for parsing XML Tkabber uses (modified) TclXML library that comes with it distribution. This parser is pure-Tcl, and it performance can be not suitable. Then you can install tDOM with built-in expat support and require it in the config file:

package require tdom 0.8


 TOC 

6.1.5. Debugging Output

Tkabber has a lot of debugging output. By default, it gets printed to the standard output by a Tcl procedure called debugmsg. However, only information about those modules listed in a variable called debug_lvls will be printed.

If you know how to program Tcl, then this will seem rather obvious:

set debug_lvls [list message presence ssj warning]

# if you want a different behavior,
#     define your own...

proc debugmsg {module msg} {
#    ...
}

Most users won't care about debugmsg because they're running Tkabber under an application launcher so the standard output is never seen. However, if this isn't the case for you, and you just don't want to see any of this stuff, put this one line in your configuration file:

set debug_lvls {}


 TOC 

6.1.6. Splash window

By default, when Tkabber startup, it show loading process in splash window. To disable this feature, put this in your configuration file:

set show_splash_window 0


 TOC 

6.1.7. I18n/L10n

Tkabber can show all messages in user's native language. This is done by using Tcl's built-in msgcat package which looks for a directory called msgs/ wherever you installed Tkabber, and then uses the LC_MESSAGES environment variable (or LANG if LC_MESSAGES not set) to select the appropriate file. If you wish, you can force use of a particular language by putting a line like this in your configuration file:

::msgcat::mclocale en


 TOC 

6.1.8. Searching

Tkabber allows the user to perform textual searching in certain classes of its windows. This searching is controlled by several settings which can be specified in this section.

These settings are described in detail in Section 8.1 (Searching).



 TOC 

6.2. Post-load

After Tkabber reads your configuration file, it loads all of its own modules, it then invokes a procedure called postload. This procedure is supposed to perform module-specific configuration.

The default version of this procedure doesn't do anything. If you want to configure one more module modules, then you need to define the procedure in your configuration file, e.g.,

proc postload {} {
# look-and-feel

    set pixmaps::options(pixmaps_theme) Default

    global alert colors alert_lvls

    set alert_lvls(error)        1
    set alert_lvls(server)       1
    set alert_lvls(message)      2
    set alert_lvls(mesg_to_user) 3
    set alert_colors             {Black DarkBlue Blue Red}

    set ifacetk::options(raise_new_tab) 1


# the autoaway module

    set plugins::autoaway::options(awaytime)  5
    set plugins::autoaway::options(xatime)   15
    set plugins::autoaway::options(status) "Automatically away due to idle"
    set plugins::autoaway::options(drop_priority) 1


# the avatar module

    set avatar::options(announce) 0
    set avatar::options(share)    0


# the chat module

    set chat::options(default_message_type) chat
    set chat::options(stop_scroll)          0
    set plugins::options(timestamp_format)  {[%R]}


# the clientinfo module

    set plugins::clientinfo::options(autoask) 0


# the conferenceinfo module

    set plugins::conferenceinfo::options(autoask)        0
    set plugins::conferenceinfo::options(interval)       1
    set plugins::conferenceinfo::options(err_interval)  60


# the cryptographic module

    set ssj::options(encrypt,fred@example.com) 1


# the emoticon module

    set plugins::emoticons::options(theme) \
                $::configdir/emoticons/rythmbox


# the file transfer module

    set ft::options(download_dir) "/tmp"


# the groupchat module

    global gra_group gra_server
    global gr_nick gr_group gr_server
    global defaultnick

    set defaultnick(adhoc@conference.example.com) publius
    set defaultnick(*@conference.example.com) cicerone


# the ispell module

    set plugins::ispell::options(enable)              1
    set plugins::ispell::options(executable)          /usr/bin/ispell
    set plugins::ispell::options(command_line)        -C -d russian
    set plugins::ispell::options(dictionary_encoding) koi8-r
    set plugins::ispell::options(check_every_symbol)  1

# the stream initiation module

    set si::transport(allowed,http://jabber.org/protocol/bytestreams) 0
    set si::transport(allowed,http://jabber.org/protocol/ibb) 1


# the logger module

    set logger::options(logdir)        [file join $::configdir logs]
    set logger::options(log_chat)      1
    set logger::options(log_groupchat) 1


# the login module

    global loginconf loginconf1 loginconf2 autologin

    set loginconf(user)           ""
    set loginconf(password)       ""
    set loginconf(server)         example.com
    set loginconf(resource)       tkabber
    set loginconf(priority)       16
    set loginconf(usealtserver)   0
    set loginconf(altserver)      ""
    set loginconf(altport)        5422
    set loginconf(stream_options) plaintext
    set loginconf(proxy)          https
    set loginconf(usesasl)        1
    set loginconf(allowauthplain) 0
    set loginconf(proxyhost)      localhost
    set loginconf(proxyport)      3128
    set loginconf(proxyusername)  ""
    set loginconf(proxypassword)  ""

    # The following variables are useful when your jabber-server
    # (example.com) does not have SRV or A-record in DNS
    set loginconf(usealtserver)  1
    set loginconf(altserver)     "jabber.example.com"

    set loginconf1(profile)      "Default Account"
    set loginconf1(user)         mrose

    set loginconf2(profile)      "Test Account"
    set loginconf2(user)         test

    array set loginconf          [array get loginconf1]

    set autologin 0


# the message module

    set message::options(headlines,cache)    1
    set message::options(headlines,multiple) 1


# the raw xml input module

    set plugins::rawxml::set options(pretty_print) 0
    set plugins::rawxml::set options(indent)       2


# the roster module

    set roster::show_only_online            1
    set roster::roster(collapsed,RSS)       1
    set roster::roster(collapsed,Undefined) 1

    set roster::aliases(friend@some.host) \
        {friend@other.host friend@another.host}
    set roster::use_aliases                 1


# the sound module

    set sound::options(mute)                   0
    set sound::options(mute_if_focus)          0
    set sound::options(notify_online)          0
    set sound::options(mute_groupchat_delayed) 1
    set sound::options(mute_chat_delayed)      0
    set sound::options(external_play_program) /usr/bin/aplay
    set sound::options(external_play_program_options) -q
    set sound::options(delay)

    set sound::options(connected_sound)                     ""
    set sound::options(presence_available_sound)            ""
    set sound::options(presence_unavailable_sound)          ""
    set sound::options(groupchat_server_message_sound)      ""
    set sound::options(groupchat_their_message_to_me_sound) ""
}

This isn't nearly as complicated as it seems. Let's break it down by individual module



 TOC 

6.2.1. Look-and-Feel

Tkabber is shameless in borrowing icons from other Jabber clients. By setting pixmaps::options(pixmaps_theme), you can select a family of related icons. Besides "Default", you can choose one of "Gabber", "JAJC", "Jarl", "Psi", "ICQ", or a few other themes.

If you want, you can have Tkabber use a different theme by putting custom theme subdirectory to $::configdir/pixmaps/ directory (tilde means home directory). Tkabber knows that it is a theme directory by looking for icondef.xml file in the directory. To find out the structure of icon definition file, look through XEP-0038 and go to where you installed Tkabber and take a look at the directory called "pixmaps/default/".

If you're using the tabbed window interface, Tkabber needs a way of telling you that something has changed in a window that's not on top. This is where the an array called alert_lvls and a list called alert_colors come in. The array maps an incoming message to a priority number from zero to three. The list, which is indexed starting at zero, indicates what color the tab should use to let you know that something's changed. So, the way to read the example is that receiving:

  • an error or server message will cause the tab of a lowered window to go dark blue;
  • a groupchat or headline message will cause the tab to go blue; and,
  • a chat message addressed directly to you will cause the tab to go red.

By default, whenever a new tab is created, it is automatically raised. If you don't like this behavior, add this line:

set ifacetk::options(raise_new_tab) 0


 TOC 

6.2.2. The Autoaway Module

This module is presently available only if either:

  • on UNIX, if you have the Tk Xwin extension installed; or,
  • On Windows, if you have the Tcl Winidle extension installed.

There are two variables that control when Tkabber automatically marks you as away: plugins::autoaway::options(awaytime) and plugins::autoaway::options(xatime). Both define the idle threshold in minutes (the number does not have to be integer).

If variable plugins::autoaway::options(drop_priority) is set in 1 then Tkabber will set priority to 0 when moving in extended away state.

Variable plugins::autoaway::options(status) allows to specify text status, which is set when Tkabber is moving in away state.



 TOC 

6.2.3. The Avatar Module

There are two variables that you can set to control whether Tkabber will allow others to see your avatar:

  • avatar::options(announce) determines whether your presence information indicates that you have an avatar; and,
  • avatar::options(share) determines whether requests for your avatar will be honored.


 TOC 

6.2.4. The Chat Module

Most instant messaging users prefer to see all the back-and-forth communication in a single window. If you prefer to see each line sent back-and-forth in a separate window, here's what to put in your postload:

set chat::options(default_message_type) normal

The variable named chat::options(stop_scroll) determines whether a chat window should automatically scroll down to the bottom whenever something new comes in.

You can also set format of time stamp that displayed in beginning of each chat message. Refer to Tcl documentation for description of format. E.g., to display it in "dd:mm:ss" format, add this line:

set plugins::options(timestamp_format) {[%T]}


 TOC 

6.2.5. The Clientinfo Module

This module shows in popup balloons information of used by this user client name, version, and OS. You can allow or deny automatic asking of this info from users by setting this variable to 1 or 0:

set plugins::clientinfo::options(autoask) 1


 TOC 

6.2.6. The Conferenceinfo Module

After you join a conference that's listed in your roster, then whenever you mouse over that roster entry, you'll see a popup listing the conference's participants. If you want to see this popup, regardless of whether you are currently joined with the conference, add this line to your post-load:

set plugins::conferenceinfo::options(autoask) 1

You can also set interval between these requests with these two variables:

set plugins::conferenceinfo::options(interval)       1
set plugins::conferenceinfo::options(err_interval)  60

The second variable defines how many minutes to wait after receiving an error reply before trying again. (Usually an error reply indicates that the server hosting the conference doesn't support browsing, so it makes sense not to try that often.



 TOC 

6.2.7. The Cryptographic Module

Earlier (Pre-load) we saw an example where the ssj::options array from the cryptographic module was set during the preload.

In addition to signed-traffic and encrypt-traffic, you can also tell Tkabber whether to encrypt for a particular JID, e.g.,

    set ssj::options(encrypt,fred@example.com) 1


 TOC 

6.2.8. The Emoticons Module

The procedure called plugins::emoticons::load_dir is used to load emoticon definitions from a directory. The directory contains a file called "icondef.xml", which defines the mapping between each image and its textual emoticon (To find out what this file looks like, go to where you installed Tkabber and take a look at the file called "emoticons/default/icondef.xml" or read XEP-0038.)

If you have just a few icons, and you don't want to create a directory and a textual mapping, you can use the procedure called plugins::emoticons::add, e.g.,

    plugins::emoticons::add ":beer:" \
        [image create photo -file $::configdir/emoticons/beer.gif]

If you want to disable all emoticons, you can simply load empty directory. Put in postload function

    plugins::emoticons::load_dir ""


 TOC 

6.2.9. The File Transfer Module

You can set directory in which files will be saved by default:

    set ft::options(download_dir) "/tmp"


 TOC 

6.2.10. The Groupchat Module

There are several variables that set the dialog window defaults for adding a groupchat to your roster, or joining a groupchat:

add to roster dialog window:
gra_group and gra_server specify the default room and conference server, repectively; and,
join dialog window:
gr_nick, gr_group and gr_server specify the default nickname, room, and conference server, respectively.

Note that variables gra_server, gr_nick and gr_server overriden in login procedure, so better place for changing them is in connected_hook (see below).

You may want to have different nicknames for different groupchats. Accordingly, the array called defaultnick is used to set the default nickname for when you enter a conference. The array is indexed by the JID of the room, e.g.,

    set defaultnick(adhoc@conference.example.com) publius

Another possibility is to put pattern in parentheses. The following example shows how to specify default nickname for all conferences at conference.example.com:

    set defaultnick(*@conference.example.com) ciceroni

Exact JID's take the higher precedence than patterns.



 TOC 

6.2.11. The Ispell Module

On Unix, Tkabber can check spelling of what you entered by calling an external program ispell. To enable this feature, add following lines to postload function:

set plugins::ispell::options(enable) 1

If you enabled this module, then you can also define:

  • the path to the ispell executable by setting plugins::ispell::options(executable)
  • the ispell command line options by setting plugins::ispell::options(command_line); and,
  • the encoding of the output by setting plugins::ispell::options(dictionary_encoding).

If you don't care about putting a large load on your process, then you can also set plugins::ispell::options(check_every_symbol) to 1 to check correctness of current word after every entered symbol. (Usually you don't need to set this option.)



 TOC 

6.2.12. The Stream Initiation Module

Stream initiation profile is defined in XEP-0095 with two transports (XEP-0047 - IBB, XEP-0065 - SOCKS5 bytestreams). With it you can specify what transports you can use, and via negotiation choose more appropriate one. Tkabber comes with two transport implementations:

bytestreams:
that allows you to connect to any node that supports bytestreams transport (mediated connection is not supported yet);
ibb:
that uses your Jabber connection to transmit the data (which may slowdown other traffic to you).

If your machine is behind a NAT, then you can't use the bytestreams transport, so you should disable it:

    set si::transport(allowed,http://jabber.org/protocol/bytestreams) 0


 TOC 

6.2.13. The Logger Module

You can set directory to store logs:

    set logger::options(logdir) [file join $::configdir logs]

Also you can allow or disallow storing of private and group chats logs:

    set logger::options(log_chat)      1
    set logger::options(log_groupchat) 1


 TOC 

6.2.14. The Login Module

The first task is to initialize the configuration defaults for the login module. As you can see above, the global array loginconf has a whole bunch of elements, e.g., user, password, and so on.

Elements loginconf(user) and loginconf(password)specify username and password to authenticate at your Jabber server.

Element loginconf(server) must be set to Jabber server name (the part of you JID after @.

Element loginconf(stream_options) is set to one of the following values:

  • plaintext — use plaintext connection;
  • encrypted — use encrypted (via STARTTLS mechanism) connection (this option requires tls extension to be installed);
  • ssl — use encrypted (via legacy SSL mechanism) connection (this option requires tls extension to be installed);
  • compressed — use compressed connection (this option requires Ztcl extension to be installed).

Tkabber tries to resolve Jabber server name using SRV first and usual A records in DNS. If the resolution fails (for example if you are in LAN environment without DNS) you can force Tkabber to connect to the server using loginconf(altserver) and loginconf(altport) options (do not forget to set loginconf(usealtserver) to 1).

Another option is to use HTTP-polling connect method (if your server supports it) and tunnel XMPP traffic through HTTP. To enable HTTP-polling set loginconf(usehttppoll) to 1. Tkabber then tries to find connect URL using TXT record in DNS (see XEP-0156). You can specify URL manually by setting loginconf(pollurl).

This collection of elements, which is termed a login profile, is what populates the dialog window you'll see when Tkabber wants to connect to the server.

It turns out that Tkabber lets you have as many different login profiles as you want. If you want more than just one, they're named loginconf1, loginconf2, and so on.

What the example above shows is the default values for all profiles being set in loginconf, and then two profiles, one called "Default Account" and the other called "Test Account" being created.

If you want to automatically login to server, then you can set the autologin variable to 1.

If you set the autologin variable to -1, then Tkabber will not automatically login and will not show login dialog.

Default value for autologin is 0. In this case Tkabber shows login dialog.



 TOC 

6.2.15. The Message Module

By default, when you restart Tkabber it won't remember the headlines you received. If you want Tkabber to remember headlines whenever you run it, set message::options(headlines,cache) to 1.

By default, Tkabber will put all headline messages into a single window. If you want Tkabber to use a seperate window for each headline source, set message::options(headlines,multiple) to 1.



 TOC 

6.2.16. The Raw XML Input Module

With this module you can monitor incoming/outgoing traffic from connection to server and send custom XML stanzas. Also you can switch on pretty print option to see incoming and outgoing XML stanzas pretty printed. Note, that with this option they may be drawed incorrectly, e.g. for XHTML tags. Also you can set indentation level via indent option.



 TOC 

6.2.17. The Roster Module

By default, your entire roster is shown, even those items that aren't online. The variable called roster::show_only_online controls this.

Similarly by default, each item in every category is shown in the roster. If you want to hide the items in a given category, the array called roster::roster lets you do this. In the example, we see that two groups ("RSS" and "Undefined") start with their items hidden.

Some peoples use several JIDs. Tkabber lets you specify an alias for people like these, so it will show only one entry in the roster. In the example, we see that user friend@some.host have aliases friend@other.host and friend@another.host. You can also disable all aliases by setting roster::use_aliases to 0.



 TOC 

6.2.18. The Sound Module

Tkabber can play sounds on some events. It can use for this snack library or external program that can play WAV files. Sound notifications is enabled when Tkabber starts.

If you want to start Tkabber with sound muted add the following line:

set sound::options(mute) 1

If you want Tkabber to stop notifying you when you are not online (in away or dnd state) add the following line:

set sound::options(notify_online) 1

If you want Tkabber to mute sound when it is focued (and you are paying enough attention to it) add the following line:

set sound::options(mute_if_focus) 1

You can also mute sounds of delayed groupchat messages and delayed personal chat messages:

set sound::options(mute_groupchat_delayed) 1
set sound::options(mute_chat_delayed)      0

If you want to use external program for playing sounds and possibly this program's options, then also add something like this (these options are suitable for Linux users with ALSA installed):

set sound::options(external_play_program) /usr/bin/aplay
set sound::options(external_play_program_options) -q

You can also set minimal interval (in milliseconds) between playing different sounds.

set sound::options(delay) 200

Tkabber allows you to specify the filename it will play notifying about some more or less important events. These are:

  • sound::options(connected_sound) — sound playing when Tkabber is connected to the server;
  • sound::options(presence_available_sound) — sound playing when available presence is coming;
  • sound::options(presence_unavailable_sound) — sound playing when unavailable presence is coming;
  • sound::options(chat_my_message_sound) — sound playing when you send one-to-one chat message;
  • sound::options(chat_their_message_sound) — sound playing when you receive one-to-one chat message;
  • sound::options(groupchat_server_message_sound) — sound playing when you receive groupchat message from server;
  • sound::options(groupchat_my_message_sound) — sound playing when you receive groupchat message from server;
  • sound::options(groupchat_their_message_sound) — sound playing when you receive groupchat message from another user;
  • sound::options(groupchat_their_message_to_me_sound) — sound playing when you receive highlighted (usually personally addressed) groupchat message from another user.
If you want to disable sound notification for some of the events, then you can add line like this:
set sound::options(connected_sound)                     ""
set sound::options(presence_available_sound)            ""
set sound::options(presence_unavailable_sound)          ""
set sound::options(groupchat_server_message_sound)      ""
set sound::options(groupchat_their_message_to_me_sound) ""


 TOC 

6.3. Menu-load

After Tkabber invokes your postload procedure, it starts building the GUI. One of the most important things it does is build up a list that specifies its menu bar. It then invokes a procedure called menuload, which is allowed to modify that specification before Tkabber uses it.

The default version of this procedure is the identity function, i.e..,

proc menuload {description} { return $description }

If you really want to change the menubar specification, then here's how to get started:

  1. Go to where you installed the BWidget library and take a look at the file called "BWman/MainFrame.html". The documentation for the "-menu" option explains the syntax of the specification.
  2. Go to where you installed Tkabber and take a look at the file called "iface.tcl". Look for the line that starts with "set descmenu". This will show you the specification given to your menuload procedure.
  3. Go to where you installed Tkabber and take a look at the file called "examples/mtr-config.tcl". Look at the menuload procedure defined there. It lays out Tkabber's menu bar similar to Gabber's.
  4. Finally, study the procedures listed here.


 TOC 

6.3.1. The Avatar Module

The procedure called avatar::store_on_server stores your avatar on the server.



 TOC 

6.3.2. The Browser Module

The procedure called browser::open opens a new browser window.



 TOC 

6.3.3. The Groupchat Module

The procedure called add_group_dialog displays a dialog window when you want to add a groupchat to your roster. Similarly, the procedure called join_group_dialog displays a dialog window when you want to join a groupchat.



 TOC 

6.3.4. The Login Module

The procedure called show_login_dialog displays a dialog window when you want to login to the server. (Prior to attempting to login, if necessary it will logout). Naturally, the procedure called logout does just that; however, if you want get a dialog window for confirmation, use show_logout_dialog instead.



 TOC 

6.3.5. The Message Module

If you want to send a message to someone, the procedure called message::send_dialog will put up a dialog window. It takes upto three optional arguments: the recipient JID, the subject, and the thread.

If you want to get added to someone's roster, the procedure called message::send_subscribe_dialog will put up a dialog window. It takes one optional argument: the recipient JID.

If you want to adjust your message filters, the procecure called filters::open will put up a dialog window.



 TOC 

6.3.6. The Presence Module

If you want to display information about a user, the procecure called userinfo::open will put up a dialog window. It takes two optional arguments: the user's JID; and, whether or not the dialog window should be editable.

Obviously, the second argument makes sense only if it's your own information, i.e.,

    global loginconf

    userinfo::open \
        ${loginconf(user)}@$loginconf(server)/$loginconf(resource) 1

There are also two variables that you can use to set your own presence: userstatus and textstatus. The first variable takes one of five values:

  • available;
  • chat;
  • away;
  • xa;
  • dnd; or,
  • invisible.

The second variable takes any textual value.

Changes to your presence information are propagated only when userstatus is changed. Accordingly, if you make a change to textstatus, be sure to write userstatus immediately afterwards, even if it's a no-op, e.g.,

    global userstatus textstatus

    set textstatus "Out to lunch"
    set userstatus $userstatus


 TOC 

6.3.7. Miscellany

Finally, you can use the procedure named help_window to display some textual help. This procedure takes two arguments: the title for the window; and, the text to display.

Also, instead of calling exit to terminate Tkabber, please use the quit procedure instead.



 TOC 

6.4. Final-Load

Finally, right before Tkabber goes to display the login dialog, it invokes a procedure called finload, which does whatever you want it to.



 TOC 

7. Extensibility

In addition to various configuration mechanisms, Tkabber lets you define procedures, termed "hooks" that get run when certain events happen.

Here's an example. When Tkabber receives a chat message, how does it know what to process and what to draw? The short answer is that it doesn't need to know anything, all it does is:

hook::run draw_message_hook $chatid $from $type $body $extras

The hook::run procedure invokes whatever hooks have been defined for draw_message_hook. In fact, more than ten procedures may get invoked to satisfy this hook!

Here's how it works: Tkabber comes with a number of plugins, which get loaded automatically. Each plugin makes one or more calls that look like this:

hook::add draw_message_hook [namespace current]::my_draw_hook $prio

where the last two parameters are: the name of a procedure to run; and, a relative integer priority.

When hook::run is invoked for draw_message_hook, each of these procedures is called, in the priority order (from smallest to largest). If one of the procedures wants to prevent the later procedures from being called, it returns the string "stop".

To continue with the example, in between the pre-load and post-load stages of configuration, the following calls get made by different plugins:

hook::add draw_message_hook [list ...::events::process_x 0] 0
hook::add draw_message_hook ...::chatstate::process_x 1
hook::add draw_message_hook ...::check_draw_empty_body 4
hook::add draw_message_hook ...::chat_open_window 5
hook::add draw_message_hook [list ...::events::process_x 1] 6
hook::add draw_message_hook ...::draw_signed 6
hook::add draw_message_hook ...::draw_encrypted 7
hook::add draw_message_hook ...::handle_error 10
hook::add draw_message_hook ...::handle_info 10
hook::add draw_message_hook ...::draw_timestamp 15
hook::add draw_message_hook    ::logger::log_message 15
hook::add draw_message_hook      muc::set_message_timestamp 15
hook::add draw_message_hook ...::add_number_of_messages_to_title 18
hook::add draw_message_hook ...::chat_message_notify19
hook::add draw_message_hook ...::handle_server_message 20
hook::add draw_message_hook ...::roster::update_chat_activity 50
hook::add draw_message_hook ...::check_nick 60
hook::add draw_message_hook    ::wmdock::msg_recv 70
hook::add draw_message_hook ...::handle_last_nick 79
hook::add draw_message_hook ...::::add_bookmark 80
hook::add draw_message_hook ...::handle_me 83
hook::add draw_message_hook ...::xhtml::draw_xhtml_message 85
hook::add draw_message_hook ...::draw_normal_message 87

Many of these procedures look at the incoming chat message and operate on only certain kinds of messages. Some of these procedures may return "stop", e.g., handle_me which handles chat bodies that start with "/me" and draw_xhtml_message which visualizes XHTML formatted messages. (In this example, the actual namespaces were replaced with "...:" to make it more readable).

Now let's look at the different kind of hooks that Tkabber knows about.



 TOC 

7.1. Chat Hooks

When Tkabber decides that it needs to open a (tabbed) window for a chat or groupchat, two hooks are run:

open_chat_pre_hook  $chatid $type
open_chat_post_hook $chatid $type

Both hooks are given two parameters: the chatid (ID of the chat or conference room window, you always can obtain JID using chat::get_jid and connection ID using chat::get_connid routines); and, and the type of chat (either "chat" or "groupchat").

Similarly, when Tkabber encounters activity on a tabbed window, a hook is run:

raise_chat_tab_hook $path $chatid

The hook is given two parameters: the path of the Tk widget for the tabbed window; and, the chatid of the chat or conference room window.

When you want to send a chat message, a hook is run:

chat_send_message_hook $chatid $user $body $type

The hook is given four parameters: the chatid of the recipient; the localpart of your login identity; the body of the message; and, the type of chat.

draw_message_hook $chatid $from $type $body $extras

The hook is given five parameters: the chatid of the sender window (JID includes a resource); the JID of the sender (without the resource); the type of chat; the body of the message; and, a nested-list of additional payload elements. (This last parameter isn't documented in this version of the documentation.)

Chat windows have menubuttons, and two hooks are used to add items in menu:

chat_create_user_menu_hook $path $connid $jid
chat_create_conference_menu_hook $path $connid $jid

The first is used in user chat windows, and second in groupchat ones. Hooks are given three parameters: the path of the Tk menu widget; connection ID; and, the JID of user or conference.

In groupchat windows it is possible to complete participants' nicks or commands by pressing TAB key. List of completions is generated by running this hook:

generate_completions_hook $chatid $compsvar $wordstart $line

The hook is given four parameters: the chatid of conference window; name of global variable, in which current list of possible completions is stored; index of position where completion must be inserted; and content of text widget where completion is requested.

When someone enters/exits conference, the following hooks are called:

chat_user_enter $group $nick
chat_user_exit  $group $nick

The hooks are given two parameters: chatid of conference and nick of participant.



 TOC 

7.2. Login Hooks

Two hooks are invoked whenever a session is connected or disconnected:

connected_hook $connid

disconnected_hook $connid

Both hooks are given one parameter: connection ID (Tkabber allows several connections at once).



 TOC 

7.3. Presence Hooks

When our presence status changes, a hook is run:

change_our_presence_post_hook $status

The hook is given one parameter: the new presence status value, i.e., one of:

  • available;
  • chat;
  • away;
  • xa;
  • dnd; or
  • unavailable.

Similarly, when someone else's presence changes, a hook is run:

on_change_user_presence_hook $label $status

The hook is given two parameters: the label associated with the JID (e.g., "fred") or the JID itself (e.g., "fred@example.com") if no label exists in the roster; and, the user's new status.

And for all received presence packets, a hook is run:

client_presence_hook $connid $from $type $x $args

The hook is given four parameters: connection ID, who send this presence, type of presence (e.g., "error", "unavailable"), list of extended subtags and parameters of this presence (e.g., "-show xa -status online").



 TOC 

7.4. Roster Hooks

When an item is added to the roster window, one of the four hooks is run to add stuff to the menu associated with that item:

roster_conference_popup_menu_hook $path $connid $jid

roster_service_popup_menu_hook $path $connid $jid

roster_jid_popup_menu_hook $path $connid $jid

roster_group_popup_menu_hook $path $connid $name

When run, each hook is given three parameters: the path of the Tk menu widget; the connection ID; and, a JID of the roster item (or the name of the roster group for the last one).

Also the following hook is run to add stuff to the menu in groupchats:

roster_create_groupchat_user_menu_hook $path $connid $jid

The hook is given three parameters: the path of the Tk menu widget; the connection ID; and, a JID of user.

The following hook is run to add stuff to the popup balloon for each roster item:

roster_user_popup_info_hook $varname $connid $jid

The hook is given three parameters: the variable name in which current popup text is stored, the connection ID, and the JID of the roster item.



 TOC 

7.5. Miscellaneous Hooks

There are three "obvious" hooks:

postload_hook

finload_hook

quit_hook

The first two, by default, run the postload and finload procedures, respectively. postload_hook is run after all code has been loaded and before initializing main Tkabber window. After that finload_hook is run. The final hook is called just before Tkabber terminates (cf., Section 6.3.7 (Miscellany)).

You can add custom pages to userinfo window using

userinfo_hook $path $connid $jid $editable


 TOC 

8. User Interface basics



 TOC 

8.1. Searching

Search panel may be invoked in certain classes of Tkabber windows using the <<OpenSearchPanel>> Tk virtual event which is bound by default to the <Control-S> keyboard command.

Search panel can be dismissed by pressing the <Escape> key and the default search action ("search down") is activated by pressing the <Return> key while entering the search pattern.

Search panel is currenlty available in:

  • Chat and groupchat windows;
  • Service discovery window;
  • Chat history logs;
  • All windows of the "Chats history" tool.

Searching may be customized using the settings located under the Plugins → Search group of the Customize window. These setings are:

  • ::plugins::search::options(case): perform case-sensitive searching (off by default);
  • ::plugins::search::options(mode): selects searching mode which can be one of:
    • substring — use simple substring search: the typed search string is taken verbatim and then the attempt to locate it is performed. This is the default mode.
    • glob — uses "glob-style" (or "shell-style") matching: special symbols are recognized and they provide for "wildcarding":
      • * matches zero or more characters;
      • ? matches exactly one character;
      • [ and ] define character classes, e.g., [A-Z] will match any character in the series "A", "B", ... "Z".
      The full syntax is described in Tcl string manual page. That is, this search mode can be convenient for those who want more general yet simple approach to searching and is familiar with the "shell globbing" concept found in Unix shells.
    • regexp — provides for searching using full-blown regular expressions engine. The full syntax is described in Tcl re_syntax manual page.



 TOC 

Appendix A. Releases History



 TOC 

A.1. Main changes in 0.11.1

  • New default sound theme by Serge Yudin
  • Added new plugins: quotelastmsg, singularity, stripes
  • Many fixes and enhancements



 TOC 

A.2. Main changes in 0.11.0

  • New tabbed user interface. Tab headers now occupy several rows and tab bar can be docked to the left and right sides of chat window
  • Roster filter
  • Added support for pixmaps (in particular emoticons) JISP archives (XEP-0038)
  • Added support for SOCKS4a and SOCKS5 proxy for the main connection
  • Added user location support (XEP-0080)
  • Added user mood support (XEP-0107)
  • Added user activity support (XEP-0108)
  • Added user tune support (XEP-0118)
  • Added entity capabilities (XEP-0115 v.1.5, only reporting) support
  • Added basic robot challenges support (XEP-0158, v.0.9)
  • Added partial data forms media element support (XEP-0221, v.0.2, URIs and images only)
  • Roster is now exported to XML instead of Tcl list
  • Added support for entity time (XEP-0202)
  • Tkabber version is now reported in disco#info (XEP-0232)
  • Moved deprecated Jabber Browser (XEP-0011) to an external plugin
  • Moved Jidlink file transfer to an external plugin
  • Added several new plugins: attline, ctcomp, custom-urls, floatinglog, gmail, openurl, presencecmd, receipts
  • Many fixes and enhancements



 TOC 

A.3. Main changes in 0.10.0

  • New artwork by Artem Bannikov
  • Mediated SOCKS5 connection support for file transfer (XEP-0065)
  • Blocking communicaation with users not in roster (using XEP-0016 via simple interface)
  • Translatable outgoing error messages support (based on recipient's xml:lang)
  • Remote controlling clients support (XEP-0146)
  • Extended stanza addressing support (XEP-0033)
  • New chats history tool with search over the all chatlog files
  • Roster item icons are chosen based on Disco queries to item server
  • Search in Disco, Browser, Headlines, RawXML, and Customize windows
  • New internal plugins: abbrev allows to abbreviate words in chat input windows, postpone stores/restores current input window content
  • New external plugins (aniemoticons, latex, tkabber-khim, traffic, renju)
  • Emoticons theme now can be loaded using GUI
  • Most Tkabber's tabs can now be stored on exit and restored on start
  • XMPP ping support (XEP-0199). Reconnecting based on XMPP ping replies
  • Delayed delivery now recognizes XEP-0203 timestamps
  • Added optional 'My Resources' roster group, which contains other connected resources of the same JID
  • Many fixes and enhancements



 TOC 

A.4. Main changes in 0.9.9

  • Improved privacy lists interface
  • Support for stream compression (XEP-0138)
  • Support for SRV DNS-records
  • Support for TXT DNS-records (XEP-0156)
  • Support for ad-hoc commands (XEP-0050)
  • Improved headlines support
  • Chat state notification support (XEP-0085)
  • Many fixes and enhancements



 TOC 

A.5. Main changes in 0.9.8

  • Support for STARTTLS
  • Reorganized menu
  • Support for searching in chat window
  • Support for annotations about roster items (XEP-0145)
  • Support for conference rooms bookmarks (XEP-0048)
  • Added multilogin support for GPGME
  • Better support for xml:lang
  • Support for service discovery extensions (XEP-0128)
  • Support for NTLM authentication
  • Many fixes and enhancements



 TOC 

A.6. Main changes in 0.9.7beta

  • Updated support for file transfer (XEP-0095, XEP-0096, XEP-0047, XEP-0065)
  • Support for colored nicks and messages in conference
  • Better multiple logins support
  • Updated support for xml:lang
  • Support for IDNA (RFC3490)
  • Many fixes and enhancements



 TOC 

A.7. Main changes in 0.9.6beta

  • Multiple logins support
  • History now splitted by month
  • Animated emoticons support
  • Many user interface improvements
  • More XMPP support
  • More translations
  • Bugfixes



 TOC 

A.8. Main changes in 0.9.5beta

  • Nested roster groups
  • Messages emphasizing
  • User interface improvements
  • Support for XMPP/Jabber MIME Type
  • Bugfixes



 TOC 

Appendix B. Tk option database resources

Here is list of the most essential Tkabber-specific Tk option database resources that you need to change look:

Tkabber.geometry
Geometry of main window.
*Chat.chatgeometry
*Chat.groupchatgeometry
*Customize.geometry
*RawXML.geometry
*Stats.geometry
*Messages.geometry
*JDisco.geometry
Geometry of various windows (when not using tabs).
*mainRosterWidth
The width of the main roster window.
*Chat.inputheight
*RawXML.inputheight
Height of input windows in chat and raw XML windows.
*Balloon.background
*Balloon.foreground
Background and foreground colors of popup balloon.
*Balloon.style
Behaviour of popup balloon: can be delay (balloon appeared after some time) and follow (balloon appeared immediately and follows mouse).
*JDisco.fill
Color of service discovery browser item name.
*JDisco.identitycolor
Color of service discovery browser item identity.
*JDisco.featurecolor
Color of service discovery browser entity feature.
*JDisco*Tree*background
Background of service discovery browser.
*Chat.meforeground
Color of user's messages in chat windows.
*Chat.theyforeground
Color of other peoples messages in chat windows.
*Chat.serverlabelforeground
Color of label before server message.
*Chat.serverforeground
Color of server messages in chat windows.
*Chat.errforeground
Color of error messages in chat windows.
*Chat.urlforeground
Color of URLs in chat windows.
*Chat.urlactiveforeground
Color of mouse highlighted URLs in chat windows.
*JDisco.fill
Default color of items in Service Discovery Browser.
*JDisco.featurecolor
Default color of feature items in Service Discovery Browser.
*JDisco.identitycolor
Default color of identity items in Service Discovery Browser.
*JDisco.optioncolor
Default color of option items in Service Discovery Browser.
*JDisco*Tree*background
Default color of background in Service Discovery Browser.
*NoteBook.alertColor0
*NoteBook.alertColor1
*NoteBook.alertColor2
*NoteBook.alertColor3
Tabs alert colors.
*Roster.cbackground
Roster background color.
*Roster.groupindent
Indentation for group title.
*Roster.groupiconindent
Indentation for group icon.
*Roster.jidindent
Indentation for item name.
*Roster.jidmultindent
Indentation for item with multiple resources.
*Roster.subjidindent
Indentation for item resource.
*Roster.iconindent
Indentation for item icon.
*Roster.subitemtype
*Roster.subiconindent
Indentation for resource icon.
*Roster.textuppad
Top pad for item's names.
*Roster.textdownpad
Bottom pad for item's names.
*Roster.linepad
Vertical distance between items.
*Roster.foreground
Color of item's names.
*Roster.jidfill
Background of roster item.
*Roster.jidhlfill
Background of roster item when mouse is over.
*Roster.jidborder
Color of item's border.
*Roster.groupfill
*Roster.grouphlfill
*Roster.groupborder
The same to roster groups.
*Roster.groupcfill
Background color of collapsed group.
*Roster.stalkerforeground
*Roster.unavailableforeground
*Roster.dndforeground
*Roster.xaforeground
*Roster.awayforeground
*Roster.availableforeground
*Roster.chatforeground
Colors of item name for different presences.



 TOC 

Appendix C. Documentation TODO

The next revision of this documentation should discuss:

  • Pre-load:
    • browseurl
  • Post-load:
    • chat_height and chat_width (appear to be no-ops).
  • Menu-load:
    • change_password_dialog
    • conference::create_room_dialog
    • disco::browser::open_win
    • message::send_msg
    • privacy::request_lists
    • rawxml::open_window
    • userinfo::show_info_dialog
  • Hooks: the additional payload format.


 TOC 

Appendix D. Acknowledgements

Rebecca Malamud was kind enough to design the "enlightened feather" motif used in the Tkabber look-and-feel.

The "new look" appeared in the 0.10.0 release ("golden feather" and "blue feather" pixmap themes and the "Earth bulb" logo) was designed by Artem Bannikov.

The new sound theme appeared in 0.11.1 release was created by Serge Yudin



 TOC 

Appendix E. Copyrights

Copyright (c) 2002-2008 Alexey Shchepin

Tkabber is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

Tkabber is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.



 TOC 

Authors' Addresses

  Alexey Yurievich Shchepin
  Process-One
Email:  alexey@process-one.net
  
  Marshall T. Rose
  Dover Beach Consulting, Inc.
  POB 255268
  Sacramento, CA 95865-5268
  US
Phone:  +1 916 483 8878
Fax:  +1 916 483 8848
Email:  mrose@dbc.mtview.ca.us
  
  Sergei Golovan
  New Economic School
Email:  sgolovan@nes.ru
  
  Michail Yurievich Litvak
  Colocall Ltd.
Email:  mci@shadow.in.ua
  
  Konstantin Khomoutov
  Service 007
Email:  khomoutov@gmail.com
tkabber-0.11.1/doc/tkabber.xml0000644000175000017500000031547511076045704015446 0ustar sergeisergei Tkabber 0.11.1 Process-One
alexey@process-one.net
Dover Beach Consulting, Inc.
POB 255268 Sacramento CA 95865-5268 US +1 916 483 8878 +1 916 483 8848 mrose@dbc.mtview.ca.us
New Economic School
sgolovan@nes.ru
Colocall Ltd.
mci@shadow.in.ua
Service 007
khomoutov@gmail.com
Tkabber is an open source Jabber client, written in Tcl/Tk. This memo describes the installation, configuration, and extension of Tkabber.
Tkabber provides a Tcl/Tk interface to the Jabber/XMPP instant messaging and presence service. Tcl/Tk is a graphical scripting language that runs on the Unix, Windows, and Macintosh platforms. The choice of Tcl/Tk for a Jabber client is three-fold: it is portable: once you install a Tcl/Tk interpreter on your system, the Tkabber script "just runs" — without having to compile anything; it is customizable: Tkabber reads a configuration file when it starts that tells it the settings of various parameters; and, it is extensible: the configuration file is actually a Tcl script, so you can replace or augment entire portions of Tkabber (if you're so inclined). Tkabber is fully-featured: TCP and HTTP-polling session transports XMPP SRV and TXT DNS-records handling hashed passwords SASL authentication encrypted sessions (if you install an optional extension) compressed sessions (if you install an optional extension) login via SOCKS4a, SOCKS5 or HTTPS proxy user-defined hooks for connection establishment and release XMPP/Jabber MIME type privacy rules signed/encrypted messages (if you install an optional extension) file transfers (HTTP, SOCKS bytestream, DTCP and IBB transports) groupchat (GroupChat-1.0 and Multi-User Chat conferencing protocols) headline messages message events completions of nick and commands hyperlinks emoticons user-defined hooks for chat window events signed presence (if you install an optional extension) avatars browsing groupchat and roster invitations conference room bookmarks annotations about roster items vCards user-defined hooks for presence changes configurable look-and-feel via a resources database unicode tabbed/non-tabbed interface sound notifications nested roster groups for Unix: auto-away, spell checking, KDE or freedesktop docking, and WMaker icons for Windows: auto-away, and taskbar icons
You should already have installed: Tcl/Tk version 8.3.3 (or later, Tcl/Tk 8.4.9 or later is recommended) tcllib version 1.2 (or later, tcllib 1.8 or later is required for SRV and TXT DNS-records support). BWidget 1.3 (or later) Most systems already come with these packages pre-installed. If not, various Unix systems have them available as ready-made packages. Otherwise, go to the URLs above and click on the appropriate download link for your system. Both tcllib and BWidget are script libraries — no compiling is necessary. In the case of Tcl/Tk, there are many ready-made binary packages available on the download site. The ActiveTcl distribution contains all three packages (along with the Img package mentioned next); so, you may want to use that instead of three separate downloads. At your discretion, there are several optional packages that you may also install. Tkabber will run just fine without them, but if they're available Tkabber will make additional features available to you. So, here's the list: Tcl/Tk supports only a small number of image formats (i.e., bitmaps, GIFs and portable pixmaps). If presence information contains avatars, these may be in other formats (e.g., PNGs or JPGs). Accordingly, you may want to install Img version 1.2 (or later). This package works on both Unix and Windows. By default, Tkabber uses pure-Tcl XML parser. If its performance is insufficient, you may want to install tDOM version 0.8.0 (or later) and use expat based XML parser. By default, communications between the server and client take place over a plaintext connection. While this may not be a problem in some local, wired environments, if your server is distant or your client is wireless, then you may want to encrypt all the client/server traffic. Accordingly, you may to install tls version 1.4.1 (or later). This package works on both Unix and Windows. Note that if you're using Unix, then you'll also need to have OpenSSL installed. Fortunately, this comes preinstalled on many Unix systems. If it's not on your system, check OpenSSL source page. (The Windows distribution of tls comes with all the necessary DLLs.) Another option in Unix is to compress connection between client and server (it currently disables encryption). If you want to compress traffic you should install ZTcl version 1.0b4 (or later) and Tclmore version 0.7b1 (or later). (At the time of 0.11.0 release ZTcl and Tclmore home page were unavailable, so you may grab them from a mirror.) By default, end-to-end communications between two or more Jabber clients is plaintext. Depending on your environment, this may not be a problem for you. Alternatively, you may want to digitally-sign all of your outgoing messages, and allow others to encrypt their messages to you. Accordingly, you may want to install the gpgme package, which, at present, works only on Unix. Depending on what's already installed on your system, you may have to download upto three files: Tcl GPGME version 1.0 (or later); GPGME version 0.3.11 (or later but only 0.3.x); and, GPG version 1.0.7 (or later). If you're running Unix or Windows, then you may want Tkabber to automatically mark you as away after a priod of inactivity. Accordingly (if you're using Tcl/Tk 8.3 or 8.4), on Unix, you may want to install Tk Xwin version 1.0 (or later), whilst on WIndows, you may want to install Tcl Winidle version 0.1 (or later). Users of Tcl/Tk 8.5 don't have to use external packages to measure their idle time. If you're running Unix, then you may want Tkabber to use the docking tray. Accordingly, you may want to install Tk Theme version 1.20 (or later) for KDE icon, or tktray version 1.1 (or later) for freedesktop icon (supported by modern KDE and GNOME). If you're running Windows, then you may want Tkabber to use the system tray. Accordingly, you may want to install Winico version 0.6 (or later). If you're a Tcl/Tk guru, then you may want to access the Tk console to debug things. Accordingly, you may want to install tkcon version 2.3 (or later). Please keep in mind that these are all "optional extras" — if they're not right for you or your environment, don't bother with them!
Latest stable version is 0.11.1 and available at http://tkabber.jabber.ru/download. Older versions can be found at http://files.jabber.ru/tkabber/.
You can always find the latest development version via SVN. Execute the following command:
And if you want to test some plugins, then do
If you use the Debian GNU/Linux distribution, you may want to get all required packages by using apt. Just execute
or to get the version included into Debian repository.
No real installation is required, simply copy the tkabber/ directory to a commonly-available area, and then either: put this directory in your search-path; or, make a calling script/shortcut to the file tkabber.tcl in that directory. Although Tkabber comes with a Makefile, there's really not much to do — most folks prefer to simply copy the distribution directory to somewhere in their home directory.
From the shell, you can invoke Tkabber as: whilst on a windowing system, simply double-click on that file or a short-cut to it.
If you're a Tcl/Tk guru and have installed tkcon, then you may want to invoke Tkabber as: Tkabber will automatically know that it's running under tkcon and will start by hiding the Tk console window. Look under the Help menu to find the checkbutton to show the console.
Also you can setup Tkabber as handler for XMPP/Jabber MIME Type . For this you need to set hanler for application/xmpp+xml MIME type in your browser to something like this: tkabber -mime %s
When upgrading Tkabber from version 0.10.0 or earlier note that several configuration options and user interface elements have been changed.
There are notable changes in handling connection through proxy servers, managing fonts and balloon colors, and detecting breaks in underlying TCP connection to a server.
Since SOCKS4 and SOCKS5 proxy types were implemented in addition to HTTP proxy type, the whole set of connection options regarding proxy servers has been changed. This means that after upgrade the old values stored using the Customize mechanism will be lost and the same values in loginconf arrays will not be recognized any longer. If you do not use HTTP proxy, you can skip this section because these changes will not affect you. If your options are set using the Customize interface, write down values for options relevant to proxy server from the "Login" group of Customize settings, then after upgrade visit this group of settings, select "HTTPS" for the option ::loginconf(proxy) and then fill in the rest of relevant settings with recorded values. As usual, save each setting after you change them. Do not be surprised with the word "HTTPS" (which stands for "HTTP over SSL"). It just means that Tkabber will use CONNECT method to tunnel TCP connection through a proxy. If you maintain loginconf arrays in config.tcl, you have to modify each array using this scheme: Rename variable "useproxy", if present, to just "proxy" and change its value to either "https" if "useproxy" was set to true or to "none" (yes, the word "none", do not leave it empty) if it was set to false. Modify existing variables in these arrays using this map: Rename "httpproxy" to "proxyhost". Rename "httpport" to "proxyport". Rename "httplogin" to "proxyusername". Rename "httppassword" to "proxypassword".
Fonts handling has been partially reworked: the global variable font that controls chat and roster fonts has been removed and now Tkabber relies on Tk option database to manage these settings. You can override roster and chat fonts independently of each other. To do that on systems not based on X Window use Customize options described below. The main consequence of this change is that now the fonts are taken from Tk option database and if it contains sane values you don't need to touch anything (until the update you had to tweak the font variable because it was set to font "fixed" by default). The variable font does not have any special meaning starting from 0.11.0 release. The second consequence is that you are now able to set fonts for chat and roster windows separately from each other using this list as a reference: *font Tk option database resource sets default font for all widgets used in Tkabber. *Chat*Text.font Tk option database resource can be used to override font used for chat windows. This resource can be overridden by the ::ifacetk::options(font) option from the "Main Interface" group of Customize settings. *Roster*font Tk option database resource can be used to override font used for roster windows. This resource can be overridden by the ::ifacetk::options(roster_font) option from the "Main Interface" group of Customize settings.
Keep-alive mechanism that was used to keep NATP devices from disconnecting idle XMPP sessions was accompanied in 0.10.0 with "XMPP ping" mechanism which also implemented dead link detection with support for disconnecting upon detection of network outage. In version 0.11.0, the old keep-alive mechanism has been dropped, so the following two global options have no effect now: keep_alive keep_alive_interval In order to get the same functionality, enable XMPP ping using these options in the "IQ" group of Customize settings: Enabling ::plugins::ping::options(ping) will make Tkabber periodically send xmpp:ping IQ request to the server. Set ::plugins::ping::options(timeout) option to a number of seconds Tkabber should wait for either a xmpp:ping reply or an error to arrive from the server; if there is no answer from the server during this timeout, the socket for this connection will be forcibly disconnected.
Resources controlling the appearance of balloon windows have been made more generic. If you use custom Tk option database settings for balloon windows, change the relevant resources using this map: Change references to *Balloon.background and *Balloon.foreground resources to *Balloon*background and *Balloon*foreground, respectively. Change references to *Balloon*padX and *Balloon*padY resources to *Balloon.text.padX and *Balloon.text.padY, respectively.
Support for TclXML as an external XML parser has been removed (since TclXML has anyway been unable to support partial XML processing) along with the global variable use_external_tclxml which controlled the loading of TclXML.
Now expat-based Tcl package tDOM is supported as an external XML parser. It can be enabled by loading it manually in config.tcl using the Tcl package command, for example:
There are notable changes in systray mouse gestures, appearance of a main tabbed window, and in behavior of paned window splitters.
Mouse gestures bound to system tray (system notification area) icon have been reworked: Single click on it with the left mouse button now unconditionally brings the main Tkabber window to front, possibly deiconifying it first. Single click with the middle mouse button now unconditionally iconifies the main Tkabber window. This differs from the previois behaviour where single click with the left mouse button on Tkabber's system tray icon toggled the iconified/visible state of the main Tkabber window.
The notebook widget which was used to render tabs in tabbed interface mode has been replaced with a new custom widget providing the ability for multi-row placement of tabs and docking them to the left or right sides of the chat window (in addition to top or bottom docking available in 0.10.0 version and earlier). If you adjusted any specific Tk option database resources pertaining to that notebook widget, you have to change them keeping in mind that the new widget is just a bunch of Tk buttons (class Button) placed in a frame (called .nb as before). The class name for the new widget is ButtonBar. So if you explicitly set, say *Notebook*font option, you have to change it to *ButtonBar*font and so on.
Window splitters (thin vertical and horizontal windows used to change relative sizes of windows between which a splitter is placed) have been changed to "Windows" style. This differs from previous "Motif" style which implemented explicit "grip box" on each splitter which was the only "active point" of a splitter.
When upgrading Tkabber from version 0.9.9 or earlier note the following: On Macintosh or Microsoft Windows Tkabber will copy it's configuration directory to a new location (see the next section for details). If the transfer of the config directory goes smoothly you may delete old "~/.tkabber" directory and replace its name in your config file by $::configdir. Also, Tkabber will convert chatlogs directory to a new format. Also, Tkabber changed the way it works with emoticons. Instead of loading them in config file you may put you faivorite emoticons directory into $::configdir/plugins directory, restart Tkabber and then choose emoticons set using Customize GUI.
Tkabber maintains its configuration using a set of files placed in a special configuration directory which location depends on the operating system Tkabber runs on. These locations are: Unix systems: "~/.tkabber"; Macintosh: "~/Library/Application Support/Tkabber"; Under Microsoft Windows this location is governed by the policy of the particular flavor of this OS, but the general rule is that the Tkabber configuration directory is named "Tkabber" and is located in the special system folder for storing application-specific data. For example, under Windows XP this will be something like "C:\Documents and Settings\USERNAME\Application Data\Tkabber", where "USERNAME" is the login name of a particular operating system's user. Tkabber also honors the value of the "TKABBER_HOME" environment variable — if it exists the whole OS-based guessing of the configuration directory location is cancelled and the value of this environment variable is used instead. Once the pathname of the Tkabber configuration directory is known, its value is assigned to the "configdir" global Tcl variable which can be accessed from within the main Tkabber configuration file (see below). One of the first things that Tkabber does when it's starting up is reading a file located in its configuration directory under the name "config.tcl". This is a Tcl source file, so obviously, it's a lot easier to maintain this file if you know the Tcl programming language. If you're not familiar with it, that's okay — most things you'll need to do are pretty simple! (In fact, if you don't have your own configuration file, you'll get the vanilla Tkabber, which hopefully you'll find quite usable.) Note that almost all Tkabber options can be cofigured using graphical interface (menu Tkabber->Customize), so editing configuration file is not strictly necessary. Tkabber is configured in four stages: in the pre-load stage, configuration options which guide the loading process are set; in the post-load stage, configuration options for each module are set; in the menu-load stage, the user is given an option to re-arrange Tkabber's menu bar; and, the final-load stage allows any last changes to be made before the "login" dialog window is displayed to the user. Let's look at each, in turn.
There are a few things that you may let Tkabber know immediately. These are:
The first of these options, ifacetk::options(use_tabbar), tells Tkabber whether you want a tabbed interface or not. If not, here's what to put in your configuration file: Although Tkabber immediately applies most of its configuration changes, in order to apply changed option ifacetk::options(use_tabbar) you have to restart Tkabber. So, basically you have two options: set ifacetk::options(use_tabbar) at the beginning of your configuration file, or using graphical interface save the option and restart Tkabber.
Many aspects of the Tkabber's visual appearance such as fonts, colors and geometry of windows can be configured using the Tk option database. The corresponding Tk's option command can be used in the Tkabber's configuration file in any acceptable way: from small tweaks to reading files containing elaborate sets of configuration commands; ready-to-use examples of such files are included in the distribution and are located under the "examples/xrdb" directory. The Tk toolkit is able to initialize its option database from the XRDB (X Resource Database) if its availability is detected at run time. This means that any settings described here can be tuned via the standard XRDB mechanism (see man xrdb). Beware though that the Tk's semantics of matching option specifications against the option database differ in some subtle details from that of the Xt toolkit. The most notable one is the priority of options: Tk prefers the latest option it sees, while Xt prefers "the most specific" one. When specifying Tkabber-specific options in your XRDB file use the "Tkabber" class as the root element of the options. See for a list of all the resources that you can set to control Tkabber's look-and-feel.
Probably the most commonly used way to configure Tkabber's visual appearance (especially on Windows platforms which lack XRDB mechanism) is to put all the necessary settings in some file and then ask Tk to update its option database from it, like this: The first line tells Tkabber not to load its default "xrdb" file, whilst the second line tells Tkabber which file to load instead. Look at the provided example "xrdb" files to get the idea about how they are organised. Of course, you can use any of that files as a template. And of course, you can simply specify any of the example files instead of your own to the option readfile command to get the provided "theme".
Alternatively, if you're a Tcl "old timer", you can always do: to set the palette to a pleasing color scheme. Read more about this in man palette.
You can also customize the fonts Tkabber uses to render its user interface: The above setting (operating on the Tk option database) selects the font used for all UI elements like buttons and labels and roster and conversation windows. Obviously, you should choose fonts that suit your taste.
If you want to specify another font for roster labels use the following option: When picking fonts, observe these rules: Under X, encoding (charset) of fonts must match that of your locale. Ensure that the specified font exists, since if it's not, Tk will try hard to pick the most suitable one which often yields not what you want. (The best bet is to first pick the font using some tool like xfontsel.) Note that when specifying settings using the Tkabber's configuration files (i.e. not using XRDB directly) you are not forced to use "X-style" (XLFD) font descriptions and may instead specify fonts using sometimes more convenient Tk features described in Tk font manual page.
Next, you may want to Tkabber to use cryptography by default. There are two options: whether the traffic you send should be digitally-signed; and, if you have cryptographic information for someone, should the default action be to encipher your traffic for them. (By defining these options early on, Tkabber will complain immediately if it isn't able to load its cryptographic module; otherwise, the default behavior is to proceed without any cryptographic buttons, menus, and so on.)
By default for parsing XML Tkabber uses (modified) TclXML library that comes with it distribution. This parser is pure-Tcl, and it performance can be not suitable. Then you can install tDOM with built-in expat support and require it in the config file: package require tdom 0.8
Tkabber has a lot of debugging output. By default, it gets printed to the standard output by a Tcl procedure called debugmsg. However, only information about those modules listed in a variable called debug_lvls will be printed.
If you know how to program Tcl, then this will seem rather obvious:
Most users won't care about debugmsg because they're running Tkabber under an application launcher so the standard output is never seen. However, if this isn't the case for you, and you just don't want to see any of this stuff, put this one line in your configuration file:
By default, when Tkabber startup, it show loading process in splash window. To disable this feature, put this in your configuration file:
Tkabber can show all messages in user's native language. This is done by using Tcl's built-in msgcat package which looks for a directory called msgs/ wherever you installed Tkabber, and then uses the LC_MESSAGES environment variable (or LANG if LC_MESSAGES not set) to select the appropriate file. If you wish, you can force use of a particular language by putting a line like this in your configuration file:
Tkabber allows the user to perform textual searching in certain classes of its windows. This searching is controlled by several settings which can be specified in this section. These settings are described in detail in .
After Tkabber reads your configuration file, it loads all of its own modules, it then invokes a procedure called postload. This procedure is supposed to perform module-specific configuration.
The default version of this procedure doesn't do anything. If you want to configure one more module modules, then you need to define the procedure in your configuration file, e.g., This isn't nearly as complicated as it seems. Let's break it down by individual module
Tkabber is shameless in borrowing icons from other Jabber clients. By setting pixmaps::options(pixmaps_theme), you can select a family of related icons. Besides "Default", you can choose one of "Gabber", "JAJC", "Jarl", "Psi", "ICQ", or a few other themes. If you want, you can have Tkabber use a different theme by putting custom theme subdirectory to $::configdir/pixmaps/ directory (tilde means home directory). Tkabber knows that it is a theme directory by looking for icondef.xml file in the directory. To find out the structure of icon definition file, look through XEP-0038 and go to where you installed Tkabber and take a look at the directory called "pixmaps/default/". If you're using the tabbed window interface, Tkabber needs a way of telling you that something has changed in a window that's not on top. This is where the an array called alert_lvls and a list called alert_colors come in. The array maps an incoming message to a priority number from zero to three. The list, which is indexed starting at zero, indicates what color the tab should use to let you know that something's changed. So, the way to read the example is that receiving: an error or server message will cause the tab of a lowered window to go dark blue; a groupchat or headline message will cause the tab to go blue; and, a chat message addressed directly to you will cause the tab to go red.
By default, whenever a new tab is created, it is automatically raised. If you don't like this behavior, add this line: set ifacetk::options(raise_new_tab) 0
This module is presently available only if either: on UNIX, if you have the Tk Xwin extension installed; or, On Windows, if you have the Tcl Winidle extension installed. There are two variables that control when Tkabber automatically marks you as away: plugins::autoaway::options(awaytime) and plugins::autoaway::options(xatime). Both define the idle threshold in minutes (the number does not have to be integer). If variable plugins::autoaway::options(drop_priority) is set in 1 then Tkabber will set priority to 0 when moving in extended away state. Variable plugins::autoaway::options(status) allows to specify text status, which is set when Tkabber is moving in away state.
There are two variables that you can set to control whether Tkabber will allow others to see your avatar: avatar::options(announce) determines whether your presence information indicates that you have an avatar; and, avatar::options(share) determines whether requests for your avatar will be honored.
Most instant messaging users prefer to see all the back-and-forth communication in a single window. If you prefer to see each line sent back-and-forth in a separate window, here's what to put in your postload:
The variable named chat::options(stop_scroll) determines whether a chat window should automatically scroll down to the bottom whenever something new comes in.
You can also set format of time stamp that displayed in beginning of each chat message. Refer to Tcl documentation for description of format. E.g., to display it in "dd:mm:ss" format, add this line: set plugins::options(timestamp_format) {[%T]}
This module shows in popup balloons information of used by this user client name, version, and OS. You can allow or deny automatic asking of this info from users by setting this variable to 1 or 0: set plugins::clientinfo::options(autoask) 1
After you join a conference that's listed in your roster, then whenever you mouse over that roster entry, you'll see a popup listing the conference's participants. If you want to see this popup, regardless of whether you are currently joined with the conference, add this line to your post-load: set plugins::conferenceinfo::options(autoask) 1
You can also set interval between these requests with these two variables: The second variable defines how many minutes to wait after receiving an error reply before trying again. (Usually an error reply indicates that the server hosting the conference doesn't support browsing, so it makes sense not to try that often.
Earlier we saw an example where the ssj::options array from the cryptographic module was set during the preload.
In addition to signed-traffic and encrypt-traffic, you can also tell Tkabber whether to encrypt for a particular JID, e.g.,
The procedure called plugins::emoticons::load_dir is used to load emoticon definitions from a directory. The directory contains a file called "icondef.xml", which defines the mapping between each image and its textual emoticon (To find out what this file looks like, go to where you installed Tkabber and take a look at the file called "emoticons/default/icondef.xml" or read XEP-0038.)
If you have just a few icons, and you don't want to create a directory and a textual mapping, you can use the procedure called plugins::emoticons::add, e.g.,
If you want to disable all emoticons, you can simply load empty directory. Put in postload function
You can set directory in which files will be saved by default:
There are several variables that set the dialog window defaults for adding a groupchat to your roster, or joining a groupchat: gra_group and gra_server specify the default room and conference server, repectively; and, gr_nick, gr_group and gr_server specify the default nickname, room, and conference server, respectively. Note that variables gra_server, gr_nick and gr_server overriden in login procedure, so better place for changing them is in connected_hook (see below).
You may want to have different nicknames for different groupchats. Accordingly, the array called defaultnick is used to set the default nickname for when you enter a conference. The array is indexed by the JID of the room, e.g.,
Another possibility is to put pattern in parentheses. The following example shows how to specify default nickname for all conferences at conference.example.com: Exact JID's take the higher precedence than patterns.
On Unix, Tkabber can check spelling of what you entered by calling an external program ispell. To enable this feature, add following lines to postload function: set plugins::ispell::options(enable) 1
If you enabled this module, then you can also define: the path to the ispell executable by setting plugins::ispell::options(executable) the ispell command line options by setting plugins::ispell::options(command_line); and, the encoding of the output by setting plugins::ispell::options(dictionary_encoding). If you don't care about putting a large load on your process, then you can also set plugins::ispell::options(check_every_symbol) to 1 to check correctness of current word after every entered symbol. (Usually you don't need to set this option.)
Stream initiation profile is defined in XEP-0095 with two transports (XEP-0047 - IBB, XEP-0065 - SOCKS5 bytestreams). With it you can specify what transports you can use, and via negotiation choose more appropriate one. Tkabber comes with two transport implementations: that allows you to connect to any node that supports bytestreams transport (mediated connection is not supported yet); that uses your Jabber connection to transmit the data (which may slowdown other traffic to you).
If your machine is behind a NAT, then you can't use the bytestreams transport, so you should disable it:
You can set directory to store logs: set logger::options(logdir) [file join $::configdir logs]
Also you can allow or disallow storing of private and group chats logs: set logger::options(log_chat) 1 set logger::options(log_groupchat) 1
The first task is to initialize the configuration defaults for the login module. As you can see above, the global array loginconf has a whole bunch of elements, e.g., user, password, and so on. Elements loginconf(user) and loginconf(password)specify username and password to authenticate at your Jabber server. Element loginconf(server) must be set to Jabber server name (the part of you JID after @. Element loginconf(stream_options) is set to one of the following values: plaintext — use plaintext connection; encrypted — use encrypted (via STARTTLS mechanism) connection (this option requires tls extension to be installed); ssl — use encrypted (via legacy SSL mechanism) connection (this option requires tls extension to be installed); compressed — use compressed connection (this option requires Ztcl extension to be installed). Tkabber tries to resolve Jabber server name using SRV first and usual A records in DNS. If the resolution fails (for example if you are in LAN environment without DNS) you can force Tkabber to connect to the server using loginconf(altserver) and loginconf(altport) options (do not forget to set loginconf(usealtserver) to 1). Another option is to use HTTP-polling connect method (if your server supports it) and tunnel XMPP traffic through HTTP. To enable HTTP-polling set loginconf(usehttppoll) to 1. Tkabber then tries to find connect URL using TXT record in DNS (see XEP-0156). You can specify URL manually by setting loginconf(pollurl). This collection of elements, which is termed a login profile, is what populates the dialog window you'll see when Tkabber wants to connect to the server. It turns out that Tkabber lets you have as many different login profiles as you want. If you want more than just one, they're named loginconf1, loginconf2, and so on. What the example above shows is the default values for all profiles being set in loginconf, and then two profiles, one called "Default Account" and the other called "Test Account" being created. If you want to automatically login to server, then you can set the autologin variable to 1. If you set the autologin variable to -1, then Tkabber will not automatically login and will not show login dialog. Default value for autologin is 0. In this case Tkabber shows login dialog.
By default, when you restart Tkabber it won't remember the headlines you received. If you want Tkabber to remember headlines whenever you run it, set message::options(headlines,cache) to 1. By default, Tkabber will put all headline messages into a single window. If you want Tkabber to use a seperate window for each headline source, set message::options(headlines,multiple) to 1.
With this module you can monitor incoming/outgoing traffic from connection to server and send custom XML stanzas. Also you can switch on pretty print option to see incoming and outgoing XML stanzas pretty printed. Note, that with this option they may be drawed incorrectly, e.g. for XHTML tags. Also you can set indentation level via indent option.
By default, your entire roster is shown, even those items that aren't online. The variable called roster::show_only_online controls this. Similarly by default, each item in every category is shown in the roster. If you want to hide the items in a given category, the array called roster::roster lets you do this. In the example, we see that two groups ("RSS" and "Undefined") start with their items hidden. Some peoples use several JIDs. Tkabber lets you specify an alias for people like these, so it will show only one entry in the roster. In the example, we see that user friend@some.host have aliases friend@other.host and friend@another.host. You can also disable all aliases by setting roster::use_aliases to 0.
Tkabber can play sounds on some events. It can use for this snack library or external program that can play WAV files. Sound notifications is enabled when Tkabber starts.
If you want to start Tkabber with sound muted add the following line: set sound::options(mute) 1
If you want Tkabber to stop notifying you when you are not online (in away or dnd state) add the following line: set sound::options(notify_online) 1
If you want Tkabber to mute sound when it is focued (and you are paying enough attention to it) add the following line: set sound::options(mute_if_focus) 1
You can also mute sounds of delayed groupchat messages and delayed personal chat messages: set sound::options(mute_groupchat_delayed) 1 set sound::options(mute_chat_delayed) 0
If you want to use external program for playing sounds and possibly this program's options, then also add something like this (these options are suitable for Linux users with ALSA installed): set sound::options(external_play_program) /usr/bin/aplay set sound::options(external_play_program_options) -q
You can also set minimal interval (in milliseconds) between playing different sounds. set sound::options(delay) 200
Tkabber allows you to specify the filename it will play notifying about some more or less important events. These are: sound::options(connected_sound) — sound playing when Tkabber is connected to the server; sound::options(presence_available_sound) — sound playing when available presence is coming; sound::options(presence_unavailable_sound) — sound playing when unavailable presence is coming; sound::options(chat_my_message_sound) — sound playing when you send one-to-one chat message; sound::options(chat_their_message_sound) — sound playing when you receive one-to-one chat message; sound::options(groupchat_server_message_sound) — sound playing when you receive groupchat message from server; sound::options(groupchat_my_message_sound) — sound playing when you receive groupchat message from server; sound::options(groupchat_their_message_sound) — sound playing when you receive groupchat message from another user; sound::options(groupchat_their_message_to_me_sound) — sound playing when you receive highlighted (usually personally addressed) groupchat message from another user. If you want to disable sound notification for some of the events, then you can add line like this:
After Tkabber invokes your postload procedure, it starts building the GUI. One of the most important things it does is build up a list that specifies its menu bar. It then invokes a procedure called menuload, which is allowed to modify that specification before Tkabber uses it.
The default version of this procedure is the identity function, i.e..,
If you really want to change the menubar specification, then here's how to get started: Go to where you installed the BWidget library and take a look at the file called "BWman/MainFrame.html". The documentation for the "-menu" option explains the syntax of the specification. Go to where you installed Tkabber and take a look at the file called "iface.tcl". Look for the line that starts with "set descmenu". This will show you the specification given to your menuload procedure. Go to where you installed Tkabber and take a look at the file called "examples/mtr-config.tcl". Look at the menuload procedure defined there. It lays out Tkabber's menu bar similar to Gabber's. Finally, study the procedures listed here.
The procedure called avatar::store_on_server stores your avatar on the server.
The procedure called browser::open opens a new browser window.
The procedure called add_group_dialog displays a dialog window when you want to add a groupchat to your roster. Similarly, the procedure called join_group_dialog displays a dialog window when you want to join a groupchat.
The procedure called show_login_dialog displays a dialog window when you want to login to the server. (Prior to attempting to login, if necessary it will logout). Naturally, the procedure called logout does just that; however, if you want get a dialog window for confirmation, use show_logout_dialog instead.
If you want to send a message to someone, the procedure called message::send_dialog will put up a dialog window. It takes upto three optional arguments: the recipient JID, the subject, and the thread. If you want to get added to someone's roster, the procedure called message::send_subscribe_dialog will put up a dialog window. It takes one optional argument: the recipient JID. If you want to adjust your message filters, the procecure called filters::open will put up a dialog window.
If you want to display information about a user, the procecure called userinfo::open will put up a dialog window. It takes two optional arguments: the user's JID; and, whether or not the dialog window should be editable.
Obviously, the second argument makes sense only if it's your own information, i.e.,
There are also two variables that you can use to set your own presence: userstatus and textstatus. The first variable takes one of five values: available; chat; away; xa; dnd; or, invisible. The second variable takes any textual value.
Changes to your presence information are propagated only when userstatus is changed. Accordingly, if you make a change to textstatus, be sure to write userstatus immediately afterwards, even if it's a no-op, e.g.,
Finally, you can use the procedure named help_window to display some textual help. This procedure takes two arguments: the title for the window; and, the text to display. Also, instead of calling exit to terminate Tkabber, please use the quit procedure instead.
Finally, right before Tkabber goes to display the login dialog, it invokes a procedure called finload, which does whatever you want it to.
In addition to various configuration mechanisms, Tkabber lets you define procedures, termed "hooks" that get run when certain events happen.
Here's an example. When Tkabber receives a chat message, how does it know what to process and what to draw? The short answer is that it doesn't need to know anything, all it does is: The hook::run procedure invokes whatever hooks have been defined for draw_message_hook. In fact, more than ten procedures may get invoked to satisfy this hook!
Here's how it works: Tkabber comes with a number of plugins, which get loaded automatically. Each plugin makes one or more calls that look like this: where the last two parameters are: the name of a procedure to run; and, a relative integer priority.
When hook::run is invoked for draw_message_hook, each of these procedures is called, in the priority order (from smallest to largest). If one of the procedures wants to prevent the later procedures from being called, it returns the string "stop".
To continue with the example, in between the pre-load and post-load stages of configuration, the following calls get made by different plugins: Many of these procedures look at the incoming chat message and operate on only certain kinds of messages. Some of these procedures may return "stop", e.g., handle_me which handles chat bodies that start with "/me" and draw_xhtml_message which visualizes XHTML formatted messages. (In this example, the actual namespaces were replaced with "...:" to make it more readable).
Now let's look at the different kind of hooks that Tkabber knows about.
When Tkabber decides that it needs to open a (tabbed) window for a chat or groupchat, two hooks are run: Both hooks are given two parameters: the chatid (ID of the chat or conference room window, you always can obtain JID using chat::get_jid and connection ID using chat::get_connid routines); and, and the type of chat (either "chat" or "groupchat").
Similarly, when Tkabber encounters activity on a tabbed window, a hook is run: The hook is given two parameters: the path of the Tk widget for the tabbed window; and, the chatid of the chat or conference room window.
When you want to send a chat message, a hook is run: The hook is given four parameters: the chatid of the recipient; the localpart of your login identity; the body of the message; and, the type of chat.
The hook is given five parameters: the chatid of the sender window (JID includes a resource); the JID of the sender (without the resource); the type of chat; the body of the message; and, a nested-list of additional payload elements. (This last parameter isn't documented in this version of the documentation.)
Chat windows have menubuttons, and two hooks are used to add items in menu: The first is used in user chat windows, and second in groupchat ones. Hooks are given three parameters: the path of the Tk menu widget; connection ID; and, the JID of user or conference.
In groupchat windows it is possible to complete participants' nicks or commands by pressing TAB key. List of completions is generated by running this hook: The hook is given four parameters: the chatid of conference window; name of global variable, in which current list of possible completions is stored; index of position where completion must be inserted; and content of text widget where completion is requested.
When someone enters/exits conference, the following hooks are called: The hooks are given two parameters: chatid of conference and nick of participant.
Two hooks are invoked whenever a session is connected or disconnected: Both hooks are given one parameter: connection ID (Tkabber allows several connections at once).
When our presence status changes, a hook is run:
The hook is given one parameter: the new presence status value, i.e., one of: available; chat; away; xa; dnd; or unavailable.
Similarly, when someone else's presence changes, a hook is run: The hook is given two parameters: the label associated with the JID (e.g., "fred") or the JID itself (e.g., "fred@example.com") if no label exists in the roster; and, the user's new status.
And for all received presence packets, a hook is run: The hook is given four parameters: connection ID, who send this presence, type of presence (e.g., "error", "unavailable"), list of extended subtags and parameters of this presence (e.g., "-show xa -status online").
When an item is added to the roster window, one of the four hooks is run to add stuff to the menu associated with that item: When run, each hook is given three parameters: the path of the Tk menu widget; the connection ID; and, a JID of the roster item (or the name of the roster group for the last one).
Also the following hook is run to add stuff to the menu in groupchats: The hook is given three parameters: the path of the Tk menu widget; the connection ID; and, a JID of user.
The following hook is run to add stuff to the popup balloon for each roster item: The hook is given three parameters: the variable name in which current popup text is stored, the connection ID, and the JID of the roster item.
There are three "obvious" hooks: The first two, by default, run the postload and finload procedures, respectively. postload_hook is run after all code has been loaded and before initializing main Tkabber window. After that finload_hook is run. The final hook is called just before Tkabber terminates (cf., ).
You can add custom pages to userinfo window using It is run with four arguments: the userinfo notebook widget name; the connection ID; the JID of the user; and a boolean parameter which indicates whether the form is editable.
Search panel may be invoked in certain classes of Tkabber windows using the <<OpenSearchPanel>> Tk virtual event which is bound by default to the <Control-S> keyboard command. Search panel can be dismissed by pressing the <Escape> key and the default search action ("search down") is activated by pressing the <Return> key while entering the search pattern. Search panel is currenlty available in: Chat and groupchat windows; Service discovery window; Chat history logs; All windows of the "Chats history" tool. Searching may be customized using the settings located under the Plugins → Search group of the Customize window. These setings are: ::plugins::search::options(case): perform case-sensitive searching (off by default); ::plugins::search::options(mode): selects searching mode which can be one of: substring — use simple substring search: the typed search string is taken verbatim and then the attempt to locate it is performed. This is the default mode. glob — uses "glob-style" (or "shell-style") matching: special symbols are recognized and they provide for "wildcarding": * matches zero or more characters; ? matches exactly one character; [ and ] define character classes, e.g., [A-Z] will match any character in the series "A", "B", ... "Z". The full syntax is described in Tcl string manual page. That is, this search mode can be convenient for those who want more general yet simple approach to searching and is familiar with the "shell globbing" concept found in Unix shells. regexp — provides for searching using full-blown regular expressions engine. The full syntax is described in Tcl re_syntax manual page.
New default sound theme by Serge Yudin Added new plugins: quotelastmsg, singularity, stripes Many fixes and enhancements
New tabbed user interface. Tab headers now occupy several rows and tab bar can be docked to the left and right sides of chat window Roster filter Added support for pixmaps (in particular emoticons) JISP archives (XEP-0038) Added support for SOCKS4a and SOCKS5 proxy for the main connection Added user location support (XEP-0080) Added user mood support (XEP-0107) Added user activity support (XEP-0108) Added user tune support (XEP-0118) Added entity capabilities (XEP-0115 v.1.5, only reporting) support Added basic robot challenges support (XEP-0158, v.0.9) Added partial data forms media element support (XEP-0221, v.0.2, URIs and images only) Roster is now exported to XML instead of Tcl list Added support for entity time (XEP-0202) Tkabber version is now reported in disco#info (XEP-0232) Moved deprecated Jabber Browser (XEP-0011) to an external plugin Moved Jidlink file transfer to an external plugin Added several new plugins: attline, ctcomp, custom-urls, floatinglog, gmail, openurl, presencecmd, receipts Many fixes and enhancements
New artwork by Artem Bannikov Mediated SOCKS5 connection support for file transfer (XEP-0065) Blocking communicaation with users not in roster (using XEP-0016 via simple interface) Translatable outgoing error messages support (based on recipient's xml:lang) Remote controlling clients support (XEP-0146) Extended stanza addressing support (XEP-0033) New chats history tool with search over the all chatlog files Roster item icons are chosen based on Disco queries to item server Search in Disco, Browser, Headlines, RawXML, and Customize windows New internal plugins: abbrev allows to abbreviate words in chat input windows, postpone stores/restores current input window content New external plugins (aniemoticons, latex, tkabber-khim, traffic, renju) Emoticons theme now can be loaded using GUI Most Tkabber's tabs can now be stored on exit and restored on start XMPP ping support (XEP-0199). Reconnecting based on XMPP ping replies Delayed delivery now recognizes XEP-0203 timestamps Added optional 'My Resources' roster group, which contains other connected resources of the same JID Many fixes and enhancements
Improved privacy lists interface Support for stream compression (XEP-0138) Support for SRV DNS-records Support for TXT DNS-records (XEP-0156) Support for ad-hoc commands (XEP-0050) Improved headlines support Chat state notification support (XEP-0085) Many fixes and enhancements
Support for STARTTLS Reorganized menu Support for searching in chat window Support for annotations about roster items (XEP-0145) Support for conference rooms bookmarks (XEP-0048) Added multilogin support for GPGME Better support for xml:lang Support for service discovery extensions (XEP-0128) Support for NTLM authentication Many fixes and enhancements
Updated support for file transfer (XEP-0095, XEP-0096, XEP-0047, XEP-0065) Support for colored nicks and messages in conference Better multiple logins support Updated support for xml:lang Support for IDNA (RFC3490) Many fixes and enhancements
Multiple logins support History now splitted by month Animated emoticons support Many user interface improvements More XMPP support More translations Bugfixes
Nested roster groups Messages emphasizing User interface improvements Support for XMPP/Jabber MIME Type Bugfixes
Here is list of the most essential Tkabber-specific Tk option database resources that you need to change look: Geometry of main window. Geometry of various windows (when not using tabs). The width of the main roster window. Height of input windows in chat and raw XML windows. Background and foreground colors of popup balloon. Behaviour of popup balloon: can be delay (balloon appeared after some time) and follow (balloon appeared immediately and follows mouse). Color of service discovery browser item name. Color of service discovery browser item identity. Color of service discovery browser entity feature. Background of service discovery browser. Color of user's messages in chat windows. Color of other peoples messages in chat windows. Color of label before server message. Color of server messages in chat windows. Color of error messages in chat windows. Color of URLs in chat windows. Color of mouse highlighted URLs in chat windows. Default color of items in Service Discovery Browser. Default color of feature items in Service Discovery Browser. Default color of identity items in Service Discovery Browser. Default color of option items in Service Discovery Browser. Default color of background in Service Discovery Browser. Tabs alert colors. Roster background color. Indentation for group title. Indentation for group icon. Indentation for item name. Indentation for item with multiple resources. Indentation for item resource. Indentation for item icon. Indentation for resource icon. Top pad for item's names. Bottom pad for item's names. Vertical distance between items. Color of item's names. Background of roster item. Background of roster item when mouse is over. Color of item's border. The same to roster groups. Background color of collapsed group. Colors of item name for different presences.
The next revision of this documentation should discuss: Pre-load: browseurl Post-load: chat_height and chat_width (appear to be no-ops). Menu-load: change_password_dialog conference::create_room_dialog disco::browser::open_win message::send_msg privacy::request_lists rawxml::open_window userinfo::show_info_dialog Hooks: the additional payload format.
Rebecca Malamud was kind enough to design the "enlightened feather" motif used in the Tkabber look-and-feel. The "new look" appeared in the 0.10.0 release ("golden feather" and "blue feather" pixmap themes and the "Earth bulb" logo) was designed by Artem Bannikov. The new sound theme appeared in 0.11.1 release was created by Serge Yudin
Copyright (c) 2002-2008 Alexey Shchepin Tkabber is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Tkabber is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
tkabber-0.11.1/filters.tcl0000644000175000017500000002751210574536044014715 0ustar sergeisergei# $Id: filters.tcl 1038 2007-03-10 14:09:40Z sergei $ # # Obsolete jabberd 1.4 mod_filter (which has been never documented in XEP) support. # namespace eval filters { set condtags {unavailable from resource subject body show type} set acttags {settype forward reply offline continue} set fromtag(unavailable) [::msgcat::mc "I'm not online"] set fromtag(from) [::msgcat::mc "the message is from"] set fromtag(resource) [::msgcat::mc "the message is sent to"] set fromtag(subject) [::msgcat::mc "the subject is"] set fromtag(body) [::msgcat::mc "the body is"] set fromtag(show) [::msgcat::mc "my status is"] set fromtag(type) [::msgcat::mc "the message type is"] set fromtag(settype) [::msgcat::mc "change message type to"] set fromtag(forward) [::msgcat::mc "forward message to"] set fromtag(reply) [::msgcat::mc "reply with"] set fromtag(offline) [::msgcat::mc "store this message offline"] set fromtag(continue) [::msgcat::mc "continue processing rules"] set totag($fromtag(unavailable)) unavailable set totag($fromtag(from)) from set totag($fromtag(resource)) resource set totag($fromtag(subject)) subject set totag($fromtag(body)) body set totag($fromtag(show)) show set totag($fromtag(type)) type set totag($fromtag(settype)) settype set totag($fromtag(forward)) forward set totag($fromtag(reply)) reply set totag($fromtag(offline)) offline set totag($fromtag(continue)) continue set rulecondmenu [list $fromtag(unavailable) $fromtag(from) \ $fromtag(resource) $fromtag(subject) $fromtag(body) \ $fromtag(show) $fromtag(type)] set ruleactmenu [list $fromtag(settype) $fromtag(forward) $fromtag(reply) \ $fromtag(offline) $fromtag(continue)] set m [menu .rulecondmenu -tearoff 0] $m add command -label $fromtag(unavailable) $m add command -label $fromtag(from) $m add command -label $fromtag(resource) $m add command -label $fromtag(subject) $m add command -label $fromtag(body) $m add command -label $fromtag(show) $m add command -label $fromtag(type) set m [menu .ruleactmenu -tearoff 0] $m add command -label $fromtag(settype) $m add command -label $fromtag(forward) $m add command -label $fromtag(reply) $m add command -label $fromtag(offline) $m add command -label $fromtag(continue) custom::defgroup Privacy [::msgcat::mc "Blocking communication options."] -group Tkabber custom::defvar options(enable) 0 \ [::msgcat::mc "Enable jabberd 1.4 mod_filter support (obsolete)."] \ -type boolean -group Privacy \ -command [namespace code setup_menu] } proc filters::setup_menu {args} { variable options set mlabel [::msgcat::mc "Edit message filters"] set m [.mainframe getmenu privacy] catch { set idx [$m index $mlabel] } if {$options(enable) && ![info exists idx]} { $m add separator $m add command -label $mlabel -command [namespace code open] return } if {!$options(enable) && [info exists idx]} { $m delete [expr {$idx - 1}] $idx return } } hook::add finload_hook [namespace current]::filters::setup_menu proc filters::open {} { variable rf if {[winfo exists .filters]} { .filters draw return } jlib::send_iq get \ [jlib::wrapper:createtag item \ -vars {xmlns jabber:iq:filter}] \ -connection [jlib::route ""] \ -command [list filters::recv] } proc filters::recv {res child} { variable rf variable rule variable rulelist debugmsg filters "$res $child" if {![cequal $res OK]} { MessageDlg .filters_err -aspect 50000 -icon error \ -message [format [::msgcat::mc "Requesting filter rules: %s"] \ [error_to_string $child]] \ -type user -buttons ok -default 0 -cancel 0 return } Dialog .filters -title [::msgcat::mc "Filters"] -separator 1 -anchor e \ -modal none \ -default 0 -cancel 1 set f [.filters getframe] set bf [frame $f.bf] pack $bf -side right -anchor n set bb [ButtonBox $bf.bb -orient vertical -spacing 0] $bb add -text [::msgcat::mc "Add"] -command {filters::add} $bb add -text [::msgcat::mc "Edit"] -command {filters::edit} $bb add -text [::msgcat::mc "Remove"] -command {filters::remove} $bb add -text [::msgcat::mc "Move up"] -command {filters::move -1} $bb add -text [::msgcat::mc "Move down"] -command {filters::move 1} pack $bb -side top set sw [ScrolledWindow $f.sw] set rf [listbox $sw.rules] pack $sw -expand yes -fill both $sw setwidget $rf set ok [.filters add -text [::msgcat::mc "OK"] \ -command {filters::commit}] .filters add -text [::msgcat::mc "Cancel"] -command {destroy .filters} $rf delete 0 end array unset rule set rulelist {} jlib::wrapper:splitxml $child tag vars isempty chdata children if {[cequal [jlib::wrapper:getattr $vars xmlns] jabber:iq:filter]} { foreach child $children { process_rule $child } } $rf activate 0 .filters draw } proc filters::process_rule {child} { variable rf variable rulelist jlib::wrapper:splitxml $child tag vars isempty chdata children set rname [jlib::wrapper:getattr $vars name] $rf insert end $rname lappend rulelist $rname foreach data $children { process_rule_data $rname $data } } proc filters::process_rule_data {name child} { variable rule jlib::wrapper:splitxml $child tag vars isempty chdata children lappend rule($name) $tag $chdata debugmsg filters [array get rule] } proc filters::edit {} { variable rf set name [$rf get active] debugmsg filters $name if {$name != ""} { open_edit $name } } proc filters::open_edit {rname} { variable rule variable tmp set w [win_id rule $rname] if {[winfo exists $w]} { focus -force $w return } Dialog $w -title [::msgcat::mc "Edit rule"] -separator 1 -anchor e -modal none \ -default 0 -cancel 1 set f [$w getframe] label $f.lrname -text [::msgcat::mc "Rule Name:"] entry $f.rname -textvariable filters::tmp($rname,name) set tmp($rname,name) $rname grid $f.lrname -row 0 -column 0 -sticky e grid $f.rname -row 0 -column 1 -sticky ew set cond [TitleFrame $f.cond -text [::msgcat::mc "Condition"] -borderwidth 2 -relief groove] set fc [$cond getframe] button $fc.add -text [::msgcat::mc "Add"] pack $fc.add -side right -anchor n set swc [ScrolledWindow $fc.sw -relief sunken -borderwidth $::tk_borderwidth] pack $swc -expand yes -fill both set sfc [ScrollableFrame $swc.f -height 100] $swc setwidget $sfc grid $cond -row 1 -column 0 -sticky news -columnspan 2 set act [TitleFrame $f.act -text [::msgcat::mc "Action"] -borderwidth 2 -relief groove] set fa [$act getframe] button $fa.add -text [::msgcat::mc "Add"] pack $fa.add -side right -anchor n set swa [ScrolledWindow $fa.sw -relief sunken -borderwidth $::tk_borderwidth] pack $swa -expand yes -fill both set sfa [ScrollableFrame $swa.f -height 100] $swa setwidget $sfa grid $act -row 2 -column 0 -sticky news -columnspan 2 grid columnconfig $f 1 -weight 1 -minsize 0 grid rowconfig $f 1 -weight 1 grid rowconfig $f 2 -weight 1 set fcond [$sfc getframe] set fact [$sfa getframe] $w add -text [::msgcat::mc "OK"] -command [list filters::accept_rule $w $rname $fcond $fact] $w add -text [::msgcat::mc "Cancel"] -command [list destroy $w] variable ruleactmenu variable rulecondmenu $fc.add configure \ -command [list filters::insert_item \ $fcond unavailable "" $rulecondmenu] $fa.add configure \ -command [list filters::insert_item $fact settype "" $ruleactmenu] fill_rule $rname $fcond $fact $w draw } proc filters::fill_rule {rname fcond fact} { variable rule variable condtags variable acttags variable ruleactmenu variable rulecondmenu variable items set items($fcond) {} set items($fact) {} foreach {tag value} $rule($rname) { if {[lcontain $condtags $tag]} { debugmsg filters "C $tag $value" insert_item $fcond $tag $value $rulecondmenu } elseif {[lcontain $acttags $tag]} { debugmsg filters "A $tag $value" insert_item $fact $tag $value $ruleactmenu } } } proc filters::insert_item {f tag val menu} { variable items variable fromtag if {[llength $items($f)]} { set n [expr {[lindex $items($f) [expr {[llength $items($f)] - 1}]] + 1}] } else { set n 0 } # TODO: hiding entry for some tags eval [list OptionMenu $f.mb$n $f.mb$n.var] $menu global $f.mb$n.var set $f.mb$n.var $fromtag($tag) entry $f.e$n $f.e$n insert 0 $val Separator $f.sep$n -orient vertical button $f.remove$n -text [::msgcat::mc "Remove"] -command [list filters::remove_item $f $n] grid $f.mb$n -row $n -column 0 -sticky ew grid $f.e$n -row $n -column 1 -sticky ew grid $f.sep$n -row $n -column 2 -sticky ew grid $f.remove$n -row $n -column 3 -sticky ew lappend items($f) $n debugmsg filters $items($f) } proc filters::remove_item {f n} { variable items set idx [lsearch -exact $items($f) $n] set items($f) [lreplace $items($f) $idx $idx] eval destroy [grid slaves $f -row $n] debugmsg filters $items($f) } proc filters::accept_rule {w rname fcond fact} { variable items variable totag variable rule variable tmp variable rf variable rulelist set newname $tmp($rname,name) if {$newname == ""} { MessageDlg .rname_err -aspect 50000 -icon error \ -message [::msgcat::mc "Empty rule name"] -type user \ -buttons ok -default 0 -cancel 0 return } if {$rname != $newname && [lcontain $rulelist $newname]} { MessageDlg .rname_err -aspect 50000 -icon error \ -message [::msgcat::mc "Rule name already exists"] -type user \ -buttons ok -default 0 -cancel 0 return } set rule($newname) {} foreach n $items($fcond) { set tag $totag([set ::$fcond.mb$n.var]) set val [$fcond.e$n get] debugmsg filters "$tag $val" lappend rule($newname) $tag $val } foreach n $items($fact) { set tag $totag([set ::$fact.mb$n.var]) set val [$fact.e$n get] debugmsg filters "$tag $val" lappend rule($newname) $tag $val } debugmsg filters [array get rule] set idx [lsearch -exact $rulelist $rname] set rulelist [lreplace $rulelist $idx $idx $newname] $rf delete 0 end foreach r $rulelist { $rf insert end $r } set items($fcond) {} set items($fact) {} destroy $w } proc filters::add {} { variable rule set rule() {} open_edit "" } proc filters::remove {} { variable rf variable rulelist set name [$rf get active] debugmsg filters $name if {$name != ""} { set idx [lsearch -exact $rulelist $name] set rulelist [lreplace $rulelist $idx $idx] $rf delete active debugmsg filters $rulelist } } proc filters::commit {} { variable rulelist variable rule set result {} foreach rname $rulelist { set rtags {} foreach {tag val} $rule($rname) { lappend rtags [jlib::wrapper:createtag $tag -chdata $val] } lappend result [jlib::wrapper:createtag rule \ -vars [list name $rname] \ -subtags $rtags] } debugmsg filters $result jlib::send_iq set \ [jlib::wrapper:createtag item \ -vars {xmlns jabber:iq:filter} \ -subtags $result] \ -connection [jlib::route ""] \ destroy .filters } proc filters::move {shift} { variable rulelist variable rf set name [$rf get active] set idx [lsearch -exact $rulelist $name] set rulelist [lreplace $rulelist $idx $idx] set newidx [expr {$idx + $shift}] set rulelist [linsert $rulelist $newidx $name] debugmsg filters $rulelist $rf delete 0 end foreach r $rulelist { $rf insert end $r } $rf activate $newidx $rf selection set $newidx #set newidx [expr [$rf index active] - 1] #$rf move active $newidx } tkabber-0.11.1/tclxml/0000755000175000017500000000000011076120366014027 5ustar sergeisergeitkabber-0.11.1/tclxml/sgmlparser.tcl0000644000175000017500000024104311033713562016715 0ustar sergeisergei# sgmlparser.tcl -- # # This file provides the generic part of a parser for SGML-based # languages, namely HTML and XML. # # NB. It is a misnomer. There is no support for parsing # arbitrary SGML as such. # # See sgml.tcl for variable definitions. # # Copyright (c) 1998-2002 Zveno Pty Ltd # http://www.zveno.com/ # # Zveno makes this software available free of charge for any purpose. # Copies may be made of this software but all of this notice must be included # on any copy. # # The software was developed for research purposes only and Zveno does not # warrant that it is error free or fit for any purpose. Zveno disclaims any # liability for all claims, expenses, losses, damages and costs any user may # incur as a result of using, copying or modifying this software. # # Copyright (c) 1997 ANU and CSIRO on behalf of the # participants in the CRC for Advanced Computational Systems ('ACSys'). # # ACSys makes this software and all associated data and documentation # ('Software') available free of charge for any purpose. You may make copies # of the Software but you must include all of this notice on any copy. # # The Software was developed for research purposes and ACSys does not warrant # that it is error free or fit for any purpose. ACSys disclaims any # liability for all claims, expenses, losses, damages and costs any user may # incur as a result of using, copying or modifying the Software. # # $Id: sgmlparser.tcl 1465 2008-07-05 15:46:58Z sergei $ package require -exact sgml 1.8 package require uri 1.0 package provide sgmlparser 1.0 namespace eval sgml { namespace export tokenise parseEvent namespace export parseDTD # NB. Most namespace variables are defined in sgml-8.[01].tcl # to account for differences between versions of Tcl. # This especially includes the regular expressions used. variable ParseEventNum if {![info exists ParseEventNum]} { set ParseEventNum 0 } variable ParseDTDnum if {![info exists ParseDTDNum]} { set ParseDTDNum 0 } variable declExpr [cl $::sgml::Wsp]*([cl ^$::sgml::Wsp]+)[cl $::sgml::Wsp]*([cl ^>]*) variable EntityExpr [cl $::sgml::Wsp]*(%[cl $::sgml::Wsp])?[cl $::sgml::Wsp]*($::sgml::Name)[cl $::sgml::Wsp]+(.*) #variable MarkupDeclExpr <([cl ^$::sgml::Wsp>]+)[cl $::sgml::Wsp]*([cl ^$::sgml::Wsp]+)[cl $::sgml::Wsp]*([cl ^>]*)> #variable MarkupDeclSub "} {\\1} {\\2} {\\3} {" variable MarkupDeclExpr <[cl $::sgml::Wsp]*([cl ^$::sgml::Wsp>]+)[cl $::sgml::Wsp]*([cl ^>]*)> variable MarkupDeclSub "\} {\\1} {\\2} \{" variable ExternalEntityExpr ^(PUBLIC|SYSTEM)[cl $::sgml::Wsp]+("|')(.*?)\\2([cl $::sgml::Wsp]+("|')(.*?)\\2)?([cl $::sgml::Wsp]+NDATA[cl $::sgml::Wsp]+($::xml::Name))?\$ variable StdOptions array set StdOptions [list \ -elementstartcommand [namespace current]::noop \ -elementendcommand [namespace current]::noop \ -characterdatacommand [namespace current]::noop \ -processinginstructioncommand [namespace current]::noop \ -externalentitycommand {} \ -xmldeclcommand [namespace current]::noop \ -doctypecommand [namespace current]::noop \ -commentcommand [namespace current]::noop \ -entitydeclcommand [namespace current]::noop \ -unparsedentitydeclcommand [namespace current]::noop \ -parameterentitydeclcommand [namespace current]::noop \ -notationdeclcommand [namespace current]::noop \ -elementdeclcommand [namespace current]::noop \ -attlistdeclcommand [namespace current]::noop \ -paramentityparsing 1 \ -defaultexpandinternalentities 1 \ -startdoctypedeclcommand [namespace current]::noop \ -enddoctypedeclcommand [namespace current]::noop \ -entityreferencecommand {} \ -warningcommand [namespace current]::noop \ -errorcommand [namespace current]::Error \ -final 1 \ -validate 0 \ -baseurl {} \ -name {} \ -emptyelement [namespace current]::EmptyElement \ -parseattributelistcommand [namespace current]::noop \ -parseentitydeclcommand [namespace current]::noop \ -normalize 1 \ -internaldtd {} \ -reportempty 0 \ ] } # sgml::tokenise -- # # Transform the given HTML/XML text into a Tcl list. # # Arguments: # sgml text to tokenize # elemExpr RE to recognise tags # elemSub transform for matched tags # args options # # Valid Options: # -internaldtdvariable # -final boolean True if no more data is to be supplied # -statevariable varName Name of a variable used to store info # # Results: # Returns a Tcl list representing the document. proc sgml::tokenise {sgml elemExpr1 elemExpr2 elemExpr3 elemSub args} { array set options {-final 1} array set options $args set options(-final) [Boolean $options(-final)] # If the data is not final then there must be a variable to store # unused data. if {!$options(-final) && ![info exists options(-statevariable)]} { return -code error {option "-statevariable" required if not final} } if {[info exists options(-statevariable)]} { # Several rewrites here to handle -final 0 option. # If any cached unparsed xml (state(leftover)), prepend it. upvar #0 $options(-statevariable) state set sgml $state(leftover)$sgml set state(leftover) {} } # Pre-process stage # # Extract the internal DTD subset, if any catch {upvar #0 $options(-internaldtdvariable) dtd} if {[regexp {$comm1] unset state(commentdata) set tag {} set param {} set close {} set state(mode) normal } elseif {[regexp ([cl ^-]*)-->(.*) $text discard comm1 text]} { # end of comment (in text) uplevel #0 $options(-commentcommand) [list $state(commentdata)<$close$tag$param>$comm1] unset state(commentdata) set tag {} set param {} set close {} set state(mode) normal } else { # comment continues append state(commentdata) <$close$tag$param>$text continue } } cdata { if {[regexp ([cl ^\]]*)\]\][cl $Wsp]*\$ $tag discard cdata1]} { # end of CDATA (in tag) uplevel #0 $options(-characterdatacommand) \ [list $state(cdata)<[subst -nocommand -novariable $close$cdata1]] set text [subst -novariable -nocommand $text] set tag {} unset state(cdata) set state(mode) normal } elseif {[regexp ([cl ^\]]*)\]\][cl $Wsp]*\$ $param discard cdata1]} { # end of CDATA (in attributes) uplevel #0 $options(-characterdatacommand) \ [list $state(cdata)<[subst -nocommand -novariable $close$tag$cdata1]] set text [subst -novariable -nocommand $text] set tag {} set param {} unset state(cdata) set state(mode) normal } elseif {[regexp (.*)\]\][cl $Wsp]*>(.*) $text discard cdata1 text]} { # end of CDATA (in text) uplevel #0 $options(-characterdatacommand) \ [list $state(cdata)<[subst -nocommand -novariable $close$tag$param>$cdata1]] set text [subst -novariable -nocommand $text] set tag {} set param {} set close {} unset state(cdata) set state(mode) normal } else { # CDATA continues append state(cdata) [subst -nocommand -novariable <$close$tag$param>$text] continue } } continue { # We're skipping elements looking for the close tag switch -glob -- [string length $tag],[regexp {^\?|!.*} $tag],$close { 0,* { continue } *,0, { if {![string compare $tag $state(continue:tag)]} { set empty [uplevel #0 $options(-emptyelement) [list $tag $param $empty]] if {![string length $empty]} { incr state(continue:level) } } continue } *,0,/ { if {![string compare $tag $state(continue:tag)]} { incr state(continue:level) -1 } if {!$state(continue:level)} { unset state(continue:tag) unset state(continue:level) set state(mode) {} } } default { continue } } } default { # The trailing slash on empty elements can't be automatically separated out # in the RE, so we must do it here. regexp (.*)(/)[cl $Wsp]*$ $param discard param empty } } # default: normal mode # Bug: if the attribute list has a right angle bracket then the empty # element marker will not be seen set empty [uplevel #0 $options(-emptyelement) [list $tag $param $empty]] switch -glob -- [string length $tag],[regexp {^\?|!.*} $tag],$close,$empty { 0,0,, { # Ignore empty tag - dealt with non-normal mode above } *,0,, { # Start tag for an element. # Check if the internal DTD entity is in an attribute value regsub -all &xml:intdtd\; $param \[$options(-internaldtd)\] param set code [catch {ParseEvent:ElementOpen $tag $param [array get options]} msg] set state(haveDocElement) 1 switch -- $code { 0 {# OK} 3 { # break return {} } 4 { # continue # Remember this tag and look for its close set state(continue:tag) $tag set state(continue:level) 1 set state(mode) continue continue } default { return -code $code -errorinfo $::errorInfo $msg } } } *,0,/, { # End tag for an element. set code [catch {ParseEvent:ElementClose $tag [array get options]} msg] switch -- $code { 0 {# OK} 3 { # break return {} } 4 { # continue # skip sibling nodes set state(continue:tag) [lindex $state(stack) end] set state(continue:level) 1 set state(mode) continue continue } default { return -code $code -errorinfo $::errorInfo $msg } } } *,0,,/ { # Empty element # The trailing slash sneaks through into the param variable regsub -all /[cl $::sgml::Wsp]*\$ $param {} param set code [catch {ParseEvent:ElementOpen $tag $param [array get options] -empty 1} msg] set state(haveDocElement) 1 switch -- $code { 0 {# OK} 3 { # break return {} } 4 { # continue # Pretty useless since it closes straightaway } default { return -code $code -errorinfo $::errorInfo $msg } } set code [catch {ParseEvent:ElementClose $tag [array get options] -empty 1} msg] switch -- $code { 0 {# OK} 3 { # break return {} } 4 { # continue # skip sibling nodes set state(continue:tag) [lindex $state(stack) end] set state(continue:level) 1 set state(mode) continue continue } default { return -code $code -errorinfo $::errorInfo $msg } } } *,1,* { # Processing instructions or XML declaration switch -glob -- $tag { {\?xml} { # XML Declaration if {$state(haveXMLDecl)} { uplevel #0 $options(-errorcommand) \ [list illegalcharacter \ "unexpected characters \"<$tag\" around line $state(line)"] } elseif {![regexp {\?$} $param]} { uplevel #0 $options(-errorcommand) \ [list missingcharacters \ "XML Declaration missing characters \"?>\" around line $state(line)"] } else { # We can do the parsing in one step with Tcl 8.1 RE's # This has the benefit of performing better WF checking set adv_re [format {^[%s]*version[%s]*=[%s]*(\"|')(-+|[a-zA-Z0-9_.:]+)\1([%s]+encoding[%s]*=[%s]*("|')([A-Za-z][-A-Za-z0-9._]*)\4)?([%s]*standalone[%s]*=[%s]*("|')(yes|no)\7)?[%s]*\?$} $::sgml::Wsp $::sgml::Wsp $::sgml::Wsp $::sgml::Wsp $::sgml::Wsp $::sgml::Wsp $::sgml::Wsp $::sgml::Wsp $::sgml::Wsp $::sgml::Wsp] if {![regexp $adv_re $param discard delimiter version discard \ delimiter encoding discard delimiter standalone]} { uplevel #0 $options(-errorcommand) \ [list illformeddeclaration \ "XML Declaration not well-formed around line $state(line)"] } else { # Invoke the callback uplevel #0 $options(-xmldeclcommand) [list $version $encoding $standalone] } } } {\?*} { # Processing instruction set tag [string range $tag 1 end] if {[regsub {\?$} $tag {} tag]} { if {[string length [string trim $param]]} { uplevel #0 $options(-errorcommand) \ [list [list unexpectedtext "unexpected text \"$param\"\ in processing instruction around line $state(line)"]] } } elseif {![regexp ^$Name\$ $tag]} { uplevel #0 $options(-errorcommand) \ [list illegalcharacter "illegal character in processing instruction target \"$tag\""] } elseif {[regexp {^[xX][mM][lL]$} $tag]} { uplevel #0 $options(-errorcommand) \ [list illegalcharacters "characters \"xml\" not\ permitted in processing instruction target \"$tag\""] } elseif {![regsub {\?$} $param {} param]} { uplevel #0 $options(-errorcommand) \ [list missingquestion "PI: expected '?' character around line $state(line)"] } set code [catch { uplevel #0 $options(-processinginstructioncommand) \ [list $tag [string trimleft $param]] } msg] switch -- $code { 0 {# OK} 3 { # break return {} } 4 { # continue # skip sibling nodes set state(continue:tag) [lindex $state(stack) end] set state(continue:level) 1 set state(mode) continue continue } default { return -code $code -errorinfo $::errorInfo $msg } } } !DOCTYPE { # External entity reference # This should move into xml.tcl # Parse the params supplied. Looking for Name, ExternalID and MarkupDecl set matched [regexp ^[cl $Wsp]*($Name)[cl $Wsp]*(.*) $param x state(doc_name) param] set state(doc_name) [Normalize $state(doc_name) $options(-normalize)] set externalID {} set pubidlit {} set systemlit {} set externalID {} if {[regexp -nocase ^[cl $Wsp]*(SYSTEM|PUBLIC)(.*) $param x id param]} { switch -- [string toupper $id] { SYSTEM { if {[regexp ^[cl $Wsp]+\"([cl ^\"]*)\"(.*) $param x systemlit param] || \ [regexp ^[cl $Wsp]+'([cl ^']*)'(.*) $param x systemlit param]} { set externalID [list SYSTEM $systemlit] ;# " } else { uplevel #0 $options(-errorcommand) \ [list XXX "syntax error: SYSTEM identifier not followed by literal"] } } PUBLIC { if {[regexp ^[cl $Wsp]+\"([cl ^\"]*)\"(.*) $param x pubidlit param] || \ [regexp ^[cl $Wsp]+'([cl ^']*)'(.*) $param x pubidlit param]} { if {[regexp ^[cl $Wsp]+\"([cl ^\"]*)\"(.*) $param x systemlit param] || \ [regexp ^[cl $Wsp]+'([cl ^']*)'(.*) $param x systemlit param]} { set externalID [list PUBLIC $pubidlit $systemlit] } else { uplevel #0 $options(-errorcommand) \ [list syntaxerror "syntax error: PUBLIC identifier\ not followed by system literal around line $state(line)"] } } else { uplevel #0 $options(-errorcommand) \ [list syntaxerror "syntax error: PUBLIC identifier\ not followed by literal around line $state(line)"] } } } if {[regexp -nocase ^[cl $Wsp]+NDATA[cl $Wsp]+($Name)(.*) $param x notation param]} { lappend externalID $notation } } set state(inDTD) 1 ParseEvent:DocTypeDecl [array get options] $state(doc_name) \ $pubidlit $systemlit $options(-internaldtd) set state(inDTD) 0 } !--* { # Start of a comment # See if it ends in the same tag, otherwise change the # parsing mode regexp {!--(.*)} $tag discard comm1 if {[regexp ([cl ^-]*)--[cl $Wsp]*\$ $comm1 discard comm1_1]} { # processed comment (end in tag) uplevel #0 $options(-commentcommand) [list $comm1_1] } elseif {[regexp ([cl ^-]*)--[cl $Wsp]*\$ $param discard comm2]} { # processed comment (end in attributes) uplevel #0 $options(-commentcommand) [list $comm1$comm2] } elseif {[regexp ([cl ^-]*)-->(.*) $text discard comm2 text]} { # processed comment (end in text) uplevel #0 $options(-commentcommand) [list $comm1$param$empty>$comm2] } else { # start of comment set state(mode) comment set state(commentdata) "$comm1$param$empty>$text" continue } } {!\[CDATA\[*} { regexp {!\[CDATA\[(.*)} $tag discard cdata1 if {[regexp {(.*)]]$} $cdata1 discard cdata2]} { # processed CDATA (end in tag) uplevel #0 $options(-characterdatacommand) [list [subst -novariable -nocommand $cdata2]] set text [subst -novariable -nocommand $text] } elseif {[regexp {(.*)]]$} $param discard cdata2]} { # processed CDATA (end in attribute) # Backslashes in param are quoted at this stage uplevel #0 $options(-characterdatacommand) \ [list $cdata1[subst -novariable -nocommand $cdata2]] set text [subst -novariable -nocommand $text] } elseif {[regexp {(.*)]]>(.*)} $text discard cdata2 text]} { # processed CDATA (end in text) # Backslashes in param and text are quoted at this stage uplevel #0 $options(-characterdatacommand) \ [list $cdata1[subst -novariable -nocommand $param]$empty>[subst -novariable -nocommand $cdata2]] set text [subst -novariable -nocommand $text] } else { # start CDATA set state(cdata) "$cdata1$param>$text" set state(mode) cdata continue } } !ELEMENT - !ATTLIST - !ENTITY - !NOTATION { uplevel #0 $options(-errorcommand) \ [list illegaldeclaration "[string range $tag 1 end] declaration\ not expected in document instance around line $state(line)"] } default { uplevel #0 $options(-errorcommand) \ [list unknowninstruction "unknown processing\ instruction \"<$tag>\" around line $state(line)"] } } } *,1,* - *,0,/,/ { # Syntax error uplevel #0 $options(-errorcommand) \ [list syntaxerror "syntax error: closed/empty tag:\ tag $tag param $param empty $empty close $close around line $state(line)"] } } # Process character data if {$state(haveDocElement) && [llength $state(stack)]} { # Check if the internal DTD entity is in the text regsub -all &xml:intdtd\; $text \[$options(-internaldtd)\] text # Look for entity references if {([array size entities] || \ [string length $options(-entityreferencecommand)]) && \ $options(-defaultexpandinternalentities) && \ [regexp {&[^;]+;} $text]} { # protect Tcl specials # NB. braces and backslashes may already be protected regsub -all {\\({|}|\\)} $text {\1} text regsub -all {([][$\\{}])} $text {\\\1} text # Mark entity references regsub -all {&([^;]+);} $text \ [format {%s; %s {\1} ; %s %s} \}\} \ [namespace code \ [list Entity [array get options] \ $options(-entityreferencecommand) \ $options(-characterdatacommand) \ $options(entities)]] \ [namespace code [list DeProtect $options(-characterdatacommand)]] \ \{\{] text set text "uplevel #0 [namespace code [list DeProtect1 $options(-characterdatacommand)]] {{$text}}" eval $text } else { # Restore protected special characters regsub -all {\\([][{}\\])} $text {\1} text uplevel #0 $options(-characterdatacommand) [list $text] } } elseif {[string length [string trim $text]]} { uplevel #0 $options(-errorcommand) \ [list unexpectedtext "unexpected text \"$text\" in document prolog around line $state(line)"] } } # If this is the end of the document, close all open containers if {$options(-final) && [llength $state(stack)]} { eval $options(-errorcommand) \ [list unclosedelement "element [lindex $state(stack) end] remains unclosed around line $state(line)"] } return {} } # sgml::DeProtect -- # # Invoke given command after removing protecting backslashes # from given text. # # Arguments: # cmd Command to invoke # text Text to deprotect # # Results: # Depends on command proc sgml::DeProtect1 {cmd text} { if {[string compare {} $text]} { regsub -all {\\([]$[{}\\])} $text {\1} text uplevel #0 $cmd [list $text] } } proc sgml::DeProtect {cmd text} { set text [lindex $text 0] if {[string compare {} $text]} { regsub -all {\\([]$[{}\\])} $text {\1} text uplevel #0 $cmd [list $text] } } # sgml::ParserDelete -- # # Free all memory associated with parser # # Arguments: # var global state array # # Results: # Variables unset proc sgml::ParserDelete var { upvar #0 $var state if {![info exists state]} { return -code error "unknown parser" } catch {unset $state(entities)} catch {unset $state(parameterentities)} catch {unset $state(elementdecls)} catch {unset $state(attlistdecls)} catch {unset $state(notationdecls)} catch {unset $state(namespaces)} unset state return {} } # sgml::ParseEvent:ElementOpen -- # # Start of an element. # # Arguments: # tag Element name # attr Attribute list # opts Options # args further configuration options # # Options: # -empty boolean # indicates whether the element was an empty element # # Results: # Modify state and invoke callback proc sgml::ParseEvent:ElementOpen {tag attr opts args} { variable Name variable Wsp array set options $opts upvar #0 $options(-statevariable) state array set cfg {-empty 0} array set cfg $args if {$options(-normalize)} { set tag [string toupper $tag] } # Update state lappend state(stack) $tag # Parse attribute list into a key-value representation if {[string compare $options(-parseattributelistcommand) {}]} { if {[catch {uplevel #0 $options(-parseattributelistcommand) [list $opts $attr]} attr]} { if {[string compare [lindex $attr 0] "unterminated attribute value"]} { uplevel #0 $options(-errorcommand) \ [list unterminatedattribute "$attr around line $state(line)"] set attr {} } else { # It is most likely that a ">" character was in an attribute value. # This manifests itself by ">" appearing in the element's text. # In this case the callback should return a three element list; # the message "unterminated attribute value", the attribute list it # did manage to parse and the remainder of the attribute list. foreach {msg attlist brokenattr} $attr break upvar text elemText if {[string first > $elemText] >= 0} { # Now piece the attribute list back together regexp ($Name)[cl $Wsp]*=[cl $Wsp]*(\"|')(.*) $brokenattr discard attname delimiter attvalue regexp (.*)>([cl ^>]*)\$ $elemText discard remattlist elemText regexp ([cl ^$delimiter]*)${delimiter}(.*) $remattlist discard remattvalue remattlist append attvalue >$remattvalue lappend attlist $attname $attvalue # Complete parsing the attribute list if {[catch { uplevel #0 $options(-parseattributelistcommand) \ [list $options(-statevariable) $remattlist] } attr]} { uplevel #0 $options(-errorcommand) [list $attr around line $state(line)] set attr {} set attlist {} } else { eval lappend attlist $attr } set attr $attlist } else { uplevel #0 $options(-errorcommand) \ [list unterminatedattribute "$attr around line $state(line)"] set attr {} } } } } set empty {} if {$cfg(-empty) && $options(-reportempty)} { set empty {-empty 1} } # Check for namespace declarations upvar #0 $options(namespaces) namespaces set nsdecls {} if {[llength $attr]} { array set attrlist $attr foreach {attrName attrValue} [array get attrlist xmlns*] { unset attrlist($attrName) set colon [set prefix {}] if {[regexp {^xmlns(:(.+))?$} $attrName discard colon prefix]} { switch -glob -- [string length $colon],[string length $prefix] { *,0 - 0,0 { # *,0 is a HACK: Ignore empty namespace prefix # TODO: investigate it # default NS declaration lappend state(defaultNSURI) $attrValue lappend state(defaultNS) [llength $state(stack)] lappend nsdecls $attrValue {} } 0,* { # Huh? } *,0 { # Error uplevel #0 $state(-warningcommand) \ "no prefix specified for namespace URI \"$attrValue\" in element \"$tag\"" } default { set namespaces($prefix,[llength $state(stack)]) $attrValue lappend nsdecls $attrValue $prefix } } } } if {[llength $nsdecls]} { set nsdecls [list -namespacedecls $nsdecls] } set attr [array get attrlist] } # Check whether this element has an expanded name set ns {} if {[regexp {([^:]+):(.*)$} $tag discard prefix tag1]} { set nsspec [lsort -dictionary -decreasing [array names namespaces $prefix,*]] if {[llength $nsspec]} { set tag $tag1 set nsuri $namespaces([lindex $nsspec 0]) set ns [list -namespace $nsuri] } else { # HACK: ignore undeclared namespace (and replace it by default one) # TODO: investigate it #uplevel #0 $options(-errorcommand) \ # [list namespaceundeclared "no namespace declared for prefix \"$prefix\" in element $tag"] if {[llength $state(defaultNSURI)]} { set ns [list -namespace [lindex $state(defaultNSURI) end]] } } } elseif {[llength $state(defaultNSURI)]} { set ns [list -namespace [lindex $state(defaultNSURI) end]] } # Prepend attributes with XMLNS URI set attr1 {} foreach {key val} $attr { if {[regexp {([^:]+):(.*)$} $key discard prefix key1]} { set nsspec [lsort -dictionary -decreasing [array names namespaces $prefix,*]] if {[llength $nsspec]} { set nsuri $namespaces([lindex $nsspec 0]) lappend attr1 $nsuri:$key1 $val } else { # HACK: ignore undeclared namespace # TODO: investigate it #uplevel #0 $options(-errorcommand) \ # [list namespaceundeclared "no namespace declared for prefix \"$prefix\" in attribute $key"] lappend attr1 $key $val } } else { lappend attr1 $key $val } } # Invoke callback set code [catch {uplevel #0 $options(-elementstartcommand) [list $tag $attr1] $empty $ns $nsdecls} msg] return -code $code -errorinfo $::errorInfo $msg } # sgml::ParseEvent:ElementClose -- # # End of an element. # # Arguments: # tag Element name # opts Options # args further configuration options # # Options: # -empty boolean # indicates whether the element as an empty element # # Results: # Modify state and invoke callback proc sgml::ParseEvent:ElementClose {tag opts args} { array set options $opts upvar #0 $options(-statevariable) state array set cfg {-empty 0} array set cfg $args # WF check if {[string compare $tag [lindex $state(stack) end]]} { uplevel #0 $options(-errorcommand) \ [list illegalendtag "end tag \"$tag\" does not match open\ element \"[lindex $state(stack) end]\" around line $state(line)"] return } # Check whether this element has an expanded name upvar #0 $options(namespaces) namespaces set ns {} if {[regexp {([^:]+):(.*)$} $tag discard prefix tag1]} { set nsspec [lsort -dictionary -decreasing [array names namespaces $prefix,*]] if {[llength $nsspec]} { set tag $tag1 set nsuri $namespaces([lindex $nsspec 0]) set ns [list -namespace $nsuri] } else { # HACK: ignore undeclared namespace (and replace it by default one) if {[llength $state(defaultNSURI)]} { set ns [list -namespace [lindex $state(defaultNSURI) end]] } } } elseif {[llength $state(defaultNSURI)]} { set ns [list -namespace [lindex $state(defaultNSURI) end]] } # Pop namespace stacks, if any if {[llength $state(defaultNS)]} { if {[llength $state(stack)] == [lindex $state(defaultNS) end]} { set state(defaultNS) [lreplace $state(defaultNS) end end] set state(defaultNSURI) [lreplace $state(defaultNSURI) end end] } } foreach nsspec [array names namespaces *,[llength $state(stack)]] { unset namespaces($nsspec) } # Update state set state(stack) [lreplace $state(stack) end end] set empty {} if {$cfg(-empty) && $options(-reportempty)} { set empty {-empty 1} } # Invoke callback # Mats: Shall be same as sgml::ParseEvent:ElementOpen to handle exceptions in callback. set code [catch {uplevel #0 $options(-elementendcommand) [list $tag] $empty $ns} msg] return -code $code -errorinfo $::errorInfo $msg } # sgml::Normalize -- # # Perform name normalization if required # # Arguments: # name name to normalize # req normalization required # # Results: # Name returned as upper-case if normalization required proc sgml::Normalize {name req} { if {$req} { return [string toupper $name] } else { return $name } } # sgml::Entity -- # # Resolve XML entity references (syntax: &xxx;). # # Arguments: # opts options # entityrefcmd application callback for entity references # pcdatacmd application callback for character data # entities name of array containing entity definitions. # ref entity reference (the "xxx" bit) # # Results: # Returns substitution text for given entity. proc sgml::Entity {opts entityrefcmd pcdatacmd entities ref} { array set options $opts upvar #0 $options(-statevariable) state if {![string length $entities]} { set entities [namespace current]::EntityPredef } switch -glob -- $ref { %* { # Parameter entity - not recognised outside of a DTD } #x* { # Character entity - hex if {[catch {format %c [scan [string range $ref 2 end] %x tmp; set tmp]} char]} { return -code error "malformed character entity \"$ref\"" } uplevel #0 $pcdatacmd [list $char] return {} } #* { # Character entity - decimal if {[catch {format %c [scan [string range $ref 1 end] %d tmp; set tmp]} char]} { return -code error "malformed character entity \"$ref\"" } uplevel #0 $pcdatacmd [list $char] return {} } default { # General entity upvar #0 $entities map if {[info exists map($ref)]} { if {![regexp {<|&} $map($ref)]} { # Simple text replacement - optimise uplevel #0 $pcdatacmd [list $map($ref)] return {} } # Otherwise an additional round of parsing is required. # This only applies to XML, since HTML doesn't have general entities # Must parse the replacement text for start & end tags, etc # This text must be self-contained: balanced closing tags, and so on set tokenised [tokenise $map($ref) $::xml::tokExpr1 $::xml::tokExpr2 $::xml::tokExpr3 $::xml::substExpr] set options(-final) 0 eval parseEvent [list $tokenised] [array get options] return {} } elseif {[string compare $entityrefcmd "::sgml::noop"]} { set result [uplevel #0 $entityrefcmd [list $ref]] if {[string length $result]} { uplevel #0 $pcdatacmd [list $result] } return {} } else { # Reconstitute entity reference uplevel #0 $options(-errorcommand) \ [list illegalentity "undefined entity reference \"$ref\""] return {} } } } # If all else fails leave the entity reference untouched uplevel #0 $pcdatacmd [list &$ref\;] return {} } #################################### # # DTD parser for SGML (XML). # # This DTD actually only handles XML DTDs. Other language's # DTD's, such as HTML, must be written in terms of a XML DTD. # #################################### # sgml::ParseEvent:DocTypeDecl -- # # Entry point for DTD parsing # # Arguments: # opts configuration options # docEl document element name # pubId public identifier # sysId system identifier (a URI) # intSSet internal DTD subset proc sgml::ParseEvent:DocTypeDecl {opts docEl pubId sysId intSSet} { array set options {} array set options $opts set code [catch {uplevel #0 $options(-doctypecommand) [list $docEl $pubId $sysId $intSSet]} err] switch -- $code { 3 { # break return {} } 0 - 4 { # continue } default { return -code $code $err } } # Otherwise we'll parse the DTD and report it piecemeal # The internal DTD subset is processed first (XML 2.8) # During this stage, parameter entities are only allowed # between markup declarations ParseDTD:Internal [array get options] $intSSet # The external DTD subset is processed last (XML 2.8) # During this stage, parameter entities may occur anywhere # We must resolve the external identifier to obtain the # DTD data. The application may supply its own resolver. if {[string length $pubId] || [string length $sysId]} { uplevel #0 $options(-externalentitycommand) [list $options(-name) $options(-baseurl) $sysId $pubId] } return {} } # sgml::ParseDTD:Internal -- # # Parse the internal DTD subset. # # Parameter entities are only allowed between markup declarations. # # Arguments: # opts configuration options # dtd DTD data # # Results: # Markup declarations parsed may cause callback invocation proc sgml::ParseDTD:Internal {opts dtd} { variable MarkupDeclExpr variable MarkupDeclSub array set options {} array set options $opts upvar #0 $options(-statevariable) state upvar #0 $options(parameterentities) PEnts upvar #0 $options(externalparameterentities) ExtPEnts # Tokenize the DTD # Protect Tcl special characters regsub -all {([{}\\])} $dtd {\\\1} dtd regsub -all $MarkupDeclExpr $dtd $MarkupDeclSub dtd # Entities may have angle brackets in their replacement # text, which breaks the RE processing. So, we must # use a similar technique to processing doc instances # to rebuild the declarations from the pieces set mode {} ;# normal set delimiter {} set name {} set param {} set state(inInternalDTD) 1 # Process the tokens foreach {decl value text} [lrange "{} {} \{$dtd\}" 3 end] { # Keep track of line numbers incr state(line) [regsub -all \n $text {} discard] ParseDTD:EntityMode [array get options] mode replText decl value text $delimiter $name $param ParseDTD:ProcessMarkupDecl [array get options] decl value delimiter name mode replText text param # There may be parameter entity references between markup decls if {[regexp {%.*;} $text]} { # Protect Tcl special characters regsub -all {([{}\\])} $text {\\\1} text regsub -all %($::sgml::Name)\; $text "\} {\\1} \{" text set PElist "\{$text\}" set PElist [lreplace $PElist end end] foreach {text entref} $PElist { if {[string length [string trim $text]]} { uplevel #0 $options(-errorcommand) \ [list unexpectedtext "unexpected text in internal DTD subset around line $state(line)"] } # Expand parameter entity and recursively parse # BUG: no checks yet for recursive entity references if {[info exists PEnts($entref)]} { set externalParser [$options(-name) entityparser] $externalParser parse $PEnts($entref) -dtdsubset internal } elseif {[info exists ExtPEnts($entref)]} { set externalParser [$options(-name) entityparser] $externalParser parse $ExtPEnts($entref) -dtdsubset external #$externalParser free } else { uplevel #0 $options(-errorcommand) \ [list illegalreference "reference to undeclared parameter entity \"$entref\""] } } } } return {} } # sgml::ParseDTD:EntityMode -- # # Perform special processing for various parser modes # # Arguments: # opts configuration options # modeVar pass-by-reference mode variable # replTextVar pass-by-ref # declVar pass-by-ref # valueVar pass-by-ref # textVar pass-by-ref # delimiter delimiter currently in force # name # param # # Results: # Depends on current mode proc sgml::ParseDTD:EntityMode {opts modeVar replTextVar declVar valueVar textVar delimiter name param} { upvar 1 $modeVar mode upvar 1 $replTextVar replText upvar 1 $declVar decl upvar 1 $valueVar value upvar 1 $textVar text array set options $opts switch -- $mode { {} { # Pass through to normal processing section } entity { # Look for closing delimiter if {[regexp ([cl ^$delimiter]*)${delimiter}(.*) $decl discard val1 remainder]} { append replText <$val1 DTD:ENTITY [array get options] $name [string trim $param] $delimiter$replText$delimiter set decl / set text $remainder\ $value>$text set value {} set mode {} } elseif {[regexp ([cl ^$delimiter]*)${delimiter}(.*) $value discard val2 remainder]} { append replText <$decl\ $val2 DTD:ENTITY [array get options] $name [string trim $param] $delimiter$replText$delimiter set decl / set text $remainder>$text set value {} set mode {} } elseif {[regexp ([cl ^$delimiter]*)${delimiter}(.*) $text discard val3 remainder]} { append replText <$decl\ $value>$val3 DTD:ENTITY [array get options] $name [string trim $param] $delimiter$replText$delimiter set decl / set text $remainder set value {} set mode {} } else { # Remain in entity mode append replText <$decl\ $value>$text return -code continue } } ignore { upvar #0 $options(-statevariable) state if {[regexp {]](.*)$} $decl discard remainder]} { set state(condSections) [lreplace $state(condSections) end end] set decl $remainder set mode {} } elseif {[regexp {]](.*)$} $value discard remainder]} { set state(condSections) [lreplace $state(condSections) end end] regexp <[cl $::sgml::Wsp]*($::sgml::Name)(.*) $remainder discard decl value set mode {} } elseif {[regexp {]]>(.*)$} $text discard remainder]} { set state(condSections) [lreplace $state(condSections) end end] set decl / set value {} set text $remainder #regexp <[cl $::sgml::Wsp]*($::sgml::Name)([cl ^>]*)>(.*) $remainder discard decl value text set mode {} } else { set decl / } } comment { # Look for closing comment delimiter upvar #0 $options(-statevariable) state if {[regexp (.*?)--(.*)\$ $decl discard data1 remainder]} { } elseif {[regexp (.*?)--(.*)\$ $value discard data1 remainder]} { } elseif {[regexp (.*?)--(.*)\$ $text discard data1 remainder]} { } else { # comment continues append state(commentdata) <$decl\ $value>$text set decl / set value {} set text {} } } } return {} } # sgml::ParseDTD:ProcessMarkupDecl -- # # Process a single markup declaration # # Arguments: # opts configuration options # declVar pass-by-ref # valueVar pass-by-ref # delimiterVar pass-by-ref for current delimiter in force # nameVar pass-by-ref # modeVar pass-by-ref for current parser mode # replTextVar pass-by-ref # textVar pass-by-ref # paramVar pass-by-ref # # Results: # Depends on markup declaration. May change parser mode proc sgml::ParseDTD:ProcessMarkupDecl {opts declVar valueVar delimiterVar nameVar modeVar replTextVar textVar paramVar} { upvar 1 $modeVar mode upvar 1 $replTextVar replText upvar 1 $textVar text upvar 1 $declVar decl upvar 1 $valueVar value upvar 1 $nameVar name upvar 1 $delimiterVar delimiter upvar 1 $paramVar param variable declExpr variable ExternalEntityExpr array set options $opts upvar #0 $options(-statevariable) state switch -glob -- $decl { / { # continuation from entity processing } !ELEMENT { # Element declaration if {[regexp $declExpr $value discard tag cmodel]} { DTD:ELEMENT [array get options] $tag $cmodel } else { uplevel #0 $options(-errorcommand) \ [list illegaldeclaration "malformed element declaration around line $state(line)"] } } !ATTLIST { # Attribute list declaration variable declExpr if {[regexp $declExpr $value discard tag attdefns]} { if {[catch {DTD:ATTLIST [array get options] $tag $attdefns} err]} { #puts stderr "Stack trace: $::errorInfo\n***\n" # Atttribute parsing has bugs at the moment #return -code error "$err around line $state(line)" return {} } } else { uplevel #0 $options(-errorcommand) \ [list illegaldeclaration "malformed attribute list declaration around line $state(line)"] } } !ENTITY { # Entity declaration variable EntityExpr if {[regexp $EntityExpr $value discard param name value]} { # Entity replacement text may have a '>' character. # In this case, the real delimiter will be in the following # text. This is complicated by the possibility of there # being several '<','>' pairs in the replacement text. # At this point, we are searching for the matching quote delimiter. if {[regexp $ExternalEntityExpr $value]} { DTD:ENTITY [array get options] $name [string trim $param] $value } elseif {[regexp (\"|')(.*?)\\1(.*) $value discard delimiter replText value]} { if {[string length [string trim $value]]} { uplevel #0 $options(-errorcommand) \ [list illegaldeclaration "malformed entity declaration around line $state(line)"] } else { DTD:ENTITY [array get options] $name [string trim $param] $delimiter$replText$delimiter } } elseif {[regexp (\"|')(.*) $value discard delimiter replText]} { append replText >$text set text {} set mode entity } else { uplevel #0 $options(-errorcommand) \ [list illegaldeclaration "no delimiter for entity declaration around line $state(line)"] } } else { uplevel #0 $options(-errorcommand) \ [list illegaldeclaration "malformed entity declaration around line $state(line)"] } } !NOTATION { # Notation declaration if {[regexp $declExpr param discard tag notation]} { DTD:ENTITY [array get options] $tag $notation } else { uplevel #0 $options(-errorcommand) \ [list illegaldeclaration "malformed entity declaration around line $state(line)"] } } !--* { # Start of a comment if {[regexp !--(.*?)--\$ $decl discard data]} { if {[string length [string trim $value]]} { uplevel #0 $options(-errorcommand) [list unexpectedtext "unexpected text \"$value\""] } uplevel #0 $options(-commentcommand) [list $data] set decl / set value {} } elseif {[regexp -- ^(.*?)--\$ $value discard data2]} { regexp !--(.*)\$ $decl discard data1 uplevel #0 $options(-commentcommand) [list $data1\ $data2] set decl / set value {} } elseif {[regexp (.*?)-->(.*)\$ $text discard data3 remainder]} { regexp !--(.*)\$ $decl discard data1 uplevel #0 $options(-commentcommand) [list $data1\ $value>$data3] set decl / set value {} set text $remainder } else { regexp !--(.*)\$ $decl discard data1 set state(commentdata) $data1\ $value>$text set decl / set value {} set text {} set mode comment } } !*INCLUDE* - !*IGNORE* { if {$state(inInternalDTD)} { uplevel #0 $options(-errorcommand) \ [list illegalsection "conditional section not permitted in internal DTD\ subset around line $state(line)"] } if {[regexp {^!\[INCLUDE\[(.*)} $decl discard remainder]} { # Push conditional section stack, popped by ]]> sequence if {[regexp {(.*?)]]$} $remainder discard r2]} { # section closed immediately if {[string length [string trim $r2]]} { uplevel #0 $options(-errorcommand) \ [list unexpectedtext "unexpected text \"$r2\" in conditional section"] } } elseif {[regexp {(.*?)]](.*)} $value discard r2 r3]} { # section closed immediately if {[string length [string trim $r2]]} { uplevel #0 $options(-errorcommand) \ [list unexpectedtext "unexpected text \"$r2\" in conditional section"] } if {[string length [string trim $r3]]} { uplevel #0 $options(-errorcommand) \ [list "unexpected text \"$r3\" in conditional section"] } } else { lappend state(condSections) INCLUDE set parser [$options(-name) entityparser] $parser parse $remainder\ $value> -dtdsubset external #$parser free if {[regexp {(.*?)]]>(.*)} $text discard t1 t2]} { if {[string length [string trim $t1]]} { uplevel #0 $options(-errorcommand) [list unexpectedtext "unexpected text \"$t1\""] } if {![llength $state(condSections)]} { uplevel #0 $options(-errorcommand) \ [list illegalsection "extraneous conditional section close"] } set state(condSections) [lreplace $state(condSections) end end] set text $t2 } } } elseif {[regexp {^!\[IGNORE\[(.*)} $decl discard remainder]} { # Set ignore mode. Still need a stack set mode ignore if {[regexp {(.*?)]]$} $remainder discard r2]} { # section closed immediately if {[string length [string trim $r2]]} { uplevel #0 $options(-errorcommand) \ [list unexpectedtext "unexpected text \"$r2\" in conditional section"] } } elseif {[regexp {(.*?)]](.*)} $value discard r2 r3]} { # section closed immediately if {[string length [string trim $r2]]} { uplevel #0 $options(-errorcommand) \ [list unexpectedtext "unexpected text \"$r2\" in conditional section"] } if {[string length [string trim $r3]]} { uplevel #0 $options(-errorcommand) \ [list unexpectedtext "unexpected text \"$r3\" in conditional section"] } } else { lappend state(condSections) IGNORE if {[regexp {(.*?)]]>(.*)} $text discard t1 t2]} { if {[string length [string trim $t1]]} { uplevel #0 $options(-errorcommand) [list unexpectedtext "unexpected text \"$t1\""] } if {![llength $state(condSections)]} { uplevel #0 $options(-errorcommand) \ [list illegalsection "extraneous conditional section close"] } set state(condSections) [lreplace $state(condSections) end end] set text $t2 } } } else { uplevel #0 $options(-errorcommand) \ [list illegaldeclaration "illegal markup declaration \"$decl\" around line $state(line)"] } } default { if {[regexp {^\?(.*)} $decl discard target]} { # Processing instruction } else { uplevel #0 $options(-errorcommand) [list illegaldeclaration "illegal markup declaration \"$decl\""] } } } return {} } # sgml::ParseDTD:External -- # # Parse the external DTD subset. # # Parameter entities are allowed anywhere. # # Arguments: # opts configuration options # dtd DTD data # # Results: # Markup declarations parsed may cause callback invocation proc sgml::ParseDTD:External {opts dtd} { variable MarkupDeclExpr variable MarkupDeclSub variable declExpr array set options $opts upvar #0 $options(parameterentities) PEnts upvar #0 $options(externalparameterentities) ExtPEnts upvar #0 $options(-statevariable) state # As with the internal DTD subset, watch out for # entities with angle brackets set mode {} ;# normal set delimiter {} set name {} set param {} set oldState 0 catch {set oldState $state(inInternalDTD)} set state(inInternalDTD) 0 # Initialise conditional section stack if {![info exists state(condSections)]} { set state(condSections) {} } set startCondSectionDepth [llength $state(condSections)] while {[string length $dtd]} { set progress 0 set PEref {} if {![string compare $mode "ignore"]} { set progress 1 if {[regexp {]]>(.*)} $dtd discard dtd]} { set remainder {} set mode {} ;# normal set state(condSections) [lreplace $state(condSections) end end] continue } else { uplevel #0 $options(-errorcommand) \ [list missingdelimiter "IGNORE conditional section closing delimiter not found"] } } elseif {[regexp ^(.*?)%($::sgml::Name)\;(.*)\$ $dtd discard data PEref remainder]} { set progress 1 } else { set data $dtd set dtd {} set remainder {} } # Tokenize the DTD (so far) # Protect Tcl special characters regsub -all {([{}\\])} $data {\\\1} dataP set n [regsub -all $MarkupDeclExpr $dataP $MarkupDeclSub dataP] if {$n} { set progress 1 # All but the last markup declaration should have no text set dataP [lrange "{} {} \{$dataP\}" 3 end] if {[llength $dataP] > 3} { foreach {decl value text} [lrange $dataP 0 [expr [llength $dataP] - 4]] { ParseDTD:EntityMode [array get options] mode replText decl value text $delimiter $name $param ParseDTD:ProcessMarkupDecl [array get options] decl value delimiter name mode repltextVar text param if {[string length [string trim $text]]} { # check for conditional section close if {[regexp {]]>(.*)$} $text discard text]} { if {[string length [string trim $text]]} { uplevel #0 $options(-errorcommand) \ [list unexpectedtext "unexpected text \"$text\""] } if {![llength $state(condSections)]} { uplevel #0 $options(-errorcommand) \ [list illegalsection "extraneous conditional section close"] } set state(condSections) [lreplace $state(condSections) end end] if {![string compare $mode "ignore"]} { set mode {} ;# normal } } else { uplevel #0 $options(-errorcommand) \ [list unexpectedtext "unexpected text \"$text\""] } } } } # Do the last declaration foreach {decl value text} [lrange $dataP [expr [llength $dataP] - 3] end] { ParseDTD:EntityMode [array get options] mode replText decl value text $delimiter $name $param ParseDTD:ProcessMarkupDecl [array get options] decl value delimiter name mode repltextVar text param } } # Now expand the PE reference, if any switch -glob -- $mode,[string length $PEref],$n { ignore,0,* { set dtd $text } ignore,*,* { set dtd $text$remainder } *,0,0 { set dtd $data } *,0,* { set dtd $text } *,*,0 { if {[catch {append data $PEnts($PEref)}]} { if {[info exists ExtPEnts($PEref)]} { set externalParser [$options(-name) entityparser] $externalParser parse $ExtPEnts($PEref) -dtdsubset external #$externalParser free } else { uplevel #0 $options(-errorcommand) \ [list entityundeclared "parameter entity \"$PEref\" not declared"] } } set dtd $data$remainder } default { if {[catch {append text $PEnts($PEref)}]} { if {[info exists ExtPEnts($PEref)]} { set externalParser [$options(-name) entityparser] $externalParser parse $ExtPEnts($PEref) -dtdsubset external #$externalParser free } else { uplevel #0 $options(-errorcommand) \ [list entityundeclared "parameter entity \"$PEref\" not declared"] } } set dtd $text$remainder } } # Check whether a conditional section has been terminated if {[regexp {^(.*?)]]>(.*)$} $dtd discard t1 t2]} { if {![regexp <.*> $t1]} { if {[string length [string trim $t1]]} { uplevel #0 $options(-errorcommand) [list unexpectedtext "unexpected text \"$t1\""] } if {![llength $state(condSections)]} { uplevel #0 $options(-errorcommand) [list illegalsection "extraneous conditional section close"] } set state(condSections) [lreplace $state(condSections) end end] if {![string compare $mode "ignore"]} { set mode {} ;# normal } set dtd $t2 set progress 1 } } if {!$progress} { # No parameter entity references were found and # the text does not contain a well-formed markup declaration # Avoid going into an infinite loop upvar #0 $options(-errorcommand) \ [list syntaxerror "external entity does not contain well-formed markup declaration"] break } } set state(inInternalDTD) $oldState # Check that conditional sections have been closed properly if {[llength $state(condSections)] > $startCondSectionDepth} { uplevel #0 $options(-errorcommand) \ [list syntaxerror "[lindex $state(condSections) end] conditional section not closed"] } if {[llength $state(condSections)] < $startCondSectionDepth} { uplevel #0 $options(-errorcommand) [list syntaxerror "too many conditional section closures"] } return {} } # Procedures for handling the various declarative elements in a DTD. # New elements may be added by creating a procedure of the form # parse:DTD:_element_ # For each of these procedures, the various regular expressions they use # are created outside of the proc to avoid overhead at runtime # sgml::DTD:ELEMENT -- # # defines an element. # # The content model for the element is stored in the contentmodel array, # indexed by the element name. The content model is parsed into the # following list form: # # {} Content model is EMPTY. # Indicated by an empty list. # * Content model is ANY. # Indicated by an asterix. # {ELEMENT ...} # Content model is element-only. # {MIXED {element1 element2 ...}} # Content model is mixed (PCDATA and elements). # The second element of the list contains the # elements that may occur. #PCDATA is assumed # (ie. the list is normalised). # # Arguments: # opts configuration options # name element GI # modspec unparsed content model specification proc sgml::DTD:ELEMENT {opts name modspec} { variable Wsp array set options $opts upvar #0 $options(elementdecls) elements if {$options(-validate) && [info exists elements($name)]} { eval $options(-errorcommand) elementdeclared [list "element \"$name\" already declared"] } else { switch -- $modspec { EMPTY { set elements($name) {} uplevel #0 $options(-elementdeclcommand) $name {{}} } ANY { set elements($name) * uplevel #0 $options(-elementdeclcommand) $name * } default { # Don't parse the content model for now, # just pass the model to the application if {0 && [regexp [format {^\([%s]*#PCDATA[%s]*(\|([^)]+))?[%s]*\)*[%s]*$} $Wsp $Wsp $Wsp $Wsp] \ discard discard mtoks]} { set cm($name) [list MIXED [split $mtoks |]] } elseif {0} { if {[catch {CModelParse $state(state) $value} result]} { eval $options(-errorcommand) element [list $result] } else { set cm($id) [list ELEMENT $result] } } else { set elements($name) $modspec uplevel #0 $options(-elementdeclcommand) $name [list $modspec] } } } } } # sgml::CModelParse -- # # Parse an element content model (non-mixed). # A syntax tree is constructed. # A transition table is built next. # # This is going to need alot of work! # # Arguments: # state state array variable # value the content model data # # Results: # A Tcl list representing the content model. proc sgml::CModelParse {state value} { upvar #0 $state var # First build syntax tree set syntaxTree [CModelMakeSyntaxTree $state $value] # Build transition table set transitionTable [CModelMakeTransitionTable $state $syntaxTree] return [list $syntaxTree $transitionTable] } # sgml::CModelMakeSyntaxTree -- # # Construct a syntax tree for the regular expression. # # Syntax tree is represented as a Tcl list: # rep {:choice|:seq {{rep list1} {rep list2} ...}} # where: rep is repetition character, *, + or ?. {} for no repetition # listN is nested expression or Name # # Arguments: # spec Element specification # # Results: # Syntax tree for element spec as nested Tcl list. # # Examples: # (memo) # {} {:seq {{} memo}} # (front, body, back?) # {} {:seq {{} front} {{} body} {? back}} # (head, (p | list | note)*, div2*) # {} {:seq {{} head} {* {:choice {{} p} {{} list} {{} note}}} {* div2}} # (p | a | ul)+ # + {:choice {{} p} {{} a} {{} ul}} proc sgml::CModelMakeSyntaxTree {state spec} { upvar #0 $state var variable Wsp variable name # Translate the spec into a Tcl list. # None of the Tcl special characters are allowed in a content model spec. if {[regexp {\$|\[|\]|\{|\}} $spec]} { return -code error "illegal characters in specification" } regsub -all [format {(%s)[%s]*(\?|\*|\+)?[%s]*(,|\|)?} $name $Wsp $Wsp] $spec \ [format {%sCModelSTname %s {\1} {\2} {\3}} \n $state] spec regsub -all {\(} $spec "\nCModelSTopenParen $state " spec regsub -all [format {\)[%s]*(\?|\*|\+)?[%s]*(,|\|)?} $Wsp $Wsp] $spec \ [format {%sCModelSTcloseParen %s {\1} {\2}} \n $state] spec array set var {stack {} state start} eval $spec # Peel off the outer seq, its redundant return [lindex [lindex $var(stack) 1] 0] } # sgml::CModelSTname -- # # Processes a name in a content model spec. # # Arguments: # state state array variable # name name specified # rep repetition operator # cs choice or sequence delimiter # # Results: # See CModelSTcp. proc sgml::CModelSTname {state name rep cs args} { if {[llength $args]} { return -code error "syntax error in specification: \"$args\"" } CModelSTcp $state $name $rep $cs } # sgml::CModelSTcp -- # # Process a content particle. # # Arguments: # state state array variable # name name specified # rep repetition operator # cs choice or sequence delimiter # # Results: # The content particle is added to the current group. proc sgml::CModelSTcp {state cp rep cs} { upvar #0 $state var switch -glob -- [lindex $var(state) end]=$cs { start= { set var(state) [lreplace $var(state) end end end] # Add (dummy) grouping, either choice or sequence will do CModelSTcsSet $state , CModelSTcpAdd $state $cp $rep } :choice= - :seq= { set var(state) [lreplace $var(state) end end end] CModelSTcpAdd $state $cp $rep } start=| - start=, { set var(state) [lreplace $var(state) end end [expr {$cs == "," ? ":seq" : ":choice"}]] CModelSTcsSet $state $cs CModelSTcpAdd $state $cp $rep } :choice=| - :seq=, { CModelSTcpAdd $state $cp $rep } :choice=, - :seq=| { return -code error \ "syntax error in specification: incorrect delimiter\ after \"$cp\", should be \"[expr {$cs == "," ? "|" : ","}]\"" } end=* { return -code error "syntax error in specification: no delimiter before \"$cp\"" } default { return -code error "syntax error" } } } # sgml::CModelSTcsSet -- # # Start a choice or sequence on the stack. # # Arguments: # state state array # cs choice oir sequence # # Results: # state is modified: end element of state is appended. proc sgml::CModelSTcsSet {state cs} { upvar #0 $state var set cs [expr {$cs == "," ? ":seq" : ":choice"}] if {[llength $var(stack)]} { set var(stack) [lreplace $var(stack) end end $cs] } else { set var(stack) [list $cs {}] } } # sgml::CModelSTcpAdd -- # # Append a content particle to the top of the stack. # # Arguments: # state state array # cp content particle # rep repetition # # Results: # state is modified: end element of state is appended. proc sgml::CModelSTcpAdd {state cp rep} { upvar #0 $state var if {[llength $var(stack)]} { set top [lindex $var(stack) end] lappend top [list $rep $cp] set var(stack) [lreplace $var(stack) end end $top] } else { set var(stack) [list $rep $cp] } } # sgml::CModelSTopenParen -- # # Processes a '(' in a content model spec. # # Arguments: # state state array # # Results: # Pushes stack in state array. proc sgml::CModelSTopenParen {state args} { upvar #0 $state var if {[llength $args]} { return -code error "syntax error in specification: \"$args\"" } lappend var(state) start lappend var(stack) [list {} {}] } # sgml::CModelSTcloseParen -- # # Processes a ')' in a content model spec. # # Arguments: # state state array # rep repetition # cs choice or sequence delimiter # # Results: # Stack is popped, and former top of stack is appended to previous element. proc sgml::CModelSTcloseParen {state rep cs args} { upvar #0 $state var if {[llength $args]} { return -code error "syntax error in specification: \"$args\"" } set cp [lindex $var(stack) end] set var(stack) [lreplace $var(stack) end end] set var(state) [lreplace $var(state) end end] CModelSTcp $state $cp $rep $cs } # sgml::CModelMakeTransitionTable -- # # Given a content model's syntax tree, constructs # the transition table for the regular expression. # # See "Compilers, Principles, Techniques, and Tools", # Aho, Sethi and Ullman. Section 3.9, algorithm 3.5. # # Arguments: # state state array variable # st syntax tree # # Results: # The transition table is returned, as a key/value Tcl list. proc sgml::CModelMakeTransitionTable {state st} { upvar #0 $state var # Construct nullable, firstpos and lastpos functions array set var {number 0} foreach {nullable firstpos lastpos} [ \ TraverseDepth1st $state $st { # Evaluated for leaf nodes # Compute nullable(n) # Compute firstpos(n) # Compute lastpos(n) set nullable [nullable leaf $rep $name] set firstpos [list {} $var(number)] set lastpos [list {} $var(number)] set var(pos:$var(number)) $name } { # Evaluated for nonterminal nodes # Compute nullable, firstpos, lastpos set firstpos [firstpos $cs $firstpos $nullable] set lastpos [lastpos $cs $lastpos $nullable] set nullable [nullable nonterm $rep $cs $nullable] } \ ] break set accepting [incr var(number)] set var(pos:$accepting) # # var(pos:N) maps from position to symbol. # Construct reverse map for convenience. # NB. A symbol may appear in more than one position. # var is about to be reset, so use different arrays. foreach {pos symbol} [array get var pos:*] { set pos [lindex [split $pos :] 1] set pos2symbol($pos) $symbol lappend sym2pos($symbol) $pos } # Construct the followpos functions catch {unset var} followpos $state $st $firstpos $lastpos # Construct transition table # Dstates is [union $marked $unmarked] set unmarked [list [lindex $firstpos 1]] while {[llength $unmarked]} { set T [lindex $unmarked 0] lappend marked $T set unmarked [lrange $unmarked 1 end] # Find which input symbols occur in T set symbols {} foreach pos $T { if {$pos != $accepting && [lsearch $symbols $pos2symbol($pos)] < 0} { lappend symbols $pos2symbol($pos) } } foreach a $symbols { set U {} foreach pos $sym2pos($a) { if {[lsearch $T $pos] >= 0} { # add followpos($pos) if {$var($pos) == {}} { lappend U $accepting } else { eval lappend U $var($pos) } } } set U [makeSet $U] if {[llength $U] && [lsearch $marked $U] < 0 && [lsearch $unmarked $U] < 0} { lappend unmarked $U } set Dtran($T,$a) $U } } return [list [array get Dtran] [array get sym2pos] $accepting] } # sgml::followpos -- # # Compute the followpos function, using the already computed # firstpos and lastpos. # # Arguments: # state array variable to store followpos functions # st syntax tree # firstpos firstpos functions for the syntax tree # lastpos lastpos functions # # Results: # followpos functions for each leaf node, in name/value format proc sgml::followpos {state st firstpos lastpos} { upvar #0 $state var switch -- [lindex [lindex $st 1] 0] { :seq { for {set i 1} {$i < [llength [lindex $st 1]]} {incr i} { followpos $state [lindex [lindex $st 1] $i] \ [lindex [lindex $firstpos 0] [expr $i - 1]] \ [lindex [lindex $lastpos 0] [expr $i - 1]] foreach pos [lindex [lindex [lindex $lastpos 0] [expr $i - 1]] 1] { eval lappend var($pos) [lindex [lindex [lindex $firstpos 0] $i] 1] set var($pos) [makeSet $var($pos)] } } } :choice { for {set i 1} {$i < [llength [lindex $st 1]]} {incr i} { followpos $state [lindex [lindex $st 1] $i] \ [lindex [lindex $firstpos 0] [expr $i - 1]] \ [lindex [lindex $lastpos 0] [expr $i - 1]] } } default { # No action at leaf nodes } } switch -- [lindex $st 0] { ? { # We having nothing to do here ! Doing the same as # for * effectively converts this qualifier into the other. } * { foreach pos [lindex $lastpos 1] { eval lappend var($pos) [lindex $firstpos 1] set var($pos) [makeSet $var($pos)] } } } } # sgml::TraverseDepth1st -- # # Perform depth-first traversal of a tree. # A new tree is constructed, with each node computed by f. # # Arguments: # state state array variable # t The tree to traverse, a Tcl list # leaf Evaluated at a leaf node # nonTerm Evaluated at a nonterminal node # # Results: # A new tree is returned. proc sgml::TraverseDepth1st {state t leaf nonTerm} { upvar #0 $state var set nullable {} set firstpos {} set lastpos {} switch -- [lindex [lindex $t 1] 0] { :seq - :choice { set rep [lindex $t 0] set cs [lindex [lindex $t 1] 0] foreach child [lrange [lindex $t 1] 1 end] { foreach {childNullable childFirstpos childLastpos} \ [TraverseDepth1st $state $child $leaf $nonTerm] break lappend nullable $childNullable lappend firstpos $childFirstpos lappend lastpos $childLastpos } eval $nonTerm } default { incr var(number) set rep [lindex [lindex $t 0] 0] set name [lindex [lindex $t 1] 0] eval $leaf } } return [list $nullable $firstpos $lastpos] } # sgml::firstpos -- # # Computes the firstpos function for a nonterminal node. # # Arguments: # cs node type, choice or sequence # firstpos firstpos functions for the subtree # nullable nullable functions for the subtree # # Results: # firstpos function for this node is returned. proc sgml::firstpos {cs firstpos nullable} { switch -- $cs { :seq { set result [lindex [lindex $firstpos 0] 1] for {set i 0} {$i < [llength $nullable]} {incr i} { if {[lindex [lindex $nullable $i] 1]} { eval lappend result [lindex [lindex $firstpos [expr $i + 1]] 1] } else { break } } } :choice { foreach child $firstpos { eval lappend result $child } } } return [list $firstpos [makeSet $result]] } # sgml::lastpos -- # # Computes the lastpos function for a nonterminal node. # Same as firstpos, only logic is reversed # # Arguments: # cs node type, choice or sequence # lastpos lastpos functions for the subtree # nullable nullable functions forthe subtree # # Results: # lastpos function for this node is returned. proc sgml::lastpos {cs lastpos nullable} { switch -- $cs { :seq { set result [lindex [lindex $lastpos end] 1] for {set i [expr [llength $nullable] - 1]} {$i >= 0} {incr i -1} { if {[lindex [lindex $nullable $i] 1]} { eval lappend result [lindex [lindex $lastpos $i] 1] } else { break } } } :choice { foreach child $lastpos { eval lappend result $child } } } return [list $lastpos [makeSet $result]] } # sgml::makeSet -- # # Turn a list into a set, ie. remove duplicates. # # Arguments: # s a list # # Results: # A set is returned, which is a list with duplicates removed. proc sgml::makeSet s { foreach r $s { if {[llength $r]} { set unique($r) {} } } return [array names unique] } # sgml::nullable -- # # Compute the nullable function for a node. # # Arguments: # nodeType leaf or nonterminal # rep repetition applying to this node # name leaf node: symbol for this node, nonterm node: choice or seq node # subtree nonterm node: nullable functions for the subtree # # Results: # Returns nullable function for this branch of the tree. proc sgml::nullable {nodeType rep name {subtree {}}} { switch -glob -- $rep:$nodeType { :leaf - +:leaf { return [list {} 0] } \\*:leaf - \\?:leaf { return [list {} 1] } \\*:nonterm - \\?:nonterm { return [list $subtree 1] } :nonterm - +:nonterm { switch -- $name { :choice { set result 0 foreach child $subtree { set result [expr $result || [lindex $child 1]] } } :seq { set result 1 foreach child $subtree { set result [expr $result && [lindex $child 1]] } } } return [list $subtree $result] } } } # sgml::DTD:ATTLIST -- # # defines an attribute list. # # Arguments: # opts configuration opions # name Element GI # attspec unparsed attribute definitions # # Results: # Attribute list variables are modified. proc sgml::DTD:ATTLIST {opts name attspec} { variable attlist_exp variable attlist_enum_exp variable attlist_fixed_exp array set options $opts # Parse the attribute list. If it were regular, could just use foreach, # but some attributes may have values. regsub -all {([][$\\])} $attspec {\\\1} attspec regsub -all $attlist_exp $attspec "\}\nDTDAttribute {$options(-attlistdeclcommand)} $name $options(attlistdecls) {\\1} {\\2} {\\3} {} \{" attspec regsub -all $attlist_enum_exp $attspec "\}\nDTDAttribute {$options(-attlistdeclcommand)} $name $options(attlistdecls) {\\1} {\\2} {} {\\4} \{" attspec regsub -all $attlist_fixed_exp $attspec "\}\nDTDAttribute {$options(-attlistdeclcommand)} $name $options(attlistdecls) {\\1} {\\2} {\\3} {\\4} \{" attspec eval "noop \{$attspec\}" return {} } # sgml::DTDAttribute -- # # Parse definition of a single attribute. # # Arguments: # callback attribute defn callback # name element name # var array variable # att attribute name # type type of this attribute # default default value of the attribute # value other information # text other text (should be empty) # # Results: # Attribute defn added to array, unless it already exists proc sgml::DTDAttribute args { # BUG: Some problems with parameter passing - deal with it later foreach {callback name var att type default value text} $args break upvar #0 $var atts if {[string length [string trim $text]]} { return -code error "unexpected text \"$text\" in attribute definition" } # What about overridden attribute defns? # A non-validating app may want to know about them # (eg. an editor) if {![info exists atts($name/$att)]} { set atts($name/$att) [list $type $default $value] uplevel #0 $callback [list $name $att $type $default $value] } return {} } # sgml::DTD:ENTITY -- # # declaration. # # Callbacks: # -entitydeclcommand for general entity declaration # -unparsedentitydeclcommand for unparsed external entity declaration # -parameterentitydeclcommand for parameter entity declaration # # Arguments: # opts configuration options # name name of entity being defined # param whether a parameter entity is being defined # value unparsed replacement text # # Results: # Modifies the caller's entities array variable proc sgml::DTD:ENTITY {opts name param value} { array set options $opts if {[string compare % $param]} { # Entity declaration - general or external upvar #0 $options(entities) ents upvar #0 $options(extentities) externals if {[info exists ents($name)] || [info exists externals($name)]} { eval $options(-warningcommand) entity [list "entity \"$name\" already declared"] } else { if {[catch {uplevel #0 $options(-parseentitydeclcommand) [list $value]} value]} { return -code error "unable to parse entity declaration due to \"$value\"" } switch -glob -- [lindex $value 0],[lindex $value 3] { internal, { set ents($name) [EntitySubst [array get options] [lindex $value 1]] uplevel #0 $options(-entitydeclcommand) [list $name $ents($name)] } internal,* { return -code error "unexpected NDATA declaration" } external, { set externals($name) [lrange $value 1 2] uplevel #0 $options(-entitydeclcommand) [eval list $name [lrange $value 1 2]] } external,* { set externals($name) [lrange $value 1 3] uplevel #0 $options(-unparsedentitydeclcommand) [eval list $name [lrange $value 1 3]] } default { return -code error "internal error: unexpected parser state" } } } } else { # Parameter entity declaration upvar #0 $options(parameterentities) PEnts upvar #0 $options(externalparameterentities) ExtPEnts if {[info exists PEnts($name)] || [info exists ExtPEnts($name)]} { eval $options(-warningcommand) parameterentity [list "parameter entity \"$name\" already declared"] } else { if {[catch {uplevel #0 $options(-parseentitydeclcommand) [list $value]} value]} { return -code error "unable to parse parameter entity declaration due to \"$value\"" } if {[string length [lindex $value 3]]} { return -code error "NDATA illegal in parameter entity declaration" } switch -- [lindex $value 0] { internal { # Substitute character references and PEs (XML: 4.5) set value [EntitySubst [array get options] [lindex $value 1]] set PEnts($name) $value uplevel #0 $options(-parameterentitydeclcommand) [list $name $value] } external - default { # Get the replacement text now. # Could wait until the first reference, but easier # to just do it now. set token [uri::geturl [uri::resolve $options(-baseurl) [lindex $value 1]]] set ExtPEnts($name) [lindex [array get $token data] 1] uplevel #0 $options(-parameterentitydeclcommand) [eval list $name [lrange $value 1 2]] } } } } } # sgml::EntitySubst -- # # Perform entity substitution on an entity replacement text. # This differs slightly from other substitution procedures, # because only parameter and character entity substitution # is performed, not general entities. # See XML Rec. section 4.5. # # Arguments: # opts configuration options # value Literal entity value # # Results: # Expanded replacement text proc sgml::EntitySubst {opts value} { array set options $opts # Protect Tcl special characters regsub -all {([{}\\])} $value {\\\1} value # Find entity references regsub -all (&#\[0-9\]+|&#x\[0-9a-fA-F\]+|%${::sgml::Name})\; $value "\[EntitySubstValue [list $options(parameterentities)] {\\1}\]" value set result [subst $value] return $result } # sgml::EntitySubstValue -- # # Handle a single character or parameter entity substitution # # Arguments: # PEvar array variable containing PE declarations # ref character or parameter entity reference # # Results: # Replacement text proc sgml::EntitySubstValue {PEvar ref} { switch -glob -- $ref { &#x* { scan [string range $ref 3 end] %x hex return [format %c $hex] } &#* { return [format %c [string range $ref 2 end]] } %* { upvar #0 $PEvar PEs set ref [string range $ref 1 end] if {[info exists PEs($ref)]} { return $PEs($ref) } else { return -code error "parameter entity \"$ref\" not declared" } } default { return -code error "internal error - unexpected entity reference" } } return {} } # sgml::DTD:NOTATION -- # # Process notation declaration # # Arguments: # opts configuration options # name notation name # value unparsed notation spec proc sgml::DTD:NOTATION {opts name value} { return {} variable notation_exp upvar opts state if {[regexp $notation_exp $value x scheme data] == 2} { } else { eval $state(-errorcommand) notationvalue [list "notation value \"$value\" incorrectly specified"] } } # sgml::ResolveEntity -- # # Default entity resolution routine # # Arguments: # name name of parent parser # base base URL for relative URLs # sysId system identifier # pubId public identifier proc sgml::ResolveEntity {name base sysId pubId} { variable ParseEventNum if {[catch {uri::resolve $base $sysId} url]} { return -code error "unable to resolve system identifier \"$sysId\"" } if {[catch {uri::geturl $url} token]} { return -code error "unable to retrieve external entity \"$url\" for system identifier \"$sysId\"" } upvar #0 $token data set parser [uplevel #0 $name entityparser] $parser parse $data(body) -dtdsubset external #$parser free return {} } tkabber-0.11.1/tclxml/tclparser-8.1.tcl0000644000175000017500000003620510735727467017064 0ustar sergeisergei# tclparser-8.1.tcl -- # # This file provides a Tcl implementation of a XML parser. # This file supports Tcl 8.1. # # See xml-8.[01].tcl for definitions of character sets and # regular expressions. # # Copyright (c) 1998-2002 Zveno Pty Ltd # http://www.zveno.com/ # # Zveno makes this software and all associated data and documentation # ('Software') available free of charge for any purpose. # Copies may be made of this Software but all of this notice must be included # on any copy. # # The Software was developed for research purposes and Zveno does not warrant # that it is error free or fit for any purpose. Zveno disclaims any # liability for all claims, expenses, losses, damages and costs any user may # incur as a result of using, copying or modifying the Software. # # Copyright (c) 1997 Australian National University (ANU). # # ANU makes this software and all associated data and documentation # ('Software') available free of charge for any purpose. You may make copies # of the Software but you must include all of this notice on any copy. # # The Software was developed for research purposes and ANU does not warrant # that it is error free or fit for any purpose. ANU disclaims any # liability for all claims, expenses, losses, damages and costs any user may # incur as a result of using, copying or modifying the Software. # # $Id: tclparser-8.1.tcl 1338 2007-12-30 14:46:15Z sergei $ package require Tcl 8.1 package provide xml::tclparser 2.0 package require -exact xmldefs 2.0 package require -exact sgmlparser 1.0 namespace eval xml::tclparser { namespace export create createexternal externalentity parse \ configure get delete # Tokenising expressions variable tokExpr1 $::xml::tokExpr1 variable tokExpr2 $::xml::tokExpr2 variable tokExpr3 $::xml::tokExpr3 variable substExpr $::xml::substExpr # Register this parser class ::xml::parserclass create tcl \ -createcommand [namespace code create] \ -createentityparsercommand [namespace code createentityparser] \ -parsecommand [namespace code parse] \ -configurecommand [namespace code configure] \ -deletecommand [namespace code delete] } # xml::tclparser::create -- # # Creates XML parser object. # # Arguments: # name unique identifier for this instance # # Results: # The state variable is initialised. proc xml::tclparser::create name { # Initialise state variable upvar \#0 [namespace current]::$name parser array set parser [list \ -name $name \ -final 1 \ -validate 0 \ -statevariable [namespace current]::$name \ -baseurl {} \ internaldtd {} \ entities [namespace current]::Entities$name \ extentities [namespace current]::ExtEntities$name \ parameterentities [namespace current]::PEntities$name \ externalparameterentities [namespace current]::ExtPEntities$name \ elementdecls [namespace current]::ElDecls$name \ attlistdecls [namespace current]::AttlistDecls$name \ notationdecls [namespace current]::NotDecls$name \ depth 0 \ leftover {} \ ] # Initialise entities with predefined set array set [namespace current]::Entities$name [array get ::sgml::EntityPredef] return $name } # xml::tclparser::createentityparser -- # # Creates XML parser object for an entity. # # Arguments: # name name for the new parser # parent name of parent parser # # Results: # The state variable is initialised. proc xml::tclparser::createentityparser {parent name} { upvar #0 [namespace current]::$parent p # Initialise state variable upvar \#0 [namespace current]::$name external array set external [array get p] array set external [list \ -name $name \ -statevariable [namespace current]::$name \ internaldtd {} \ line 0 \ ] incr external(depth) return $name } # xml::tclparser::configure -- # # Configures a XML parser object. # # Arguments: # name unique identifier for this instance # args option name/value pairs # # Results: # May change values of config options proc xml::tclparser::configure {name args} { upvar \#0 [namespace current]::$name parser # BUG: very crude, no checks for illegal args # Mats: Should be synced with sgmlparser.tcl set options { -elementstartcommand -elementendcommand \ -characterdatacommand -processinginstructioncommand \ -externalentitycommand -xmldeclcommand \ -doctypecommand -commentcommand \ -entitydeclcommand -unparsedentitydeclcommand \ -parameterentitydeclcommand -notationdeclcommand \ -elementdeclcommand -attlistdeclcommand \ -paramentityparsing -defaultexpandinternalentities \ -startdoctypedeclcommand -enddoctypedeclcommand \ -entityreferencecommand -warningcommand \ -errorcommand -final \ -validate -baseurl \ -name -emptyelement \ -parseattributelistcommand -parseentitydeclcommand \ -normalize -internaldtd \ -reportempty -ignorewhitespace \ -reportempty \ } set usage [join $options ", "] regsub -all -- - $options {} options set pat ^-([join $options |])$ foreach {flag value} $args { if {[regexp $pat $flag]} { # Validate numbers if {[info exists parser($flag)] && \ [string is integer -strict $parser($flag)] && \ ![string is integer -strict $value]} { return -code error "Bad value for $flag ($value), must be integer" } set parser($flag) $value } else { return -code error "Unknown option $flag, can be: $usage" } } return {} } # xml::tclparser::parse -- # # Parses document instance data # # Arguments: # name parser object # xml data # args configuration options # # Results: # Callbacks are invoked proc xml::tclparser::parse {name xml args} { array set options $args upvar \#0 [namespace current]::$name parser variable tokExpr1 variable tokExpr2 variable tokExpr3 variable substExpr # Mats: if {[llength $args]} { eval {configure $name} $args } set parseOptions [list \ -emptyelement [namespace code ParseEmpty] \ -parseattributelistcommand [namespace code ParseAttrs] \ -parseentitydeclcommand [namespace code ParseEntity] \ -normalize 0] eval lappend parseOptions \ [array get parser -*command] \ [array get parser -reportempty] \ [array get parser -name] \ [array get parser -baseurl] \ [array get parser -validate] \ [array get parser -final] \ [array get parser -defaultexpandinternalentities] \ [array get parser entities] \ [array get parser extentities] \ [array get parser parameterentities] \ [array get parser externalparameterentities] \ [array get parser elementdecls] \ [array get parser attlistdecls] \ [array get parser notationdecls] # Mats: # If -final 0 we also need to maintain the state with a -statevariable ! if {!$parser(-final)} { eval lappend parseOptions [array get parser -statevariable] } set dtdsubset no catch {set dtdsubset $options(-dtdsubset)} switch -- $dtdsubset { internal { # Bypass normal parsing lappend parseOptions -statevariable $parser(-statevariable) array set intOptions [array get ::sgml::StdOptions] array set intOptions $parseOptions ::sgml::ParseDTD:Internal [array get intOptions] $xml return {} } external { # Bypass normal parsing lappend parseOptions -statevariable $parser(-statevariable) array set intOptions [array get ::sgml::StdOptions] array set intOptions $parseOptions ::sgml::ParseDTD:External [array get intOptions] $xml return {} } default { # Pass through to normal processing } } lappend tokenOptions \ -internaldtdvariable [namespace current]::${name}(internaldtd) # Mats: If -final 0 we also need to maintain the state with a -statevariable ! if {!$parser(-final)} { eval lappend tokenOptions [array get parser -statevariable] \ [array get parser -final] } # Mats: # Why not the first four? Just padding? Lrange undos \n interp. # It is necessary to have the first four as well if chopped off in # middle of pcdata. set tokenised [lrange \ [eval {::sgml::tokenise $xml $tokExpr1 $tokExpr2 $tokExpr3 $substExpr} $tokenOptions] \ 0 end] lappend parseOptions -internaldtd [list $parser(internaldtd)] eval ::sgml::parseEvent [list $tokenised] $parseOptions return {} } # xml::tclparser::ParseEmpty -- Tcl 8.1+ version # # Used by parser to determine whether an element is empty. # This is usually dead easy in XML, but as always not quite. # Have to watch out for empty element syntax # # Arguments: # tag element name # attr attribute list (raw) # e End tag delimiter. # # Results: # Return value of e proc xml::tclparser::ParseEmpty {tag attr e} { switch -glob -- [string length $e],[regexp "/[::xml::cl $::xml::Wsp]*$" $attr] { 0,0 { return {} } 0,* { return / } default { return $e } } } # xml::tclparser::ParseAttrs -- Tcl 8.1+ version # # Parse element attributes. # # There are two forms for name-value pairs: # # name="value" # name='value' # # Arguments: # opts parser options # attrs attribute string given in a tag # # Results: # Returns a Tcl list representing the name-value pairs in the # attribute string # # A ">" occurring in the attribute list causes problems when parsing # the XML. This manifests itself by an unterminated attribute value # and a ">" appearing the element text. # In this case return a three element list; # the message "unterminated attribute value", the attribute list it # did manage to parse and the remainder of the attribute list. proc xml::tclparser::ParseAttrs {opts attrs} { set result {} while {[string length [string trim $attrs]]} { if {[regexp ($::xml::Name)[::sgml::cl $::xml::Wsp]*=[::sgml::cl $::xml::Wsp]*(\"|')([::sgml::cl ^<]*?)\\2(.*) \ $attrs -> attrName delimiter value attrs]} { lappend result $attrName [NormalizeAttValue $opts $value] } elseif {[regexp $::xml::Name[::sgml::cl $::xml::Wsp]*=[::sgml::cl $::xml::Wsp]*(\"|')[::sgml::cl ^<]*\$ \ $attrs]} { return -code error [list {unterminated attribute value} $result $attrs] } else { return -code error "invalid attribute list" } } return $result } # xml::tclparser::NormalizeAttValue -- # # Perform attribute value normalisation. This involves: # . character references are appended to the value # . entity references are recursively processed and replacement value appended # . whitespace characters cause a space to be appended # . other characters appended as-is # # Arguments: # opts parser options # value unparsed attribute value # # Results: # Normalised value returned. proc xml::tclparser::NormalizeAttValue {opts value} { # sgmlparser already has backslashes protected # Protect Tcl specials regsub -all {([][$])} $value {\\\1} value # Deal with white space regsub -all "\[$::xml::Wsp\]" $value { } value # Find entity refs regsub -all {&([^;]+);} $value {[NormalizeAttValue:DeRef $opts {\1}]} value return [subst $value] } # xml::tclparser::NormalizeAttValue:DeRef -- # # Handler to normalize attribute values # # Arguments: # opts parser options # ref entity reference # # Results: # Returns character proc xml::tclparser::NormalizeAttValue:DeRef {opts ref} { switch -glob -- $ref { #x* { scan [string range $ref 2 end] %x value set char [format %c $value] # Check that the char is legal for XML if {[regexp [format {^[%s]$} $::xml::Char] $char]} { return $char } else { return -code error "illegal character" } } #* { scan [string range $ref 1 end] %d value set char [format %c $value] # Check that the char is legal for XML if {[regexp [format {^[%s]$} $::xml::Char] $char]} { return $char } else { return -code error "illegal character" } } lt - gt - amp - quot - apos { array set map {lt < gt > amp & quot \" apos '} return $map($ref) } default { # A general entity. Must resolve to a text value - no element structure. array set options $opts upvar #0 $options(entities) map if {[info exists map($ref)]} { if {[regexp < $map($ref)]} { return -code error "illegal character \"<\" in attribute value" } if {![regexp & $map($ref)]} { # Simple text replacement return $map($ref) } # There are entity references in the replacement text. # Can't use child entity parser since must catch element structures return [NormalizeAttValue $opts $map($ref)] } elseif {[string compare $options(-entityreferencecommand) "::sgml::noop"]} { set result [uplevel #0 $options(-entityreferencecommand) [list $ref]] return $result } else { return -code error "unable to resolve entity reference \"$ref\"" } } } } # xml::tclparser::ParseEntity -- # # Parse general entity declaration # # Arguments: # data text to parse # # Results: # Tcl list containing entity declaration proc xml::tclparser::ParseEntity data { set data [string trim $data] if {[regexp $::sgml::ExternalEntityExpr $data \ -> type delimiter1 id1 discard delimiter2 id2 optNDATA ndata]} { switch -- $type { PUBLIC { return [list external $id2 $id1 $ndata] } SYSTEM { return [list external $id1 {} $ndata] } } } elseif {[regexp {^(\"|')(.*?)\1$} $data discard delimiter value]} { return [list internal $value] } else { return -code error "badly formed entity declaration" } } # xml::tclparser::delete -- # # Destroy parser data # # Arguments: # name parser object # # Results: # Parser data structure destroyed proc xml::tclparser::delete name { upvar \#0 [namespace current]::$name parser catch {::sgml::ParserDelete $parser(-statevariable)} catch {unset parser} return {} } # xml::tclparser::get -- # # Retrieve additional information from the parser # # Arguments: # name parser object # method info to retrieve # args additional arguments for method # # Results: # Depends on method proc xml::tclparser::get {name method args} { upvar #0 [namespace current]::$name parser switch -- $method { elementdecl { switch -- [llength $args] { 0 { # Return all element declarations upvar #0 $parser(elementdecls) elements return [array get elements] } 1 { # Return specific element declaration upvar #0 $parser(elementdecls) elements if {[info exists elements([lindex $args 0])]} { return [array get elements [lindex $args 0]] } else { return -code error "element \"[lindex $args 0]\" not\ declared" } } default { return -code error "wrong number of arguments: should be\ \"elementdecl ?element?\"" } } } attlist { if {[llength $args] != 1} { return -code error "wrong number of arguments: should be\ \"get attlist element\"" } upvar #0 $parser(attlistdecls) return {} } entitydecl { } parameterentitydecl { } notationdecl { } default { return -code error "unknown method \"$method\"" } } return {} } # xml::tclparser::ExternalEntity -- # # Resolve and parse external entity # # Arguments: # name parser object # base base URL # sys system identifier # pub public identifier # # Results: # External entity is fetched and parsed proc xml::tclparser::ExternalEntity {name base sys pub} { } tkabber-0.11.1/tclxml/xml-8.1.tcl0000644000175000017500000000753410735727467015670 0ustar sergeisergei# xml.tcl -- # # This file provides generic XML services for all implementations. # This file supports Tcl 8.1 regular expressions. # # See tclparser.tcl for the Tcl implementation of a XML parser. # # Copyright (c) 1998-2000 Zveno Pty Ltd # http://www.zveno.com/ # # Zveno makes this software and all associated data and documentation # ('Software') available free of charge for any purpose. # Copies may be made of this Software but all of this notice must be included # on any copy. # # The Software was developed for research purposes and Zveno does not warrant # that it is error free or fit for any purpose. Zveno disclaims any # liability for all claims, expenses, losses, damages and costs any user may # incur as a result of using, copying or modifying the Software. # # Copyright (c) 1997 Australian National University (ANU). # # ANU makes this software and all associated data and documentation # ('Software') available free of charge for any purpose. You may make copies # of the Software but you must include all of this notice on any copy. # # The Software was developed for research purposes and ANU does not warrant # that it is error free or fit for any purpose. ANU disclaims any # liability for all claims, expenses, losses, damages and costs any user may # incur as a result of using, copying or modifying the Software. # # $Id: xml-8.1.tcl 1338 2007-12-30 14:46:15Z sergei $ package require Tcl 8.1 package provide xmldefs 2.0 package require -exact sgml 1.8 namespace eval xml { namespace export qnamesplit # Convenience routine proc cl x { return "\[$x\]" } # Define various regular expressions # Characters variable Char $::sgml::Char # white space variable Wsp " \t\r\n" variable allWsp [cl $Wsp]* variable noWsp [cl ^$Wsp] # Various XML names and tokens variable NameChar $::sgml::NameChar variable Name $::sgml::Name variable Names $::sgml::Names variable Nmtoken $::sgml::Nmtoken variable Nmtokens $::sgml::Nmtokens # XML Namespaces names # NCName ::= Name - ':' variable NCName $::sgml::Name regsub -all : $NCName {} NCName variable QName (${NCName}:)?$NCName ;# (Prefix ':')? LocalPart # table of predefined entities variable EntityPredef array set EntityPredef { lt < gt > amp & quot \" apos ' } # Expressions for pulling things apart #variable tokExpr <(/?)([::xml::cl ^$::xml::Wsp>/]+)([::xml::cl $::xml::Wsp]*[::xml::cl ^>]*)> variable tokExpr1 {<()(\?[^\s>]+)(([^>]+|[^?]>)*\?)>} variable tokExpr2 {<()(![^\s>]+)(\s*[^>]*)>} variable tokExpr3 {<(/?)([^!?][^\s>/]*)((\s*[^'\"\s]+\s*=\s*('[^']*'|\"[^\"]*\"))*\s*/?)>} variable substExpr "\}\n{\\2} {\\1} {\\3} \{" } ### ### Exported procedures ### # xml::qnamesplit -- # # Split a QName into its constituent parts: # the XML Namespace prefix and the Local-name # # Arguments: # qname XML Qualified Name (see XML Namespaces [6]) # # Results: # Returns prefix and local-name as a Tcl list. # Error condition returned if the prefix or local-name # are not valid NCNames (XML Name) proc xml::qnamesplit qname { variable NCName variable Name set prefix {} set localname $qname if {[regexp : $qname]} { if {![regexp ^($NCName)?:($NCName)\$ $qname discard prefix localname]} { return -code error "name \"$qname\" is not a valid QName" } } elseif {![regexp ^$Name\$ $qname]} { return -code error "name \"$qname\" is not a valid Name" } return [list $prefix $localname] } ### ### General utility procedures ### # xml::noop -- # # A do-nothing proc proc xml::noop args {} ### Following procedures are based on html_library # xml::zapWhite -- # # Convert multiple white space into a single space. # # Arguments: # data plain text # # Results: # As above proc xml::zapWhite data { regsub -all "\[ \t\r\n\]+" $data { } data return $data } tkabber-0.11.1/tclxml/sgml-8.1.tcl0000644000175000017500000001657510512530014016004 0ustar sergeisergei# sgml-8.1.tcl -- # # This file provides generic parsing services for SGML-based # languages, namely HTML and XML. # This file supports Tcl 8.1 characters and regular expressions. # # NB. It is a misnomer. There is no support for parsing # arbitrary SGML as such. # # Copyright (c) 1998-2001 Zveno Pty Ltd # http://www.zveno.com/ # # Zveno makes this software available free of charge for any purpose. # Copies may be made of this software but all of this notice must be included # on any copy. # # The software was developed for research purposes only and Zveno does not # warrant that it is error free or fit for any purpose. Zveno disclaims any # liability for all claims, expenses, losses, damages and costs any user may # incur as a result of using, copying or modifying this software. # # Copyright (c) 1997 ANU and CSIRO on behalf of the # participants in the CRC for Advanced Computational Systems ('ACSys'). # # ACSys makes this software and all associated data and documentation # ('Software') available free of charge for any purpose. You may make copies # of the Software but you must include all of this notice on any copy. # # The Software was developed for research purposes and ACSys does not warrant # that it is error free or fit for any purpose. ACSys disclaims any # liability for all claims, expenses, losses, damages and costs any user may # incur as a result of using, copying or modifying the Software. # # $Id: sgml-8.1.tcl 753 2006-10-09 20:24:44Z sergei $ package require Tcl 8.1 package provide sgml 1.8 namespace eval sgml { # Convenience routine proc cl x { return "\[$x\]" } # Define various regular expressions # Character classes variable Char \t\n\r\ -\uD7FF\uE000-\uFFFD\u10000-\u10FFFF variable BaseChar \u0041-\u005A\u0061-\u007A\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF\u0100-\u0131\u0134-\u013E\u0141-\u0148\u014A-\u017E\u0180-\u01C3\u01CD-\u01F0\u01F4-\u01F5\u01FA-\u0217\u0250-\u02A8\u02BB-\u02C1\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03CE\u03D0-\u03D6\u03DA\u03DC\u03DE\u03E0\u03E2-\u03F3\u0401-\u040C\u040E-\u044F\u0451-\u045C\u045E-\u0481\u0490-\u04C4\u04C7-\u04C8\u04CB-\u04CC\u04D0-\u04EB\u04EE-\u04F5\u04F8-\u04F9\u0531-\u0556\u0559\u0561-\u0586\u05D0-\u05EA\u05F0-\u05F2\u0621-\u063A\u0641-\u064A\u0671-\u06B7\u06BA-\u06BE\u06C0-\u06CE\u06D0-\u06D3\u06D5\u06E5-\u06E6\u0905-\u0939\u093D\u0958-\u0961\u0985-\u098C\u098F-\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09DC-\u09DD\u09DF-\u09E1\u09F0-\u09F1\u0A05-\u0A0A\u0A0F-\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32-\u0A33\u0A35-\u0A36\u0A38-\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8B\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2-\u0AB3\u0AB5-\u0AB9\u0ABD\u0AE0\u0B05-\u0B0C\u0B0F-\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32-\u0B33\u0B36-\u0B39\u0B3D\u0B5C-\u0B5D\u0B5F-\u0B61\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99-\u0B9A\u0B9C\u0B9E-\u0B9F\u0BA3-\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB5\u0BB7-\u0BB9\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C60-\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CDE\u0CE0-\u0CE1\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D28\u0D2A-\u0D39\u0D60-\u0D61\u0E01-\u0E2E\u0E30\u0E32-\u0E33\u0E40-\u0E45\u0E81-\u0E82\u0E84\u0E87-\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA-\u0EAB\u0EAD-\u0EAE\u0EB0\u0EB2-\u0EB3\u0EBD\u0EC0-\u0EC4\u0F40-\u0F47\u0F49-\u0F69\u10A0-\u10C5\u10D0-\u10F6\u1100\u1102-\u1103\u1105-\u1107\u1109\u110B-\u110C\u110E-\u1112\u113C\u113E\u1140\u114C\u114E\u1150\u1154-\u1155\u1159\u115F-\u1161\u1163\u1165\u1167\u1169\u116D-\u116E\u1172-\u1173\u1175\u119E\u11A8\u11AB\u11AE-\u11AF\u11B7-\u11B8\u11BA\u11BC-\u11C2\u11EB\u11F0\u11F9\u1E00-\u1E9B\u1EA0-\u1EF9\u1F00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2126\u212A-\u212B\u212E\u2180-\u2182\u3041-\u3094\u30A1-\u30FA\u3105-\u312C\uAC00-\uD7A3 variable Ideographic \u4E00-\u9FA5\u3007\u3021-\u3029 variable CombiningChar \u0300-\u0345\u0360-\u0361\u0483-\u0486\u0591-\u05A1\u05A3-\u05B9\u05BB-\u05BD\u05BF\u05C1-\u05C2\u05C4\u064B-\u0652\u0670\u06D6-\u06DC\u06DD-\u06DF\u06E0-\u06E4\u06E7-\u06E8\u06EA-\u06ED\u0901-\u0903\u093C\u093E-\u094C\u094D\u0951-\u0954\u0962-\u0963\u0981-\u0983\u09BC\u09BE\u09BF\u09C0-\u09C4\u09C7-\u09C8\u09CB-\u09CD\u09D7\u09E2-\u09E3\u0A02\u0A3C\u0A3E\u0A3F\u0A40-\u0A42\u0A47-\u0A48\u0A4B-\u0A4D\u0A70-\u0A71\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0B01-\u0B03\u0B3C\u0B3E-\u0B43\u0B47-\u0B48\u0B4B-\u0B4D\u0B56-\u0B57\u0B82-\u0B83\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C01-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55-\u0C56\u0C82-\u0C83\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5-\u0CD6\u0D02-\u0D03\u0D3E-\u0D43\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB-\u0EBC\u0EC8-\u0ECD\u0F18-\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86-\u0F8B\u0F90-\u0F95\u0F97\u0F99-\u0FAD\u0FB1-\u0FB7\u0FB9\u20D0-\u20DC\u20E1\u302A-\u302F\u3099\u309A variable Digit \u0030-\u0039\u0660-\u0669\u06F0-\u06F9\u0966-\u096F\u09E6-\u09EF\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0BE7-\u0BEF\u0C66-\u0C6F\u0CE6-\u0CEF\u0D66-\u0D6F\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F29 variable Extender \u00B7\u02D0\u02D1\u0387\u0640\u0E46\u0EC6\u3005\u3031-\u3035\u309D-\u309E\u30FC-\u30FE variable Letter $BaseChar|$Ideographic # white space variable Wsp " \t\r\n" variable noWsp [cl ^$Wsp] # Various XML names variable NameChar \[-$Letter$Digit._:$CombiningChar$Extender\] variable Name \[_:$BaseChar$Ideographic\]$NameChar* variable Names ${Name}(?:$Wsp$Name)* variable Nmtoken $NameChar+ variable Nmtokens ${Nmtoken}(?:$Wsp$Nmtoken)* # table of predefined entities for XML variable EntityPredef array set EntityPredef { lt < gt > amp & quot \" apos ' } } # These regular expressions are defined here once for better performance namespace eval sgml { variable Wsp # Watch out for case-sensitivity set attlist_exp [cl $Wsp]*([cl ^$Wsp]+)[cl $Wsp]*([cl ^$Wsp]+)[cl $Wsp]*(#REQUIRED|#IMPLIED) set attlist_enum_exp [cl $Wsp]*([cl ^$Wsp]+)[cl $Wsp]*\\(([cl ^)]*)\\)[cl $Wsp]*("([cl ^")]*)")? ;# " set attlist_fixed_exp [cl $Wsp]*([cl ^$Wsp]+)[cl $Wsp]*([cl ^$Wsp]+)[cl $Wsp]*(#FIXED)[cl $Wsp]*([cl ^$Wsp]+) set param_entity_exp [cl $Wsp]*([cl ^$Wsp]+)[cl $Wsp]*([cl ^"$Wsp]*)[cl $Wsp]*"([cl ^"]*)" set notation_exp [cl $Wsp]*([cl ^$Wsp]+)[cl $Wsp]*(.*) } ### Utility procedures # sgml::noop -- # # A do-nothing proc # # Arguments: # args arguments # # Results: # Nothing. proc sgml::noop args { return 0 } # sgml::identity -- # # Identity function. # # Arguments: # a arbitrary argument # # Results: # $a proc sgml::identity a { return $a } # sgml::Error -- # # Throw an error # # Arguments: # args arguments # # Results: # Error return condition. proc sgml::Error args { uplevel return -code error [list $args] } ### Following procedures are based on html_library # sgml::zapWhite -- # # Convert multiple white space into a single space. # # Arguments: # data plain text # # Results: # As above proc sgml::zapWhite data { regsub -all "\[ \t\r\n\]+" $data { } data return $data } proc sgml::Boolean value { regsub {1|true|yes|on} $value 1 value regsub {0|false|no|off} $value 0 value return $value } tkabber-0.11.1/tclxml/pkgIndex.tcl0000644000175000017500000000122510701637340016303 0ustar sergeisergei# Tcl package index file - handcrafted # # $Id: pkgIndex.tcl 1244 2007-10-06 07:53:04Z sergei $ package ifneeded xml 2.0 { package require -exact xml::tcl 2.0 package require -exact xmldefs 2.0 package require -exact xml::tclparser 2.0 package provide xml 2.0 } package ifneeded xml::tcl 2.0 [list source [file join $dir xml__tcl.tcl]] package ifneeded sgmlparser 1.0 [list source [file join $dir sgmlparser.tcl]] package ifneeded sgml 1.8 [list source [file join $dir sgml-8.1.tcl]] package ifneeded xmldefs 2.0 [list source [file join $dir xml-8.1.tcl]] package ifneeded xml::tclparser 2.0 [list source [file join $dir tclparser-8.1.tcl]] tkabber-0.11.1/tclxml/xml__tcl.tcl0000644000175000017500000001517310701637340016342 0ustar sergeisergei# xml__tcl.tcl -- # # This file provides a Tcl implementation of the parser # class support found in ../tclxml.c. It is only used # when the C implementation is not installed (for some reason). # # Copyright (c) 2000 Zveno Pty Ltd # http://www.zveno.com/ # # Zveno makes this software and all associated data and documentation # ('Software') available free of charge for any purpose. # Copies may be made of this Software but all of this notice must be included # on any copy. # # The Software was developed for research purposes and Zveno does not warrant # that it is error free or fit for any purpose. Zveno disclaims any # liability for all claims, expenses, losses, damages and costs any user may # incur as a result of using, copying or modifying the Software. # # $Id: xml__tcl.tcl 1244 2007-10-06 07:53:04Z sergei $ package provide xml::tcl 2.0 #if {![catch {package require xml::c}]} { # return -code error "this package is incompatible with xml::c" #} namespace eval xml { namespace export configure parser parserclass # Parser implementation classes variable classes array set classes {} # Default parser class variable default {} # Counter for generating unique names variable counter 0 } # xml::configure -- # # Configure the xml package # # Arguments: # None # # Results: # None (not yet implemented) proc xml::configure args {} # xml::parserclass -- # # Implements the xml::parserclass command for managing # parser implementations. # # Arguments: # method subcommand # args method arguments # # Results: # Depends on method proc xml::parserclass {method args} { variable classes variable default switch -- $method { create { if {[llength $args] < 1} { return -code error "wrong number of arguments, should be\ xml::parserclass create name ?args?" } set name [lindex $args 0] if {[llength [lrange $args 1 end]] % 2} { return -code error "missing value for option\ \"[lindex $args end]\"" } array set classes [list $name [list \ -createcommand [namespace current]::noop \ -createentityparsercommand [namespace current]::noop \ -parsecommand [namespace current]::noop \ -configurecommand [namespace current]::noop \ -getcommand [namespace current]::noop \ -deletecommand [namespace current]::noop \ ]] # BUG: we're not checking that the arguments are kosher set classes($name) [lrange $args 1 end] set default $name } destroy { if {[llength $args] < 1} { return -code error "wrong number of arguments, should be\ xml::parserclass destroy name" } if {[info exists classes([lindex $args 0])]} { unset classes([lindex $args 0]) } else { return -code error "no such parser class \"[lindex $args 0]\"" } } info { if {[llength $args] < 1} { return -code error "wrong number of arguments, should be\ xml::parserclass info method" } switch -- [lindex $args 0] { names { return [array names classes] } default { return $default } } } default { return -code error "unknown method \"$method\"" } } return {} } # xml::parser -- # # Create a parser object instance # # Arguments: # args optional name, optional -namespace, configuration options # # Results: # Returns object name. Parser instance created. proc xml::parser {args} { variable classes variable default if {[llength $args] < 1} { # Create unique name, no options set parserName [FindUniqueName] } else { if {[string index [lindex $args 0] 0] == "-"} { # Create unique name, have options set parserName [FindUniqueName] } else { # Given name, optional options set parserName [lindex $args 0] set args [lrange $args 1 end] } # consume first -namespace if any if {[string equal [lindex $args 0] "-namespace"]} { set args [lrange $args 1 end] } } array set options [list \ -parser $default ] array set options $args if {![info exists classes($options(-parser))]} { return -code error "no such parser class \"$options(-parser)\"" } # Now create the parser instance command and data structure # The command must be created in the caller's namespace uplevel 1 [list proc $parserName {method args} \ "eval [namespace current]::ParserCmd [list $parserName]\ \[list \$method\] \$args"] upvar #0 [namespace current]::$parserName data array set data [list class $options(-parser)] array set classinfo $classes($options(-parser)) if {[string compare $classinfo(-createcommand) ""]} { eval $classinfo(-createcommand) [list $parserName] } if {[string compare $classinfo(-configurecommand) ""] && \ [llength $args]} { eval $classinfo(-configurecommand) [list $parserName] $args } return $parserName } # xml::FindUniqueName -- # # Generate unique object name # # Arguments: # None # # Results: # Returns string. proc xml::FindUniqueName {} { variable counter return xmlparser[incr counter] } # xml::ParserCmd -- # # Implements parser object command # # Arguments: # name object reference # method subcommand # args method arguments # # Results: # Depends on method proc xml::ParserCmd {name method args} { variable classes upvar #0 [namespace current]::$name data array set classinfo $classes($data(class)) switch -- $method { configure { # BUG: We're not checking for legal options array set data $args eval $classinfo(-configurecommand) [list $name] $args return {} } cget { return $data([lindex $args 0]) } entityparser { set new [FindUniqueName] upvar #0 [namespace current]::$name parent upvar #0 [namespace current]::$new data array set data [array get parent] uplevel 1 [list proc $new {method args} \ "eval [namespace current]::ParserCmd [list $new]\ \[list \$method\] \$args"] eval $classinfo(-createentityparsercommand) [list $name $new] $args return $new } free { eval $classinfo(-deletecommand) [list $name] unset data uplevel 1 [list rename $name {}] } get { eval $classinfo(-getcommand) [list $name] $args } parse { if {[llength $args] < 1} { return -code error "wrong number of arguments, should be\ $name parse xml ?options?" } eval $classinfo(-parsecommand) [list $name] $args } reset { eval $classinfo(-deletecommand) [list $name] eval $classinfo(-createcommand) [list $name] } default { return -code error "unknown method" } } return {} } # xml::noop -- # # Do nothing utility proc # # Arguments: # args whatever # # Results: # Nothing happens proc xml::noop args {} tkabber-0.11.1/joingrdialog.tcl0000644000175000017500000001375610736174616015725 0ustar sergeisergei# $Id: joingrdialog.tcl 1342 2007-12-31 14:15:42Z sergei $ #set gr_nick $user set gr_group "talks" set gr_server conference.jabber.org set gr_passwd "" custom::defvar gr_nick_list {} \ [::msgcat::mc "Join group dialog data (nicks)."] -group Hidden custom::defvar gr_group_list {} \ [::msgcat::mc "Join group dialog data (groups)."] -group Hidden custom::defvar gr_server_list {} \ [::msgcat::mc "Join group dialog data (servers)."] -group Hidden proc ecursor_entry {e} { $e icursor end } proc pack_input {fr row var lab args} { label $fr.l$var -text $lab ecursor_entry [eval entry $fr.$var -textvar $var $args] grid $fr.l$var -row $row -column 0 -sticky e grid $fr.$var -row $row -column 1 -sticky ew } proc pack_combo {fr row var lab args} { label $fr.l$var -text $lab ecursor_entry [eval ComboBox $fr.$var -textvariable $var $args].e grid $fr.l$var -row $row -column 0 -sticky e grid $fr.$var -row $row -column 1 -sticky ew } proc update_combo_list {list entry num} { set ind [lsearch -exact $list $entry] if {$ind >= 0} { set newlist [linsert [lreplace $list $ind $ind] 0 $entry] } else { set newlist [linsert $list 0 $entry] } if {[llength $newlist] > $num} { return [lreplace $newlist end end] } else { return $newlist } } proc join_group_dialog {args} { global gr_nick gr_group gr_server gr_connid gr_passwd global gr_nick_list gr_group_list gr_server_list if {[llength [jlib::connections]] == 0} return set gr_passwd "" foreach {opt val} $args { switch -- $opt { -server {set server $val} -group {set group $val} -nick {set nick $val} -password {set gr_passwd $val} -connection {set connid $val} } } set gw .joingroup catch { destroy $gw } Dialog $gw -title [::msgcat::mc "Join group"] -separator 1 -anchor e \ -default 0 -cancel 1 -parent . -modal none set gf [$gw getframe] grid columnconfigure $gf 1 -weight 1 if {[info exists group]} { set gr_group $group # set gr_group_list [update_combo_list $gr_group_list $gr_group 20] } elseif {[llength $gr_group_list]} { set gr_group [lindex $gr_group_list 0] } if {[info exists server]} { set gr_server $server # set gr_server_list [update_combo_list $gr_server_list $gr_server 10] } elseif {[llength $gr_server_list]} { set gr_server [lindex $gr_server_list 0] } if {[info exists nick]} { set gr_nick $nick # set gr_nick_list [update_combo_list $gr_nick_list $gr_nick 10] } else { set gr_nick [get_group_nick ${gr_group}@$gr_server $gr_nick] } if {![info exists connid]} { set connid [jlib::route ${gr_group}@$gr_server] } set gr_connid [jlib::connection_jid $connid] pack_combo $gf 0 gr_group [::msgcat::mc "Group:"] -values $gr_group_list pack_combo $gf 1 gr_server [::msgcat::mc "Server:"] -values $gr_server_list pack_combo $gf 2 gr_nick [::msgcat::mc "Nick:"] -values $gr_nick_list pack_input $gf 3 gr_passwd [::msgcat::mc "Password:"] -width 30 -show * if {[llength [jlib::connections]] > 1} { foreach c [jlib::connections] { lappend connections [jlib::connection_jid $c] } pack_combo $gf 5 gr_connid [::msgcat::mc "Connection:"] \ -values $connections } $gw add -text [::msgcat::mc "Join"] -command [list join_group1 $gw] $gw add -text [::msgcat::mc "Cancel"] -command [list destroy $gw] $gw draw $gf.gr_group } proc join_group1 {gw} { global gr_nick gr_group gr_server gr_connid gr_passwd global gr_nick_list gr_group_list gr_server_list destroy $gw set gr_nick_list [update_combo_list $gr_nick_list $gr_nick 10] set gr_group_list [update_combo_list $gr_group_list $gr_group 20] set gr_server_list [update_combo_list $gr_server_list $gr_server 10] foreach c [jlib::connections] { if {[jlib::connection_jid $c] == $gr_connid} { set connid $c } } if {![info exists connid]} { set connid [jlib::route ${gr_group}@$gr_server] } join_group ${gr_group}@$gr_server \ -nick $gr_nick \ -password $gr_passwd \ -connection $connid } proc join_group {jid args} { global gr_nick set password "" foreach {opt val} $args { switch -- $opt { -connection { set connid $val } -password { set password $val } -nick { set nick $val } } } if {![info exists connid]} { set connid [jlib::route $jid] } if {![info exists nick]} { set nick [get_group_nick $jid $gr_nick] } set cw [chat::winid [chat::chatid $connid $jid]] muc::join_group $connid $jid $nick $password raise_win $cw focus -force $cw.input } proc set_our_groupchat_nick {group nick} { global groupchats set group [tolower_node_and_domain $group] set groupchats(nick,$group) $nick } proc get_our_groupchat_nick {group} { global groupchats debugmsg conference "GET NICK: [list $group]" return $groupchats(nick,$group) } ############################################################################### proc joingroup_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 "Join group..."] \ -command [list join_group_dialog \ -server [server_from_jid $jid] \ -group [node_from_jid $jid] \ -connection $connid] break } } } } } hook::add disco_node_menu_hook \ [namespace current]::joingroup_disco_node_menu_setup 45 ############################################################################### tkabber-0.11.1/sounds/0000755000175000017500000000000011076120366014037 5ustar sergeisergeitkabber-0.11.1/sounds/psi/0000755000175000017500000000000011076120366014632 5ustar sergeisergeitkabber-0.11.1/sounds/psi/groupchat_server_message.wav0000644000175000017500000002504207747030166022452 0ustar sergeisergeiRIFF*WAVEfmt ø*ðUdataö)ÄÿŽ] ÷|÷QúRù>ø¾÷êø­ùbøìøín = rJ € ß 6Ì ŒïjëSðoñTð7ïøî³ð¨ñ¾í;ïtþ%ŠùB~¼ë TÏøüñð´ðÉïúîUðóðï©ñsúZØ :Jh«Ð3âm2[{õïíRð¡ñËïgï˜ð£ðpïÓñ¼ûÒ ~r£ºz›„*ª3Pòý¬ðNíoðëðâðÏï€ì«ðþ³]‡Q¸FbÞÉþÿìõÜî2ïÔðññÓî®ï`ûETþ¢ÿ1 ¾Íçp^L3 Ï{gö¢í¢ïyñò4ïõî{ø7Ò1gþëù;aȃbéžþµd1ú¹îï^ò4òÞïæïàø!(ÿý–žm_À” èþÁÿl¦(ý±ðµîÕò`ðhîˆ÷½z·ÿ²ÿþWWjÙU ÿ|ÿvøÿ]»þ†ô(ïYñ ð/ï«öøÿéZÿÿù C€´“ žuŠlŒæ¼û]ôìðÿïÇðL÷ßÿUdÿdæ/ÿ¼ñ؃ ¯øŸÁÿÔÿmÁýÙò îFðNøonÿ~–L¢þˆÀ òú DõþÀžsÿ×þMXô•êÇñoÆùíÂð þd»‘ ïUš“f] ׸þ.5Ç÷@î¥ï…ñ(òÔï(î;ù:%þãa%büø ®þ÷Bò5Èÿ ÿýð­öœ¿TÇÿ/Òÿ/¿ÿÔÿyOOk¦ †I˜ùXø¡ÿ³šÿ;ìÿöÿéÿþÿ¬ÁóÿöÿÜÿ/»ÿÙÿŽ3˜ÿ;Õÿæÿ/¤²ÙûT÷ÇþI¡ÿåÿ7"e9þÛG _*þ¯ñU»ÿÈÿ(û·ð-ùBDDdþ=' ESÿ“:¦Ìÿæ¾þ†ôjïù]¢xÿ¦úñ–ÖT: ¡ÿÒþ¦ƒûÿÌÿåÊþõOïö—°dÿr¢Ú¦ÿCI ¢S Aöþ¶É>½ÿÍíþDö ð‘õÀÿCG”—“ÿ:Ä `Ç{ûjþcî*ÁpüÙõòóò¹õ6üõW¾æÿ4| QFÏæÊÿ\ÿK)”ÿûõYó›ó™ñû÷'²»ÿ–ÿ¶.[— ò e,yÿ"YÂ_ùÑñRô öEòMôŸþßKàÿh| € 3s ÈË<ÖUùÄñuô‚ö»óáòƒøÆÞÿðþ²˜Ns ÷ Ú çƒjþmjú…òzóõâôÛôXó$òÎø1jôÿÝ<  Ç  ¾ ZX¼ÿ þ÷IôNõ öö4õ óøT=‚Ü B ² ë ( Ø Ñ åDþÍúÉô¹ôöõõ§ö¢ôöhþ„ƒõ þ x e Ï p  è  ÜÝýfø-ööÇõ1õfõQö õÆôðù4V ä ¸ 9 Ï œ w  ðü‘ö5ö.÷îööNõ~õáö¨öÃó0ùq„ K B Î ÷ Î þ D Ñ Û=÷·õÛ÷P÷<ö&ö ÷ø¾õ(÷'À F +   Ô Ü ´ v Ê ¾ ûõúøƒøýö$÷ ÷÷ÊøQöÆö Œ Z T %   J $ Û ™ Öû;÷^øÄø|÷÷£÷Õø7øZ÷&ütÕ ¯  e ó % O » ªüúö~÷Üø°øø¿÷¿ø¡ø(ùöýáÿRŽó P<ÇsRÉz¬á@ÿ9ûúøÊùZùUùéù!ùÿøÌü´ÿOi Î8۟ꎖý<ùúíúõúðúüùhùöüÛr!—ë¢9üYþö”zgPûEûÒüÃüü¥û¹ýÚÿþ­üÓþç(yﺺçóäôðÿ%þˆþÊþ þêýôý-þÏþ£þyý„þ–¤›ÉRÓàZëUbûÿøÿþÿÿÿûÿùÿòÿŠí ”þµýLþ±ÿ/æÿ&6šýøoó‰òróôäô±õßõïôXóòžñ&óDúÕGú)øÿòÿsè¿èÍE ë ¥ n ² e ýçŸþþ|ÿùÿìÿÅíý¹ö}ò?ò óêóŒônõïõNõyôÆóõòÄòBô†ù¥âê—¹ýÿëØ 0Tmb û õ Ú c è ªÎ” ÇŒÿ«ýþmÿÌìHŸúÅò{ò$óaóõäõ öæõõ‡óxòíñFôÎü‘ÿZþµõÿQÿ¦ô ¡AÅî ; r å ý ¡ f 3óbÔ “'ÿôýMÿ ËÿÛü4÷‡ó0óøóÈô’õö öö±õ×ô ôãóKô°÷²þr¯){ÑÿØà cÿ &  à  ð õ  Ø & tqCšýÝýaÿ/ËþÌø,ó†ò}óqôÞõ$öÿõçõ6õ=ôüóåóõRû€å§Ë¯ éJÙ Kî ì  ; ó ú  í @ ä ã  FjþÿâÿŠþÜø•õBôôòôÃõ öööúõ öøõ3õuôäó öÈü ú1z  F»   • ý î ê  ½ ƒ Së Ñ ÌÍý“ýoÿìÿAgÄûØõôãóEô9õØõööõö,öçôôóÞóûó1ùØ×³ Úÿ™ÿòì™ m– Ú  ê  þ ú  õ ù Á . Å × ”·þãÿ»ÖýÇöôõõÞõöñõööôõöö4õ õÇô¥õáû\õ`ÃÿÎOº ù ! þ M B ó  ¼  † „   [ ï³þ…ÿIñ—ÿ‡ú½õ×ôýô<õööâõ@öåö-÷™öÙõõÓôºøüþØ ¨Ïÿ!L > ô Ê ú ð ø ý  è  è Œ e F _ÿ'ÿéÿjåýCù_öÐõðõöºö6÷±ööŸö÷ùö÷÷ÉöØõ•õªùXÿȺò7 k è   ø  ü ÿ ý  ý  H ýSºþbø;ö7÷ëöÿö÷÷ýö>öPö÷÷îö÷æö(öHöm÷ïù1þîÓòŽîê 5  Ï  Ú j  n Ú × ò S Ü wÍøÿÜÿÉüøÚö÷íö÷ÿöüö÷úö÷îö÷É÷øÜ÷ùööˆ÷Ðûjÿñ) ù ï æ % Û é < ä  ü ý 6 š Ã;ÿ–ü ù–÷øú÷þ÷øø øR÷>÷ö÷øó÷øøï÷øÛ÷ÄøýÛòdމ  ó  õ  þ ÿ  ÷  ´  œ    .½;ØÿtþÓúBøË÷øþ÷þ÷øý÷øû÷øñ÷ø±øùùôøeø$øYú¦þÕÎz Ü U  õçU ó  ñ  ÷ M ì÷ý| è  G%þSù4÷=÷&øèøùùìø8øï÷÷÷ø®øùøø ùùËøÞ÷›÷OûÝÿþ‚ß P × ÷î†   œ öø æ3 ¼ M ”'Ñüê÷€øåùãùú ú|ù÷øøøùùøøüø•ù#úñùEùcøñ÷ùø’üö| ‚ ¤þøí7ê õ «‡H  1 ¾¾ý°ø"ø^ùúÌú(ûÌúú;ùôøöøüø–ùúûùú úÑù ùzøDûxÿ…½~ ú5€Ú²ÿýçCÌ?õTýÙúù’ùªúûú ûû™úýùñù úèùúÂúû ûîúpú€ù¯ú9þ¬êUx» ¥Öó Ž»ÂË5ì¿„üÝùúúúúÁûüèû*ûPúöùøùðù‡úþúû¼ûÀûÛú ú¥ùQû‚…“Ù‚=ÿ‹üùÀççÿ)>’ÅôüÂúèú¼ûüüüúûüëû:ûêúûúûœûŽüãü?ü?ûûÞúmûÉÿ'ëZ É(~þúÏ?ìÿèMC7ÿUý:ý'þêþÿÿëþ:þêýþþýþíý%þÙþ'ÿºþìý+ýýßþÀ–?¶JÔ ó÷u'ø›Õüüù ùOêÿýÿþÿÿÿÿÿýÿûÿçÿ|Ü0äÿ üÿÿÿýÿÿÿÿÿýÿÿÿüÿæÿ1Ú‚×ÿÇ"ÈÒÿ”µVÿ¿þYÿüÿmÿ)ÿãÿ6Rÿtÿ{^‹ ¸)ÆÕ¿\%ÿHÿûÿ…ÿäþýþÒÿÿ$ÿÔÿçÿ«ØMS)úJï~‹ÿÿ°ÿ6±ÿÿ¤ÿÔÿ¯Ú`¹XÛL\ç<>Ýÿ/ÿjÿ ¥ÿîþíþ©ÿëÿ-„A¾Ùzé0Qðÿjÿ+ÿæÿ&’ÿôþöþ”ÿøÿÛÿÝðí4áèÍÿ|ÿêþÿ©ÿ-Ïÿÿ‰ÿÔÿÈ‚ºBåÝÛÿüÿÿÿ»ÿÿÿúÿüÿøÿ×ÿpÖ8x$ÉEU èÿ ôÿDÿHÿIÿEÿòÿøÿúÿ’–Ù.ýµðÿûÿþÿõÿ Sÿ>ÿóÿìÿ ËÿðÓ4¢| àÿôÿýÿþÿÿÿýÿþÿþÿÛÿK®UQãÿ ûÿýÿõÿ Rÿ>ÿ÷ÿ÷ÿüÿðÿÚŸ1×qÔÿýÿÿÿÿÿkÿÛþÿÀÿ/´ÿÿÿôÿüÿ€oåJËJåpüÿôÿÿÿ´ÿ/Àÿÿßþhÿ Ôÿ›+Èÿ‹T÷ÿèÿôÿôÿõÿ>ÿQÿ ÷ÿüÿÿÿÿÿýÿÿÿüÿ äÿ0Ü|èÿþÿøÿöÿÍÿ"ÿ‚ÿøÿûÿúÿÉÿbºùÎÿöÿüÿÿÿÿÿþÿþÿþÿóÿèÿóÿ[ƒÜÿôÿýÿþÿÿÿÿÿÿÿüÿõÿýÿ$ê6ìÿþÿþÿÿÿÿÿÿÿûÿöÿøÿš  ‚ðÿüÿûÿþÿÿÿÿÿÿÿüÿõÿüÿ•ùÁíÿýÿÿÿüÿõÿúÿ˜ý ùOèÿüÿÿÿþÿýÿêÿO÷òöOêÿýÿþÿÿÿþÿýÿéÿOù ü˜úÿöÿüÿÿÿÿÿýÿüÿêÿO÷øù×'ëÿýÿÿÿþÿÿÿüÿêÿPøøùÖ'ëÿýÿÿÿýÿýÿÿÿüÿìÿÅûþÿý®òÿüÿþÿÿÿüÿíÿÄûþÿý®ñÿüÿþÿüÿúÿòÿ ûýùé9éÿÿÿþÿýÿüÿûÿóÿ üýùé:éÿÿÿþÿþÿýÿøÿøÿuý7V ü ñÿûÿüÿýÿÿÿþÿéÿ:êùýý ~òÿúÿüÿÿÿÿÿÿÿþÿðÿ ¡4Ì¥®#¿¡çÿýÿøÿýÿýÿûÿÿÿçÿ|Ü0åÿ üÿÿÿýÿÿÿÿÿþÿüÿîÿÄúÿýýÿûÄíÿüÿÿÿÿÿþÿþÿÿÿéÿ;éùþÿýù ÷Oêÿüÿþÿÿÿÿÿÿÿýÿýÿÿÿéÿ:éøÿÿþýù×&ëÿýÿÿÿþÿÿÿÿÿÿÿþÿüÿñÿ®þÿýýÿÿýú fìÿýÿüÿþÿÿÿÿÿþÿÿÿýÿëÿ'×ùþþþÿùé:êÿÿÿþÿþÿÿÿÿÿüÿõÿûÿ–ýýÿýú òÿúÿüÿÿÿÿÿÿÿþÿýÿíÿÄûýþþù øOéÿüÿþÿÿÿÿÿÿÿþÿüÿíÿÄúÿýÿýû—ûÿõÿüÿÿÿÿÿÿÿÿÿÿÿÿÿþÿþÿÿÿèÿ:éùÿþÿÿýú gìÿýÿüÿþÿÿÿÿÿÿÿÿÿÿÿüÿðÿ®ýþýÿÿþþÿùé:éÿÿÿþÿþÿþÿÿÿýÿêÿ'Ùùýÿýû ~òÿúÿüÿÿÿÿÿÿÿþÿÿÿþÿêÿ'Øùþÿÿÿþþù øOêÿüÿþÿÿÿÿÿþÿüÿéÿO÷ ùþÿþþÿýü–úÿôÿüÿÿÿÿÿÿÿÿÿÿÿþÿüÿìÿÄûýý÷µŸjéÿüÿþÿÿÿÿÿÿÿÿÿþÿþÿìÿ7í –óÿðÿÿý ÷S×ÿ'Ø(ªòÿýÿÿÿÿÿÿÿÿÿýÿñÿ ¨+Õ"ôÿñÿÁø’þÿôÿôÿGÿwöÿùÿüÿÿÿÿÿÿÿÿÿÿÿÿÿüÿüÿðÿaaðÿüÿüÿÿÿÿÿtkabber-0.11.1/sounds/psi/chat_their_message.wav0000644000175000017500000001245207747030166021203 0ustar sergeisergeiRIFF"WAVEfmt |ø*dataþ'úÛù´Ñ])þî÷§ü‡ ý†ó¿ü¢< ¸ÿñó_ù u *Çô÷Ï 0võ¾ò{£ Éxú¯òCúa  XÿHñ¢ö= p5ñÏñŒ þôZïEÿ± øïÎüyŠ Êû<ï÷M Ñ/2ñFó=ÿxô¿ñVrË ÷ëïzüœ ¬ ïüðüöÊ ýn_ñôø@Ïô`ñ:z, LøGðüÒ ] Ãü+ð÷÷ ZRƒñ!ôë¸KôšñÃ?Ä ‡øUð üy P <ýÄð•÷q ȇñ‰ónæôÐð‚1 øbï:ûO ”NýŠï¥öu F¹©ñ°òØÕcžôOðêÿ’˜ åøïÏú œ”ý¢ï°öˆ 8cbñúò£‹ôÐðŠc Søóïü | Àü=ðŸ÷ª zšßñQô«½æšô¥ñ;ß !øðü ? Æüqðû÷ð ¡ñaô€ô¡ñƒ|Ä ™÷ðýü¥ Ö äû'ðwøg  FñŽôiú>úóòÙEA u÷•ðEýV Ÿ Õû>ðæø… ¨M”ñ/õ„x½ôòääµ÷ñzý  ÄûØðù $K ò}õL¶côÕò¾¬}÷%ñ›ýó Ú ¢ûÁðHù Næÿ¸ñÉõÈ* ôó¡$÷}ñ;þ< t ûýðôùƒ º –ÿîñöèðËÕóyóË·ìö›ñ•þW  Ðú3ñvúÊ H ÙþâñÓöi˜F¸ó§ó<¢a½öæñ ÿK ’ rúeñùúò ô Œþ÷ñ+÷|¿ÔóiôÃHÆ ö\òÿ,  Cú|ñ*ûÜ £ ^þòl÷¦³Êó‰ôê=Š|öòÿ ò ú¾ñ‡ûì u ;þAò±÷®Ú ^âó¸ôß `ƒö¤òºÿ) × ú×ñ¦û 7 êýIòøÁ ¹óÿôF ^öäò 7 ›ùò-ü Ñ ýeò‰øG ¬ùó¥õ|Ž tmö}óhÁ ×Åù°ò‚ü° W ¸ýìò½øÈ¼ {iô ö>ü BËöïó_= |úùó‚üO ê ¡ýjó%ù†P wÁôPöCÒ âö=ôyÿ JúfóÈü> œ uý„ó}ùÅ0 ŠôlöfÁ ôÛöuôÑ ä¿ùó"ýZ \ 'ývó¡ùÅü þÀôóö¸r qÚöÔôóà ¡¥ùËóZý7 # *ýÍóúùÀƒ ©õ7÷©> %¾öõ6´ Q§ùô¥ý( ¨ ÜüôpúÍC Yîôž÷ù ÃÚö~õ[_ à‘ùgôþ( C œü?ôÝú  ëôâ÷· xÊöÑõ〠g4ù²ô‘þ8 æQü_ô!û› §ÿ/õŽø_Y ø×öYö- >ùòô±þ ‹%üºôŸûô! …ÿzõËøO ¹÷¶öà Ðuù~õîþ¦ 0jüõ›û®ã qÿ»õ ù± ÎT÷Íöö ¨›ù½õåþZ Þ[ühõïû¦§ pÿûõ<ù  s÷-÷9 QªùÿõÿJ Àdü­õüjO uÿFöù Q•÷…÷1 (¸ù=ö&ÿ ybüîõCü>öJÿ‡öäùÇ .¿÷Á÷(Ç ÿÔù†ö4ÿÛ<Yü8ö‰üBÖÿ†öú³ úÃ÷ú÷S£ ©ËùÔö™ÿìÜü;öÃüo¥Úþsöú<¬ Ò´÷Eø±Ÿ UvùÜöèÿ —ÊûWöýiZ¶þÌö¸úe6 dÐ÷–øÆj •ù@÷ùÿª`ü«öEýKë‰þ÷Þú7ëOøäøª øÞù ÷]ïü<÷…ýú¬™þP÷&û1Ÿ,Sø6ù§§þùø*´üp÷ºýðTpþ÷ZûøAhøtùà~Iîù3øiƒôûŽ÷ÞýË^þÂ÷¾û(ºzøÕù déùoøù6ÒûÈ÷%þÍÈþÒ÷éû1Û‚øùùù0ú£ø¢Ôìûñ÷/þ½¬þü÷ü“¨ø úÝúÝø¯•Òâû!øfþ¼‡þø!ü’t¿øKúØ™úùîÌû_øŸþŒ3þý\ø„ü.ãø­ú7­nú6ùûqxÓû{øÀþþØýtø±ü#×ø¿úAˆE úhùüQ^Õû¢øÑþïÐýqø¬ü%ÿÿâøÐúM‹:úù?ežû¾øÿ—Ñœýzøíü2áÖÿùûo\åú¼ù\5â­û÷ø'ÿUg¥ýéø>ý `ªÿVùqû[Ï\úú^岨ûAù?ÿ#2¯ýùEýòR«ÿrù—ûRϬpúKú]Ÿpàû‰ù^ÿöù¨ýRùýÙ£ÿœù´û6š˜ˆúpúi•eêû±ùÿùç•ýdù•ýËè…ÿÅùñûJh]«úÁúwL* üçù{ÿª–µýÊùÄý’™†ÿ ú!ü  aëúàúP+ü<úœÿaUÒýúÖý[U|ÿJúZüöÔU-û;ûU¾Ù]ü–ú£ÿ"ÉýQú þ= wÿ›ú•üß„"TûtûV¡güºúÂÿ%Éýeú-þFçTÿ˜úÀüoÜ2û±û¬iGüêú¨«ý¬úƒþ1‘ÿÈúý»dûéû44aü2ûÍ]©ýöúªþRÿûKý÷LJ®ûJü™àîŽü›ûC’¹ýJûÚþÜöÿRûŽý×€vÍûü¦¨µœüÚûOhô²ý`ûïþÑØûþkû¼ýçSJãû¹ü·€š®üüi7ªÃý¾û-ÿ¨ƒðþ½ûðýµ A-üûü”j÷üZüKàuáý ü ÿHJ$ÿüüýqÁD„ü2ýpÚ[$ý‹üY¬O þIüJÿ&ÿOüCþd{/™üeý~ž4<ýÊüt‚ýýmümÿÐêþ]ü†þ‡Bäÿ«ü°ý£~ã#ýý¯^ÉýýÊü®ÿøŠëþ¦ü¦þdÜÿÙüØýŠLîZýýŽIÚ þ±üˆÿéöþ§ü‰þ<áü·ýwWõVýýŽJâþ¯üÿý´ùþü‡þX+öÿÈü¸ý”m÷Dý ýœgäòýžü–ÿž×þüªþ}!ËÿªüÈý¶sÙ(ýý®`Åîý¸üµÿ‰Ëþ‘ü³þ,Øÿ¶üÌý±eÍ6ý-ý¿Z´áý¹üÃÿ|³þ–üÍþzô¤ÿÁüýýÂFš(ýWýæK~×ýðüæÿ@™þ¿üÿ‹Ãyÿáü=þÖ hIý™ýÿFÎý*ý)æþ˜þÿü>ÿk„cÿýünþÛä?MýÊý ñ ÜýSý;ÏÏþý]ÿniYÿýþâË+[ýãýãûØýkýHÍÆ…þ!ýlÿvVDÿ ýžþÞ¹Yýïý)áæÅýýaèaþ"ý…ÿzI'ÿýÀþò¯úÿMýþSâ˯ý„ý€âGþ3ý¹ÿ+ÿýÚþ¦Òÿ6ý(þdЫ£ý¡ý¬Õb(þCýÑÿšåþ#ýÿ„ºÿKýIþ}Í‚—ýÅýÂÃL4þ`ýáÿ„ëãþHý"ÿ[§ÿgýuþ{šo¹ýÞý¸ª6-þrýôÿzרþGý&ÿT ÿdýtþ§h¥ýèýÓ§#,þ‡ý |ÈÉþVýLÿ$N•ÿ`ý‚þ‡–Z­ýôý×­þý#·¸þUýLÿ =zÿ_ý¡þœ€6­ýþåž!þ•ý~±½þgýZÿ+8tÿhý¥þž†=£ýþ÷ªùþ ý3€¡®þeýfÿ!\ÿfý¸þ§y™ý)þšÕþ¶ýPwq”þ‰ýÿ$ðJÿýóþªC¾ý[þ hµþðýZJ[®þ¯ý¡ÿÕAÿ£ýÿþ–'öÿÔýpþýF¦1þþT2F»þÉý¦ÿùË_ÿÈýûþ"æýtþó@¶EþýýE3HÃþØý§ÿç¾]ÿÃýÿ†÷ÿßýqþñ9ª5þþ_'0±þÜý¿ÿò­AÿËýÿ€òÿøý”þû%Kþ1þa#½þõý»ÿß¡Pÿàýÿyîîÿþý”þ÷ˆGþ5þ^ (Äþôý½ÿΗVÿéý'ÿsäîÿþ¦þó—Wþ9þcþËþþÊÿЊTÿöý:ÿ|Öåÿþ«þïþ‚XþKþbìÿÆþþÒÿ¼sQÿ þ8ÿ\¾äÿ3þÏþæ×y|þhþ\ÚþÜþ*þÊÿ¦neÿ"þCÿNµõÿ?þÊþÞÏixþ€þa½æÝþIþáÿ“DTÿ?þbÿBÔÿ^þýþâ¦S‘þ¥þx©Åìþlþôÿ‡ Iÿ[þ‰ÿUn¯ÿUþÿž/…þÀþ”¦˜Âþ€þ!‘$ÿOþ‘ÿYg¦ÿVþ%ÿ–yþ¿þ™´¦¼þeþ¨&ÿKþ›ÿgfœÿLþ%ÿ­fþ·þ¤Á¦¸þhþ¢$ÿBþ—ÿqkÿ=þ&ÿ"«Wþ¶þ¯ÈžŸþnþA¶þÿNþ¼ÿ‡bxÿ5þ:ÿ3ŸfþÑþ¿²x¢þ‰þP¬ëüþIþÃÿ‰SnÿGþGÿ*ìÿ[þâþÕ®\•þ’þZ´ã÷þ\þÑÿ}9fÿXþeÿ4{æÿlþñþÊ¥t­þ–þF™ç ÿlþÌÿiCÿ[þRÿ&ƒ÷ÿjþÝþ±t·þ™þA‹ÝÿpþÔÿm2sÿdþZÿvòÿ„þûþ¼‹Z¸þ»þ\‹Ãÿ~þßÿg!rÿ~þqÿ[Øÿ…þÿÈyD¯þ»þ^„»ÿ‡þéÿdgÿyþÿ%RÎÿ„þÿÍvD¶þÌþdy¯ÿ¡þþÿWü_ÿˆþ’ÿ)HÈÿŽþ*ÿÍc7¿þÝþhi–üþ«þUïWÿ’þœÿ"7Ãÿþ=ÿÓQÁþûþ€b‡ÿ»þJá`ÿ­þ°ÿ¿ÿ°þLÿËJ+ÒþôþfSÿ¹þüÿ8àcÿ¢þ˜ÿ.Àÿ¢þ=ÿÅQ/ÍþòþjYŽÿÅþHß]ÿ§þžÿ,Ìÿ®þ@ÿÄL0ÖþùþiOÿ¼þÿÿ?Ý_ÿ¨þÿÆÿ¼þKÿ¹0âþÿg<~"ÿæþÆ{ÿÝþ°ÿëôÄÿãþgÿª(ÿ!ÿT}Dÿýþüÿ÷¯ÿïþ²ÿÙá¿ÿìþoÿ¤þÿ<ÿ^P:ÿÿ÷‘vÿ ÿÔÿÖĽÿ ÿ‹ÿá %ÿXÿ`çGFÿ.ÿ!å‰ÿÿÓÿÅ·ºÿÿ›ÿŽÅûÿ.ÿcÿ_Þ=Qÿ=ÿ΂“ÿ6ÿÜÿ® Åÿ4ÿ©ÿŽÃ>ÿlÿQËJkÿMÿ·vœÿ@ÿÜÿ§œÂÿ1ÿ¡ÿ}¸>ÿhÿMÂ<bÿNÿÂnƒÿ3ÿåÿ³ Âÿ.ÿ¥ÿ…¹AÿyÿYÅ5[ÿTÿ%Çxÿ2ÿÛÿµ­Èÿ,ÿ¡ÿ†Á5ÿiÿUÑEXÿ8ÿ Æÿ+ÿÔÿ­©Îÿ/ÿ•ÿ„Ï9ÿ[ÿFÔYmÿ7ÿÇŒ ÿ/ÿÌÿ­·Øÿ&ÿŒÿ‚ÑEÿaÿ@Ètkabber-0.11.1/sounds/psi/groupchat_their_message_to_me.wav0000644000175000017500000001763607747030166023454 0ustar sergeisergeiRIFF–WAVEfmt |ø*datarþÿýÿüÿûÿüÿýÿýÿþÿýÿýÿÿÿÿÿþÿýÿüÿûÿüÿüÿûÿúÿùÿøÿúÿûÿþÿþÿþÿþÿþÿýÿþÿÿÿÿÿþÿþÿþÿþÿÿÿÿÿþÿýÿþÿÿÿÿÿÿÿÿÿÿÿùÿøÿøÿìÿãDÿþsÌ0<ÿý'‘ºü8þõ2uþHù3ÿ¢Žý/û\ÿH*ýòú ãRþÕüÖÿzoÆþÝ$ÿ4þþJûJýùÿÒ÷ üñX[ýõœü é3ü¨ôÂü ”’ü-ö¹ýÎ>QüjøÿDf:ýûBÿ§óþÿfÿHÿ®þjÿ Ï$ÿûþ~aþ>øýþÌoýäõ†ü“¢|üVõýÉ8üö©ýâ§ÇüUøþÉuÆýMûÿñXoÿ–þPÿjÿìÿÔ@ÿÃûþt{uþ¶øãüD}Óý­öªüîjý˜õ£ül`Ûü=ö+ýr@ý#øéýŒ÷_þ:ûvþjt:îþ¥þÔþIoP‘þwû\þ¬n-þrøý~x¾ý™önü’olýÕõxüýE7ýhöýG fý#øËý™"Fþ×ú^þÙÙçÿ6þ½þÀÿœ¨ŠÃþküáþÛgdþgùsýÌ­ þe÷¹ü"Ûý_ö¹ü½ù?ý‰öîü%$œýþ÷rý¬iþhúõý<ŠÒÿmýDþ9`‹£|þ$ýXÿg¬wþWúÐý-5þÿ÷Õü›„ÇýËöüCíý»ö¸üòCÎýë÷3ýµÖfþúØý̓ÿôüoþØ” ±þîý•ÿÉ´þ ûâýz©œþ—øµüýUBþ0÷QüÊâòýèö‰üÉpñý³÷õüË%gþ¤ù¤ýøHaÿZü;þn!³Vÿ¡þœþ^RªþªûTþ ¨þCùýË\þ ÷mü~³þúöTü±¬-þŠ÷µüþdþ%ùRýPÏCÿ¹ûþ啊Éþƒþ(ÿz È¢þ:ü«þÇt€þ©ùeýVfPþû÷§üDYþR÷¦üOþÍ÷éü×\{þVù[ý;ÈRÿ¬ûØýíÙš‚þEþIÿÜ_tþ‘üÿ£ësþ8ú½ýþâ`þ‡øöüý=þ«÷ü/5Sþì÷¼ü´v”þ9ù<ýYüBÿUûÃýPQ þLþÏÿ%½߈þ$ýXÿ2eœþÐúêý†y˜þùý‚™yþ5ø­üËÓmþYøÑüS+ÁþŠù8ý#íXÿkûÁýP6LÖý9þ`t’þ©ý‘ÿÆôÕþtûþõâÇþ¿ù6ýö2´þ¨ø¨üa·Âþ”ø¥üMìþnùý6_ÿ$û‹ýŒ…+sýþm°NŒþþàÿŽw»þåûjþºwÇþ'úrý›µËþ.ùíüOÂþëøËüâýþ«ùý qÿ8û—ý“-Hý þ©ó+ÿmþuþ4Mø²þeüËþpîËþªú¶ý_dÏþ{ùýÝ Ýþ2ùåüÐäçþ´ù$ýaÿûŽýÁà ÷ü þ2å)ÿoþýþi¥þíü)ÿ[ÓþEûþÝÆñþ,úRý[–ÿ·ù ý`¡6ÿ úýÕ ‘ÿ%ûeý´íÆüæý#^×åþ`þHÿÀ±Ïþ~ýIÿ—óÿÒûþon4ÿžúKýð[[ÿ"úÿüwÿFúõü”´ÿ&ûFý¦û)¸üÍýLšÁ”þUþ¤ÿ }ŽÄþéý’ÿT|ÿ^üWþÿ^ÿ(ûyýñ„ÿ‡úþü¢J©ÿžúýYèÐÿPûVý˜ù"—üÆýo±¢fþUþÖÿ"FTÜþ;þ¸ÿ#ÿ³ü‘þÞ¶TÿdûºýW{€ÿ8û„þL7ýþ'ü^þ ØUýªûÅVýÂûJ(ýaüÑÑû%ûGãäÚùüW#ÿáúÜýQ¤jþ«ûÿ“;þgýÈKþ¨æ@ü¹ýDŸþ¨úÿÎÛñúÊøØà°ø³øìÝLø<ú„ݸÿoø[ü8Yþóùmþs}¼ý-ü¢_E4ýkÿ¶ ýÒýÎç~þ©ú ÿ¤ðûAùÊÐŽ³ùÊøŠ¬%ø´ù¼JöÄøwû;BZÿ6úäý ÒIþ=ü·³ þTÿÑWýCþÌw@þØúnÿÎõÉûù¥î×Âù‘øNäÍ´ø ùNª©²ø—úÞßóùïüµ5Ûþ6übÿ€þkþWÿŽ£øý–þC•þuûeÿ/¯0ü¢ùP¤gúùÚ/Å<ùoù31[áøµúÊß!ðùÇü¸†ñþÌûÿéÈvþŠþ (ÇþŠþ‘ýþ)üGÿW[»ü=új£Y´ú[ùÏõ¸wù„ùßš)ù¾ú‡Ü…þùvü•Û^ÿ­û~þÀ>Ãþ þz_gÿžþãsÿÙüÿž,pýÀú×ÿÝ”—û•ù_&%úvù?×)wù<ú ìù¶û>†ôÿ>û·ýÒÿRýÉÿÉfÅþåÿo×ýÿº#þ‡ûžÿi9üûù¦Ò7¬ú“ùæ°n°ùþùÌ]`ÄùMû<ú5Ñú*ýà]ÿªüÿ ?ïþ,ÿç}“þ ÿÞ8ƒþ<ü²ÿjö”ü‘ú@ÿúäù¹^}Þùú²k¤·ùåúp¥|ú}üöyÆÿ2üjþ1ñ4ÿ™þGÃPÿ$ÿ>ÌèþÞü§ÿÔ±éüûú‘øë7ûÿù‰1™úýù€`ÆÜùÏúøuÁ†úKüÛ½üþ R‡ÿVþÌÿÁÎÿmÿÒFÿrýÊÿRFJý—ûx^¹·ûxúS·”„úú/úµú“m'¥úöû±ÿCïû»ý'Å£ÿîý‚ÿ7eÿexÿÛýÿÁ;Éýáû&êÍ#ü’úûg»èú'ú¼ä>ú¸úML]ÙúÜûp ™èû@ýå ËýëþíÚÃÿïÿ{›ÿŠþÊÿ8µ þˆü/?i˜ü3ûàÂŒgû|úLÆú¢úó[Èëúmû.[íÈûÝüæ°]Dýcþtoÿåÿ&ÿâÿªKdþý/ÀÛü©ûØPZ°ûÑú\1?ÿúÌúã8Îûmûr)½û•üÎÚ’2ýþ'êúþ“ÿ¼ÿ'å£þžý5=ÖFýü¨ÐMüû4Õ=Pûãú²Õ"ûtûý]0¾ûŒüáóüøýT!¬þzÿhÞÿ¬Àÿþ Ÿ¬ÓýˆüO1E½üˆûÂ0Tü:û4½ûû‹|#ünüuóÙýÂý%IK˜þ:ÿo^ëÿT”vÿtþÊÿ-®DþÕü »E*ý¾ûvÐjfüRûÝ?2 üû7ï³WüZüO$ý‡ýÿv|vþõþo£ E”ÿßþòÿÉO€þNý H†ýü?_kØüû¤ï;^ü ûøÔávü-üa)ý:ýæÀ½KþŽþjGÆÿîÿ®ÿ<ÿl½þ«ýöÖ²ýpüO9þüÇû‡£D¨ü»û͌ԸüRüñë`KýDý¿«äfþ~þX![¬ÿËÿÅÿ}ÿ'âïþüýþÿ†´#þÉü–/uýüBDJýíûŠP ý_ü¯¸~zý@ý³¸âQþgþXFo•ÿ¬ÿÌÿŸÿ þÍÿ.þìÿL§Kþøü g“ýFüF-$ýü.ùýgü§º‹{ý(ý–à NþAþXsŒfÿhÿÜÿðÿ$±?ÿyþíÿ‡þ<ýâÿéýtü Ç7jý,üQLý`ün§·žýýzË*PþþM–¢Mÿ?ÿêÿ-8{R]ÿÖþ¬9µþ¡ýòÿ±Ò#þÏüÿÿaÀýtü#¢£ý•üAoÓÖýý:»_qþêý²èFÿøþÓÿsnCkÿ#ÿmÿÒþÝýîÿ{¼Oþÿüôÿ1ãý”ü“ªý”ü6hÚÞýüü1ÕpUþÎýÖû$ÿÐþãÿŸw!æÿ‡ÿbÿ *Îÿ4þôÿ'€zþQýñÿäì!þÑüôÿ4ûý¾ü /Úþý¹‰wþÂýáÿ¬þ×ÿÍ”ôÿ¨ÿ”ÿ¬ÿ:ç‰"ÿŒþþÿÐF¹þ¬ýåÿˆ¼cþ!ýáÿëì9þþüçÿàÔTþ?ýóÿއœþÑýäÿÔ)2ÿšþÀÿÞ´èÿ…ÿ™ÿØÿG³eOÿÐþõÿ(øþæýÆÿ2§¶þfý³ÿŽèŒþ*ý·ÿ§Þ€þPýÓÿi˜´þØýæÿÉ"#ÿ•þàÿñ£Åÿyÿºÿýÿ:‚Qxÿÿèÿ; :ÿ8þ¶ÿÙ}åþ«ý´ÿG»¶þiý¶ÿe½´þýÁÿ:ŠÕþåýÑÿÇ90ÿ|þÆÿ Ï»ÿ8ÿ§ÿArPõÿ{ÿbÿú¦FÿžþßÿŒ) ÿþÄÿéuæþÉýÀÿÖþÀý»ÿüsÿþ½ÿ–0Pÿþ¼ÿÒµÿ-ÿªÿZ…BÒÿoÿˆÿ;ÖuNÿÝþùÿJì0ÿbþÍÿ¨E ÿþ¸ÿÌmÿþý«ÿ¸a8ÿ3þžÿi3uÿþ¤ÿðßÈÿ-ÿ§ÿb‡)Áÿÿ¶ÿ/Ÿb{ÿÿâÿÛmÿ˜þ«ÿJ'^ÿ\þ–ÿoWeÿFþˆÿiJtÿsþŒÿ.žÿËþÿ»ÕëÿBÿ—ÿG6Çÿ•ÿÃÿ3ŠA‰ÿMÿóÿέ‡ÿßþºÿ‚ÿšþÿ"/ÿ†þŠÿ'*™ÿ˜þ„ÿ ¬ÿÅþ‰ÿÉÛÚÿ6ÿ£ÿdƒ¬ÿ¬ÿöÿ;Qµÿ„ÿêÿ“”½ÿÿ¦ÿÊí¾ÿÊþtÿî.Çÿ þSÿôJÔÿŸþTÿè4ÖÿÃþiÿ¾øÿÿpÿnÄ+}ÿ{ÿoVéÿ‘ÿ§ÿ ‡Y ÿ@ÿÓÿÁǰÿåþŒÿá¼ÿ³þpÿö0Äÿ¢þ^ÿò7Þÿ½þOÿµÿ_ÿiÏ4mÿjÿŠjÜÿxÿ©ÿ9“K•ÿJÿéÿ½§¤ÿûþ­ÿèõ¬ÿÃþwÿè(Êÿ³þ_ÿß+àÿÅþWÿÃõÿýþ^ÿ„æLÿpÿ3–A·ÿŠÿÛÿGj"œÿ}ÿ›y¬ÿ7ÿÃÿµÆ¾ÿÿ‘ÿ¾ïÇÿáþ|ÿÄýÞÿóþwÿ¥éýÿ ÿuÿqÄ]ÿvÿ-˜J°ÿwÿØÿbt‹ÿ•ÿ!ŠLžÿ\ÿóÿ§Œ°ÿ-ÿÂÿ¯¹Ëÿÿ‘ÿ¢Ûëÿÿyÿ‘Ûþÿ,ÿzÿjÀ \ÿsÿ2 F›ÿrÿñÿ|lÛÿ{ÿ³ÿI!†ÿyÿ¤c”ÿKÿîÿ²•©ÿ#ÿÂÿ³µÄÿ ÿŸÿ”Áîÿ5ÿˆÿo¿LÿlÿE¿Dwÿ[ÿ £j³ÿZÿÎÿ}‡ëÿhÿ™ÿH 5€ÿdÿ §l£ÿIÿÜÿ¥”¾ÿ:ÿµÿ´éÿ2ÿ‡ÿvÇHÿoÿH·9uÿaÿ¤`¬ÿ\ÿÔÿƒíÿbÿšÿR£&qÿmÿ(·Z€ÿFÿûÿº‰£ÿ5ÿÊÿ ¤Ñÿ<ÿ¤ÿ€³üÿFÿ~ÿRµ5sÿcÿ hªÿZÿÚÿ‰ŠÖÿNÿ£ÿp±TÿnÿA¾DvÿZÿ°iŸÿNÿÞÿ˜ŽÎÿJÿ¬ÿx§\ÿ…ÿA¦7ÿiÿ j§ÿNÿÖÿ”‘ÎÿIÿ´ÿ~¡öÿUÿÿX®!mÿwÿ*¤G•ÿsÿ†^ÀÿvÿÛÿitðÿ~ÿ®ÿ>‚'•ÿ…ÿ Q±ÿqÿàÿzvÑÿcÿ¸ÿh”üÿeÿ•ÿM›uÿ„ÿ2˜5“ÿÿƒVÂÿ€ÿ×ÿ[rþÿ‡ÿ¥ÿ3{*Ÿÿ…ÿ ‡V²ÿfÿÜÿ„‚ÐÿUÿ³ÿtœñÿVÿÿ`¢ gÿ‰ÿ@œ-Œÿÿ †T¼ÿÿáÿ`fòÿÿµÿ7w&§ÿÿxVÂÿpÿÖÿvàÿ]ÿ©ÿhž[ÿŒÿO©!jÿ}ÿ4 :ŠÿvÿˆN¼ÿƒÿâÿ_hóÿÿ¶ÿ1l$§ÿ”ÿtVÂÿqÿØÿx€àÿ_ÿ¬ÿh—÷ÿ]ÿ™ÿWœqÿÿ7’/–ÿˆÿ yD¾ÿ•ÿîÿUSíÿÿÂÿ0d!³ÿ¢ÿaNÓÿ‰ÿÒÿ]yïÿoÿªÿXoÿ˜ÿD”yÿ‹ÿ3’)Œÿ‹ÿz4¯ÿ›ÿY>Øÿ©ÿäÿ5BÃÿÁÿH4Ùÿ¥ÿâÿMYéÿŒÿÅÿOwùÿuÿ©ÿVnÿ•ÿG•ÿ‘ÿ-‰'•ÿšÿp/¸ÿ¤ÿûÿJ=ïÿ·ÿÏÿE%Óÿ¬ÿêÿKYêÿ„ÿÀÿ]…öÿiÿ¢ÿZ›aÿ‹ÿO¥lÿƒÿ?˜‡ÿ•ÿ'z*¬ÿ£ÿK<éÿ°ÿÔÿ"G Êÿ§ÿñÿ\XØÿ{ÿÊÿj„ëÿeÿ®ÿh—ôÿ\ÿ¢ÿdœaÿ—ÿT• ÿÿ1u«ÿ«ÿ N0æÿ¼ÿÖÿ"L!Èÿ£ÿôÿbWÏÿyÿÔÿp~Üÿ]ÿºÿz–äÿRÿ¬ÿr˜ïÿaÿ©ÿX†…ÿ®ÿ6d¶ÿµÿ9+õÿÄÿÐÿH+Êÿ ÿïÿb[ÏÿsÿÐÿz…ÕÿUÿ½ÿƒ’ØÿSÿ¸ÿ“ÜÿYÿ¶ÿq‰íÿ~ÿ¾ÿHg¦ÿÆÿ?ÜÿÌÿëÿ6Òÿ²ÿóÿUQÓÿÿ×ÿnx×ÿaÿÁÿ}‘ÚÿQÿ¹ÿ}“ßÿ[ÿ¸ÿn†êÿrÿ»ÿXsöÿ•ÿÂÿ0O ÈÿÎÿÿÿ!#ÙÿÎÿüÿ>7ÜÿÿÝÿYdàÿwÿÅÿkãÿeÿ¹ÿr’æÿ[ÿ´ÿpŒêÿjÿ»ÿ`tñÿŽÿÆÿ:OÂÿÓÿ $úÿßÿÛÿüÿ/3êÿ§ÿÕÿIeóÿÿµÿZõÿaÿ¤ÿh¢ùÿYÿÿf¡ÿÿeÿžÿSŽ ÿ«ÿ=m¬ÿ¾ÿ9èÿÖÿåÿ("êÿ·ÿÙÿ9Zûÿÿ¸ÿG~wÿ ÿS—iÿ˜ÿSš sÿÿG† ‰ÿ®ÿ9g °ÿÉÿ9 ãÿèÿûÿÔÿÕÿG¬ÿ²ÿ)p“ÿšÿ8Œ}ÿ“ÿE–vÿšÿI ÿ®ÿGlüÿ£ÿÓÿ7<îÿÎÿøÿ òÿóÿÔÿûÿ9$Êÿ«ÿd1§ÿ”ÿ#„&‡ÿ‹ÿ5”!ƒÿ—ÿ>† „ÿ°ÿElúÿœÿÑÿ9?ðÿÈÿôÿ êÿùÿÜÿíÿ*)Úÿ°ÿúÿ_8¬ÿ‘ÿ€6“ÿ‡ÿ*‘%}ÿŽÿ?’~ÿŸÿC{–ÿÂÿ:Oóÿ·ÿìÿ/êÿéÿ çÿðÿ#&àÿ´ÿùÿV6¸ÿ“ÿ }8–ÿÿ“2…ÿ‡ÿ-Ž$‡ÿ™ÿ8€•ÿ°ÿ0[¹ÿÚÿ %öÿêÿ íÿðÿ%åÿºÿ÷ÿS:¾ÿ“ÿzC¡ÿ~ÿ=Žÿ}ÿ ’1ÿÿ+~›ÿ²ÿ0Vÿÿ¸ÿàÿ(%ïÿèÿ îÿîÿ'ìÿ¼ÿñÿK<Êÿ™ÿýÿnA©ÿƒÿˆ;‘ÿ€ÿ$(‰ÿ“ÿ6ÿ³ÿ=cûÿ§ÿÖÿ5:íÿÍÿüÿ!æÿþÿ!Ôÿéÿ/7àÿ©ÿöÿ\=¶ÿÿ ;˜ÿÿ 1‡ÿ…ÿ-Œ‡ÿÿ:x —ÿ¾ÿ8Tøÿµÿâÿ)"íÿæÿïÿëÿ)ðÿ¾ÿôÿL;Èÿ˜ÿtC©ÿƒÿ‰<”ÿ‚ÿ -‹ÿÿ+|šÿ°ÿ-\´ÿÖÿ'.öÿÝÿýÿúÿðÿòÿÈÿðÿ=7Òÿ ÿùÿhG´ÿ„ÿ†EŸÿ~ÿˆ8”ÿˆÿ€'šÿ¢ÿ&d²ÿÊÿ"6ýÿÚÿôÿðÿýÿÐÿèÿ7>Þÿ ÿêÿ_NÆÿŒÿùÿwJ«ÿ€ÿ ‡Aÿ‡ÿx-©ÿ¨ÿWºÿÏÿ/ûÿÝÿûÿúÿìÿ #ùÿÆÿæÿ:>Üÿ ÿîÿbNÀÿÿøÿ€Q©ÿ|ÿ ‡AŸÿ‡ÿ)žÿ§ÿ%_±ÿÌÿ&3õÿÔÿúÿæÿúÿÖÿàÿ)=íÿ¨ÿâÿRQÔÿÿëÿkQºÿ…ÿ|D©ÿŽÿt*©ÿ«ÿ Y ¶ÿÐÿ#5öÿÏÿ÷ÿãÿøÿ Öÿ×ÿ@øÿ®ÿÙÿEPÞÿ’ÿâÿbTÈÿ‡ÿóÿpH¶ÿ‘ÿ q1®ÿ¦ÿ^·ÿËÿ"8øÿÌÿöÿ$Üÿïÿ#ÛÿÎÿC³ÿÌÿ8Xòÿ“ÿÒÿY^Öÿ‡ÿâÿhVÆÿŒÿøÿh=¾ÿ¤ÿ Z¾ÿÆÿ9ÿÿÑÿðÿ áÿíÿâÿÎÿ > ¹ÿÊÿ0S÷ÿœÿÎÿM\âÿŒÿÙÿ^VÎÿ’ÿóÿaAÈÿ¦ÿT#ÇÿÉÿ6Ôÿòÿ ãÿëÿäÿÒÿ :½ÿÆÿ+Sþÿ£ÿÌÿtkabber-0.11.1/sounds/psi/presence_unavailable.wav0000644000175000017500000001270007747030166021530 0ustar sergeisergeiRIFF¸WAVEfmt |ø*data”ûÿýÿÿÿÿÿúÿþÿ úÿÆÿœÿCÈ/^ÿîþàÿ:âÿýþÝOòÿéý@üéýÿÿ†Ì:ÿËüXü²üüý†ÿóþ‰æ ñCs¥ÂKÿÿýqþþWþoýkûuûdþíÿÉþ-ýÆûâû'þCB\šÿÁ Fúaÿšþá ÿ¥ü#üiûnüèýZýnýþýýŠþáþþeýmû(ü¶þ…þ³ýùþAÌE_~\µ4ÁÉÇ€±Òù’Ïý1üzúùŸù£ù!ùùú+ýÁý£þ¯ÿØÿ‹ö—Oþ…ýÿüüúüÑýþüÔýñÿ)”Ìé’ô¤;_¾øaŒöÿ)gJDÿ‘þ6þ©üïûâüZüQúù‰÷«öÅ÷{ø&ùöú1ûŒúÞûûýÄÉMOú Á 2 _ £ " … _¨<ÿÃÿC6ÿ1þ¤üeú’úeü½üJü?û+ùGødøDøùZû=ûûsû8û³ûLý–þ¥bHIÀ9© a ô È  ¬0[}_ÿäþòýMü$ü=üÏû¾ûœú¥øGø†øø}ùûùÿøÚørù$ú}üÿÌÿÇõ(¾]¼<È?0e|JÒJºa^Ÿÿuÿæÿ¬þÓüèûˆúˆùóùËùùºøÆ÷÷Þ÷søËøtú»ûEüzý3þÑþFM©b –’8¥ } R &[6ò®èÂ#ÿý@ü"û‰úXú1ùoø5ø÷„ö†÷ø–ømùù÷ø”úü¼ý4vÝÜtH—. 4`q/ø1(‘„ÇHôÃìÿ^þ—ûúÃù0ùHùVù:ø±÷Ò÷Q÷¸÷+ùéùÜú!üQüêü}þsÿûvš'!7¼ŽW ~ - ­M¯ôc-*ÿÕüãûëúzùðøé÷ìõ õÜô×ôöh÷É÷¤øNùzùCû©ýÿÜvà „> ¾ v Ÿ : ¬ |-fDø$§ÿHÿþ-ü½úÝøk÷J÷´öö‚ööSõöåöƒ÷cùöú¬ûýOþÿ垸‰ÅÓ÷¡_ > ½ ) ‚P¥ûÎÿVþ“ýôûÀú=úóøÔ÷{÷³ö6ö†öö÷Nø¾øUùû_ü©ýíÿ~cϵ_8ú0 ¥çØ:‚‘r¯½“Õ“ÿpûMùúÅù]øéõ!óýò4õ‹õ¨ô÷ÀøðùýpþÕÿwAàRbº÷æ¡:ùš6ØÇ½ITÅ€Qíiçý«û4ü:ü=ùQöNô„ô5õ—ôõ"õ›õ©÷dø—ööoù”ûÕüiÿèrÎa¡ ñYƒÇ  Œ Û éxPÿÍütú¼ùÃù!ú%úxùGùù¥øÓöÝôôôlô?óùóröøÙû¿HÐ ñ " A ~ Q m H ÄÖÏn-¬Ðý2û­øý÷4÷ö;õˆóLó¸õú$ýÿª¯æµ¨Éÿ PêþýÉý1½þœýý÷ü¨þïÿ*ÿ/ÿòþÜþ`t¤ÉBÒÏò â c nÔÏ+; ýæúªø€ö™õ[ô|ó(ò™ðñ“ò@ôõ¦õ÷$úãþéQîH á +ÁŸå+1Q uA+³ÿ|ü0ù·õ.òôðÌï€íÛë ë±ëîìÖîRñÊó>ö©ø÷üè» æ ÜU6 ½ÞBÔše 4óîÿDýú÷þôòqð«ð]ðð‰ï’ï-ñÜó£öcø{úüÿ2ÿÆä$ µ  æ š • Ú ; í­¼¿ÿèýý–üóú›ùŠø÷u÷øuø ùºù]ú‡û÷ýØÿgâ²ÜÉrgs™9Àêÿïüúúðù®øw÷Ñõ–ôBô›õJ÷wøïùÜúùü ~­q]6 nÌ!_J œ ] Ž zô\ÿ ü‘ú]÷]ô†ñïûíí:íÉìÉí‡ï°ñõé÷ ûnþŸ~\ Ë fô¨);ð;¯ç Ô qBUÿ™û÷±ô\ñAîmìªê›é¬éŸê˜ëiíDðó'÷<û¼þlÄ„ ØáWˆ¯Ý}8< ÔƒxÿûÃ÷Ùôó§ñøïïƒîÎî9ð"òçó¸õ¾øMûÚý(Æã†[ < ­ ” O  ’ ñ Äåa£ýû3ú5øÉööeõÖõJöáöÇ÷ÑøtúýÈÿBôÿyq¶ ã Œ & Ðþ[2ïKþ®üûëøùönõuôô£ôÃôëô=öÈ÷ úüÉþ†:­  dc1É• »  yº4lþ×úÁ÷úô£ò¥ðãîííNí…íqîðuòÆôž÷iú|ýIB¶ H ·œ/†ä¯m ø ܈éPýúO÷ô…ñ ï–íËìnìjìeíåîÚðþóÅö­ù4ý:K–¿ . 4¾ŸÁæ ç Ô y[E€þ0ûšøeö7ôàò­ñÀðŸðgñˆòôöÌ÷Œú£ýðÿq zHö ò 4 ƒ  h ’ üiŠRþÿþ)üú›ø8÷hö”ökötö+÷wøýùËûÑý‚ÿ¶Îo KG æ ÷ ¦ & zãJ·»íÿ¸ýIû ùc÷"öàô$ô”óóGô,õÏöœø˜úÒü3ÿÏ^ a 8 î Ûï`| ?  ¡hÉÞAþhûÒø{ö?ôHò˜ð‡ïïiï9ðBñó×ô?÷@úRýw* ¤ ç ¡¡‹+&¦  1[6þ#ûø\õ5ó^ñðïþîIïð‡ñaóÉõEøÇúœýiIã>R ! à |ÊÂ%3   ° †?²öÿŒý&ûù'÷VõTôÚóÈóþó°ôáõG÷/ùûÿü"ÿ24ËDži w W ð Ö8‘éTŠþ¬üKûúù*ø‘÷Ÿ÷î÷‹øYùŒúüýlÿ´õß§  ÕòÉD­³³þ´üÃúÁø÷ö0õ—ôoô®ôuõ‚öø¿ùÔû.þ…ñGL Ä  é h ^ ô % Õ m ‹F½ùÿ†ýû§øböôóÎñ.ñõð>ñ<òxóõ÷AùÈû[þ—dÖ¬ Q – ™!oC ñ # ší|ðý]û÷øäö8õÑóèòMòDòÊòjósôëõè÷'úRüsþ†á Íe¤ Á d t  † Î ™&uáÐÿÆýü’úUù+øV÷ÇöÒö6÷œ÷„ø¸ù*û¬üþ•ÿ&Ç!A/Òiw |¸ÀjžLÿþªü{û‡úÔùcùù"ùùIú$û üSý´þTñL£åö 3 ËüÊxôSwÿ—ýÎûUúù¯÷²ööÄõôõCöéöó÷lù û¼ü¿þËïê¥@  Î õ ò Œ ì ® ~šu ¬ýnûhù†÷Ãõ{ô˜ó0óó,óãóõªöiøSú†üÓþ9v‹…/ Œ t W K ã Ù '}«fWþtü¤úÛøW÷ö;õÅô ôüôžõ‡ö°÷)ùõúîüûþÌ‘bùYKí[ ˆ V ¢±‰AÞ7÷þuý üÎúðù^ù ùÒø×øHùøùÝúÍûÔüþVÿ˜©»Ä—I²ÜÃmÚ IL¶ÿUþ:ýGüoû¯ú'úúúpúáú™û¨ü¸ýãþd©ÄǤr+²<”Ž@ÍU¶þ*ýÃûhúBùCø‹÷#÷÷B÷Ã÷ƒø|ùÚúcüÉýTÿΘ?𙄠3 } t  O Šè0QJÿSýtûÀù[ø÷öuõ/õNõ´õlö]÷šøúµû£ýÿkCôŠõ Û @ [  — ·,ƒÝ/pÿ´ýü¶úmù|øÒ÷Y÷÷!÷’÷RøOùwú¯ûüü[þíÿ}Õ ÞzæçüA\KÏœÿ…þšýÄüâû/û¹ú–úÍúûzûüÊü¨ý™þ©ÿ¢Wþ–JHÌTÅçí 8ÿyþ¦ýÆü ü¥ûlûNû{ûËû9üÀü\ýDþ^ÿwoYP5üu¤ÊÎržª¥zLÿþØü³û¡úËùBùãøšø|øÂøcùCúFûeü¶ý,ÿ¨~Ô÷ä„ñ-Â&b‰…/'Îþsýü¾ú›ù¼øø·÷›÷Ê÷5øéøÁùÃúüsý×þ:¬#lw<Þ^©²`ÌCAì±ZÿþÙüÖûóú@ú¹ùeùXù…ùçùnú*û"ü'ý,þ:ÿMOH<ú‚å!$ö³F­ì/>Qÿxþ­ýýü$üåûÛûü^üáü{ý.þëþ™ÿK»TàDj|Q„îD«ÿØþþdýÕüWüøûÄû³ûÝû5ü¶üVýþÊþ ÿ‰{e2Þrß%I9Œá*,ÿóýûüü?û™úúàùÜùøù:ú­ú[û3ü%ý6þ\ÿ”ºÎéè´F«àÕS}{b*âÿ¬þ…ýpü{û¯ú ú›ùYù7ùXùÇùcúûòûïüþNÿz¤ÐÓ°bÒ%]HéiÃ÷ ôÿëþéýõü&üû û¾ú’ú±ú ûlûäûü[ý@þ3ÿíʼn2¬ñ"8©TØ/†ÆûÿOÿªþþžý5ýöüßüÒüêü2ýƒýíýþÿ¤ÿIçsý€â" ë¦3°]Ãÿ)ÿ}þåýeýðüšühü[üvü˜üËü=ýÙýþ<ÿ³uSŸq©°3Ç&g£ÃÜÿöþöýýaüÑûOûïú½úÀúöúLû½û^üýäýÑþÉÿ¸¥„Cø `vU ÏEŒ·Ìßñÿíþôýý:üûûÌúªúµúÛú3ûÌûwü1ýþÝþ³ÿ›{;âoçM„”†AÖ_É GvœÿåþIþ°ý)ý²ücüYüoüŒüÈüýyýþþÿ«ÿ1®6Â7†³Ïåã³^èbØO¿ÿ&ÿŸþ'þÈý‘ýqýeýpý“ýÓýBþÇþ2ÿ¡ÿ•õF{”¦¨{9Ù[æhÊÿÿuþðýŠý9ýêü´ü«üÀüýkýÙýSþÔþ^ÿüÿ·bðlÐ<šÈÜΓ;ÔEÉþÿBÿþÑý$ýˆüüÊû³û´ûÆûûûLüÏüxý.þôþ´ÿr:¾L¸ FfV°F¿"ˆ×Uÿþëý`ýßüiüüÔûÆûðû$ülüãü|ý3þëþ ÿX¾TáE}Ÿ–uP ˜wïlÏÿ$ÿ‘þ þžýLýýýü ý)ýZý°ýþ’þÿžÿ!¬-‰Î"CJ%î¥S ¹Oáÿrÿÿþ”þ@þüýÉý¯ý°ý×ý!þrþÉþ>ÿºÿ7³vÆ6RT>á¡]ÿŠ“ÿÿ–þ'þ¶ýZýýÚüÙü÷ü$ýpýßýbþüþ£ÿ?Üjïvæ,Ug]@ÍhçO·!|ÿËþ%þ‘ýý«üaü8ü3üEüzüÓüFýÆýTþõþœÿT"“cœ­žt2è„ö\· jÿÑþCþ¿ýRýÿüÉü¯üŸü´üíü8ý£ý þ—þÿ®ÿ9ÂX×3x¨ÍÙÁ‘Sý?¿7ÅÿRÿÞþƒþ=þþýÇý«ý¯ýÏýöý,þ„þçþSÿÒÿ?”øW±ÉÍ¡q:ó Lôÿ—ÿLÿÿ´þuþLþ2þ5þOþlþ”þÍþÿnÿÕÿ?¦Ožè.:6Þš9ÉWæÿoÿíþlþtkabber-0.11.1/sounds/psi/presence_available.wav0000644000175000017500000001527007747030166021172 0ustar sergeisergeiRIFF°WAVEfmt |ø*dataŒþÿýÿÊÿª2Ë+þÏûÔýã—iÅšúøÌý5=8°ü”÷×ùñþàO§ Jùqò4÷Šÿœß â fUûãó®ôaü­µ ¯ ]ùû"õþóèùûI Ý 0­þ«õdñ„õA W z¶øóó›ùý7 ‚ÄýÍó“ð2öÒÐ ‡ñ ªÿ_ô¾îTòvý, ®ªI2ø;ïŒïûø©Ý/û‹ñ·ï*÷Û’ þhó\ï¯óêþü ô³÷«ï(ñdú›P—ŒûÔñFð;÷Ã" |É ýþgóïQô;ÿZ •þ ½¾÷ð›ðrùêÆ4v"û9ñPï&öiz =| Qÿ±óÎîñò?þ¸ 'Kë`÷‘ï©ðâù{­\8…ûñï=ö™‹ s Òÿ9ôÐîÖò þB ðLì÷•ï‚ðú‡yCBèûÖñ;ïÆõíÎ ¸ƒ äÿ…ôrïdósþK fà ›E÷¶ïýðeúÑaÑö¬û«ñgïúõ 3 ,› ¯ÿôëî%óLþV Þ-¼`÷ªïÈð<úÅ ¬)ûPñAïSöà ÷( Hÿñó!ï]óŽþ ˜Ó ¨b÷ÅïñðMúâ¢Ï|ûQñ ïÒöøx ™Î 2ÿôó5ïšóÎþ¡ œ˜ <÷Áïmñ*ûZQ ±’úeñVðæ÷°Q ï €þÍóÚï›ôkÿ’ Û ‹éö^ðTò­ûRø{oúÝñèð,ø¼= —… Vþ ô=ðÔôˆÿk ¢y œP÷¯ðfò‘û«J&žúòþð$ø su OþôMðõÄÿŸ ¾M <òö€ð…òçûuóRítúòñ<ø¦ j^ .þôMðõëÿØ » åàöÔðãòõûEªÝoúò?ñ˜øû ãöýô¥ð°õræ Y{ ~¯öÜðKó¨üƤ < úò§ñù>ò þüƒô"óøZ´  ™Vþ?÷Ûóëöeÿ± =á <ÿóï—õ) „uÝ qý†ï›éeðÀþ­ ƒ µüñZë–ïˆýö F² ’Mû%÷‰ø2ýw¦úÿ¾ûsû;À ã¾öˆï?ðù>²`£Õðæ†æ@óP) ºôkê ëàôoã <Þ <_üÐùqûûþUeýú,û 9Ï 7 ¾Óú®îøè•í„û Cf±ûþ…ì\âOåôÄåý:¥¦óÉêlìö:» Ö €ÕüCúˆûgþ¯ÿ‡ý úùIüV= &oùP÷öëèÉï ÿhX]¥ û`ëåäùê#úò $4ºÿOóéí•ð ù¹ð” -”ÿ˜ÿ‰ßþâùÊõ¾õNû-â~‘6ô×é©èò{bK ûh÷ê¼æ^îûüÓ ‹Ê» žþ6õÁñ¢ôfûó<ø…΂‰põü½öNó@õýüC°9 ïÿNñ èé½ô‡qÃ7õ®é*èÄðGÿ¿ 9øbúýYö`ô÷¾üð¹ißèÞÿLû}ô™ñhõ+ÿó PÀ oüJîGçë9ø ýR¹«óÁê}ë®ôrÙ ì –”ýøø„ú}ý'ÿdÿ@ÿm¥ž´ €«€÷,ðï¹õìl{# ù—ëÎæÚì(û| viuÿÿŸòìeî·÷ãü _ + å%þ3ûû+ü÷üÁüGü&ý–ç¡ Û ±ÄþŒô÷íÉîƒ÷eÚ•ï?ö‘ê%èðœþQ ²jµ wý˜òTî´ñSúºÓ Ç |š¶þýýGý}ü"û¬úŽüR¬v ‰ °œüuòöìyïâùÖfµôó^ê0êbó¼¾¢E&ûŸòªðõéü9"ò÷&¾ÿ}ÿþrûÑøPø‡û– `R èÆúžð`ì­ð4ü G] ŠÿûñÕêíìåö¶Zž˜úLôŸó·÷ÜýöS:—Zý*ù^ö<÷jü‰X Ü *y÷îìÏò\ÿ§ ‚c íüñúënïsùLó 2¼ LûQöö1ù‹ý,4ÙüS˜¹Þ&ü2÷Áôàöšý¬Bv Iõ\í%í>õEbH€°ú½ðíòçûf% Æ  ÊkûøMøÃú¯ýÞÿ2S܆SóÐúMõmóîöÿ·´så †þFóíÈî¹÷DçéÝø¯ù¸ñðóô³ý&è à Î|ý×úúnûvü—ý(ÿŠ¥ySÚïø€óÀò°÷Ä è/œü8ò‹íœðúíê^Ž ý ùÊòiòR÷¿þd增¸’þÐü ü™ûMû­ûžý_Û= ª ÿ:÷òOò­øÏl 9Þ‚úñîœò…ük¶% <Ðø0ô§ô7ù]ÿvå¡·mk¨þëü$û¿ùÝù‰ü X Πݧý^õ¿ðMòôùÆŒŸ ûÁøµð8ïµô‰þ[$Ò ÐÿÚø¡õŸöˆúXÿFC`Šcóúÿ:ý-úø‚øTü˜ëƒ A üêûµóðóÍû¹  ã æV÷ ðoð’ö!Þ> ñ : ÿtù<÷lø±ûJÿŽ8^%;^ýlù÷ÿ÷‡üw  ä ÇdúµòOð„ô¼ý û¯× «öñ–òçøw•} ¢ œÚþ úùúUü þ‚ÉqŠ…ðü`øöõh÷åü¡O ² e bÉøÙñÄðöŸÿM ø?ªMþDöÂòÒô ûW¼s r>õþ-üHûµûŸü™ýÊþލܦÑEü÷åôH÷Óý g Ø Y ˜X÷¥ñÜñè÷Fß D ™5ýªöiôùöªü¤ŸŒº‡|ÿ–ýÜü•üSüdüpýâÿ]©#s‚ûµõôw÷ýþŽG ‚ ÿÿVöªñóÊùåg 7 f §3ü÷þõÍøÀý˜‡éq_Ž>ÿþ³üfûû\ü®ÿá ºÈù¹ôô‚ø¤ñ³ ¯ 4ý<õòÀôåû]ƒ å d±ûØ÷±÷™ú¨þóK œª•ÙþyüiúÜù°ûåÿ%& ² iÿ`øòóiôðùU ” g oºûõ,ó„ö…ýÁ ! ¢.üNùmù®û”þ œFX1Ì“ÿæûwù#ù®ûœ'× ² TAþk÷Ëó$õ4û€b ã  !-û|õ\ôø‘þÁ­oȸü™ú˜úü9þ"‘§Œºìµþ ûø³øþûA… ˆ QíüöÑó,ö¯ü£¡  ž³kúÞõ»õ«ù£ÿè]+$ýšûÎûîü/þPÿ‚þ™©noÆþ‘úÏ÷8ø.üVÒ iêûèõô[÷<þ¼«  åÃù€öJ÷Uû æ“ú,þýýBýuýöý^ÿª'Är«þù÷#øÃü`  jªú{õÀô¸ø’ÿVB Ì Y ÿßùŸ÷çøœüæ?`fv$ÿQþ³ý"ýÎü5ý×þª¼z¾sýêø¸öhøý,O À •ú¥õŸõÕùn’¬ ?¨þ2ú’øú`ýïVŽPûÿ ÿèý¹ü ü”ü»þ] ù¶üøöÞø€þ Z ˆñÿcù±õgöûvÅè_"2þ¦ú£ùûãýÁš.ój¸¼dÿÁý"üNû1üÿÝ>Œ·zûf÷²öÛùÐÿí Œ (µþ÷øLö¸÷eü$“+> þ>û¥úñû2þ`Ée¢²iu­ÿfý]ûŽúçûZÿ§×YG¨úûöÿöÅú×¶Í µô¹ý¹øðöáø„ý´Aþ~þâû›ûÃü{þùÿú±XÞéþÿEýçú"úÂûƒÿ‹þõÿúíöu÷“û²+… ÌíýÁø©÷ú€þþ»õüõRþîüÅüaý=þÿíÿøPœù»ÿÿ¤üúŒùÖûLÇ vþCùÞöOøøüÜxã·lüù¶øLûRÿýùÍ»Ñþºýyýµýþþfÿݱvcÿôû¤ù»ù¤üfï'øÉTýãød÷‚ùMþ¦H¼ûsCü úIú˜üØÿª§B¯qÿœþ þ¥ý„ýþFÿ"i=6ÉþUûuù3ú˜ýPA¶ùª’üæøKøøúœÿ$µd•ÿ8ü¶úmû¼ýfU ©´³óÿ\ÿ þÆý4ýkýÄþ†=þÎú?ùuú7þö•s)±óûôøùýûjY7mœ*ÿŠüžûlüMþP§ç’JäÓþsý“üÞü˜þZ g”™ýFúIùûÿŒ¥öHÒÿûLùíùûüþ7vòÿþöü|üFýžþïÿÙL‹Íì…i¹þ÷üöûƒüÏþ«¨Tõçüíùlù·ûÛÿšDV+ÿ†ûèùÚúÃý=Ó™Q"ÿÅýwýøýÍþŠÿªX\ö’yþ†ü·û¢ü&ÿaòŽËK|ü úú£üš6÷=l¾þÌûÍúòû~þF'©†ÿ|þ&þMþ¦þÿžÿdYJ½ ^þ>ü¹ûñü­ÿß.'®ÿ/üEúÏú€ý#aZštþ:ü­û×ü ÿ@’½àÌÿÿ°þ…þzþ®þKÿL‡¡ò¸ý üÔûaý9-è£w,ÿ&ü¾ú‡û'þvÑ¡WþŒüEüjýQÿ9`ÁÙNÿÇþtþOþ~þ.ÿaÐâúÛÀÿiýäûüûÐýµmÓBâªþüû+üÑþØîLø DþÕüÄüáý…ÿþØñ|ÝIºÿÿ|þþ3þÿþjùû¸„ÿ8ýãû:ü8þ“¦ÇS\þühû¥ü3ÿç¥Ù–uþDý=ý$þqÿšLŒ{4½ÿ9þºýìýûþ®lkYìþ½üÆûü·þŠÍ†bÜþ0üíû?ýŽÿ×59C¯þÔýÜý…þiÿ:ÙFucO;ÿþký§ýìþÛ±š>±þ‚ü°ûŸüûþÎáP÷xíýYüKü¶ýãÿÓØ²œ/ÿ^þJþ˜þÿÂÿt »þ—{òþˆýÜü^ýÿYAóÔ$þ*ü½ûý“ÿ-Õä`úÿÄýŸüÛü9þ¾~C]BPÿ³þ{þ”þáþlÿ:&è*¹ŠÝþcýÏü„ýVÿ“P£`ìýAüüˆýýÿZ¤häÅÿåýýLý~þ \áC~Äÿ"ÿªþsþ”þÿ7![´M˜þ:ýÚüÄý¯ÿÞg“Bûÿ´ýaüŽüþA>>àf‘ÿ'þ–ýéýàþürx&¢xÿáþhþQþ×þôÿRf£Ð$>þîüËüúý.z[Ô‡ÿyýüý·þ³=Ä2æwÿqþ þrþÿÙÿyï/; ƒ«ÿºþ þþ¾þ¨­©µÿÙýÉüýþ˜zYÑ'ÿ‡ýüü«ý7ÿêN±•wÿ»þ†þÀþ6ÿ¿ÿNÈ8”²ÿ«þóýöýËþ=Æ´šczÿ´ý×üFýáþõš$d»äþ”ýLýþ’ÿãðOe—ÿ ÿÇþÞþ3ÿŸÿ˜b@Ÿ”ÿvþÐýþ ÿˆô³\õÿ™ýý¾ýOÿ#s·ãdÖþÖýÀýˆþ¿ÿ㎓fÅÿSÿÿÿÿeÿèÿ+€Z¡ÿbþÍý þ#ÿ­ ¡­ûþ¶ýXý þ‹ÿ.Db’>÷þ8þ/þÃþ¤ÿ„G§)±ÿ5ÿÍþ®þÿÆÿ¹èŽƒ ÿþ›ý$þuÿG“Ø^µþ‘ýnýUþÑÿB#)\!üþWþ\þåþ«ÿjï(ÇI³ÿ"ÿ¿þ«þÿÏÿÕ°ú„dÿãýý:þ¤ÿ9Y‰±%’þ ý¥ý“þNüÞ ÿ”þœþ ÿ¬ÿQÆþÝxÚÿ%ÿ™þpþÖþÇÿõé/”EÂþ°ý…ý\þÞÿpmhhàÿvþµýæýäþ7PË”Ùñÿ6ÿÔþÍþÿ‚ÿ„ñ1#¶úÿÿ`þ(þ®þÔÿ)Cx ‹þ›ý ýžþ/¬n)©ÿoþâý)þÿF*…RÁƒÿÿ÷þ ÿQÿÃÿVåEJÛÿ?þþ½þóÿM7;OÕÿbþý¾ý×þe¿ZÿÛsÿfþþ}þdÿ` ? £ÿgÿDÿ-ÿ8ÿ‰ÿÅMféúÿðþ3þþÄþq>¤ÿIþ¡ýöýÿ“¿)±œfÿˆþPþÇþ¤ÿy÷ Ëdºÿÿ[ÿFÿXÿ›ÿ¶:JÒðÿìþ5þ&þâþ.}<üxÿ2þ±ý)þ\ÿÃÊ rM'ÿ|þ€þÿÚÿˆçç§VÒÿ˜ÿZÿ)ÿ-ÿ†ÿ/é`W¿ºÿ±þþAþ-ÿ€¨+Ę0ÿ#þÜýzþ°ÿõÇÔ(!*ÿ¢þ¯þ0ÿÜÿp¿ÆŸd-òÿ¡ÿDÿÿÿ‰ÿE ‡o±Œÿvþìý;þUÿÂã: Yñþþýèý´þûÿ,Æ›ÕÜÿÿÔþûþiÿäÿD|–˜ˆk.¸ÿ'ÿËþÝþuÿfOÀz‰Hÿ7þÚýkþ¬ÿHñÿ±þ þ6þÿ8.B‰ÈÿDÿÿ<ÿ‘ÿâÿEh‹¢Œ6©ÿÿ¼þäþ”ÿŽe¸UQÿ6þþ¸þæÿ$éÞÂÿ°þ6þ{þPÿTQû^ÇÿbÿFÿgÿ¢ÿÕÿüÿ+g¹ž/†ÿëþ¶þÿÄÿ´w¬$ ëþ9þ?þÿ0Bɵ™ÿµþlþÍþ•ÿeí½GØÿ‘ÿ|ÿ‹ÿ¡ÿ®ÿÍÿnºÕ£dÿÐþ®þÿíÿÞ‰éãÿãþOþqþ>ÿV<•H~‹ÿÙþ±þÿ³ÿXÀÒ—;ïÿ»ÿ—ÿ‡ÿ…ÿ“ÿ¾ÿÙä–NÿÅþ²þ2ÿý†p¹¯ÿÅþ`þ¥þ{ÿƒI}BkÿäþàþMÿèÿk°¨h!òÿÑÿ·ÿ¡ÿÿ’ÿ¸ÿrÌß“øÿCÿÉþÈþOÿ-o@‡ÿÍþŒþçþ³ÿ"9Ò#vÿÿÿ}ÿðÿK€Y- îÿÊÿ ÿÿ|ÿ©ÿ …ÖÕ}Üÿ4ÿÖþîþzÿGY^„ÿáþ´þÿÒÿ“ « yÿ8ÿRÿžÿòÿ;aaQ: Üÿ¡ÿoÿeÿ ÿƒÕÝ|Öÿ1ÿÓþðþ„ÿOüBXtkabber-0.11.1/sounds/psi/connected.wav0000644000175000017500000002136007747030166017325 0ustar sergeisergeiRIFFè"WAVEfmt ||dataÄ"€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€~}|{yvtrponnonke`\Z[_djpvz|}}|}‰‘™¡¦ª°¹ÃÎ×ÜÝÛ×ÑÌÇÄ¿»¶±¨Ÿ—“‰ƒ|vnd][]\WNHB;4/-*% $0>HNT`nwyz}€‚‚…”™¢§¨¦¥©®±³¹¿ÂÂÂÆÊÇ¿¹¶³­©§§£˜˜–Šˆˆ„ymggikr}‰–¤¥¢Ÿ¡¤¡˜‹†z|}sjd^RGEJPPNQWZZ\bd`Z[afhlvƒŠŠŠ‹……‰‰ƒ}~€~}„“Ÿ¢ žœ–†„wjb_ZQKLOLGEHKKMWelljnrqmpy„‰‹‘› ¢¨²¹³¤–Šƒ€„‹ŽŽ‘™¡£¢¨³»¸²°±®©©¯³­ –ˆ€{~zl`\\]bmz|€†ˆ„ƒ„‚yme_XPMT\_\\`b`akvwla[]_clx~z{€ƒ—›œ¢¬²´·ÀËÐÍÉÇú²±´±¤’ƒxnggntrmlopkede`VOKE90/6;;EHMXfptv{~ytof\Ycvˆ•Ÿ¨¬¨¤£¤zlb\\gzˆŽ“™š”‰„|tqrpidiw„‹ŽŒ†…ˆ‚ui_VRVbouvy‚‹’•–•‰„‚€{y€¡°»ÂÄÁ»¸¶¯Ÿ‹ylb^exŒ™Ÿ¢¦¨¥¡žš‘…}||wqs~Š‘””’‡ƒ„„|nbYPHDISY[Z[^_adfaWNJFA<>J[m|Š•œ¡§®°¨›‡xwŸª³¹¸²ª¢šŽtpnljny‡”Ÿ¨­®¬¬­¬¤˜Œƒxk^WX[`gnqoiea\RIEA:2.2=K[m}‰Ž‘’‡{spoljls~Œ›©±®¤˜Žƒwnlnpoqx„‘ ¯½ÈËÌÊÆ¾²ª¨¨¤–‘ŽŽ“¤¥Ÿ•Š|kZMFA;89=CM^s†“˜˜‚rgehmoqtw}‰š«³²ªŸ’€oedgkotwy}‡™­½Åެ—†€€}wnfabl|‰‘“…s]K@;9:<<97=Mauƒ‰…vaQLPX_ejlpw…–¤¬¯®§—ƒpc]]cltwvxƒ–«¾ÌÑË»«£¢¤¦¦§¦¤£¦¬±³´´°¤xdVONSXZWUZgy‰”˜’„sgcdefhlosy€†ˆŠŠ}kYLEFOZdgio}‘¥·Âù¬£Ÿžžžž ¡¢£¥¦¤££¡˜†nVA4/5?FHGHO\m~‹‰~ursw{€…ŠŽ‘•–••—˜“‡s^J=8=FMPPRYf{‘¥°°«¦££¤¥§§§§¦¦¦¤£¤¥¢–„p^PKMTZ\\\`hw‰š£¢™Ž†€‚†‰Š‹Šˆ…ƒƒ††udRB747>FJKJLQ]n—™™™œ¡§­°±°®­¬®³º¿½´¥•†{snlkjhfehp~ž¨¬¬ªª©ª«¬¬¨£œ”Œ‡}obWNHECA?>>>==BL[is|ƒˆŠŠ‰‰‡ƒ|{yxz~|unje_XQLJLRX[[]dr‚“£°¸¼»¹·¶·¶·µ°©¤ —‘ˆ‚zn`SKHJNMG@?FVj•¢§¦¡œ™˜šž¡¡˜–••–˜›™‚qaVSXaec\X[h}•­¾Åľ¶±¯°³µ²¨œ†{|~}vgS@2-1;CC<31:OkˆŸ©¨¡˜‘ŽŽ‘•–“ˆƒ‚…Œ–œ‘iWLKRZ]XPKO^w”®¾Ã¿¹´°®®°±¯¨Ÿ•‰‹“œž–…q\KBBGKIC==FWn…•›˜’Œ…€}|‚|unkov{yo^L;117?EILQ[j~”¨¶¾ÂÃÀ¹±«©¬±µµ¯¥ž›ž¢£|hWNKOTZ`gox„’Ÿ©°´µ±©Ÿ—”–¦¬ª¡•ŽŒŽŽ…wcP@747úˆööù~þwÞ ÌÈÓü øöƒ÷Ìû”Þà C ŠçÿNúªö@ö1ù~þb·î ³ØýHø!öl÷¼û‰Ê  XÐÿSúÄöpö‚ùÞþš§ k¡íüFøIö±÷ü¸Æt Ô%²ÿ\ú÷Äö¾ùõþŠ|r [ÃüEøöøCüÕÊ[ ¤ôÿHú÷æöâùøþsb^ MÉüaø—öøYüæÀ. e°gÿ`úF÷,÷.ú9ÿŠN- Ý0¿üoø½ö@ø|üîª ]¶iÿ\úN÷>÷/ú.ÿtÔ‘Øü°ø÷‰ø›üê†Öyÿ‹úƒ÷p÷Wú:ÿeÌŽèüÅø"÷’øŸüÙ`­÷{uÿ˜ú÷z÷rú`ÿxò©`ܲü®ø6÷Óøõü…®×= ÿ`ú§÷Ð÷Âúvÿ]Äz8½³üßø†÷ù ýfw€æøþ|úù÷/øû³ÿz£·}Ìü'ùË÷Jù.ý8(Æ"ÿÈú?øjø<û¹ÿHPСÏü5ùøŽùZý ëÇ(ÿÑúRø…øFû«ÿ7JË’lÃüAù"ø»ùuýÎÒuèþÊú„øÒø‹ûÇÿ'ŽSJ×ü‚ùføãù„ý Ø›±r ÿûÄøûøûÌÿê[5?äü©ùøú‘ýô¦cŒkÿûÊøù¤ûÏÿ ÛJ->åü¯ù²ø5ú°ýüžOpO ÿ$ûìø*ùÆûÞÿ ËöèüÄùÇøPúÖý«9>ÝþûåøAùýû óæåüÁùËø\úèý+­8:¹þïúùƒù7ü8$ Ð£Ó¹üÍùù¢úþD«Ø¯þûùŸùQüF#Ь{·²üÕù#ùÓúMþY”çÒ¯žþû0ùµùbüQ+™²mž üÚù6ùïúiþk‘Ç ~†þûoùþùšüfhv9~”üäù[ùû‡þl}£s_~þ*ûù'ú³üa÷8HˆÍü;ú¬ùBûtþ6E~el¤þZû©ù*ú±üdý3<€Àü#úŒù(ûoþCGthv¢þLûŸù/úÌü‡)âP¢ü,úÉù‘ûÞþŽ]T Hþû¶ù~ú$ý¿öϦ-¥üVúúÂûïþ}1ÆË:þTûúÒúWýÏ ã–Oóÿ¨üú7úìûÿ˜$Îm’Bþ‘ûWú ûŽýþ ˜1 Þÿ¯ü únú?üoÿÄ ‚"f+þ„ûgúDûÈýøkýßÁÿ¶üÖúÍú™ü‹ÿ–´0åF-þ²û¼ú¢û þÑ-»¦ªÿÏü ûüú«ü|ÿ|¤.åA2þÊûÚú­ûÿý§ùŽŽ¯ÿëü6û,ûÎü“ÿ~|í¹8<þÚûñúÐû#þ¤ë‚”¾ÿôüBûBûçü”ÿ[Sʘ%Jþ ü6ûüAþö[¥Ss¯ÿýoûpûý—ÿKAÈ›!KþüFû ü/þï\¡RÉÿ,ýûuûñü‰ÿO9ŸqQþ,ü]û%üCþþ`Š O®ÿ(ýŸû û%ý£ÿ=cE|þeü—ûYü]þì)Jë7ÁÿVýÓûÎûDý«ÿ#Ù;)„þ€ü´ûnüpþø$Ê$ºÿfýÿûûûYý¢ÿ«÷„þ›üæûžü„þëùø—ûªÿqý#ü5ü”ýÀÿ™ëæâ‰þ°üüÅü£þïëàuÜ¥ÿŽýQücüºýÕÿ÷k®£®‚þÛüJüý¾þéÀ§QΠÿ–ýdüoüºýØÿm¥š«‚þâü[üýÚþÍ‘›ÿ¢ý†ü¤üíýðÿúQq…`þËü\ü0ýúþч}vÿýü¶üþ AWKwzþýžüdýÿ²[Ýcgÿýªüàü+þú(;;w†þý«ügý ÿ—AÉ`~ÿÂýÉüóü0þè2+ezþý¢üfýÿ®\âluÿ©ý²üéü0þ Þ 3=yˆþý»üýÿ˜FÉGRÿ›ýÀü ýKþè)"_þ+ýÍüƒýÿ‘7´@aÿÅýöü-ý]þØêöý\œþRýðü›ýÿózªP„ÿÚýçüý)þóÿÁð&|¦þJýáüŒýÿïv¬VŠÿÝýëüýBþ×ú'lˆþ&ýÂüƒý$ÿ +±KsÿÐýñü ýMþ ÀÛôXŽþLýöü«ý5ÿ ‚”/dÿÏýýü4ý_þÒÝæñ[©þjýýºý2ÿõ^ïz/|ÿôýýBý`þÈÍÕçR™þ[ý ýÀý8ÿôVæ{6ƒÿûý&ýPýlþ±´¿ÕJ¤þxý2ýçýPÿóKÕ_lÿ÷ý;ýuý‹þ£›©ÃD¶þýRýòýGÿÜ&­?uÿþYý‰ý˜þ%¡Š“¶A·þ£ý`ýþRÿØ£LÿþZý‘ýŸþ&Ÿ†Œª2¬þ¥ýsýþhÿå‚ëkÿþrýµýÃþ7™nc‡&³þ­ýxý-þ…ÿþ‚Ñ^ÿ$þŽýÒýÜþI™VCiµþÇý›ýJþ—ÿ^Ù±Lÿ!þ™ýåýïþT7VÉþÜý²ý[þžÿ P̬Rÿ-þ©ýýýÿf›7<¹þÚýÃý|þ·ÿò5·¢Rÿ7þºýþÿ`ƒ$+æÿªþíýîý¡þÆÿúÕ ‘‹QÿSþìý6þÿXv è!úÿÓþþþ¡þ¹ÿêÆ‘špÿsþþAþÿ>OîÛçþ*þþ”þŸÿϼ Ÿ¢rÿsþöý(þÿ<_ð5íþþöý†þ¡ÿÞÅ ¢«sÿeþëý/þÿMgþã&ýÿÊþþðý•þ³ÿçÊ ˜–]ÿYþìý;þ%ÿUhþÜëÿËþþ þ¯þÅÿëÂþ‡ˆ]ÿkþþFþ*ÿVaðÔøÿÝþ&þ þ¢þ±ÿÙ¯ðˆ“dÿhþÿýHþ*ÿXeòÔñÿÎþþ þ­þÅÿóΈ†XÿfþþSþ/ÿS[éË òÿÙþ&þþ¶þÊÿí¼ìmpHÿ[þþTþ:ÿbeïÊëÿÝþ/þþ«þ¶ÿÝ´îwcÿ{þþYþ8ÿaeá·þîÿßþ1þ þ½þÏÿë±àp‚aÿuþþ[þ5ÿOLÒ²ûïÿæþ?þ8þÐþÎÿߣÐYl^ÿˆþ3þ|þLÿ[JɨïäÿåþHþEþÛþÔÿÙ“ÁRi^ÿþCþ‰þLÿM3°×ÖÿëþcþcþêþÖÿÖŠ®8V[ÿþUþ›þ]ÿZ7£~ÛçÿùþjþmþÿêÿÒs“%Q\ÿ þcþ¼þ„ÿp6“_«¼ÿéþuþ…þÿïÿÑmEUÿ¦þlþÀþ„ÿp7’[¤³ÿçþþ™þ,ÿ éw/HÿœþjþÈþ‘ÿƒJ˜Q•«ÿÜþsþ”þ4ÿïqqë:ÿŸþþãþ¦ÿŠ@‡D«ÿáþxþ˜þ8ÿøytí<ÿšþtþÝþ°ÿœLˆ?‹§ÿÞþvþ”þ4ÿôwtí-ÿþrþáþµÿ Q‡3z›ÿÚþyþŸþAÿ&…yé8ÿœþ{þèþ·ÿžMƒ0v–ÿÚþþ«þSÿ6pXÇ÷ÿ+ÿ£þþúþÀÿŸCpm–ÿÛþ†þ¼þdÿ>û]EÀúÿ3ÿ¶þ¬þÿÍÿ˜0^aÿéþ¦þØþnÿ9òZG¾òÿ*ÿ¬þ¥þÿØÿ¥1SüOŠÿëþªþáþ{ÿAïJ2²ðÿ.ÿ·þµþ.ÿìÿ§)GòG€ÿæþ¶þüþ•ÿOî= ¤ëÿ6ÿÆþÈþ6ÿäÿ™9å?‚ÿðþ½þøþÿJì9“Üÿ1ÿÍþÔþCÿñÿ¡-Ù>ŽÿÿÎþÿÿDß,–æÿ>ÿØþßþMÿöÿ¡!Ë2…ÿþþÎþÿ”ÿHâ,…Öÿ7ÿÜþçþTÿüÿ¦Â'ÿÿáþ!ÿ±ÿ]ãémÎÿ>ÿñþÿuÿ  üþ§ÿÿõþ5ÿºÿSÊùÐ\ÈÿJÿ ÿÿwÿŒãéÿ(ÿÿHÿºÿE»ïÎfØÿWÿÿ"ÿyÿûÿ…ãéœÿ+ÿÿMÿ¾ÿI½êÁTÊÿPÿÿ*ÿˆÿ „ÖÜÿ6ÿ#ÿZÿËÿK²Û±IÐÿjÿ3ÿ>ÿ‹ÿ|ÊÒ‘ §ÿKÿ$ÿIÿ´ÿ<§Ô¹`ãÿlÿ$ÿ)ÿxÿ÷ÿuÃË”(§ÿ?ÿÿHÿ²ÿ1¡ÛËtîÿiÿÿ"ÿwÿúÿ{Òâ & ÿ:ÿÿQÿÀÿ@«àÆbÝÿcÿ ÿ)ÿzÿöÿwÏÞ—–ÿ;ÿ&ÿWÿ¾ÿ8 Ï±Väÿ{ÿ?ÿAÿ…ÿõÿk»É’*¶ÿVÿ.ÿRÿ´ÿ1ŸÑ¶_êÿzÿ6ÿ:ÿÿñÿc²ÂŽ(°ÿPÿ*ÿNÿ®ÿ'”˹bæÿwÿ:ÿ@ÿˆÿùÿn¼Å„¡ÿUÿ@ÿfÿÂÿ6™Ã§Tåÿ}ÿGÿNÿ‘ÿüÿl´¹{¨ÿVÿAÿnÿÈÿ5³”AØÿ}ÿLÿXÿ¡ÿi§«s³ÿfÿLÿqÿÆÿ1Ž·™CÖÿ{ÿOÿ_ÿ«ÿu¬©l ¥ÿ[ÿFÿqÿÊÿ4µ–?ÓÿuÿGÿXÿ¢ÿ q®«kŸÿUÿFÿwÿÙÿGµ‹6ÑÿyÿLÿ]ÿ§ÿ q¬ªk¢ÿXÿIÿ}ÿÞÿE’­‹7ÑÿxÿLÿ^ÿ¥ÿaœ¤r°ÿcÿOÿ|ÿÖÿ=±–DØÿzÿLÿ_ÿªÿ h§©q©ÿaÿTÿ~ÿÒÿ7‹±•EßÿÿOÿYÿÿbžh £ÿ^ÿTÿ„ÿÚÿ7‚¡†=Üÿ…ÿ[ÿmÿ¯ÿ`œ¡l±ÿkÿYÿƒÿÖÿ7‡¤ƒ7Ûÿ‰ÿ^ÿlÿ­ÿ^_ °ÿkÿWÿ‚ÿÙÿ=ˆ¡‚6ÖÿƒÿYÿjÿ°ÿg˜’X¬ÿmÿbÿ’ÿçÿA–z4Úÿ‰ÿaÿsÿµÿc’ŽW¥ÿgÿaÿ‘ÿãÿ9{“u*Óÿÿkÿxÿ²ÿ\’’Z¬ÿpÿcÿÿáÿ?„œ}3Öÿ‰ÿfÿvÿ¶ÿh˜‘Zªÿlÿdÿ“ÿàÿ7™w,Òÿÿ]ÿsÿ¹ÿf–Qüÿ«ÿrÿjÿ›ÿêÿ<|”z3ÙÿŒÿgÿuÿµÿ a—”Xþÿ§ÿoÿgÿ‘ÿáÿ;”n#Ìÿ…ÿiÿ{ÿ¹ÿ_†Oÿÿ¬ÿqÿjÿšÿêÿB‚hÊÿ‡ÿnÿ‡ÿÊÿcŠ|Gýÿ±ÿ}ÿxÿ¥ÿîÿ9t†h%Ôÿÿqÿ…ÿÃÿX{G÷ÿ«ÿ}ÿ}ÿ¨ÿïÿ;p€f'×ÿ“ÿuÿ†ÿÂÿaŽƒI÷ÿ§ÿuÿvÿ¨ÿöÿF€‹eÇÿ…ÿmÿ‰ÿÌÿ^v:éÿ ÿwÿxÿ©ÿøÿGz‚XÃÿ‹ÿ~ÿ›ÿÙÿ%d€p8îÿ¦ÿÿˆÿ¶ÿûÿAuZÆÿŒÿ}ÿ—ÿÑÿZp3åÿ¡ÿÿ„ÿ°ÿöÿ>s{R Æÿ‘ÿÿšÿÖÿ eƒq5ëÿ¨ÿ€ÿ…ÿ¸ÿLvxP Âÿ’ÿŠÿªÿæÿ(]r`-çÿ§ÿ„ÿ‹ÿ¸ÿüÿ>mtN Åÿÿ„ÿ¢ÿÛÿYtb0íÿ®ÿ‹ÿ’ÿ¿ÿþÿ>lrM Æÿ‘ÿƒÿ ÿÞÿ&`{m3æÿ¤ÿÿŠÿ¹ÿýÿAmpJ Äÿÿÿ¡ÿàÿ)e{f,ßÿ›ÿ{ÿ‹ÿÄÿT|zNµÿ€ÿ{ÿ¨ÿîÿ6mf'Øÿ—ÿ}ÿ•ÿÏÿTzp;ñÿ¨ÿ{ÿ~ÿ«ÿñÿ:nzYËÿÿ{ÿ”ÿÒÿ^zj9óÿ°ÿ‡ÿˆÿ²ÿ÷ÿ@pwUÎÿ“ÿ~ÿ™ÿ×ÿ#`zg2ðÿ®ÿ‚ÿ…ÿµÿúÿ?ntOÉÿÿ|ÿ–ÿØÿ%a~n3äÿ¡ÿ€ÿ‹ÿ¼ÿIvvM Éÿ™ÿ‰ÿ£ÿßÿ$^vb-ëÿ®ÿ‡ÿ‡ÿµÿEmlCÃÿ’ÿ…ÿ¥ÿáÿ$ZlY*ëÿ±ÿÿ•ÿÀÿCnoI Âÿÿ†ÿ©ÿèÿ-ar\$äÿ®ÿ’ÿtkabber-0.11.1/sounds/default/0000755000175000017500000000000011076120366015463 5ustar sergeisergeitkabber-0.11.1/sounds/default/groupchat_server_message.wav0000644000175000017500000001147411066760706023306 0ustar sergeisergeiRIFF4WAVEfmt +"Vdataüÿþÿ÷ÿûÿòÿøÿïÿùÿìÿþÿçÿ'ÿ•þÅþ¿þêþÿGÿ}ÿ¸ÿìÿ1]±öIÀJ`l›¶ÌÇÆŽ‰_ÿ?ÿfÿ ÿ€þÿòþ3ÿçÿ‡ÿ¨ÿ@¬˜¬Ô÷Òå~ ¸ – „ { . \{ã¿ûüÉä^¬&욢ËIu0 ûètOÙ€½ÿûþàþ…þmýýýþýîÿãÐ È yÀ+4ѽÅï q®ýLúóöTóáï[íóê„é‚è•çúç8éµê4ì^îð¦ñ²òüòóÜòãòÕò òVð²î+íì§êéUècèéPêAì”ï0óÂö¹ú·þ¿—¼ \–ÙÙ<ˆ  ¾ ¨R`WþíüÂûÕúÉú&ûü·ýìÿAÅ3 e  Y³Û« û c  ¹Sn¹Rs^Žý× eæYÑ ] Š # 7 Ù ç  ¤µ<þ‰úŠömòaî…ê1çˆä×â–áÒà…à¦àVáfâüãæ$èbêÜìLï0ñ§òùó-õö“ö÷i÷È÷,øtøgø„øôø­ùªúãûaý®þÃÿÐ+ÐAfRb¨ÆuÿòýŸü{ûšú1ú2ú–ú?û5üý6ÿW¼'Ÿ3 z#÷ÐRN’îòâ.¯!è õÍ,™ Ò ù þ¾KÈ&þûù«öeôîñnï>í[ë²éhè‚ç󿑿Mæ/æQæÈæç‰è£éóêeìÖí/ïðÀñùò(ôsõÒöøGùŒúÝûýüôýïþõÿà“+½B±ôÓ¡E»)+Ì{¬ÿwÿoÿŠÿÛÿ’’±á7»d/  ï Í«fíFqc ÅÏš>»ïÛ’)¿F­æ Ý Û õ J®þ1ýÑûŸúù”øÉ÷(÷“ö.öûõêõÝõìõ2ö˜ö÷Z÷·÷ ø¨øCù½ùúeúžúÕúöúû*û[û’ûßûü)üüüüüüÉûzûû’úèù0ùŒøî÷A÷¥ö.öÈõjõ3õAõõÿõ‘ö]÷?ø:ùaúÙû}ýBÿßÊ»²Ÿ t Q1À‡R%ò¹kÞ!"å"D#.#£" ! ¬øádºë fÄÿIü ùö|óñ ïHí×ë«êÝégé0é<é„éÿé¶ê„ëmì{í¦îàï2ñuò°óüôNö¨÷öø(úOûeüMý(þ÷þ­ÿL¸æÙ¤DÇÿÿ0þLýTüDû#úÔøm÷öØôœópòZñ~ðÓï^ïFï ï`ðžñ\óoõÑ÷púEýAI> Ç )I s‚<¨Ó¡.ˆ´ÖR¤‡„í q  } Ú ý Û —+¥©­ÿµý¿ûÃùÓ÷öwôOóròýñíñ,ò¶ò~óxô±õ÷˜ø3úÇûQýÒþ3_X ‰É±E“‰:ªþÜüÊúø#ö¸ó]ñ ïÇì±êÃè-çÉå›äãüâ â«âÞâÀãßåÔæ è„é?ë0íïòÇô®÷«úžýá2¸= ª'ö­Õ¥!&#$µ$Ó$‚$±#U"x '†zVØQÊ ^äÛØýûŽø9ö‘ô8óøññ‘ðXð`ð®ðñ¾ñ^ò4óô õ.öK÷Žøú=û\üVývþÐÿ&j€”2’OÆŒW1½6½ÿôý!ýêûcùì÷çöOõYóµóïôœô õMö†ö~öö¤õªõíõ ö½õöýõ'ö›øwúü5ÿŒ•è Ï ì–Îâ  ú!O!Z"å ‰ßI¸ ¤Ìí C / á N .ßé†GÏœ|Ǭ W ‘”d½þ9ú¤öõ[óYñÖïTïÆî’ïð³ð×òõî÷5úÂüþþþPþ§ü;ú‘÷éôèñoíöç£â˜Ý ÙÔ9ÏÛË´É©ÈnÈÇÉ&ÍËÐÑÔ›Ù Þä’é.ðñö=ütŠ-:^³6rÿÁþWÿÎq­î ›}!}&+q/¤2Ÿ4I5'4Œ2Ä/(,`'" Ãâ §üŽÿZý¨û‹úNúÁú©ûèü7þÚÿ°ÓÐåùsþŽûºøÔõªòTï%ì&陿Úä ä‡ä)å/æbçÎèhêñë¸íuï“ðñ\òò†ñÍïÂíƒë¯è{å;âßÜjÙ¿ÖùÓðѳÐXÐÉÐ-ÒYÔ´ÖsÙèÜ=á åëépîåò÷«ú\þW×“Ü  ïóë—? ½!#a$¢%M& &Ÿ%m%"%@$º"æ ó¯!þµŒg\ ® j ˆð°ú»Ú * … è j£X¤ ,kM Z ú 7”ógÿý÷úåø«ö9ô®ñ3ïãì¥êQèæÌã‹áßfÜŸÙÒÖÔkÑ7ÏcͼËaʰÉzÉÉÊqË‹Í%Ð"Ó§Ö»ÚDßäéçíÛòø÷ ýׄ -ßtÀƒ!æ$(Ø*-Ã.0á0Ü00©.¾,v*ù'B%8"$ ûímò ¯ Ô R"9¼­Ý>ßÚ> Ô ‰ 1Št¿ kÖ>¬…R+g2‘-N gWýµ÷ˆò«íéƒäMàuÜÙ$Ö•Ó‹Ñ&Ð]ÏÏPÏØÏ¼ÐÒ Ô’ÖƒÙÉÜMàäÚç†ë)ïó÷òú þ.¨ã¼ P¼ôÆU‰3W9¿$@K_fSvð j Ñ $ ‡¥žf‰„N é Ùò!P_y §"X$—%p&ã&'à&S&Z%ü#T"f {«¢6€k í?_ü_÷>òöì†çâ¢Ü>×ÒCÍßÈÅ·Á/¿^½)¼ë»µ¼v¾ÁhÄ\ÈûÌ7ÒÃ×aÝÞâUèàíJórøKý‡y@ – ]¥t?üLb§×‚Û/  æ¯Uëýìû<úäøÖ÷÷Bö»õõ½õtöÆ÷ùÍûþº4O Ë~Šœb"?$þ%_'N(ù(F)õ(Ï'É% #øyRã85 4-#ûOö¥ñOíaéºåCâß6Ü—Ù)×ÀÔ°ÒüЋϚΠΓ͗Í+Î7ÏÑÐÈÒíÔ¥×îÚZÞâæå êŽî2óÃ÷*üVHg $.n%Iµq” S \h¨Üý5ûöøÖöåô:ó»ñ’ðð›ïïèïŽð”ñKóõ1ø†ûjÿ±+¶ QïlÔá"&Ï),@/˜1è2±3Q4‚44C3ô1@0#.d+($k­±Ÿ] ®µÿÊùÎóÑíÕçíáŒÜ°×.ÓýÎuËÎÈçÆáÅÅ?ÆâÇqÊòÍÍÑìÕ?Ú³ÞãTç›ëÇï˜óÕöÿùÐüÿb‘¡¸´ £ Ùªãwûž ¼ E o¹µý­ú·÷¼ôòÑï³íÜëÊêJêfêë?ìYî€ñåôcø^ü ú ß4¢!ø%®)-w0k3œ5"7b8 9,9¯8o7|5ù2ê/c,Î(%Ë ƒâÁ4ø hòoüî÷Ÿójï^ë†ç/äGá“ÞëÛÚÙæØ”ÙìÚIÜ4Þ®àãç}êâíºñ²õóø§û|þå$õzn*RýIúùöÄóÞð4îBì§êöèóç6çïæ„ç3èFéûêjì«íâîðeñëò—ôùõÊ÷ÓùÉû<þÀ;àÇ ûcÑòÁ6!{#Û%Ë'Ò)ž+Ç,i-Í-O-ê+Ó*)'Î$ì!.*’$¯³ ³ŽÄ_þYûëø¯ö.ô%òfð:ï î{ííìì±ëeëÖê3ëÙëÙëì™ìœì¼ì`íéíÑî ðñþñówô öˆ÷ùcú û¨ûÖûèûÚûtûâúfú«ù\øp÷nö°õõ‚ôòóÚóÑó&ôÛôIõâõ,÷6ø:ùÙúÄüÏþKB”œ X ! ,ÕU¢š>ì Ñ8u Šï«mM<]pÁ‹Ûº;Oqòõë e Ó  ü Ð K¯æÿËý°ûÂù5øÇö õÆóéòøñ˜ñ ñ¢ð[ð@ððð=ð‘ï%ïÑî~î%î%í,í6íSíTí3í×í£î€ï©ðBòìóÚõ¼÷ìø úû®ûèûùû`û¦úúÓø4÷·õ?ô†òñ)ññ±ñ®ò÷ótõÓ÷µùÈûVÿÖ¸ v ÓØta"Ò³mVËk@èóo~Ê+JÒeƒµApÙ(zµè ü ' < U ¤ bñjÞÑrøÿ¦þBý÷ûîúßùÉøÜ÷F÷äö˜ö[ö±õõ~ôbó,òoð‡îÕìíê#ééæÛäÌâá¿ßÞÞ¿ÞÈÞ-ß¾à9âãã¼åèpêí ðòþôj÷hùžû%ýŸþ¢ÿ°éâª6Ê®l“µÖ W ÚA‘…—8-ûINORè § e b Hõ¦œÎAŽ9 ­ B À M ³ § u ? \   p ôbëcëIŽþªü5û¶ù\øN÷òõõ8ô-óòñ±ïEîYíìÂêê‘èèççYæMåýäëäÁä^åÿåIæç"èšéëNì3îCðlòuôšöÇø³úðütþWêóeXV¼R¢Á]ûr, R V ¨ ® ÷ y • # E  J É p – ô )\”€Z  Þ b ² G ô ª  g Ä)ò´_8•ÿþéüyû&ú0ù/ø‚÷Ãöøõ|õâôSôõóió=ó½òsòTòéñÛñ“ñnñÇñËñäñòòóqó ôŠô$õÌõiö ÷÷WøÐø@ùâù0úúÒúùúoû¶ûüaüËübýþÏþƒÿ<<©U­ÔùÚû<>ŽÁGÞZÛw U Ì … ×  ? . - Ð W Ä  À õ>Iþ3„ã0íKv™bŠÿ6ÿˆþ}ýûüü‡ûÏúÇù-ùWøç÷–÷G÷÷ÉöÚö÷g÷…÷‹÷ß÷ø ø¦øêøâøáø>ùù;ù!ùÞø^ùRùÀùëùëùŽúÒú\ûÉûüÖü-ýÍý€þôþ¤ÿìÿ§"’JdádµEgÖÿ"=V°ÄÓÏÔÞíßÙ¿½¹±žyc`F8ݶ–]ç”gCáŸxT5é•R¿dãÿ‡ÿÿ¡þ?þåýoýóü”üYüü³ûMûñúÀú£úJúûùÉù¨ù¨ù©ù¨ùžù«ùçù6úwú™úÉúû‘ûòûükü²ü$ýŽýëý6þ{þìþKÿ¼ÿ ?‚Ì-X‡¢É :crˆ´Ü )Mafjgenƒlqm{†z`YcXP=)ñÒ¶ tC 羆K¿€G¹ÿtÿ9ÿõþÎþ{þ’þtkabber-0.11.1/sounds/default/chat_their_message.wav0000644000175000017500000003264611066760706022042 0ustar sergeisergeiRIFFž5WAVEfmt "VD¬dataz5&wüFŽœöößöëNÿ¨ñœþLJîR¬Fé;¼€ËÄí'lê=š1éý¹íCõÌþpú[àê'T„$ˆ!îÔùéÚTúø$!þ×€éîÀê• f JëùhóÄî+(W:ò ºzæü ÖÐö6”߬øÌ÷šÌPÚ,| .„=¬)ñäÞÿžê¾4r31êDÛµÐËNõ¨ þòìHýäì¨þ-=%µLÆûÚD´çí«ýæ/ÿ\ûôÒDÛ}Ê oßöñŸ¡Ûxþz@´ 0¤hߎØ4Ò"\3ôöþãf'å>åÜVç¤õP*êÿr [ÆÊý9CR Y+vníÇô2Šóæ )ÊÌš¸Dæ0ÙM 'ÈíXè =× i4wS æ1ˆ€ìÒÒöâãØÐá’ (ÞØè1’Ü*ë L ':g:DñüõfÓŽÿ† ¿² ŽÙ&æè[ÆÀõE4ÎíºíëM ŽÐ³Îù dù ç¸ÿN&ÌRßüT uä¢äŸþØð†ÝÓ]òW5(I0ô`ÿª ÖçPùø'ÿ­ ¦ðöÑØ ûÄÊó”ìý£ëøT “õ ®*ºè'Â(²ê²ðTÿ€÷ö;îͯÏ%ãVâË88þ±ðtúZ7ptVúôŒë¸îãðíûü€ð4Ðí¸|îR"5 „ì,bÈì~÷Ê"Æ@èká^èéÀòÖ•¯üVïÐÓ\&'àDFô(öè„ÞþðrRÿ[ü&äêÕb:ñ˜ ¾ý°áî¸îìí *-¦,ÒrèüA²‚,4tøöùŒâ;ÙÉðjé ïª 0û±ÜéB{vì'«™Ð5û é|Ç gÿýÞ{Íáªæcìî´ , –ùpû4ýÑ":;ï#Èûýîsç¸ä,÷ÄÿóHø–ûãë„ð öíO )„T²{gòÆùôýRjHÆÜׇõ5*„2ü+òÈ÷œáÄì›" ð ZÄò â[õ nL G³ÿ°ùJìê¬ ú¶ù;þpÜÙãøì÷¶>&ÀDˆj÷„¢ª!@-¾ ãµæß×[ÛÜÂùî,ÿôßëVþÿ2,À$T ÐÿÃùŠù[ÿÄõ ú ¾ãÎÇÎà@õº· ‘ úíùF.HŽìÂã¤ÜæñðøSý JòÔã´üð´þJD´ûpíòøÐ¾ŠÞú’÷RðÚï0Ñ$dé¤ÜPêÀâÜõÊ,yýJû\ø(´ a÷)4]ÿþãý:õê¦ý7"æôòœÞsÒY÷¢!ê!Ö:»þB÷Á$€Ž ÈýÙìºÓ}È5ò¿ôõó„¾ï.îl ‰Ôø"¿ þñšó´üPÿ\ýÖü¸Ôî¯Ø*êùþïÀð)V˜óéŒûö ¶|>~üëˆðô÷øý§þت>á®îPžøRøç 8®ø¸ü–’÷VèÝý¨Z#â©ùº÷xøðÌ„Îô”ìàê›Ø4ÛH‚ÀMúüæüÌ~Z"ÞùO˜ Žü­íèKõÊÿFðfëùõÜç¹Þ$÷1½ v*¬Ê&óŒvæ¤æÒà¦àtçVúÖ÷¬ø¤ -ûéþx*ÀÎiÈÿÆøDëþx ˆ0ÿÐìýá6ó²ü1ßÕ púý>ôVîúÿÀèªôöñxöûux£0Þöø_ïìNø†ü*ö¬îæùJi neV¼òéö$– ˜Ÿê4ÛvÛãdõPý6ÿ® ² ýlþÔ a6 5¾2øöcùûè‰åÚõØ÷ õŒðÉãDêœþ º4$ê7 æôìÞõ(âæ2äAïV öûöºúûrÿš2ÿ jâ²Êsùäö<ûŠF3ªÖ ÷ãääóöÿÖöv}ïë]ëTüù –  HþŒû‰Vèr‰óÿè?øèõ°ëñÚõ´ûZõò“þô u"–¯D€ÿ­ü–ÿz ìüå¯ÝØÛÁä`ý¬ f<$|M œFÜZxögòÜîJñùöóàï~øâ÷yî4òºþÕ ªö\ü÷¬< Ú # ª÷:ñzîJñ ýÔ²ú î÷‡üþS6Ôóþ•ûðühšøúÞöùªøÊ÷6)/ôììélö°|›CÎ $ ‚ ¨6|tþfôî„è+æöü¸íaò"õþÉûÂÒßÎúkð&þ¹ÿ´öî\ì…æØàóò„‰e6yüF©šo ÿ ô¤öÔó¤ñìøˆ#èøtê2÷„ÐÿÿpVÝÎöLúÄœ tiîðõHŒ^2¬ÿró|ó›ù¾òô(žçüú À ”žB, ( *šñ¬íˆ÷töþúì¤ç@ñÐî<ïÜŽBH3®˜jJÿ<ø@ûÅó–í¨é¨émñ`óbù~çüæôb|#?†dä µø¶ù9ÿúšÿ~DïãŒè ô¾$þáLˆ ­ú W n á õ6üÎ÷øÊˆ’ÿÈôZó…ö€þ êÎùaùjûKý¾Y¦ÖˆˆØ¶ú>N|øæòFïžò‡óÞðVö¢û™ÿ‰’T´X Z’T çšúó€ô`ñ•óvù|ô¢évåHîÉ” ® ÒZ °œ‚ þ ‘Ïôý îéòñKò[îŒóøúú ”Ñ¢šÄv'nýžý~þÓþ¸ÿ ùô¹öFó^ò@Ý Ô…ý£ûbpB`ÿ>¹Èüý„Ý lþ~®ý¾ôWõ¦÷©÷ü0¥þ ÷¼ñbþÚBÍ _†`ˆ úiü¾õ2èhé\ñõc÷»ù†8 à L& æžy Hü8ôðö¼õ¨ðÔòò˜î8ñ¸óÆö ÿº ö`. Ba ^ ï "¦þøüQû*öTó@ïøîdù¹ý üŽýÂRûä o ü üØúù6ÇjÒúšøVüxýVþLþáý>þýô÷Èöxùxÿ¢Ppø¨î ¼ îŒn * nû>ópñ¢òöô^øêõêò>ùXþ€þI V¢ž  à×l2þÎñúî*ðtï"ì4ì÷ÿLÿŸ ) — ÆÈ¬8  üŽïàòûõHõÌõjô¤ò–ñöê— òèÚH Uä†2 s+ÿ4°÷bó ýüþ@÷€öý{Bøoüîäþ†Ì=ÿ†.;ÿ¡ pýöûhþ—ü$üÌýšüõ[ïv÷þÜ÷oøU„ ¢äÔ /* ® $Ø´ûpü~þõøê¤ëôô(øzóöÂýý=tœ²R¶æùü9Ý´÷¾ñ-ñ^íPì“ò~ú”ûùd– ü …{ ”¼k 6¹²üê÷ûøúzòÐòúûBý÷þõÈü¹é@ûìtÿDwòøÿéúT¤úžûŒüÿÿL¤ü„øzú ýfýù÷Ã÷‘ë ÿó Jl È Î ÇLXðûÊöåùÓùFöôñbïôò÷-ýh Ù ÐŽJ Þ ¶ î hTüøØñÝñÎóéïÈîó^ùBÿ”ÿÀ vŠ#Ðoê–Å:ýäöúöf÷—ñüïÌó¢ö`ü20²äØ„m ïVˆ$þ¤ûˆûXü>þqü¦÷LúÿQýûqüøÿnÜÓþÖÿ¼h Þ³zø$l–‚üàøö÷ôìóûøÚúsù ù}ý < ‚& õ ô ò • bÌÿàû5ühúò¤îÌòôòôðŽó`ù²€ð   S ´0– þòˆÿøú(ôpñAò‹ðoñDöN÷¦ø´ÿ V  žÚ† [X Âþ>ÿüö¦ò$õœú<ú¦øfý?ÈÐxÎ9fV|ÿ.TÅÒýÆþ@ÎûýÔüòúú{ü ü^ù¦ú¿üœþ0ÿbæ˜ l ÁÜ¢¾÷*ˆû=öÆö¶öóòÄó~öŽûý¯þ@º ° Šª M  H @_ÿ÷öÁöpó½ðrïŽðö|ú|þ¾vè Ôî c  Ò öŠú]øNøÄöèöÊõ~ò ôwù~þXçôe  ääÃT\JîþÌüÜüOvÿ7ø.÷ ýêÐýü`ýÐýXþBó\þ+w ¸{( \ ]®¾¨ÚÿƒÿªùHôêó³÷8ûøºõýÌÝ(f  î  6 +Ù(ˆøDïêïÞóõPôô†÷¼úÿ$’ J ä ”ÈH ŽÞ¤JûþôöôóÝñfõ\öóóˆõZýê' 7( & œ @ªØýÎüÉû÷c÷–ýÂûêô´õZû{¶ÀäÌ® 9îÿ|ù¯ÿjd:…üNþÉý¼ûèýþ’ùöõ7÷]þ ÅÿþýDbú r † N\D€ûÂýzü<õYñ¦ñ{ôÂøëúüœþhXj! D Ø f ˆ´ÿzùpóâòò…ðÊô€ùàù²ùü̘ º@ ÷ *, ÂN¦û~ø^øôõóäõäøŠø$úþü­ÿb&s5„ Ný”þÙûKüþ°þ¥þ`ü\úqüýEû0þý@þ]üNýöœÒÊZö &Üs’$íÿýtügú8öÑõ]÷S÷ŽùíþÞ/Pj Ò ^ "â,Ðþ†øó#ócóRñ¶óøùÞý®ÿ<& Ô °¢@ (^½ê–ùøóÕò óªó÷•ùÞ÷úÁÿè‚þ K æ."†¦jAü÷6öøøzüˆûý÷Qú²þ´þ‚ÿ£¼ ?&†:Úboü¹þB,‹Üü€ú~úFú€ýJÿþúXøíùÜûšý¢ÿ.¤xÚŸ¡, ‹ Õ<XüÎúSütú;óˆð¢ó„ö¢ù0ý.–æb” F<Ø ºÜý6ý‚þ üÒõ~ð,ïðÛô;ûºýpþ\R˜ ¢ * "h *$—ÿNýNùÂôÞòœóøðüÐû¯øªúþÿ¨_ Ì ³žj ÝŠ2ý`ù^øxûžÿàû¢úJûKýh.ÿŸýØþø4°ø¢b¾ö—ý.ú“ø ùØü’ý<øÇóøô•úÔ øtøÆš á | ö‡,û:÷"øø÷ó›ðøò:÷õüFà0¾ Þî¬ ïNDýÒû'üÒùjôÜñ†ñÚò7ùÊ— f ¼ Z  @¼‚ýÒùì÷ùlùùü<Èþü~üCRœýŒüTò ÞÿÕþþTþ”ÔÔÿ¼ýüŠù¤ùtü²þsýúÔû6n®t´„ô Î oÛýÎûDú¶÷bøúâø–õóóõÊü ¬ Åö° Þ ÆåÿÔû$ø6÷ëõ{óSóHõ©÷’ú¸þË:þ<š 4}J s…ý±ûaýÿTü ö ôjôyõ2ùÈþ¹¦JÖÈÊ! Bè¸ÿöL'ÿ‚ûAú„ûý<ÿ†ÿ¦üÎú¸û›ý 7ƒþSÿ’ü"ÿ"D · Öý¨ÿüÒp‚üøùÖ÷–÷ùðù8ûÈüæý$$ Å”5X Æ 8˜|ùöFö2ù¾ú~÷tô®ô`ö"û`P¶ \ ²²æ" Î ‘êÿöùC÷$÷W÷zõ–ôüõøDü P¦­D¬ Þ . 4 ©xýÖú½ûµýnÿžýŒøFô„ôÄú‚d©,*°ìµ¯ˆ‰ÿ€þÈÈ.ÿ1ý>þÊÕþ¸ûäùù7üŒ'£þüxüùþ0ÌR = ³$nP\ò¤¶ùªóôæ÷æøù@ûŽýžÿĦîa†³ v ªÁÄgüÛõÎóÞöìùRùi÷œõxô|ø.^ > 5 Œ¾O<`œòúû%øÞõœõˆ÷ÜùÖù`øÀú„Bޏj^RÀ zÙ ýUüýýÐþ$ôHþùöõÄøÿì“Ê<ý!úÈüRL^ȾøJRšÖÿÌü ûHùÈö4÷,ü!vÿÒü½ûþvà ¤ ¤÷´N¡$Díúãóðò9ö&úÄýÿEÿâŠz @ Ð  ì  –3û¨öõNö¶ø2ù(øq÷löÊ÷Ýþø“ @ Œ~ˆóÜ`ɰýXù÷÷3øCú”üÅüúûBýˆÿ4z°›?Àÿ¬ûsý~’^—íû¹øùmývZÌäü£øø÷äû5d~Ë´ 8”´ +õÚ–ý9ù÷œö ÷>ù üÕý¤ýŠü¢ýJ\Ìš ðÞÿßÿŽj´‡û-õ–ðòðòôyùrý\ÃZØŠb Ý à N är¤ü¸÷àôøõ@úäüXûãøPø úÁþv Ÿ ìpBÁk(§ú÷ÎøüTþÊÿÞÿœþuþhÿÄÿÄÿ+`š’b^v½ý¾ýŸõ%û>ùü€¨ºÿøúÄö¢õXø þôjj²ž•þÒ H °Ž2ÿbý úìö=õNõì÷„ûQýLýäü\þ£D Í ?úýúþá øý÷ºðôï”ôpú8ÿœ™«O $ âöˆäÿýJú^øô÷Dú’ýLþDü`ùø¿ü¾Ú! Ðzþˆþ`H¾f“ÿVúø¸ûBÒÔþnüøûOütýcþ¹þThÆÄU¤òªìЍFýŠù¡ù0ýfpûºôÇòÎöZýäáòÖèB²Œ ¼ÄýÄù ø÷ýõœõÁ÷éúâü.þ°þ¼þzÓ” ËŒªýùüÎÿ¸FÿžùÎóêð¾ò ùú ¢R¶ˆ¤ÌëÞåö¦ÿlü­ùúüû,ýþÿÂþ'üÀù”ûüʶ0@ûVú'ÿøPìý¬ú8ü‚ƒâéýäùø2úý3þÂý,ÿK¾Ô( ä êøýüú@ú@ûýÐþü¸õâñ ôbú@  ÐÏ’Ë> J t2þÏøhöØõúõ÷ZùfûüVýÔÿ0Y$¡ ¾ ìHü@ûžþìxWûDö¬ó~ô ùNû¥–ÿŽR0° PÒþÝý`ürü^þ&þ¼/ÿŒüDúû°þ¨l6’ûžùæüÜV é y&ý¶ýÚG,Š”üø.õÄõƒùýÖþŽÿúÿÆ6@¦ŠÝ  > ŽÎþŽùÿ÷­ùþûœü_úêõ¶ò0ô$ú$F  ®jPl  Dýøsõ˜õ÷ øEúNü„ýºý‰þ|R¸Æ œ Ò ª/ý£ûÈýŠä¢ÿjùÜô†õ€ú¸LÅb\þ®üGþ ž0ž„þžý!ÿÏ×ÞÿUýÍúµùÈû˜ÿ¾Ħý½ú:úúüÈ Ö ª ·òÿdþ R v8üö¹ó¸ô6ø&ü¤þšÿÖÿ&94 „ ´ †ù6Aû8ø¤ø÷úŠüÅûBø]ôHô®ù<x 4 ¢ Å`î š,¼þHøÊô˜õOù’ü©ý¶ýþ®þ”ÿ½~öxèñ"]ÿBüìûþ!2&þXùª÷Ðúì5ìý ùÀúÿ[8fž¸þªýÿ6@X@¯´ÿZý¾û¶úçúŒü˜þ.ÿ&ýúù>üš. y  ‹äëÿFã,.þŠö®ñòºöFü¡ÿ`Ïÿ¾ÿ—³œ V ªÄ§þ+ûlùpùèúìû>û ù†ööRù)0ª ìªÆN² ¤ÖÿÒùzö6öáøPýy’€þÎüTý>ÿdѼ7q<²ÿŠü#üWÿªDwÌÿ¼ûŒù%û˜ÿÊÂÀ”üè÷Üö@ûÿ˜­øÿ9ÿ¸ù+ör¸®ÿHûÅøäøeúûòû^üÞûVúSúnýë x € ÖƒjÿꦔŸlý…ödñþð2õûÐÿj,Vä]ö < õ „æý²úôøùûýƒü¼ù¡÷5øRûcê Z ÃÝxþ˜ÿdÏ5¹(ú÷øKûlÿ ðйý”ü<ýÿÈ ºˆšÿVþ\ýpýØÿñ¶Rfÿ’ûÈûÿ?^®ÿžúlöìôö÷„þL:¢³òÿ$Bª ¨  (àþöúKø¿÷ÊøúÜú&ûÜú'úûîþNB œ  |Êÿÿ*jþ÷žññ‹õîûÐ+#XV2° ö 1 ,:TüÔúÊú*ûHü²ýþŠüIúŒù ûîÿüD„,ÿýüþo|¾0þÒùfùÌüÆ}Êpüúpú_üâþ·¢Ðþ›ý#þp¬ÝŠºâö`ýþûLýÖÿÞ8þéøLôJóüö¿ýRé]xúÉ| \ J Â.ýXø•ö÷}øÒùlúoúkúÆú<ü’ÿ¢ü 4   üXœFÿIØ¥ZþÎøÓó%ò)õ®ûèu<‘Fÿ®È¼ ~¾@vüÀú“ûÔýÂÿÑþ7ýºûòúü ÿÊ<à«mýìú_üõA·ïû@ý+ü†þâЬü3øU÷éùnýŒÿœÿšþ¢ýUýŽþšZ¤f „ ŸHþ@ýÔý–þ•þ£ü†øZôòòØõRüXÄD´6BŽ ç åØbýð÷ªõ€öÎøûòû6û_úîú\ýËR  Ô4HÿÖýÿ^¾þú,ö:õº÷öü¼ùvHþþpx*þ‰û?û×üZÿÖøìŽÿ\ýhüLý‘ÿɨt©þœûªùdúgþ´ ž$‚ÿrþ”†X^Äüú÷äõ*÷²úþ,ÿìýpüyü³þ¾  ð À Ö´þ¤üý þäý‘ûÏ÷xôžópöJü© Xœj€Pƒ ÁŒ,ýøúõ-÷¼ùæûüüÕüØû4ûxü/¶ÿL n“öÿþøþÂüýœø÷Rù þšÈ»HäüüþŸÖÄ^$ÿüMüÿX€ðR}ëý^ü üTýRÿ€RÿFü®ù+ùû ÿô‰&ñÇÐ<úÜŽœû|ö‚ôÉõù²üšþjþ¢ý¶ýdÿ Òv  ¾ ö-Þþ¾üQüµüŒü&û†øµõ¢ô÷Ùü>F*°9¶~e‹Ðýføãõe÷ûþôþHþ-ý§ü{ýRhmnÊÿ~ýwýÿîó¢ÿŠüÆú°ûîþÕúÝíÿ˜ûÓùzûÝþöZVÀÿ…ýý'äÒîoþ¤üWüÔübý‚ý«ü´úÊø†ø¤úÿH2@ Ÿù2&‰7Êüiöfó>ôö÷>üìþ0ÿdþþ}ó Þ Ê •ÌýDüXüØü€üûùw÷D÷2ù_ý³ÌòLdvÖèçÛ•þfú4øùNüÜÿ¬Ûtþ”ü–ü™þ¡øŒa”þ.ý’ýØÿÆ„,kÿÈýþÌÿùÛfüýþùˆ÷LøðûEøüIàÿ.¡<ür <øXþû úáúðûÓû•úðøò÷´ø–û&2 u D fèR=†û–ö²ó"ôh÷¦ûÿþ>œÿáþîÿF’š  êò˜~ýHü±ü²ýþæü™únø2øxúHþJ+ÜbÈÚÿðÿÛ<K¡Êÿ ü|ú¸û»þ´6m³ÿÌü|ûYüÔþjb€þcü8üðýÒ0\–êèÿÿ¼B^òÿÞûøö´öÃùüý‡Úý8†Op Ñ þ8yþûˆù¼ùÌú,û6úŒøy÷Vø©û¾Ü& æ Àˆ(Ü¢,Žûüöfôõ®øíüíÿà ,€> ã‚þØûžû ýþÿŽþ@ý ûêúLürÿÜÞ:4ÿ8ýdý9ÿ^Ê­ºûý|ü¢ýïLÆŽ Zý<ûLû²üRþ5ÿ¼þæüòúÆú0ý4<ÐVæ']&*ÿ0ûîö“ôFõ øýÞ²®D½nÎ À ¦0þ`úôøjù•úûcú+ùønùøû(¸˜ ïLPÒX:àü`ùðöÇörù ýݵDÿæþ<ç€{W¤UÿÉüYü'þ³bxÿxýcüãü·þÇÊ `ýHû^ûÜý$fßÌ"®ŸÄƾ€ý”ù¦øú üFý<ýbü£û$ü„þGD=  f8]ÖžˆÿJýúâöõtõ5øxüÀˆ!’P( w –¬ÚþÎú¸øÅø@ú¼ûæû¾ú¸ùZúüüÔ¯zN¬RÔ˜ÂýîúzùÖùÅûšþ,Vº £þžþDµ4˜LÆþKý}ý@ÿÊΖ5Jþáýÿ˜Ðÿrý5ûú^únü™ÿ˜Nf¾ªT¦î—†ýÛùÅ÷Ü÷ ù¤û¤ütüíûzü ÿLœ\ Î 1 L3ôºÿàþÊü¸ùÈöjõföuùfýžæöÈÿ‡{ó†þÚú1ù•ù(ûÚüÂý‚ý‰üü^ýx„Áê<&vÿ¸‚þ€üü`þÈ~¬Hÿ<ýü>ýðþÔÄdÿ'þÁþ:b² Pn·ÿþÑý\þÀþðý¬û ùÆ÷Ùøðûàÿ\‡8èc;¨jôR°üÁø·öÄö^øŠú?üýFýÙý¥ÿü,Š d l ä…Pfÿ,ÿ±þEýíúyøþöh÷÷ùìý ´ Š;¸ê»ÿ—üÚúNû`ýyÿ>Šÿ(þý#ý¥þ*‚äýTýØþ_;Žœ*ºÿ†ßÀYn‚ýËú›ù`úJü4þxÿöÿÞÿ¿ÿƒ¬®J$ š"f÷ý7ý@ýýòû(ú#ø÷á÷æú4ÿZìfÄàk™ä öý@ùèöŸö!ø€ú‚üeý˜ý5þúÿÆì¤ pXÎLÿrþÌþ$ÿSþ>üÿùôø¢ù´ûþb*bt\ô‡ª|ЉÿßýýWýßþè4Þ,6þ,ý²ýWÿÈê®ÿâý|ü@ü£ýV$°ŒR°F ®\ÿªü$ú|øhøìù:üFþzÿõÿ`‰¾dx$ <vþ@üëûüpûãùø÷øûÿ¸rÌÐ h`Št¢8ý.úRøã÷ºøzúü'þÄþÜþ€ÿPúpжY|ÿ”þ¸þTÿ„ÿšþÈü0ûõú\ü¥þ¸¼¯ÙÿrÿœÿXk:Ôÿ,ÿ†ÿ´Ú~çþøüüoü¼ýµþqþ*ý ü2üþýܸ^6~PüÄpþ ûFùø ø@ù9û„ý¨ÿDA&䯢è^þäûøúâúàúrú˜ùìøgù¤û?ÿèbFhÊNÌÄÐýŒûêùˆùtúüÐý*ÿòÿ<YÎêj€íz~þôýÁþöÿ ]nÿhþøýlþˆÿ°0ªSÿìýBýŽýmþbÿ7ìd”Ô€‚@òB²ÿ=ý¬û.û€ûülü8üÚû*üÑýÀŒX¢P6u¦k¨ÿvýûùê÷î÷*ùFû®ýÚÿš0&þÄ,Šu:áý„ûªúòúoûjûöú¼ú`ûý´ÿм–øöwMöšÿ&þýjü:ü§üÀý*ÿ@œI»ÿ‚ÿîÿКÐF. ÿ£þrÿ%¬3¼–ÿHÿ¢ÿòÿœÿ˜þFýü|û¾ûðü²þj¹žAÃ2Чj¦¢ÿ¿ülúvùÌù¾ú’ûüHü ýÈþr_Äð 2¼ÎØRÿ:ýûOùŒøØø÷ù®ûÎýÔü°Pú„¦¤lòþåüÎûÐû‹ü-ýýüLü&ýúþ¸Z3z)8xŽ$:?ÿ·þ¶þûþVÿ¦ÿÓÿ¹ÿDÿŠþÕý ý8þPÿ6p.òÿ8"ŠØeÞxÌ|ÿäþÆþwþtýüãú£ú\ûÈüŒþPÞ"š×îÔEVCÿý'ûðùÂùvúûŠü8ýäý&ÿCÉ̦O$¦K=U=ÿÒý<üÜú2ú†ú²û.ýþÎÿÌ.Vkn2l jÿ&þ“ý¦ýþþºþ~þ"þ&þØþ!$D¨ÿ¿ÿTñBDÚ²°ÁÇ¢6ÿ¥þÛý?ýÞüèüwýpþgÿbÚÈ(z’>¢1ÿRþœý¾ü­û¾úpúûü‘þnäÜL.–¯ˆ?ÿKýû|ú>ú¼ú¬û¾üÆý¾þÉÿ,즲žŠºÜ4^ÿ:þýü¶ûêû¤üµýÚþÚÿ¢;¸=4ܦ4cjÿÀþºþ;ÿÉÿêÿ†ÿâþtþ}þîþzÿÏÿ¼ÿRÿèþðþšÿª¥'6øz·Úÿÿþ*ýPüÎûàû‡üýåþ£N#î þ¢ýìüü@û¢ú¤úlûÜü®þŒ0pHÑæ6˜)Ñþzý(üû¬ú#ûJü¢ýÂþ›ÿcZ|”B=z6äìÿlÿ$ÿ¼þ þ^ý ý~ýHþÿ©ÿT¤àæ¾…_Xgz{^0&cØ(ø0+ÿjþ6þ^þuþ@þâý½ýþÿ@wfî#%ÞUOêÿ|þZý•üü˜ûuûàû÷ü†þ vwL³ö¢œjþ4ý~üü”û4û>ûüŒýbÿ8 ª JAÔÿ|þ£ýýüXü~ü&ý;þ`ÿ;³uˆŒþUÞÿ¸ÿ²ÿœÿfÿÿãþðþHÿ²ÿéÿÆÿkÿ"ÿ#ÿ^ÿÿŽÿ~ÿ¨ÿ$Ðf¸ÎÇÀ²xòÿöý/ýãüüü2ý[ý”ý*þFÿÁ46°Ê¸†(ìxÿþÖü ü¯û§ûßû_ü>ýþ)¼äé$:ì²²þ¢ýðü‚üAü2üfüöüóý@ÿ™¤B’Êû¤ÖÒèÿHÿßþ…þ+þèýÜýþ†þÿšÿñÿ8h¸ *ú¤u‘ÕùÕzæÿÏÿ®ÿdÿ÷þ‚þ,þþ<þžþÿpÿÒÿZð˜Ò£?ÙpÖôÿàþÛýý¼ü¶üõü^ýðý±þ¨ÿÎÿú…”Uû‰ÝÒ„ÿ8þBý¾ü™üªüÞüFýöýìþ?;Ý ×ŽXP:ÿbþìýÀý®ý¥ý½ýþÄþ’ÿQà6c~’š‚2«´ÿšÿ­ÿ±ÿ‚ÿ<ÿÿ*ÿnÿ¦ÿ®ÿŽÿmÿlÿ“ÿÒÿP}£Ü(všu¤Jýÿ”ÿöþCþ½ý˜ýÎý;þ±þ&ÿ­ÿT ö§ –ôM¬úÿÿþ?ýÄüÀüý–ý,þåþÐÿÞÞ¤4 ¨!tœ›ÿŠþ¥ý#ýýXý«ýùý_þ ÿûÿ×LgHÌrù]®ÿÿ‘þ`þlþŽþªþËþ ÿ~ÿa„€„¨ÚðÖ–Y;Hh€l"»ÿeÿAÿFÿJÿÿÏþ“þ¦þÿÿy×@ªûø  ˆèÿFÿ þøýhý ýHýÐý†þ3ÿÅÿb( Ø>$¤ë&e¨ÿèþ!þkýéüÈüý½ýŠþRÿܰbÂÂv ‘Kpÿ˜þôý¦ý°ýûýbþÆþÿwÿøÿ£P½Ào¸’p,Ðÿtÿ?ÿ4ÿIÿlÿŒÿ¦ÿ¶ÿÄÿÒÿÜÿØÿ¾ÿ ÿ›ÿÈÿTh_h¤HEëb×ÿnÿ)ÿôþ»þtþ0þþTþæþ¨ÿcô`¾H6Ô@˜òÿDÿþæýhý8ýdýâýŽþHÿòÿŠÃdÔÔXвxÿùþnþèýŠýxý¾ýDþôþ®ÿTÞP¨àæ²Tä{œÿÿ¦þrþþâþ8ÿoÿˆÿ ÿÕÿ(†ÇÕ¨^"8`fBöÿüÿ êÿºÿ‰ÿaÿ<ÿÿ ÿÿ@ÿÿîÿR¤Þ2d‰{p´ÿ!ÿÈþ˜þrþCþ þ,þzþÿÐÿ–:¬êêšn¼ÿÿŽþþÅý«ýÜýSþïþˆÿ‰zå*&Ó>öÿŒÿEÿÿ±þbþ:þVþ¶þ7ÿ¸ÿ#v¸é öÊŽLÆÿˆÿbÿZÿsÿ”ÿ¢ÿ“ÿuÿnÿ“ÿÔÿ4-0j¬×Ú´}O0ðÿ®ÿ^ÿÿîþÞþäþÿDÿ ÿ n½õ!F`b<â[Àÿ7ÿÞþºþ°þªþžþ¤þÜþPÿìÿŠY|‚nJÂXÞÿ`ÿ÷þ°þ‹þ‰þ­þöþ[ÿÂÿ\˜ØOP¹Pöÿ¾ÿ ÿŒÿpÿHÿ"ÿÿ@ÿ‹ÿÝÿ8@FSclnl`N2þÿôÿ÷ÿüÿøÿèÿÆÿšÿxÿlÿ†ÿ±ÿÔÿÞÿØÿÝÿMØèÔªxM(ÿÿÉÿ‚ÿ6ÿûþäþòþÿ^ÿ¨ÿþÿRÒô  ü®<Äÿ\ÿÿøþñþöþþþ ÿ.ÿxÿêÿjÔ òØ´~4àÿŒÿBÿÿúþÿ,ÿ`ÿšÿÔÿ6]~¡¾Æ¬p&îÿÖÿÕÿÖÿÊÿ¬ÿŽÿ€ÿˆÿªÿØÿûÿÿÿîÿêÿüÿ8EHDBA<60)öÿÄÿ’ÿlÿ\ÿfÿ|ÿšÿ´ÿÆÿÜÿAŒÌäÒ¢mCöÿ¾ÿ}ÿ?ÿÿþþ ÿ<ÿ}ÿÅÿCz©ÎÞÝ̤j¾ÿoÿ<ÿ,ÿ2ÿ>ÿJÿZÿ|ÿ³ÿÿÿP–¼¿¦„hR:Øÿ ÿvÿdÿgÿyÿ•ÿµÿ×ÿòÿ (8DKF8èÿâÿêÿüÿûÿäÿÐÿÌÿÚÿëÿòÿéÿÕÿÃÿºÿÆÿÞÿþÿ(.2<GNH6ûÿÕÿ®ÿŒÿ{ÿzÿ‰ÿŸÿ²ÿÆÿàÿ1`†˜rF"êÿÌÿ¤ÿzÿ\ÿWÿiÿŽÿ¸ÿäÿ ,J_ryvfF!öÿÌÿªÿ’ÿ‹ÿÿžÿªÿµÿÅÿÞÿ(FRM>, îÿØÿÄÿ½ÿÀÿÐÿÝÿæÿìÿïÿóÿøÿüÿ ÿÿ  üÿîÿâÿàÿàÿâÿÜÿÒÿÌÿÊÿØÿêÿþÿ #%&& îÿÚÿÊÿÂÿ¸ÿµÿ½ÿÌÿ×ÿäÿûÿ(42,( úÿêÿÖÿÊÿÈÿÈÿÎÿØÿâÿïÿøÿýÿ øÿîÿèÿàÿâÿêÿðÿïÿèÿèÿìÿôÿóÿöÿúÿþÿòÿíÿðÿôÿúÿþÿþÿýÿôÿîÿîÿôÿòÿîÿóÿòÿòÿôÿùÿøÿtkabber-0.11.1/sounds/default/disconnected.wav0000644000175000017500000004251411066760706020661 0ustar sergeisergeiRIFFDEWAVEfmt +"Vdata E©637  Ü}zÿÿÀþ¸þßþòþõþüþâþæþOÿ‚ÐëÜ&=¶È|{ÜŒÆ%ó‚…Ýü³¶Þð:²ÐðšE&â·ÅÓþJý üøø&õÊñ˜í4ê2ìô’üôsÕ  Ö6H¶f ¶Ê¼" eÿpþîý˜ýÆüÆûýú^ú¶ùÄùŽûˆþ¹RZ@„@"‡ý‘û4ú`ùŒùNúòú–û~üaýHþXÿN2ÊøVYæ””õ¬ŒÈýzù õöñ(ð)ïÐï@óˆøþX0ü™ó@ï¾ö͵ê ` )á>ÿ&üüÎýÿÿ¤ÿobDjÿÀýîýJþûý/þXÿÞÿâÿ_nÊÈʽT ,6@J†k´ýPúÔ÷9÷÷ ö2ôÒò`ó‚ôüôö|ø]úJüyÊt  ä  E –ú6ÞZCS)"ý°ùƒõTò+òõú6ØÜ ” À < š¨îbÝšæÔþÚ rœÅR z*øÑñ¸î¬ímì¨ëTî4ôðúXöÇâ4  u G  ÙÔZ&¹V¦¢ž¼ÚP`k4ÿàýÜüþè¶UºÿMý°ùöYôgôšõ5÷|ùü-ýòüúý¼RäÄ$ÆÄ\ à+6Ž ò b -DÔüT÷úñ°ì^è‚æbç:ê0íÖîêâáýçOún Â(¼ ž êü„üzþtOÚ7ú<PÿBþ•ý¸ý×þ_¤d/äoï8á8ýèøõ¦ñ˜ðCòÐóõ'÷ZúZþ®ÄV“®²ÚÎý¼øªôNòóv÷JýþTb¯“A¤æ÷$" o Ž 4 $ªPþ¾øõpóÉòNóòô<ö~÷ãùãü 8ëHœ öŒ‰hý¬ùÁ÷€ö0õ£ó òÜñºôìúøP‰ Ø Ü *|˜¨bhfÉdXSp³ xÈÿÿRþlýÒüêüNýlþ÷àÅŒ¿>jìëêþöúÁöØòìïÐî\ð$ôøÒútý€/ªæúJ^˜`dv  ç á ä ‘ * Ný õšëá×ÍÔbß›ð$š ¹@,¹újìä¼ç ñzû²8Ð œ ¢ê ä Íüö‘úýHúîø.úüòü›üðúzø,÷ÌöŒõ¬õâù•Ξ ž¬®aÿÕüvû ú–ùºû>ÿ ¡›þöû¤ùzø`øÚøËú<þFIE;Íì×~4ížÔPDØ~.xìÔhdúøòØíë”ééé@í óˆú:Ä $ l ×ýD÷mðOë­ê©ðÄúXæ ŽâŒb Î ´Ìt:&øÿœþ¼ý„ýjýýgüÖüéþšä&ŒPÞsÿœþ\þ½þÐÿÁc¬¼ÌµPèÖüWø¦ôøòbóœöÜûOЈTZ#,ýVú¢øù(ûÎý`Žèߨ ö t ú R  ` šý·=eJÄ@ýNù®õFòJðñô+øü¼ýýTú¿öNôóóZõZùiþŠŒ,6È‘| ÄðþPøïJåKÝBàŒíÆúÃÑ GH’ ÊÝ>´ŠWâÔ4ÿœüxù\ö°ôGôXôkô0ôõ0ø¶ûÄþŽWÅŒm 9 *ÖjŽpÿyü{úúuûÊýÚÿÜ}´ä¦ÿhþ"þpþÿ`;ÞtâÀ ^¶ t‹mø%ïbæ—ß„Ý^â\ì’÷4Jk Œ 8 Z ëç£|þ¨ý¼þº¾QH †¢®(þ²û'ù‚õüñŽð>ò>öŽú þ.àZž † ¨ º ‚ Æ  ^ûö8óžóíöWûŒÿÌÊ6Žu ¾ ÿhÿ*ú>Pþªû,ûCýf¨lTÆ(¾SÿôþÛÿb•jdD ú  ¿ ,M Œ br-üNø`ö†õ¶ô®óbòññØò õ÷Fü‹Çí ¸qýÿïÝÝ)ÏÄÒŠé´Ò~ÛëXÇ" &•þmüBýmþÍþ ÿ¦Àh²e¢°ïþ–øôñjìåèlèÚë`òËú~0 " ù î ˆ 䊓a:HLýÖûÅüTÿ:>Âþ þsýü"úÒøQù·ûèþ Žbd^Úª&ÿ˜ûàù<úŠû:ý&ÿš´…ªT—ýøIñ$ë/è>é0î"öãþe  † ÀÆH±ÿˆüúd÷cö¿û¼€PêÐüjú.úû‘ü¿þA‘˜ºa¸£Êÿ.üòøføzûðÿÆà¶€lþ’ûÄùœùJûþÑ-Ž îŽð>P¨ÿDþÿŠˆ>FÈNfzÿZÿ^&ŸZbþÎú øúötùdÿPA L½ ~G` $ @øhëUÜhÉ ·R´tÆûãÎk| ¬#!°ZÌ ~0üõõ@ö‘ Íl~C… …$þðô'îDêÊçƒæXè6îxö­þ>”ø¥0 90`Û #ý<ý$ÿªÞ8®ÿµÿ®ÿ´þGý_ü•ü”ýÐÿ|¤Ñ €Ž0ÿßûvøbõ>òïBìÌê"ì•ð’÷xÿJŸž`€ Þ:–,x ª·ÿPøzñ¾ë÷çØçìÐóLü„·„ÎMlYHþ”üäúhøöÊô˜õùÃþ›öþ ü®ú—ú˜û<ýèþ(œ$ÿþþ0ÿŒh° W˜M¼(øü„äËDTÿ3üìø€ö÷3ûæƒÂÊX»ýÜùfõñßîñÈö·ýVÀ œ  Ê × S*é7ýh÷êìêܸׄåÖø¶byÀ­Z)~Âþ‹ö<ð‚íŒî—óˆûO "Ö Æì5÷¸í‚æDâÔäÞïÉþ> œ\‡ iËÆ\®þ þôü¼÷†òºó4ü@Þ p n ›ÊÔ¥R |r">¸™LôUÿóüâø‚ôGñ9ðˆò™ö(úºüþuý¾úçöôóDôÊøÊÿð  R ö ¯póœÑªTH>X椢zEˆý²÷:òÓì”è/çkéïŠõ"úŠü¨üñú>ùù‹û¨ÿ'¾sÿˆûDøpùjþ’\ð­ôÜ¢šÿòü\ü8þ,³TdBÍ@®Æ9ìýü¯ùpö¼ó‘óªõÛ÷pøô÷2ù„ý/š¤ ºê  bPü”÷ˆò[ëLàNÕ‹Ó«âÈùÊ œÍ‚›Ä +q(´þ$ü•üQ\ o õ ß dL—ú.ó:ëRäòáÕãÒçªî.÷ ÿ˜•  ÎNêâ s ýBúYù úþÄÀBNyý¤øÝø ü–þ: ¦?€úˆ Œ¨ šÚ¦ÿ¨ü6øÑôêô(øTü2Þ jdDˆ¦ÿ8ÿ¢ÿöÿ’ÿ¬ýdú–÷š÷"û Ê >Œúþaý†üwýòÿp®àW¨èȰ´v?cq.ü únûgþÎFa‰|þ£øòïìå£ßÈà¼èÊóiý"ìî î = ² 2 (`·¾îÿ¤ýzücý7,À Xª®¯þ­üQûÊúlúŠùm÷Jô òŽò6öûäÿeÄ T3jG Nü÷¤ñéRÚ‰ÒvÝ„ôªšId€ªÆ <1¤~ÿ ÿ<iÖÿÿÚýZû<÷”ò>ï*îÎîïÁïWòÈøØ1® 6Ý’¤8F Î k šG‚K¥é=ü8÷ óTð*ïŠðÀôØú˜a ‚ 2zûùú.ûüÐ[  Äþ‘øàóÖðFð¤òø:ÿª½$Nb ª w Æ \  µ yÝ\ªèþxüèøþôÖò¶ô ú@ÿÊ$Å>Ç72¹ð tî´ëûnõ<ð¹î–ñ÷@ýÑ„“üb’þvüFü]ý ÿôé8&ÌChêœâÏ êšúÈóïcîšðžõšûæ·žŠïO"ÿÐû®÷öñÀìþé$ìõy® îD¥h ‡rû-òìÎê¯ê^äT×’Ò¼ãvü- ½¬©4ÖÍ °ÊDÄbŠ­‚îÀ ‹üù÷òšìç-ãçãÐè‹î4ó¾÷šýz (Þž : r   Cä+þœÿÜþÞþ†ÿ8åë<“* f  È õ Î`ÿøXïzæÿÞËÚ2Û¨à‡éRóÚüP<  ŒtÖÿbÿÒlH «k F ëîäÿ¼þ\ÿÚ£;&-ÿ€þDþmþõýü²úùù&ü¸ Lf Ö‹°ú~ôbñÌòˆö¼úÜþŸ"'þòûEûüIÿ ¤¸ ‡"ª…ÁÌ®#"ýPûÌýf’™ÎýmÜ„löý øÃñìëYé ëÀï:÷f¤ ôÜû 䤥ü^öqífßÜÌlÅ*Ó¬æâölÔtƒR¾ ¾î6ó$»Z0Ä*<vÿªù¸ó îé è%ìó¯úaÖjâ 0 ¾RþHüaýʆxΦhÿ”þ<þªþÂÿÉÿ§þšýÀýZÿY¡@œtpT8X®ÿ`ýú¶õ¯ñèðnõ‚ûªÿ¦]ÿvþ ÿbÔÿûüPùVöhõúöÉú£ÿfþè q Ô ªOÿSýbüuûÎûþXá@"©ÿÐþÒþþÐýbýDþŒÿøýBøfñnîœñ´ù.Nœ  À Ž £´þVü{ûdüþÉ~[k\0ÈŽ, j Ï  ®J°‹ÜÒý“úòö‹óöòJöøûèÖ»1þnù<õrôœølÈ*F ß Ë"NÔÿ þ4û×õ¬é5ÙüÓ#ãØøÄf ]ª‘ @^ÿÆûZýåÄF*š¶°Žÿ<ÿ„ÿšÿ*þ0ú.ô€îàì†ð÷¼ý>ÑcŠÆßnP<ºäÒZxý²ú úfùÕöŠó\óð÷ìþŒJTôíº*µ.U"Џ„šý-ûèøìõ ò=îQíBñª÷9þ*üŒnà²þZý†ûòøØ÷~ú‚ÿOTâOÕ²Kò: & FfZþóúôöNòmîŠíLð«õü ~.4›ûøóò”ôLøbûZü„û$úHúƒü¦ÿI:j^Ø2©þPbòŽ Û   V  Ì,žÿÑý·üÞûÚú|ùˆ÷èô¤ð#êÌãã2ë|øž FdôÊ +öêe¾þtúfóEèÀزԬä„úZ ĘYF–Ò n öD~ú£Öváþ¸ûÆûØýÿâûôêˆâ¾ßÝãLìö ÿúB @ À ¾®ª>pƒ6+®1‹²pΫÿÜþhþÔý¼üNúüöªö;ûD‚ ‚ , „x´…ÿAü¢øÂóïnîªòùøªþ-6®±FþþÁþ’ÿ&CR ¼¼ÎKÿ=ýæúF÷ÆóÐóBøþ?æÞ&ÅùŠøÿjÿÿœÿ8ˆÞŽéþšû5ú¯ýböÉ rEýzõ¦íJèxætèœíÞóöø–û‚ý(ó” Ž ^ ÜòU ˆ > . ä6xâþ"ÿ¼ýêüFü&û0ùâõ¥ñDî´îéóTû,JT ê F¤üXûðþN8 ö z âòÿðöÁì@âZÜþâÊò«e ö¦& Ææî.¶4ø:têRþLøºð³éÔåÎåþéRòªûÛr¦WþÇPd zÉžÑ 7ÞÿBú²ö\ô–òKòô;÷6ûÞþ¬’|Ærj.hDýÇø±ô#ô2÷|úÈúNù2ú<þ¸ÙZ y†)ü$ørö÷²ùžýæôX Ð  à Œ ® ˜£(ö£6ÿâýLü˜ùÌõ’ñ„ïò÷ýµÿˆývûxùßöÈólñKñ¾õšý¾² x”† âLÌÿ<üÿù ùYù˜ú@üæý†ÿ4¬2’þÅÿ\ýœþüâ ‚  °fÜüjùn÷S÷Œø úÆú°ú¬ù0÷$órî>ëJí*ô”üL&b 4 ¼ ä<°ä| e J ¯ TçýÞøŠ÷ùôøœôNí[å¢âðéxöJ© ì†æ N ô  Cb–±ýßùrõ¶ññàô–ûfËà2j£úŠôrï*ìÇíLõÚÿ ®ªgŽÁ õîµn)Põ¸•,WJ¶7æôÆô´ûäôØî¨ìéíÐï†ðNï ð&öÐþž´¨„òÿ’þþ´ý‡þ*A< F Ê Q ^  ÷°Çjƒ–þHþ ÿÿíýXü½úØø‚öó†ížæ*âZãNëòö ËŽÜrw ~ â~çÿ¬þ^þhþTþôý’ý¹ýHþ¨þ¢þšþÿüÿ&VvœP4ŠÉf¾ÿUûm÷œ÷kûŠÿ}ÖOþ®úÆöôòÕòù"ðHLæÜûäõò-òÜõ üiÀ 𠸌‚ð õ ¸­d`2þ®ùðóÀìTä4Þ—Ý$ãüíÀøÕh¬ ð â Û DÚûô¸ï$ñø¦ÄF {²d ƒ–ËüYú4ú°úû&ü…ýNþŽþÏþÿ‚þhþf ­>üxz ^ÿÕü¬ûû\úôùÐùØùðùjùô÷Šõ®ò²ð%ò.ø´ ‘>e& ¦ÎÐýÛû0ú¾øù¶üäÏI^Âôý2ý¡ýÿ,¶ Nhn}‚ÿýúOøÚörõóÖïÈìbíþò¸ú¸†\DžÿÖû ümÒC Š ø å  X°ˆôPØ®ÿÿ@ÿ¸ÿ4õü&,²‘€*ÏRrn!ýþøðó¨íTæ ßÜ€á­î>ýè*µ" 3øýl6 Ðš~Øc¿" Ì l È‚ F Û¶ ûàólíç¤àjÛzتØ\Þ›çïòòäòôñŠóóù› î vDç > dí2d#¦üÎÊÿ.þÞüVüÞülþºº@PÀ cý<þ¤X”˜öý*ú(öOñ$ì„çÑäºçð®úý Ê °e ô ?\V<ž îÉ•¢[¼þ"üÆø*ö²öMûÆðN ê Æ o  ˆ~ÈÞÆ»ýù8óvíRë¢îîô¤ú’ü!üZûsúáùÈúýÎÿ`°§õ ì@ýfø²÷þþ€D__E ‚r^œý»û|ûÜûlüýþwÿÜ58§þ„üYù*õvðïõ¦ýÐì ¤ ÄÔÙþ¿ùgõSô‡øËÿ. W v2¤ù´¤ÖöD˜TįŽïJ*|¤ÿœüÈøõMð»é áxØÓ´ØÇåXñ<ú6A8hG| ùäüV÷(õæölû»#<f k è úVäà5:ÿ×þ"þdüú6úîü¶Z4 f üÅþÎù¨òÔéoã*á¾ä€íÞöóý¨@ê R  ò¦zG¬Ò\•ò-˜!XdØ.*ÿO®„>öü úv÷Óôò8ñôvújÿ,nüH÷òòîáñ4ùLä€ \ z l½ÿ<þþ:ÿLf²êÎ YV:î‚¶¶2öû0úaú&ú´ø}÷ ÷æøJû³ýèþ´þæü ùôîî íšñËùp ˜ ÄÚRÊ áœ,vH¶ÿ+ÿþ¤üÏûªûnû^úxù¼ûváe ö  þ ÆÆšô üœ Öûöjï=èJãÒãˆè>íï„ï"ñ\ó6ö0û”$ä ¸ : äø`Ûv­hLœ$£ ^   {¦ÿ´þsþSþZþœÿªÂZ®ý+ù óàëøåUæÆìôôû—ÿL;´üùÎø°ûtÿ`^Øk\.Š<r" . ºÞ>~cQàˆÿeþÆýþ²þüþÿáþ¨ý¨ûPù„ö ò¬í‘è%æ…ètïôù×Ç Q  ,òã¦J:¨j‚}ùšHHºŠs0ð: ÇÐ Úÿšýöú,÷àòð ð,ðÀî_íŽïêõøý» î <D× ~ ! öá:ãýü—ú*ú~ûtþ_YZ î ñ è´Ò[ÿWú÷ ødû|ýìýÉþÿM1äüCûZùjõ/ñºðnöãþœX r Tâ ýbõYîgêëiðbùŒ éÒž Ä < }DJ¶ÿ<ü¶úFü€ÿ—ÔÆ6YÊöýXûTù ø÷øõ0õXôVòqðñp÷t œÀ»¯ ™&ýÔþ…þþÿÈoRÿÞúíôJðvïÔñHõùŠþ ´h  V ¨ÔüËþÝüŠû úúùöãñ'ëZå‚å<î1û¶B ª Ï ´ H<vûø°ö÷zù¢ýÛà‡Ò Nüˆ6°r6’(–šEZ(´¸*Úþ û’õØîŒééPîŸõÈûVÿöÿŸþVü(ûbü"ÿRZF $ a © Ú>šIƒ!ûÏÄÖ~‡T°;†Þ~ÿƒûðöŠòûí!éVäFáãäëäù4p˜Fðá D´Üý6úWöèòXðòïFòøõûDÿ‚|½æQ m  œc:Ð HŠûfõ}ñpðúï îGë.ê¤íjõQþOv îœ Ù 5D†òüÔ¨]üÐŽ(|Èÿ>ÿ^ÿµÖ2vþ2üúùŠûüþFDªx‘ÿñûø¯óZðWðô|úÔÿ:¦Rþxûªú*üØþB¶‚¨%vì²Øþ4ûx÷»ôèòôøæûÿ&š/Ì{Þÿƒÿ1ÿ¶þ¢ý ü•ùXöøórõøúj£Ú Ú p *ýÿù€øWøÚùìü2®Ž°ÿFþKþ’,Îb º„hF(fþýLü6üýDþRÿÂÿhÿúý-û÷BòUïñp÷ÿæV ²¨ ì ] â| Ðÿè‚&ÑþTùŠòÄëÌçìçFêdðjøhÿ|D +pæ Ä›þlüîýÓM!æÿú–óïXïŠóFølü¯ÿöªÿ!ýü<þivþ Z Jê¤Ù ¬ ‹è½Žÿ ÿnÿ”ÿEÿþÂý>ýý|ýVþbÿ"â.PŒ²¨Üü\÷!ðè´âÇãüê7õnÿbî ü c ~œ^ ”˜²ª$ ö û ‘ J´ ª * ØyVþâ÷òîìPéÐèNëêïÄõ'û·þ‡Zþ¨úš÷Îõ²ô$ó ñVðÂótú.z² dX~ "°:<þFý+ýˆýÐýëýBþäþ¬ÿ¶G¥2 æ , >ü:ÿÌûtødõŽó–óŒõÈø?üêþhµ§ÿãüâø—ôòàóÄø°þT†È ³ šÐNÎT:àt¢ì È  ³ à ¤-ú(òoé ã&á„ätì õLüAÍXh x G ÞÏ×jþDøò¨î˜ï¬ónùuÿáÖŸ } V ¨uöÔù:µTñArRQÞ°þ.ürû*û°úXú>ûxýÉÿ^šý$r˜S<þÂøÊóÜñºôŒú‰†ñ( ( êeT‰|þbügúäøQø‚ù`üÌÿ,^ £ $ ¼ ‚ Búl þ¨üÐûXû%û(ûIûü‚ý°þ:ÿLÿºþèü¢ùjõ`òjóÚøµÿhöÞ CKeúŸô„ñQòöû~_¸ þ # Ô:¤=2Ffÿæüûàù|ùxúÞû‚ý¬ÿ¢¢¸FTôÿ.þ—ûå÷fóáîÄëìSðÂõnûŸ6 Ñ M Ö]„,³G± ¼ÿÏÿA’„¦ ¸ ” $ 4þð¦FþÖûùeõvñXî„ììŽìÞìjë‚çþäçÂî+ú˜Ÿl  íÄl û á  þB$Ò^ÃüÿütøæõFô<ôõø˜û}ÿ5 hé4ülø ö·ößúáÿŒ‚ýüÞö òðòûöÊûqn"Hú8tÜç \ É – ŒyÚ®IYÿ1ÿÄþ–ý"ü‹ú4ùÞøÜùFü¦ÿ¶ÖÁ°h·–þ2ùFóóíÂê,ëµï€öŽý’Àñ n • í%²ªmV½jʈ  Ù R ª F¹úâó¸ïaí¤ì*î¨ñdövûòÿLRÀ\2ÿšû*÷cñìÌê‚îlõýýnÑ { ˜ 2 Vô>.¾ø0 ìþ¢üÚúfúû›ü®þGû§NÿÄýüüJý’þ8ö¿†Z( J 4 < iÚdþH÷„ïRéþæ’èªë}ïŠóL÷û6þM©þÚýFý_þó¶Æ_ t $ø ` 1XÄëþQüÈúlúæú@üyþð\CB@Œ4Ôüß÷Zò¦ì6èç&êüðŽù_` G F ß"þCýíþ/2 ƒ ¢ z £í…/¨·°ý1üüËûFûøúŸû@ý ÿZ#N¦ÇH殚ˆâüƒøéóñøðšóÈ÷ÎüFf À DOìÒu“\*ž@Ñ"Ú2HˆþdýEýÞýâþ` ü˜šÐ‘ëÕúnõÐðîàîæò©÷rûíýÝþ~þnýtüüjüÐý”ÿH"†<0Ò*JòÜþý‚û¬údú”úQû üVþÎÿ–³26ÿþ-ý¾üÃü›üPûù"÷÷øù,ÿX°n â } ˜®>ÿ'û’÷Xô’ñ2ð>ð{ñjôDøüú¨ýîMÒ,šÖç`õ»ºÿÿPÿ¡î È£ÿÌú.öòåî¤îõñê÷xþ»æ À 7 Ü X ²dËZ纆†ù~€2<TþZû¦ø2ö0õÞõp÷®ùFü¾þ&ܸ¬¬>6D.ŸVæúÚõˆñKïäï´óàùöx¾î:I8bàÄnb8HZÚ  ÿ>ýíû˜û_üfýþŸþ]ÿIŒ$òÕІ֣Édÿ6ü¼ødõ˜ò¾ñÈóøý22 hÐjÈŒºXRø~fÞnh(Ff¤cü#÷XòRî@ì-í ðøõ.üü˜£ ¼ :®ÒýÜøbóZïí®îžó!ûÞ´Ü , 06y ÂÐÿ xØ[|0XüÎ÷óbï î±î–ïôñôõ‹úñ½ ì C 1 Ê ¶ —Å„øýúö¾ó€ôÂ÷Hû+þòÿÊÿæýÜûtú´ùÆùÇú¤ühÿQè&ÀP ú ÍÁlŠYÿ„þ þGþÐþ ä¸üÚʹ(Ø–ÿ4ûÅöeòîîíbì íBïôò¸÷„ü¨NšFnFðf,ØŒ Þ  ~ ž–Juý ûÌùbù†ù úZû’ýg=³Â¶  ˆ  à ’Nnþúù õ(ò|ïèíSî¶ðžô‚ù‰þ„º¯IN>"ÖŸ¢™v<K[–¡.Ñÿœÿÿ–ÿÆ¢âI¤¯›:ÞÊzUbý–ø{ò ì³æ4ã-ã-ç*îÌö.ÿŒ‰ d z  ,ÑlÂ7) H X 2 J´_èEöþZý<û\øPôÕïëõçØæŽéˆîŒôæûòc‡ Ä  —¶ÿqûàøÏølúªüšÿ‚Z©ž rÞþÀý¹ý±þìÿ*ÈʪŒÊf—*DþDüŽúJùŠøèøˆú®üäþærmª8 ˜ý¡úê÷÷î÷šú>þÖÇ„m®­1þ|û¶ù@ùú.üeÿœ0!"Ü~uxfý.úTø$÷âöÞø×ü,`ßÜj,¤5á„þþü˜û˜ùZ÷>õô^ôöõù”ýŽ<• %  ¼ ¿d_6b;ª·T;ÿvþþàý–ýlýdýzý¦ýÓýþhþÿvìNZ$°ÆÝ š¢þsûøªôtòòêô>ù»þ¡… ¶ æ Ô  ð – tH`û÷ƒóiñÌñ ôr÷=û‚þàs8"N‚@´Á8úJ³Bþ*øÎñìlç˜åŽæwégï(÷’þ÷  ¶ W V Rá ˆHqbÿ þý)üpûMûuûøûÀü•ýjþÊÿ¢ò9òž;ñŽaÿ«ûø¾ô7ò‰ñòòîõ®ù¦ýøÌ>Ìòݨÿ¾þvþÎþ¾ÿ„Hfž›g}ý*óýXù*öøóžóFõšø4ý Z` Ö ä ± ´2ä9þþú²ø|÷"÷Œ÷ø®ø®ùÕúÃü¨þðÿÿèýýöý…þÿÔÿ0, žb¶ÌdEï§ ‚.ð¾¼ÔèÿÐþeO]ZDþÎûòøèõ¢òVïÆìì£íÌñ‡÷¬ý¹äSð$DÂN„¦^Æ]·‘Ä: ³+.ï–Øý”úzøèödöø¯ûöÿÔ(âbE¶¬ü÷øøõšó}ñTð…ñ¼óvõÆööö”õ#ô‡ó"õ&úujñ +  Î ” Jè ˜v¹†\ÊA ÿfþ’ý ý8ýoý$ý[üIûTúvù–øP÷°õtô‚ôƒöŽù.ü_þâÿ^"ÖÿÖÿ2¼-¬6¨E¦û <PQˆ±Z€ô^§x¡¼l’6qþûj÷ óïìLêÐê’í`òhø2þ!”D`ÀÒðÍÿÞâ6²r¨Ê‹ÿxþ*þ°ýfý’ýzþàÿDW6SÚF–Èrê4ùÿpý4ûžù‡øt÷öàôãô§öú"þ ¿Tt ,þþþ>(Z~nÔŠ Uÿõþ”þjþ‚þÿ:ÊDÙæ¸ ^ ˆ ó ²ö ˜þüøióêí^éçKçê'ï|öuþ¨Œ 2äÂG × y षý9û>ø³õÀó³òøò&ôDõööøšûºýhÿºæ$N4 u þ @ ; ª A ÞI¦þ4ú˜ö_ó‰ðÐîÈîñåôùøæüZ3€@ÿ–¸÷® P3þlü8ûyúüùÄùíùŒúŒû üšý¶þöÿ@ åÄRÂõ¶(¶ÂÇþæüêúRùjø.øù$ûýJþþŠüxúeø÷u÷Œùgücÿ::îˆ`Ìu–ÿTþ–üDû[ûúüYÿªðd ÂÄh£2¼ùáJÿJýkûýùZùÜùmû|ý˜ÿäN®âÝæÿTÿ ÿ8ÿžÿhÄ!Š®–Mø–ƒéqÌZÌD‚[Dz oþý’ûúŽøj÷¾ö ÷»ø¬û2ÿ@Jþ§ûùN÷œ÷Îù3ý/¢Ž<  †¨‘ÆF÷9’`ÿýðú¦ø.ö”ô¤ô†önùüþ> ƒ¶ÆÿDýPûúlùíøÖøÔù üëþý“(PÿÉýÀüCüBüÂüpýbþ²ÿ@²äꜢî¤"”Tÿ²þ•þŠþjþþÿDÿ$ÿ¢þ¼ýtüæú.ùh÷£õ(ôæó>õ¸÷ ûÿöñF ¬ Z ¬¾¯GçB7ý ù\öôDó2ôœöúùæýÖ–¦ì¸ÝþjýÊüªý­ÿœ$Üðýeú ÷RôÞñ(ðöïêñ‚õŠùÆýîÂÿ( > z 4 † \ ¾°]r$æþþ^ý+ýnýîý^þ»þEÿüÿØìæ‚æä¬Ã‡ÿ#ý.ûÎùÚøxø¢ø4ùäù^ú8úŽù8ùãùlü. ”Ù ò S ˜ ~ Ô ð Ü€TȽ þ³ú’÷áôÆóÀôC÷°ú2þ-4HÏîøP>Ú½Òîx¬rðêÊÿývùìõ8óâð˜îÎìíúï¶ô…úš]  î B ¼ ® ,¶„ÒØÿ±ÿ*¬á¹frÿOþ ýèû û¨ú¤úûàû!ýøþ ˜ŽÖRòí¢ÿüüêùìöšôó|ònóâõwùxýxÞP|tuøH»±<©vÝÁ¢NtÄÿ ýPùšõxò7ðšïèðæóVøƒý:Ú,( ðv²ý*ùÛõzôõùWýD+jm°˜<½jÿ°þÂþFÿÒÿ4®I®:œ×ìÀ.=sôÿ™ÿ<ÿäþ ÿ¤ÿþÿF´Bˆ^ŒÉÿéþ.þ|ýºüü‡ûÌúúÞùØúôürÿP#*]ؘ†Ä¶©HÿðþÿPÿÐÿŠF/0w“©RŽÊÿ¼üôùÔ÷{ö¦ö ø”ûÿoûVi~(Ò¶Ú?Þÿˆÿ6þàû`úKújûðýzy¸=‰àùÿ<ýDú°÷„õÿó‘óRôúõŠø¥üÔ_Ñ; /µt6üúZ3­TØÝ‰2–®·ÿÉþØýý@üfûcúWùhø¤÷÷^ø?ú¯üÜþr@8h,ÿåýÜüü®ûòûýNþDÿ&Q„‚¢½m 9˜BÍRÖy¶¬ÿ…üÆøõRódòóÕô2÷“ù^ûküý®ýèý`ýnýÓýþ^þ7ÿhÕ6úVÿjý€üÈû¨úÌùú€û ýGþdÿªe<ÎóþD u  Õ  îÒN?üØþ ýbû®ùBø÷äõ6õbõöL÷vù üjþ„6ŽÝü(°ÿšÿøAš£é{ô‰šòbà0|\¨. l + L – DHÅÿfû÷òòlðð‚ñ<ôš÷ªúýqþpþ7ýûCøö2õ’öøù™ýæ„ý¤ˆÞlcøâvNç&ZøõÇ+W´ÿ"ÿþ°ü*û¸ù°ø*øHø¼ø<ùú8üŒÿgè q´ÉV«þ ýïûûXú[ùZø½÷®÷«øû!þ ^,­ÚáÔÔ4"vþ¬H²|–<®ÿ þ¡ürû¡ú’úgûÂüRþÎV@&dŸÿü¡ø õòüï§ï8ñ*ô¬÷XûÓþšl~àºèAàÍ:ßÛÜ Î ›XJèþ#ý°ûÐúû*ü@ý÷ý\þ®þ5ÿx¨ô\ÌðÎuv(uþÖü|ûÂúÐú†ûÇüpþ(Öœ¾¦r>äVœÐ%’ÿîþJþþVþdÿª¹<bu‚¦BrÖeÿ¾©vø2ötâõPüÿ ý®ù¯öNô«òøñ„ò|ôÄ÷ üˆÌÊ“k«¦˜ÅWJ&í@š˜ jqSÕÿÌÿÎÿ¢ÿ,ÿ©þCþõýþzþVÿž$ÊPuûîd^Ý÷õÿ þ8ü°úfù{øÞ÷¢÷‚÷ÿö€õ2ôõØöZùëüúTžö4´ÔÈ}&nÔ(Žÿêþþ@ý‡ü4üü2üÐüîý1ÿ< è·1|Í  $ì+„¼þîþìüÜú!ø*õæòdñ¾ð¢ñ,ôÜ÷üV·ù;è-Vÿõþ>%ñÒ‹˜ÿ ÿþ¸ý.ýpý*þ½þÿiÿ ábæ|ó ªë¤äþ8ý´û½úˆúû ü6ýxþ¢ÿž‡2œè@ŽÆ¬LÀdàbêÿ®ÿßÿnlª¶l ¼e>·£œ¤°¬Ö>9 t $ Ýõxüøòó–ðBïbð¤óeøCý8 ¹,–zRGhëž$Ìÿ!@„xþŒÂ»£¼ÿ&ÿÄþ|þhþ•þòþ€ÿF@e{W×ç}Øûòô<Ùÿ ÿFÿÜþTþ×ýJýÆü,üvûû´ûÒüþHÿ dv1¢ÿÿ®þXþ¾ýÜüý³þ¨Nf·V¯8’>,?Žð&ìÜêìü+V¬úxâβvÐØtÿ5ý_ú”÷2õšóeó¨ôîöÈùÐüªÿÀÂõxxl<~¯¤Ê–Ì Æþ@ýüûDû~û™üÔýÖþ¤ÿz«å»(% ðœ>*Èÿfþ5ýdüøûØûúûCü²ü`ý,þÿòîäª0tv„ºØöF5à¯(`sV÷u¸Æ5ôتB½$.Ö,fv2ŒÿŒýû‚øãö2öyöÔ÷úÎü¬ÿ7"\ââ’XÞ¤¬²MÃjìZÞ, ÿþÊýþýzþÿ˜ÿ,¼(zÉ"ƒüm¤¬„"„£¦Œÿxþ†ýÈü"ü…ûéúxú˜ú–û:ýhÿbâ¶õ¾Xì¡Sÿª<Ó”]™ÔÿÌþ’ýTüOû|úðù¨ùúTû>ý<ÿî<CðP\"àÀ–q^.É‚v?¶êÜÿ™þÞü²ú®ø6÷zöÔövø&ûqþ¨=þ¼8ÈTæàÿ>ÿIÿ ª¢þÿõþþ¬ýýJýAýÄýœþmÿüÿpëŠNìO{ÐTÐê÷6F66Jÿ†þþÞýÍýØýÿýFþ¿þnÿCÚ’\8´1pÜÿlÿ ÿ(ÿ~ÿñÿc¸ì'*m æ˜JÇ8–ˆþ[&ÿâûòøKö¼ôêôhöàøèûÂþ2lCÌ1ªa(¨+L¼ø@º&BôFl²žÿFÿÿþþJÿÐÿv@>WZBùLhh^`ŽÿàþQþ¸ýýMü®ûû>ü§ýeÿÆš!à†.ïâ ZÆ,q¦ÀªnkÖTèÿ£ÿŽÿ´ÿ¤@×V¨¿… €؈:ôÿ¢ÿHÿBÿ’ÿÓÿ5'òÿZÿþvüÒúNùJøRø’ùîûòþôb Üêcš¢5fÆÿüþSÿt©^L„rˆÿòþ”þLþUþÀþÿf$¼^¶îÆ}J$âlÈ"|ØÿBÿÚþ¬þ½þÿŽÿöÿ8b‘Âò&[¦Œ×åÄ}tê~48Žî:rwT*"dÈLÜ\Äéæëò丆`ûL{BÒþ ý¤üÝûû&ü@ý†þÞÿ ¢ÝâÈž€‚®ä¼DjÞÿnÿúþ×þFÿ²+`fbj•§@¥Î¼x!´jÆ0¿ÿtÿÿ’þþÞýäýJþøþâÿÖ˜}¬–Z&æ¼~D( æŸLýÿÃÿ¢ÿ”ÿžÿÑÿ*‹è>†ÊrÃ6@1èÏžDÜœŠj ŒÜÿÆþ`ýüìúúúíú†ü–þХ⒨0Þâ gÿFÿÆÿ+PŒPXjl‰ÚB˜Èìd¬Ïàö'VnV¨2¶yÎÿÑÿøÿ6ˆä>€¨¤~X/ úø öæÚÔÎÞú!P{¤Ììòò8‡èWºðêÏÖæÞ¾µŒ×°n.ÿåýØügü¢ülý þôÿúв„&ºY/RB@t¤ÒPZ*ÎYò¸šžÆFÜ.ŠØ  Þ™Dè t`h|žÀÐȨh™2ÏÿxÿLÿHÿsÿÐÿLÅ4¦Pb^J(þË–_(ýääû&[¸Ðζ‘g<"":`Š­Ðú*8(׆ó3ÿyþæý ýÅýIþúþ¨ÿ^Ðsï Ä2J”€ÐX÷`g,ÔxÆ‚g†ÎnµK}”“‚eH-à¸c:(%0M|¦Êò öŠZ*õ͸´¿â:^‚ªß:E?2  <Wn†Šxddr€ Ÿƒ@Ì/•¸ÿ”ÿÄÿ6ÎnúXŒ˜x@дª¨¸Â¸ˆ=äÊ®¤Ú8Ú ðçÞÕÝø H`^>â´ŠhXYl†¨Îð2D@,êÅœh4éÜÝàëÿ1FLIB>CIVf„²ä %4>B6  ýöíêù$."÷¼dí~.0ŠÿtÖ4,Ëjè„C&Kž”ì üàÛæêÜÐÔæõôíô&/28=:,óÚÌÂÀÂÆÎÜë÷ÿ ÷êÜÆ¨ˆhM6".T€²êBZdffmz„Ž˜œ¢¤œŒ‡|T™.ÊtEP‹æR·:RUL:$  îßìü$$øÔ¹ªžŽ~«Æáø'9>2 øæØÒÒØãíôúþÿùôðîéãÙÐËÎÔÛäïúúìßÓÉÁÀÃËÔàîøþþúôìäÜ××ÚÜÞâéôüúݸ–{nt޶è:NVRF4á³»Òï ýìàÙÔÔÚåðú !"          tkabber-0.11.1/sounds/default/groupchat_their_message_to_me.wav0000644000175000017500000003270011066760706024271 0ustar sergeisergeiRIFF¸5WAVEfmt "VD¬data”5À"ÁÈD® Zʤ‚ô\²˜0¨PøëNö1ö^Ýþ­ú\ï&NXFA’ètÓ(. úðá-âþîàÒ ÌŠIîÈfønôYò-lûµîr$ vóÄ4ù×”# èˆËžf¢ÿÔžõØ\ø•ðX.xêÅàó4Ä$Û`Ï&2kåWòÑê"õ¨ úyËßßüä@„Jì„ëö…üÛ6çF hØùpïöûµL/&ÅYñ>úTþÍÿüì¤ú¢ ^þ’é^öÆpö#ùN÷Ä ;"¨ç"DÎñKûfÜ2ù /ì8ò˜! bëðGðüüž˜Ñ¶ùâióº&ÚúðÖ&><àüüÁZ’$ûê °ú³÷.W ºÐþòÊõ"ç éÝþx4òc–0Å’î®ä0 ´ wô×ÚKj °Œ¶ûçò| í÷Rkökà+é5<$êê°Ì$ñœñ^û$uÿ&íWFòùöëÜ®ôqÞfäxrûû‚õáÝ+Lô?âüZ ö@ôeK8þžúhåêü p÷düÚîHö$$nÂèGéZö*ö÷òàùrï ßV>£ûtúõñK#[4â&óædûŸü0ûûù, KøÞ.ì€þá¸ýb)~Ìù×úññ¬óÛê|iôçÒø ¬ZÆñâí< "Fñòèÿ žŽÒçzõ×]ÿ¸êŠó ò }h ¬íüó¨ ¸ ìpà^ä>ñºþêKóú ¹èv†útÔ 2å5úTpüøÄò`ý¶ ÒùŽÛù, 4÷¢6 Ïã<üñí>  õù|÷œãDßhDÜúT÷&!=U– PúÿÞøuábðD :ýpðãÎþa»ïƒñix=5 êîª ‹ üé±î9fù*ïîz >&¬~ýðl ÓþªÞDæp¸ü~àúì„Æ6û„øö~ûã¡ô“ôL¦&:æ£þê fönë@ò¤ûj޳®÷:#›Ó÷Êì&îTõ-PùöãîôÉrøÀÓ÷I * Ú¨úPŠ®ÖöPóþ&r,ÿ$ê’ñõäïHøº÷_ùÛû]õ² ¼tíàéPìUø© `¶ïBù잢D T ²Õö:î¬Ú ôøìRëö õã*êâ Pÿ÷".ép †÷OL ½þqöÂçŠâ¿ Ù"øXó>ÿ„ ™ö |ýkó`ïgÄåIí©  üªëåÞùèƒú‚ûhýš®%ö&þÉ Büâè[÷`ý"ñ.ò£÷öò²QPÿŽù\ýfb¬õ&ìùÎÿ'ôTûU PwŠýPú‚’¾múçù 44Üù^ì\ö¦ø´ìªìwòxðžþ„ ¤ûÎõ4œ%Øîdí¸À|Âþ¢ðvö– ` 8¸Ò) ¬æìöÓ#µ¿ù¦õ0ú/¿ ³÷Ü®å¢ù.ùZûäÿ29а LŒ lÞïùOì¬étJíÚ÷Ì :>Áûb÷¼ûbâýµøû²H ­TìBî\|ñqê*üöl‚ð B k®ñü#þÜpôÂäëäù2cþüÅùˆþáþÙ4 }÷ óJýûü¸ˆ ë•øòJñ؆N'ö:úƒ ïɨœú½êðXçðEô.öÔ÷ðñáò6 `† ©öžö¡ýŠöEû°0ô–ýlü1­òÌîúÈvý–( T äûØê5æiòˆû°ò*í—ö/± < z ÊÐ Òp÷(ø™x þÐï¥ô¨øÐ÷œô,û²ú6öø8 $ íuŽûpý„Nï6äôóþÆù6¢âÉ:Z  W  ÆžñèÚöÃlôÛóòûÂþôýH-û¦ð~ÿèÞûä*¾ Ylô*øÆN¬øDîæô†mlþ𠹡þÎóìô õôJïšì“ö¸hÿ÷V÷"§ ¹úŒüž ˆ œ‚r ÿuûÅýgô²ï¼ü–ý3÷Þû$ ¥ø)äúrò„òû±ù›ì%î"þ„ûnê@ÎVé Uоý³úÂýýõùbøŽìæì˜÷ÐØþ8ÿh ƒ _ ºˆôÕï"ù_üßù ÷*ú@Ô “y ™j Ζýö´ûÚ j 2ô¬ì û>üfúðqé„õÆÀ5öÝB9Äûóè ï3óÕí&òŒü’ ˆä  f:ü¸ÿV÷VòpïÔöúìþlúrù–ô”øljý¯ü2 ô h ¸DüüÈôþó®öúö²óš‡¸ „ú›åþµü´úDôþïé÷ÿOúüü ( çü¢úÎ ŒRÓ ž @µýrý¤øÜí•è6ò&þvúpòŠ÷hºÞ† Dÿ@øûþÿ4ÿ¤úb÷Äü)&ýž & Ü+ÿ:ûhý< êL$ô¢ûz’ØöÈî.îbò>ôôõøný¤ f F\ žt ¢úJ÷tûLüÐüšÊþ’ýì‘ dj<Vþbü¸øfû~Pÿgúüfü,ûGúûûô'ò†ý¢˜ Ð]FÙ " À xþ—÷ô‘ðëð˜ûh"múpüè*ýÂý^Øûž÷Äùœü(X  5üZóžúr óûÒüFŸ f 2 €: k§²÷`í'ï÷ªö”ïôñàû} ÞÄÿ¢ 8ýZ÷¼þêùÐþ›i¬þzúZú¦, ¾Zý?¾ <ý&ñ¸òõ.ñŠðQô¡õpø4ˆ H ß tÖ Éÿlü4¶ÿ ¶ýýÜû×0oý.úÜø=÷˜ú§Þú›Œ¾ÿý…ÿýÝó‚î>òDú°þþ 6ðJ ] ž PÚúøõ¢õ*ú}þŽûÊ÷8ü.:*÷JômýÛzþÈû””óœþXýzÁþ|ó¬ð2ýxÔÒµ ò e Ö { FÿõtõŽõ§ðýî:õmýhOýû¼þžâ""ú+ýðù Ü !ó‹ÿ·ø4öú¸þ0ûý™ün? Ð Š ÐKþKú<òáî^ô*÷dôÐõÅüŸ\ „ ìÑòYÑÎêš)Üÿ˜k®úŠ÷ úÔ÷üò^÷ ÿ~öAlþ¸ù˜ô¾öÔúþ÷ ö,ý½² á à ò+TÐþšýÆÀ;û‡öú ÿŒøÂó˜õŒø ö÷nÿ`,  Î&Ð$‡þóóûåbP @  ºVýìûÌ„ü’ñïð÷¦òÿ¶úTøÇ÷àù·ÿ6Vûÿøð H > ä Àýäø(öÞö.ùøü"¸@þàxøûØ÷P÷²ö™ôHõ^ûgQ2ÿÎø‚|8ëàËþk ¼ ù oBhù„÷Ôôüïyñ‚ùü¦÷²ùÒš ² ?øÿðüÜúvû)úð÷½ü 7'Ø ¦AOÿxÿ£Ðfà¨ÊÔþÔø2ô„õ,õŠò<ñêñ‡ù(I „ ¾\L ô¬þšø»úßÿ9ÿØü(.\ ® ëJý(üƒêjü÷û0>þŸùÕû•ýú1÷æöLöh÷þ, r @>š `J ºóûÅôÑõŠøÎùàûŸÿ2ˆ¸K6þBýºþ¢ýù:÷ÞøþHæÆ üLûÙþÑnðZ³ 4 O R Œ @ ¸~÷èðÖð–õJøZõôQüÖºNìîjýŒù+ûÿðXx¿ÿt¡ÿÂÿìygÿÂ21|üç€û†öœõòôÚòúð>òÇ÷\þF#Q" Ì D €&üæý¾\lÿéýî"IÀ2ÆüÆú~úòú,ÿÈÜæÄÿ=Züý÷rùÐú"ö"òìõÄþÐ| øx £ ³ R X–ýµüïù!÷rúÔÿtUýnøœøàýÄ2þŸüÿjzwò¦þÎý‘ýìú˜÷ë÷~ÿš€ þ˜¬úuJýûü÷Gõ¾ò ó¾ùBÐüxü– ²ÿþ(r¬îæCÀö üy÷vù”ü›þÖ/²Z e fCþzúAô±ïÚñö÷.ûtûJü•þNJ 0 $|r%$®|D€ÿ:þÒÿ¬ÿÀú–öá÷Üùjúšý¾ã€ô"üÞúrý4ûsô˜ò|÷ý‚nIè ƒ µ Q `¥ÿn²¸Fþ>þÐýý€þçüøÁõ£ø ûÐøŽøuÿ " @$l¯üþéù®öù(ý}þH2@H N²ZIÃjýÿ÷¢õ÷ºú þÿÎüPûcúÞøVùÿýäŸî ·t ~ XÏüH÷ˆøtú_ûýhþàÿ.1î ¦¾üoöaõ¤ø³ùjùÎû:ÿøÿbÿ|Ò5t”Ör D œ^¬ÝÊbùDóÊôXøÑø|ø6ú˜ý¬lÃ$ζ$ý„ø¤ö¦ùÔþúvzP $ÈÿÔüsâ„àhÜþ.û¦øÎ÷Îøø&ó¦ïÔôêÿnèàüN€þbüÈú üÒôÚ¦Û¾>k\ÿhþbý´ü,ýªþgÿžýû_úxùêöêõø…ûÄÿãÚØ „ È † ,Fÿ<úP÷*ùEücþ¹rnÿ_ü)ýRþäþkþ•úîö"ú7t’ìþˆÿ0þ°úîù|þj_ F–(ø ’Œ @dúšõ(õÙõþöœø•ùÃú5ýÉÿ J¤Úþ4ú0ù¼ý\Òjvèʼ„ÿþ¸0¹–R ?"RÿHýêù ö§òñ`óÔøèüÇý  šüþ ÿpþ…]þåÿ@YBý¦úOúöü¢Þ§žüÕúaû:ûÌùò÷Àõõæøš”ú { ö ö2P,xÿÜüþùìøqü~¦˜Ôø ø^û)þÿWýü7þâ°‡zãÎÀû(÷"øxü›•HZŒ ¢ À 6zÿ“ýû(ùÜö’öÕøVü4ÿnÿþÜýXþRþïýOþó˜¨ëZœ^°ÿðúšù„ûFþEâˆlNNDÿbNú(ôFóˆõ´ø‹û1ü9ûhüv4ÔVÚÿFý@&È–ÀÀ•ÿŸþžÿÿüXùDø0ù€üÊÚÎTÿ›ý~ýü¿÷¸ôÛõû.@8ê: € vì‘k`ò¥ÿˆÿGÇöýjù ùFûü$ùºöÚøìý|f‚ìy€¯þºü¢ûæù¢øbûõ5x é Zº™0Þ>ý—ùLøÛùvý*îÿ"ý"ùzög÷æû°¥0¸RëD ô 8>ºûÒ÷ë÷rû ÿ`>ºÑT»»[ãüçú¾ùÊøÞùrüýJüýü”þVþþÖþø2æp ÎÛÞ~âý±øöL÷®ùú˜ûqÿÒGÞ ìþ¨ønõpø˜ÿ)¶hýÓýVxrŒàÞ¯ÿ²Æ– rÐ,ûIù^ûpüYùÛô ógõ0û c Ãv>ÆNyÿ,ü~ú´ü\r*o?éúÿ~ÿAÿœþ£þ,ø¼þ¨ú|÷Òöø‚ùºúfüÍ Ä È ’Ú š¡þ2þâüâú¶úÔý檔üîûrþ†þeüÚûžü§ý^ÿ4 ®ÿ/ûdøxø ý%j‚ù û § «×þ!ùm÷à÷·ø úRüÐýºüNûþýƒøÇ¢ü¼øNú€ÿ¬Þ.–¦˜ Èÿtþ¾þª~îf:½ ´þØûvøSõôõ@÷fú þhŒzi ÿ°ÿéí ƒ°ÿ¬—kùýzûZûÂýFÔÉ%®ÿúÜøŠû¤üÄùõFôØ÷zþ.§ Ú ¤ úÈ0ðbþÎù—úÄÿ"æÿûÆøÃùRüþKþæþôÿ*zB4žúD÷Ú÷DüøN¥Šv N ö6jÿýû}ùÆù‚ûeü}üý÷þoþ ü ûœü(ÿ Z³³?]gÀýÈù–ùÿüºN·]'G›‰Bý÷õQölùü7ýþü ü.ügÿ,j<Ðÿ!ý²þê Ô 8ˆ.ÿdþþZü~ù•øªûXœ(ê&þôþúþÞûlø›÷ÌøèúÊý*îݰtL66l¼8z€N’þÌûÚú0ûû”ù"ø^ù¦ýzHÖ6(ŠþÔý2þÕýüHú¶úáþTÊ M ¼°Jc¢V}wýbúáú þhèýŠø¼õq÷—ûTÿÀ)mb; &§2üLøäøâüˆ™ÿ–ÿ(e®}°,ÿDüû2ûfüíýþŸýüüþ_2ÿöüý2LÔzPp DÂþ­ûù øô÷lú:þ£Þ¨èÒV4ÿú¿ø^ûÈþ‡|Tÿ@þÖþ 1|tdÿàÿù è š¦éüQûøûLü†ú<÷áôÿõÈúÞâ-°öxìŸ ý´ûü¸ÿ\R¯LæÿÖþÆÿ9¥ ²ÿrÿSÀ̲þûpøÐ÷6ø«øêùÒü—Ë"v Æ ªMŸÿªÿ»þœüyû•ýÐVFŠý%ýhþ¤ÿ ¬ÿéþNþ>þ*ÿ)=Fûüö”÷æüŽ2.ã’ ~ $ò¸üàøÈ÷2úäý>ÿzýJûŠûþ2ªšzýøú&üoÿx ÌÔÉÿ&ÿòÿÖ—Jÿüý3þï÷ˆ¬.ªÿHý û»øÒöpöøû>þ.ÚFpîüúÀÿ¢ÿÓ­å±f_Âÿ^ÿ"ÿÌþàý–üèü°äêøªÿÓûû üAühú„÷jö±øýpú8ß Yó°5ÈÈüÂüJx0¨ÿ—û@ùù«ú^ýÞÿ ÿ&‡¬ïœÿHúÖ÷Bùgüÿº. äíTJp@ËýýüPýRýwüæûü.ýýIü€ûûøû<þÌl,×lÈŠÅ`ý ú.ú&ýÓ$oÛ``wŽ^ÿûØ÷D÷ªùý¬þý_úþùSý_ž?ÿ)þ¾øùâ\€þ¾ýxþÀþ)ý:úÂøzû‚€6þ&ÿnþúýäüûžùù¯úªü¢ÿþÉâÙ.оØ62TV7ÿáü‚ûTúYù"ùøù’ûÀý­ËÔÅŠˆþPþ þþwüjûŽü°ÿlF*®Ì·øºê&ýŒüþ°2 ý`ù ÷&÷öù@þÎXZ6 O”¼ÈÌüÎùãúæýH¨œÀHøܦýJûÔû”þŽÝÿjý»û2üÓý”þ¾ý®ü_ý>žÂ@Bï_Áý\û°ùªùŽûˆþ°ðqÈŸEnÿºüûœüèþœÜ äþ(þ´þƺŒ¾¸ÿš8 v ôþÈüüÚû`ûÖùÊ÷\÷WúóÿìŠÜúH²ôLÿªý¸ý>ÿÑìÊDXþªý¿ÿ‚Ð<ân@nÿNüàù)ø|÷”øûèý0ù5þüƒ,ƒ²Á~ÿÖýhý¶þ°Ä#…ÿoþEþ€þ4ÿ° |8ÿ§ÿ6æþÛúÒ÷FøòûN"%~8…÷ž6dwþÏú"ú ü€þrÿ"þü¤û´ýzÜ%ÿ‘ý¦ýçÿîVä)ÿÂý(þLÿxÿ?þZý^þ0ß"~@rZþý¦û•ù+øîø’û6þmÿ¢ÿ A®3ªË´æ‚ÆhvÿÿýÆýaþ¯þþŒýËþöpÔô4&þùüÉüüÂú ù6ùÚù(üþÿûCËZU܆c(æ€ÿPÿ Ær\ÿcüîù4ù–úý®jz ÐøÜŒÿºûhù¬ùÖû]þ_ÂÀÜ@Šþä”.ÿÿÿâþ:þdý°üOüêû^û&û–û¤ü&þWˆR@$8Þ”ýûðúLý>ÄœŸ¤.ôžÖJý‹úáù†ûõýœþ¶üHúüùlü–ÿ:îáÿ¾ÿxxNÀ.J>þlýBþ—þýºúúxüú²¨Œ¸ÿÅþþ„ý÷ü"üû‚úÒû¼þum²˜¤8 ç²ÈŒˆ“ý0û ùùTùXúü)þ†îtò¼ÿðþjþìý`ýçüDýôþ€ÎÂê²)}âœbÿ þ+ÿŒÿ–þ:üfùx÷Z÷RùôüçZŠËXšY`¤<þ©ûæûÜý´ÿм¾ Üò7$1šþ)ý¶ýŠÿÜ:þü‰ûäû:üoüæüåý‡ÿ¶!PʰIçwþžüûâú>üþaÿØÿË”¾åtÿDþëýRþ2ÿ2šàÿ^þ\ýÐý.ÿOª€°Ÿ ÕÝ0Dý(ü:üÒû\úîøùdûÿgîH­’hㆣÂDÿbþùþªüêý_ýÿ¾Wqþäîp,dÿHýôú×øÔ÷³ø/ûþþÿ,Ž|ïÎR¨ìV¤ÿÿÖþ<ÿ²ÿ°ÿIÿÔþpþ0þ˜þÖÿZPe´ÍXF™ÿzý©úðøVù–û¦þf.$Ö§s»áa»ÿ´üØû÷ünþµþ¼ýŠü-üýÅþ@´8ÿZÿèvÏnØþNýôü'ýcýžýêý¥þg0š4&†p:ÿ)þüÊúÛù7ú„ûýIþüþ„ÿEüP…öxh˜Ìd‚þêü{ü/ýþ<þŒþÅ%ÊŒJBþýübû¾úNúŽúüÎþÌ—zJ›@ºÒ  :eùÿ~þ`ü‚úðùIû þÀ5Rãí ~ÿ˜ü¼úoú„ûzýzÿÚ˜<8k1ë”ìËU"ÖÿJÿeþ(ýôûNûPû©ûüçüWþ`d³("ðZê¯ÿrý2üPü`ýÐþ6V.ÞxÞÌ p(ÿ&ýüoýƒþfþëü@ûÓúüìý5ÿŒÿºÿ„ôò@è¦jÖþÔýùýøýýÎû¹ûlý1¸ò–Z/ÿÒþÎþ~þ–ýtüâûnüäýtÿD+ÊÿøÿÄ[L|eRØ(þ&üfú}ù¼ùéú™ü†þ†2&:‘’ ÜÿÿZþÊý¤ýëýÁþ)žDÑìða6Ûµ€“Ìÿçþ³ý üúEøñ÷¬ùæü(¶ë¶ Îö‹®ÿ°ý,ýÖýîþØÿ8 ¾ÿÜÿ¾®ü^2ÿiÿ~ Fzþü>û¾úêú˜û·üþ–ÿF\ @zVf<8‘þYý›üVüŽü.ý þýþÞÿ|Ôç¬,ªÿ€ÿÌÿ6PÌÿÊþÀý$ý<ýëýÌþÿHTíá…$ÙþýZüÂûàúú>úÙûTþÕžò•â—ŽBÿøþÕÿŠ*øþþþ4ÿ↲*ä༂ÿæýÌûÊùÊø[ù8û‚ýnÿÄØñض÷<Àôÿ†ÿ’ÿ¶ÿ|ÿÔþ(þÞýþþ:ÿ6PW˜þÐü2ûBútúÚûþAúÞªZhnœ˜õþþñý>þ]þîý$ýžüÙüÐýþþÈÿ ޼eøpdÿ ý¤ülüºüPýþÿqM]äÚܬÿ’þpýaü¹û–ûÔûPüý3þBÿÜÿ`8jb»yÞ ë~ÿ þþüŽüžüýÞý0ÿþr̆ÿþ¶ü°ûûû^ûPüâý¾ÿ6ÎÂÖ…ŒB3f8 Tÿ‚þ`ýüûúèúüþPö4 »@R¸ÿšý²ûÔúEûœü)þtÿrFÁ#ì$9¨:”ÿˆþ1ýâûûÚúkûvüºý)ÿ»B|/IʬôóþEýtüƒüýáýâþXPîOjîxKÿÊþ¾þˆþÌý¸üÓûŽûôûÌüÐýÖþáÿZκẄ\ÿõýdý+ý×ü‰üÐüþÜÿ¡²ædsr²ÿVÿÿžþÌýý¾ü.ýþ¶þÿ:ÿ–ÿjÇ^®>øâ„rþêü›û¿úœúcûüüöþª»,@Ç5tÿÎþ-þêý#þÀþxÿùÿ(2bøðò’”^‘”RÿÏý6üÆúÎù»ùÑúØüÿÛð²v =‡(š?ÿ`þ þ€þ&ÿ”ÿ‹ÿQÿbÿ Êòàúúr6ÿŠýðûâú¦úAû€ü þˆÿêe®|bMx+ÿOþ¾ýVýýýjý$þ+ÿ'½Ò € ò9 w^ÿ:þjýýý8ý¤ýzþÉÿn$¹à<‡æßúÿjþýü2ûèúHûDü¥ýÿ`/}vo›ó&á òÿÿÆþÄþªþUþþIþ/ÿ¢PÕÀ·¾DÝ«ÿcþºüîú¼ùºùìúÈü²þE`¤%•¹T`3EÐÿ¸ÿ’ÿ ÿ0þbý*ý¿ýâþÆP©²Rw$lþ¢üCû¼ú.ûLü¸ý6ÿº4€jÒ¦èÌp†ÿ×þ`þ þ¹ýRýüüÿüŽýþ~ÿJî˜B²±./Âÿþºüü`üRýpþ|ÿ•æf¢"¦Z²(ÿ@þµý6ý¼ü]üQüÌüÇýæþ¶ÿ CÞü,ͪzG*ÿ>þ—ý4ýý>ý þŒÿuìÚ3PY@þþ±ý˜üðûÛûNüýþÿÑÿ„"Æz#‡‚r šhÿ0þ*ý€ü:üeüýdþ ªÎI(’¼¼šÿTþý3üüü¨ýëþÞxö‚œžøêòWâÿ"ÿêý„üxû,û²ûÚüRþÊÿ ڊ­Æþlýçü ýuýäýhþ9ÿf©¢¼"vßaÒÿüþäýØü6üüLü¤ü7ý6þ¢ÿ6¡ºo¥B4­†þnýÐü¬üúü¡ýŠþœÿ¼¾n¤N–¿µÿdÿÜþþBýØüþüý>þÏþZÿ*ŒìÚô&ÆFöÿÖþÄý«üÁû`ûãû@ý ÿžŠÒÎØîÈ6DHÿˆþ.þ>þŽþÜþôþèþÿ¢ÿ²Ü²$ÝNFØÿCþÓüÂû<ûJûøûýƒþòÿ<JP Š¿ëQÿ°þhþþõþ>ÿLÿLÿ“ÿ<²þô¶d„ÁÿŸþ6ýîûLû›ûµüþcÿrw Ö¶Â×Fªÿìþªþjþþ¨ý˜ý þêþæÿ·ŒxÈV²wšnÿgþÉý‡ýtýoý”ýþ6ÿÂkÅ…ž :Ö…ÿ6þýTü0ü’ü:ýîý£þmÿDö[wœ¶™$eŽÿÌþLþþ&þbþ¼þLÿ5€î@•Tåÿñþàý ü€ûûzû¼üRþ»ÿ¬4Œ¢,<˜|rêÿÐÿ´ÿ.ÿLþzý?ýÎýòþ:3È Dr^À|Êþ&ý ü´û üÊü§ý•þ¬ÿþbwîÈA ÿRµÿêþBþÎý„ýbýmý°ý:þÿâL\&¸þÿ«þ[ý†ü‚ü@ýZþjÿT:DNo@èÆÿÿ¶þ^þÈýý„ü¥üqý|þKÿ¶ÿþÿ‰|”SVZ 8ÿ¤þ=þÜýŽý”ý2þzÿ|&ŠötÒæÿ¼þ¤ýòüÈüýŽýþ‰þøþ„ÿD#ñ€Âδnææÿ¼þÖýZýIý‚ýöýªþ±ÿäô†wñ0m¬ÿôþ:þšý<ýPýâýÑþÊÿzÎþYù¢ð²ÿ8¥BÊÿþþèýéüfüœütýœþºÿ š„‡ØŽ*ÿ>þþ;þþÌþÿrÿ"ú¼**ØjôÉ\šÿ¯þæýtýSý_ý{ý¼ýRþLÿжŒöþ¼.``[ÿ~þøýßý-þ¾þ_ÿìÿlêf´¦5”»ÿœÿiÿúþ[þÒý¦ýìýzþ ÿÿøÿ¡Œ”a¥8< Hÿ¸þþmýý0ýþNÿl /ä\¦ÿÿ¸þÊþ ÿ:ÿ2ÿ ÿÿŽÿhTþGRM;ï<*ðþÙýýÅüßüPýüýÇþ©ÿœ|AµPÔÿVÿÿòþ"ÿfÿ’ÿ¢ÿ¸ÿüÿ~Ž»—?Ökìÿ<ÿTþdýÂüÀüjýrþ|ÿIí”Tõ,ÁÔ¹Øÿaÿ<ÿ&ÿòþ¡þlþþÿ¼ÿF|l^ŠöRF°Íÿüþ€þNþ:þ,þ6þ„þ5ÿ@mnÀ6šî)ÿFþµý˜ýØý=þ›þìþOÿÏÿYÊ ï”bÿÔþˆþˆþÊþ"ÿ‚ÿÀ®†è¨æö pÿÎþþlýöüúüŒý„þ„ÿ>šÈzõ4ü]¤&öÿàÿ›ÿÿbþþJþ ÿøÿ¿4iˆ¨®d§…ÿVþxý*ý\ýÔýQþÎþhÿ;3„†9؉<ÔC™ÿþþŠþHþ3þ<þ[þþÿÈÿœU»À„.Â*Vÿmþ¼ý†ýÞý‘þaÿ¸Rï|Æ›ü<¬ÿ_ÿ$ÿ¾þ&þ ýxýÔý†þ4ÿªÿñÿJäªMz2:xÿÿÊþ”þXþBþ”þhÿ‹–/;ê‡4ß\–ÿºþ þ¾ýÕý þlþ¥þÞþ:ÿÎÿŒHÒ ä™0Aÿ~þþþEþšþÿ°ÿv:Ââšrãÿjÿûþ‹þ.þþ8þ¾þnÿW„Ä<Ò>DâPÊbyÿÄþþ„ýýþÚþ¹ÿ^¿T¢¸`–¥ÿìþ¤þ¾þÿþ2ÿPÿ|ÿÚÿgr”s6úè¦bÿ¶þHþþþ-þPþ¥þBÿôœóüËwvØÿBÿÛþºþäþBÿ«ÿHˆÌ %ú <þÿâÿÇÿ†ÿÿ¨þfþpþºþ ÿ„ÿâÿMØjH¶ñ<Àÿjÿÿ³þdþdþÌþ|ÿ,𹤙ZøÿŒÿHÿBÿiÿŠÿ…ÿfÿ\ÿœÿ ÄDˆœšci¦ÿæþ\þþ)þjþÈþ1ÿªÿ1¶F,è¤pHÖÿ›ÿ~ÿŒÿ°ÿÐÿÞÿêÿH¤þ32þ²` ¨ÿ%ÿ’þ þþLþåþ’ÿ„ÞB¢ÔµB©"Ðÿ´ÿ°ÿžÿvÿFÿ<ÿkÿÆÿ!NL@T“Ð׈ÿ*ÿüþîþêþõþÿuÿ¼bËâ´e¸PÊÿBÿâþÃþÞþÿBÿeÿŒÿÂÿ Rˆ¤ª©¤™x6Öÿvÿ4ÿ&ÿJÿ‚ÿÃÿiâ^ª£JÄ:ÌÿrÿÿÁþzþhþšþ ÿ“ÿGd|®ö.1ó–Fêÿ¢ÿEÿÿ ÿ^ÿÜÿT¨ÏáîñÕïÿFÿ¼þ~þŽþÍþÿPÿšÿÿÿ‚þN`BêÉž` ¦ÿTÿ ÿÿÿÿ0ÿ_ÿ¶ÿ-¡îæ´y,ÉÿTÿìþ¸þÌþÿÿ_°ø?ot:ÎTöÿÀÿžÿpÿ$ÿÒþ¤þ¶þÿ`ÿ°ÿèÿhÌ.^BÜSÚÿˆÿ^ÿCÿ(ÿÿ2ÿŽÿ"º"=踌Nðÿ{ÿÿÐþÆþãþ ÿ.ÿHÿqÿ¸ÿ$šü0<4 þ¸G¾ÿBÿöþâþúþ,ÿmÿÀÿ#Œâ üº_»ÿÿHÿÿìþíþ"ÿ|ÿÔÿ<e£ô<Z<õN¼ÿaÿøþ¦þŒþ¾þ,ÿ²ÿ f”¸âôÔwøÿ†ÿFÿ>ÿZÿxÿÿ¢ÿÌÿjºæèж¨Ÿ~3ÈÿZÿÿáþÚþåþúþ(ÿwÿìÿhÕ# ÛT°ÿlÿIÿRÿ~ÿ½ÿòÿ>dŒ¨¥‚N!êÿÆÿŒÿJÿÿÿ ÿXÿ›ÿÞÿg¼JJ §?îÿ¸ÿŽÿ`ÿ:ÿ0ÿUÿ ÿúÿ@bbVNPRAÜÿ¬ÿ–ÿœÿ¨ÿªÿžÿ›ÿ´ÿôÿJ™ÐæêàÉT÷ÿ“ÿCÿÿÿ1ÿ^ÿ’ÿÇÿBy”‘uT:(úÿÜÿÈÿÄÿÎÿÜÿêÿóÿ!JzžªœtFâÿ¨ÿfÿ,ÿÿ&ÿbÿ²ÿúÿ2^ˆ¬ÆÁžd(üÿèÿæÿäÿØÿÄÿ¶ÿ¾ÿÞÿ"+,2F^fNÞÿ¨ÿ†ÿxÿxÿÿ–ÿºÿôÿ@‹Â×ʪ„^4Îÿ¤ÿÿ’ÿ£ÿ¶ÿÄÿÒÿâÿúÿ.@JKIB6øÿÐÿ®ÿ¢ÿªÿÄÿäÿ0`²¸œj2þÿÔÿ°ÿÿxÿnÿxÿ™ÿÆÿóÿ )8PhtiN1èÿÈÿ°ÿ¬ÿÀÿìÿD[debU9Ìÿ–ÿxÿvÿ‰ÿ¤ÿ¾ÿÙÿûÿ#Lkzvk\RF4ûÿÜÿÀÿ´ÿ°ÿ°ÿ¹ÿÆÿàÿ.O\XF0ñÿÌÿ¬ÿ˜ÿ˜ÿ°ÿÒÿüÿ >VhvznS0úÿëÿÞÿÇÿ­ÿ™ÿ–ÿ£ÿ¼ÿØÿîÿ;ZllT,âÿÐÿÅÿÁÿ¾ÿÅÿÝÿ3Vd`P@.ãÿÆÿ¬ÿ¤ÿ¦ÿ±ÿ¼ÿÄÿÎÿàÿüÿ#B\dd`TA#úÿÖÿ¸ÿ¬ÿ°ÿ¾ÿÔÿìÿ$:JJ<#îÿÝÿÎÿÁÿ¶ÿ´ÿ½ÿÐÿéÿþÿ,@VbbR;"ðÿ×ÿºÿ¦ÿ˜ÿ¢ÿºÿÞÿ(2;?9$èÿÔÿÌÿÏÿØÿÞÿæÿïÿþÿ)9?<62-&úÿÜÿÂÿ´ÿ¯ÿ°ÿ¸ÿÄÿØÿóÿ/BJE8(òÿàÿÖÿÔÿÜÿêÿøÿ &($üÿòÿæÿÖÿÊÿÃÿÆÿÐÿáÿóÿ'8DF<)ñÿèÿßÿÚÿÖÿÜÿèÿøÿüÿòÿëÿèÿèÿêÿèÿêÿîÿúÿ#)*("òÿäÿÜÿÚÿÞÿåÿèÿòÿ þÿöÿõÿôÿúÿüÿ÷ÿìÿîÿøÿÿÿøÿíÿäÿâÿèÿóÿÿÿ  þÿøÿòÿúÿùÿïÿøÿ úÿ üÿüÿôÿúÿüÿ÷ÿöÿöÿòÿtkabber-0.11.1/sounds/default/presence_unavailable.wav0000644000175000017500000002425211066760706022365 0ustar sergeisergeiRIFF¢(WAVEfmt "VD¬data~(„ìŒEÐÿ|ÿ©õFÿ¾^:ÿ”ÿÀÿNÛÄÿ1þÿúË ÿ%”þ0þJxxÿ6ÿZÿÒÿ¦Xâÿšÿ”ãÌÿ*ÿüèÎþþþ*ø ÅÿÐþŒÿ ýb‹ÿ%ÿ•b]K@¸ÿ–ÿôÿth¬,¨ëÿnêtÿ€þ´þ¸ÿÍž¸ÿ´þ®,þ Rýÿt°ÛàõÀý®þý*1ÿýïÿîÀêÿ‚0¯ýèþªÿÉ&ª˜Ò˜Üü|ý$ÿùæMV@ÿ¢]ôþÈýkþ¥ÿúr›ÿ2DªÿÛþÿNÊf8ˆÿÈýªV{àÿÊþðþZy+ÿPÿnþþÙbRHÖþ&ý2þxšüÿ*ðþÈþVÎþËü€ÿ“ýÊþ° þ¾åüþ ÿ®k$ÿý>ý§þRBëP¤0üöW*ýÁüÃÿ Jÿ2ÿÞ¢'˜þ6æ¾þÆüÂÿ¾ÿŒÿ˜>ÿdÿ_æ½üÌýˆÿßû”¼rû.þ2§ÆYÿìŽþ<ü.û ÿŠR”ÿ+ÿ?êýŠü8„:úþ>˜þ&\Üÿ¤âJòø~õèüŽ„$ÿèþâЮþ.~´HûDÿàý,þ¸ÿ<úUÿŽ !FýØÿ|šþJý$¶ÿ^üW§~þ|þ*þ¼ý>’*HŽÿF$û¤ù¡þìT^¨û#ý£=­¼ýºþ•dÿéûÈþlý ðÌý³þdÂ&üJÿÚþ†ü¦ú&˜”üvÿLÆÉ24ìûRûþn(xü‘ü&–äFxýŸÿ$XjFÿDýŠÿpýëÿàK䵬ÿRûæü ÿ€ºÙþýzÿ$<…ªþ˜þžœö¶üMû$ýêLµv+¢ÈDÌÿr®þžýþüÆÿvÂÿxn ÑÿÐÿšûœüŒÿâýµþ‰Âýìà@׫þ°û\úûÎþ<ÿŒ4Gâzþþ­ýÅùˆý.ìüþ¾Ä¤ð þ¬ÿxÞû üNÿòûþBûhþV‚ýøüâw_ÿxþ&ÿ¡åÿ¢ÿl„ ý.þ•ìÿâû/ ¨`üðý±oÿ‹«Tý÷7ÏŒ’Šü´ÿ3ÿŠý`üìÿâŒ@ÿæþ˜-[ºøXù|ÿüÿ8öÿ£þv&l.°ÿÊýØý~ÿ‡þÝýîþ4ºþ¦þ þrÒ0ýPü6þ`ÿl–¤–BüþðÃ2üÒø,KŒþ‚ûÿ_ÕÐýRÀÿ<’ûÃú˜öhjý¾ÿt§{ÿaü þxœáýÍýåÿÿŒ¼8ÿNü4ÿôüÙ†œüÑþöÿþJ^ô·ûhûPN–ðûÆÿ1pt~üÊÿšàÿÇÿzÿ:\þÿ®›Íþ¢üÈþøý®ÊRþ™ÿV*²þLüW *üÚúN|:ŽþrÿlÙÿÉÜý&þ}’ì‚þØØjü"þzäzÿû†QðSZþ…·ÿ¾ý‚ÿãþˆÿ&‰èÿ£þ°ýÎÿÿ’ÿ%þý,TüûÊþÿýÞÇýþïþ€fzþ\¡Òþ¨w RZýèýä<þ ü°Þ¶{ûÈþxFúýHýšÿÀ'þ<ütVîþÇÿbNnþþêìtþ²ýPÿXŽŠþ*ýŒ‚þ7ÿvþ’®²˜ý ÎÿÊþŒÿsþH$³Bþ¦àÿ½ý–©ŒúÕÿs0ŽþoþqVëû^ÿÃhþlâÔÿnFþÔSþýúŠÿŒ›ØÿöüþÑìòþˆÅÿ|û ý^þŠÿyþøþ]þêþ.þQ”ÒòuLýcX(oþ®ýqÿV@ÿß‘Øþ þèªûkÿF8ÿþÿëÿ3Wÿ 4éýþœ;îþjþBý~x ý[þÌT³ýí:ýÐþzýTúÿŒþxÿÀÿz$[þ ¤Q–ý×ÿµàþe3ý­þ»¨žüÿÂjìÿ6ªÿhÿ–ÿ<àþ$’ýdÿ´ ¥þþ¤þÖ¬áÿ’ÿÿÞn²ý$þtˆº ÿ¦!éþææÿ8¶þþšþʦ±ޤýdIÿ‹þ¬þ>´Qÿ,Ô†[/ÿ’þîýØÿlÿ ÿØWŒÿÔ&V‚Rþ—ý|ÿVÿDÿîŽÂ ¤ÿyÿ.ÿäþtNÞÿºþîþ1LâPÿ¢ÿöâ¢þâþn.ŠãTþÛþGdÊþîtýÙ$¢u”ÿæýºþ6´À zÐþ›ÿc”ÿÿp®þ†þv$`þnÿö*4ÿ“ÿT,áÿ2Jÿþ€—lþvvÿ)ƒ‰þ^ÿŠ<Šÿ–ÿ VJÇÿÄzÿaÿtÿ¸ÿâþŒÿº>Œ¤þXDozÿ¸(¬þý@žÄšÿÖýÿ ÙþUþKÿdþeþ~\¼dÿÎÿ’[ÿÿÜͦþ›ÿæ´ª¹õý ÿÜŽ÷ÿþÿÿÿ.ÿ‹Üâþ#ÿ4b¼yŒÿèÿXV´ÿ÷ÿ^tŠþ°ÿÆsþSxüÿ,ÿäÊAÿ„ZÚÿTƒÿ0ÿÝl &Dþw£kÿÎ@ÿŽŠÿÿ`t_´IÊþäÿÉ–TÔ.ÿ®þŸœ’ªÿRÿœÿ`$[ÿñÿXõJ^ÿoþdÆÿ¾ÿ½ÿñ¨ØÿŸÿ>ÿ:ÿ·íÿ ª°ÿLÿXzqÖ6¼ÿÀÿ>îºFÿÜÿ{ýÿ¯BÎÿþÿJhý«ýºþ;¶¾ÿê‹ÊÿBTVè¬ ÿxÿœŒêÿüÿíÿæÿ(J\¾ÿßÿžÿ_ÿP*:ÿüÿ¨ë.ÿtÿ„“6Òÿ–ÿ²ÿÜD šœòÿ_DÙþBÿŽ›ÿþÿJò¤5sÿ0È*ÿ,ÿ»ÿ(¨IÿÓz¨ÿ7œjÿ?”œÙÿ±Nd!àÿÿÆŒ&æÿÄÿPT~¤ÿ º7òÿ˜ÿ˜ Lq€˜XŠ&ä<ãÿìB¬þ SvÁ9ÿ´ÿªRª"Xÿ¡².ÿvRh|ŽB´x^ô"Áÿ•ÿ%%vÏûÿ`ÿ½-È\½VÜðÿ€äÆbÿM`z(ÎÿÔ·ê2UMöÿ€ÿLŒxpBÆÿò,˜¬op`¬†ÿêþYžNŠö®Îab&ù?¿x©mºÿÐîù¥Œê¢\G'âÆ_œâÚ¤-dá†ô×]–‚Fè†hÿÒka“¦ÿ» ´äX x˜àT<ôÄ–žhŽÒàØ`º³™t©.ÆÂ„ZgèxzÞœXZ" 6nøU|䇂zd‰ÿÜ3 ®‰ °Ïg?¸"v¸íqØ&ó`8ÿÂþ†`œä‡jÿ ¦z¶ÿSeøÐ>ŠÖP8ÿÿ"‚ù’ÿØ~ êÊS‹Ž2µ8È þ„ükÿ™ÛÒó,jĘÿÛdV ˆßVFþÝýºŠgªþ½ý°„ÜÿN,¾Ä À db‚Îî"XÿeûÿÌÿòo¶¹¨þì‘´ý„2ÿðý‹¦Müúšý`Gÿpþp®TÿdüâøáÿÞüÿž¿pKþ¤ú„üþÿÞSã9þ"‚ PÿþÐý+@$üüÆ@’<ý&ü¹üÈýޱÿèüËATGÎýÐýJvÿÛûŒûìý²ýû+ÿÿpüÕ†bÿ[ù ýÊýÀùSûĘý¨üñû.ÿÉÿ°ý=c¤ýäü®þPÿuÿbû‚ý‰þìú\üÐÿ?ÿ§ûúåû®ÿZ 5üþüüQüÃÿëúš÷„ÿ,û<üYù8øèûÖûÒü6ÿ·þûŒû2ÀÿþöÝõaú¤ÿuqÎü2þ§üùü‰üôüöý¯û¬ú!ú„þ ÿþ,KþwürüÈûþ\ÿ«ûðùüÄþþàü÷ûûôù6ú˜ûØüDýû†ýPÿNûÔúfýZûDüðþnúHûù8ó?úˆ‰ûø²õŠ÷nšþMý6ùfø3øÜ÷ý9 ûù²ûèüŠþ¦ùÉôOú}þjÿ¹ýœ÷yú&þ¼ýþû þ‘—ü.÷úBö2ôœûSFü÷Ûõçö>üXRü˜øòù,÷ö û>ûdý`Öø$ôüöüºü û˜ù üÚüùåÿþè÷6ùuö¤õ6û™ÿüüVû½ùÊôdóxô0õ2ú„÷ûBŠîòüp÷âñ÷ný§øtùÝýöüø´øüø$÷^’þ–øœøÅùÍü@øøžù$øö$ú(ü¤÷çõòûhýšüNýŠÿýªúmþHü òNðùwûŠûÂú0û.øUù"ú–ù½û¡öõwùŽù³úÐÿâ\ý²ùû)ùù=üûø òlòÛùhøR÷áøúÒû:ú×*ªù÷)öUôXû¹ù òLùöþÒýÞþ"úìúôb0þBý¢üžûºöæüTýï’óBý˜ùšûú„ü×€ùrøÆüèöˆùLüøÿÌünò6ö–üûýøzôâôÎõþýÎÿ^ø*üX$úæôÄöjôöTøý2 ÷KïÆñaþFàòÌ÷2TùÓøïü4öøVwü.ù•ûÏ–ødöPõªöúý^;ûJúìü¦ýi#øÖõ\ý°û,úçCÔøùó†fýš,ûºôÅòªòæþIÿø þu9ú`õôžõÿØHäþù(útöàû¾~ü¨ûùÊñDðbóôLþß L ¬Sü7ýöåùöÿGþ¾ö©óý0ü.üææüùèû˜þý,øÈûîþ ÚšZø>ó`þOø~~íŽþøùZþ´ø&ú  ×>s1ðý@ôŽðô”ú¥ú½ýüúÈþD0øÇõlûÁný¯üàüØñòí¸ø¼ 'tÖõ.ÿ¸Öú€ý.õq÷2¦øÒùÈ8ŒûGü¢aÿšøÍ: üû\Bð¾óiêžð‰‡ÿ”ó&\ ÄÞjúçý^à4;ýðœóþõBù¬ (çíFü¦Äþ…ûðûXz eÈùí¶ÿùtú`úÄünþùžýJ›>±…Üü.ój÷ ,öÚýŠ}8ñûØüÜüÿXŒâÅÿâDÿpý¬ÿôúúèý½ ÿ‹ÿ} fÿ¤ýxú øLû¬þÆææC-Lvöûàö¶ø7ýZ dþþ¥ÿÿ¼ü øùþS¼¶öü¦*”jÿÜü™ÙÞýný’”‚ýš¸vÿ’ü RþDªûÅrVþ¡ÎiÄÿxû—b’ý þè¨dÿ’ÿRÿBˆBŽúý¼ùÆûl|ªÿýOþR¼R¦Kü´ý„þˆýÐÿ#¾Hþnx2ü qæý^ý(<ôÿX04Â"þþAþp°g$ý‰ûö:`Üÿ¤œÀĉþ²†ÿœbúýgˆ+–ûHþ<lÿÞþþþký4º½ÿ>rýˆþ!ÿàâèþ(ü™‘ý‚þ¢ÿéû¦eÿ Øþ"rþ!üd°dþêfýåœNþÚÂp:û"ýZ´0ÿ6î÷Äåûîÿ¬?ú£ý:ü\GSŸâölXºøæW¼úOþÐý‰½8þšü2f.úúj~þdήüVþÖ ¢êþÂÌ. #`*úáþÊIþ°(’ý÷ÿ®¦ü&ßIcÆý¸ü[”üz€•â¤NÎüÊý~­ûVöæ¬þÖ~®&– yÿùþ°PJÿ1ÆÒýz#ýÄÿá_½ÿªû@Ò²ÿ|´ÿtŒ¦‹•ÿG@ÿ†ÅòàþhPn”¶ÿ ¾µÿÂîýšÂ¾hRÇ:à×b|œ \’Àt&þ¦2Jÿ2dI¶þÿØ&& 3Ç<Àt ÿÔý Åæ<pXD`æèµˆ°<’`ê$JÊþ$É,ó0¦½x Yò\™¾ÿ® –5,ÿÍ_F¢þ$ö ÿ58Š/¤2´^ætÐ^ Ÿ$`Ÿݸötè·§Fâ’òXÁtî$ŸÞzÐÿÓ2×tæ¦ ˜Nÿ×ÿ(<3þè¿þ˜q®Ù¬¦JZ[„ú›¹'^J5åÌ&ÖÌŽFÃ0æ¼þäPpÿòþ2ôò ,>ÄbQj )¸Ž£/ôß>pž\Àœ´pfq¶Büj~=¶ÿµ^rö\¬ ™;´›t¦2P“: Dò$æ ¸V&ŸaÜü¿‰ÿàü¸Ùÿ̬–02bÎzÿVšp¬Úxtðúÿ` n&˜h ôtàÿÑÿ[]BÿJ‰òÿ,XL/:¾XF¬–ÓàLóÿ$¼¸ÿ=ÿ¾ÿxhÿ¾þÄÿEŸØ2ÿ ¼öÿŽÿ2ÿFAÿ|þ¸ÿ»ân4ÿfþèÿ!¥ÿrÿÍdÿ”ÿ‘JÿyþªÿjÒÿìÿ¦6ÿÿ†ÐŒÿàþ¾þ*ºüÿ˜þ¾`L®¼ÿ·Âåþÿ4¶ÿ€ÿ~ $ù%Á¦¼ÿ½þªþ¯ÿ¼nÿÿÂÿ¦<N¿ÿ8|Óÿ,ÿÿlÿî«þ+ÿóÿmtèrÂ:±ÿ ÿD4¨ÿâÿžþ¨þXS²Vÿ®Â;®§þ5ÿoäÿ¾þVþæÿ(¨Óÿâÿ ÕžoWêÿZþk¶&ÿÅþLÿêGgÿ]Þfÿ(ÒHaÿöþXÿ&ÿ$¼Ø÷ ¾@oÿ*&¢ÿ:ÿ þŒÿ´äôÿf¬—.Œ‡ºÿ~ÿÐÿäþöýœ}Îþéþæ¶Èx<RNþ´ýºÿhÍ/ÿ0éþøþ—ÿ``¸ÿ¦ÿüzlöþÖÿáÿZÀ øÿs*–fzþFþ\ÿÛÿ"¤þ:‚Ûÿ.ÂZð¥þËüDÔäþ4@Ñþ?ÿð0ÖFÿÆúrºþZÿ€ÿ¾þŸÿÐ6·þáþ¹”¼–úsÿ•ýÂþ)jØþ˜ÿ†òÿÝÿñ¼NQÈ‚ÿäýÿZÀþ/ÿà@±aLÁÔÿ<ö)þ€þšÿtÿ‰Åþnèd„ê>˜ÿ>þŠþ„ÿêÿÿ‚ÿ\@\¶±°e^.ÿ+<ÿ}þ ÿ ÿDnȧ,¢èvJÿtþ™ÿ±ÿrÿ†þpÿšÔƒÿ¢Ñþ øÈP.!$ýJü^ÿíà†6Üœÿ Í‚ÿPìÿ<Œüìþ.·ÿíÿ8˜~ÿšÿ¼ÄUÿêþžÌàþàÿûÿÿrþ~þòä+¨©þþþ¨þ*ªÿeütþÊÊYÿú¼=Zuÿš¼þ´þÖÿhÿ?ýêÿø´V ì­ä\ÿXý+þòÿÅþ2q¼âþ±ÿÓøn”="¬ýŽþþÜþ´ÿ4TNþò62~ÿ~ðiþÞü=DFÿ ÿЫ$þ`à“Ôfž@¢þ3ýúþ¢Þ¥ÒÿT>èÿ­þjýÖjôþ$ý’þx„Lþ$¼2dŠþRþˆ3ÒýÔø–ʸv.ÿÔýË6êþ8²ÿA$þ²þF'Û_^b4Cü·üñ\ÜBüwüéüHöÿ‚ªAPŽÿ ¦›ü‚ûøþ2è¼ÿ¶äîáéýKüì{4ÿªý¦ÿHý’þ_R@ÿ{œÒbü üvþ¤ÿÛ PûOÿNZrÿª‚êøþlýþùÿxVÿ ÿŒ¬€šêþ”Üþˆÿ’^þŠÿ/‚þÑþ&bîþ(ütÚýÿnRÿxþÿÊý+<ZÍv†þ2$&'þdü¨´DþÿÀý¤üñà|Zý$þbrZbüÒûvSxþŒðRRÿƒþÐìÿÿ>`ý{ÐR²ûû²øæÿ”„¼Œšê[ÒÿKýüZü§ÿüJLT¢ÿÆú2DìÿšÚpý(ûTýˆýBÊ~hjþŽþQþþû“’–ÿZûýÎíþý™šþ´†ÌÿüwýWûÖýv³ýýWÚ¼ÿ &ýXLü†ÿ° ÖŒ¼zþ¿ýâüfúÿÛ°_N:›üÌþî™ü˜ÿ8Š%2Eü(ÿtÔ û0ýßý5ýìÿQÿR€‰ûÿÂÏn‡üJü¶ýäü#sÿ4ùæþÂÿ¤ÿ"úÔúÀ†àþîüB"xâú ÷Æýðþ`þÌP'ý¿¸ÿZý &4ùÆûöý{ýÜýDþ aÿqþ¹ÿ&ʦ”$ŠÒü„ýöéþƒýø*'Xø2‘þ^ü¸ýºý>ÿÆþGý²Åsýžþ¢Xÿ¦ÂùþŽë$ÿ–ýoú¦û8ÿêû{ÿLüáýЬþøö2úÒX`þýûpüYþyúú×õ‚þèþúü©ü‹Ç)þ, úaüaÿ¬À€ýþþL¡ÿä÷¬p”ûÊøý]ÿdÊ`Ð`ýÆü+¤Hùòõ"üË $ûsýAÓûJýÜúvÿö^šü>ü®ýûÀýLþtýøo(GÿFü‘ýÄú~& ×ÂõºÿöZÿÂþ¶ü*ú.ÿ‚þ>øù;þ¾þÖ8¬äÿø`Wþôþ4üDúò÷û„Ø‚þHXþ ÿª\ý˜úðþ: @ý÷¸øfýÃ\ý¼üT"8üÿüöeõ’ú÷K Êû#ö°÷†ÓüµÞ÷vô°úº& ÿWþM r™öPÆYž Îÿzø‚ý_ÿEÿÆþHêƒñðÎb¸˜äÿ¬ò’õÓúà >ÿâóTó¨øúü ûÀúZFq–÷Búxÿ¿ùÊüœÜÃü°úÞù@²Lý–ü>Vfû oŸ´ºû2ùÌÎþvä “gý»ÿ*8 ú"þ&î(ÌKDùû‚ ´üüøÐüÈþ Dûrûšü¸ºÃÿü@‰úH÷¼ùLõâøHý–ÿ¯HÿŽþRÿfçýóZóÇý¶rp¾Øúü dýJ *Šÿ]žÇeû?ôdì $žlZ rü.Žø«8þìþ~ýÞýpý ÿ[9¿ú4ü¤úžþ®$tƒýÒüðô‘ô8@Yÿ¦÷>õbû‚›Dþpø@êrööê;þFƒÿ2ÿÀ"Ú±¾þ€üÿEÝ`÷4›ùqj#¥+Dü³Òþ\¿J²Úþ ÿÿ#X<ý2ù¢÷ ú¿(þcþðpù^ùËîþû6ý<^ýxø þRp8Oþüú<þÖÿVþÚì¦ÿɤ@²q=n0­ÿ‘ Ð~ûîÐ¾Š¿ üùLþÄÞÿ$èeÿdü¦ù/ýˆ–ÿ²þ ýýFþþeû)û*þ†ÿbûüáDòþöþ¤”ú}ÿ\üüöýX3yìâþhÐ…˜Êÿ.¦pùTLª€š&ú¤*êùZüF z·ý¼øšýßýõþäKþºþ¥ÿ*úâüÌÄüÈý¿ýÁû×ù¼÷íüNHúèùØþ×tW üf0þÈû±þŒÿdJJý`ýñýQ îÿŒŠÿæü|fœþ× Œ8ö¼ÿƒü8nÜù¦úÄÿïþÿðü!òèù€vUÍÿIþ÷Xõfõ6ùæE®ôHó¼ï J >Dý2zjó×ô^æûàÿ^ÃûÈr‘f¬$•ÿ6X‘ý£öîù®þª:)O<Ñ0+”Q¸ùNùÚ÷ê÷j¶Ø°þôùèœÈ‚§üÿ4ü'÷\ù)0ýAû÷ýêþFþÏû:ý â · „ú¬ü+ý ødúÀý6ö`ÿãšÀDƦL¯ûšü¶nÞÿxûHûkÒX,ì.! ~þý/ýÌÿŒþ†üaöÂû^p|Lþù°ÔÞÐÿÐþîûªóÄø¢óýÿÕ?ÿŒûÈýª þëú<ýÖüa ¢ø‘þþÿxÿþe ® u tŸý4ý~ùú6Ô½þT¶5Üijù÷XÿH:1ÕünøœäØú|þ@ˆúÿœÀýrÿõÿ>ûXý‰ü«û[&Åž?ô~øâ,ÞúÄýžpÿâÿFÿ¤ùÿmÄTzäÿ*ýÔþøù û¢4<ÎÈþžþþý:ÿÐþ7d>ÿvømþszÿ"~ÄT8ÿÐÿÖýäü®'ò²þ„þcþzcôû¡ÿŸÿ”þ²ûúü<Xÿ:¨¶.ûÿjzûûâ\ÿÇÿmýÌüÄ6v ¯´ùYùîü·ú”ùDÿtýþ¤„ñ–ôÇ,ÿüRû¦ý¦hø–ù>ýøöâ ÆÚЈ,ÿžýƒþÒú øôø–< < ìü¼ô‰ýºlÿÞšÿùœõûÐ Ô Eÿúû¤ù”ú…®àú~ûu\¡¦ýØømý¶~0ýtþÁD­ÿÄöÆó sÐuý,ú”ü>’,òvûVù ÿ¸ ¹€Pÿúü8ÿ ×ü¾úöþÛþÒü Èþ8ý<ëX.faü þ\Ð<öir>²ÿKùúõÿÄýÂþ þÁÿVÿbÿøí²ÔŒÿUt´ÿæþjÿÈÿ±öüòüÆ’°²ÿ;ÿdw†*DüüúÐÓþsÿpÿ)ÿÒýœ(Ký‡þºdTüÜÿ¦.‚øvÿWþ¤ÿaVâþB0º+Äÿ¼ÿFµÿR ÜR]ÿ”ÿŸ@:®ÿöÿT2´§ÿX‚.3ÿìÿŠÿ>ÿ€&1ÿR”ÒÿÂÿ[ÿ$ÿ.¶8žÿ®d|mÐÿÜÿÒÿrÿ>°r˜ºdÆvPÆÿV0¢—Ìÿ T|Êÿò|Xu$4Ò`„ÿ´ÿÂÿÿðÿŠV¥ÿ6ü—Üÿ·ÿÌÿ»ÿVÈÄÿ#ÿtkabber-0.11.1/sounds/default/chat_my_message.wav0000644000175000017500000001101411066760706021336 0ustar sergeisergeiRIFFWAVEfmt +"Vdataà ÿÐÿÊ„ñÿ1Và†ÿµÿ5óäœòþ†ýŸ™Ëø[æ¶û$ øDù ˆ_Ê*ô>üV íßþÚ˜ç¢âí ¼ñÎð3hûZäÿ=ö!ê`!âûêöàÒ÷¦áì¨ùÐçú8ùþ „ÜèÞù«º¦þvû|ïÔø~÷è"ó ž6zj÷ÊjÀÿ6|2ë@ù¬ùÄíèû¼*ýJ‹ Ìú©ùVÿ‚ȆBWüÂëêïØNý¦ùÜÿ*ÿÄúâ=+ ~s4ÌÔïÎêÌöÚû>òʸø¢þü6 œJÿpú÷Xý⢽ú€ù¬øiù¯å 3 ’£Ð÷F÷ü4ü(û þúýÒúîPˆûÀ ÅJ êû|÷œû¸ù¿úpÌTûþ þ•ûDž¶Zþ" ÿüéýnüÎöqöÎù’ø=ý¼ ÈØ ØÎÿþ¬ý•ú~ü$þÊøŒøbýlûBü¼¶•6­ÿ@FþÔÿº8xüBû¼øþ÷ÝüAuÞüP‚ç:ìZTüµúúúÃö ø$º2ÔiÔÐÕ‚ý6ÿ‡Àþ„ÿòÿÍýÚûhü¦üÖýêìÿšÔÀB:þÚþ;ûÄöÜøJúû"ÿ’gš¦¸õJ˜’XýôúÐø€øúúþúW%â²<–3ÀýÔùÚû›ûyú&þÒÿMýžþÈTètˆ¼ ÿßùkùúÕù`þð«•žÿÝrø“ÿ<üšý"ÿHýNý]r¬ý4þþHüj¾)j_ý]ÿàüúLýðû|ùãýtXþ"8žœÎÜý þˆü¶ú°ýèÿnýQýçþšý þàbðÎ<Mº|þŒý¶þ ýrûüû%û*ûæþÒh°ý*Àãþ:ý÷ý ü’ú±üýËý?$8Þ¤ÿ§ÿÿþîÿ„6ÿÿVÿ>þëüçüvýŒþÛÿ‚¢Äéê‚@€ÿÀþrþíüÐûøüTýæýîÿy†Ð­¤ ‚8ÿ˜ÿXÿðý©ý¼ýLþ<ÿðþ[þŒÿ³)ÞË §vþJýÜýÿ¦þàÿd'‡°ª­ÿãÎÒFKþÿrÿÐÿ¼þ ¦ñîõ´ù>z Ü€ö,ô0ÿ2^ùîè¼vçÿÛþSþ&ù¼×üføG6Z i¬÷Äü6tÿ€ü»ø4ö¢| Ô¾ÿ}ðxû®sý öùf÷ê÷ K oGÿâ¸î húðùûý2Ì^Jÿ>Dý~þF\$øðø w*H{xýûpýbûdúgýIÂN°|4~ÿÓìîj$ 8ÿ:ÿFh ^ÿìýPÿú¸´ý„ó\ù!P“2tÔ¥þ@ûŸ÷.ø.N ŠPû û™þc „ æþZö'ýš¦ÿûÔû¯~Ènýúòü+† *h¼þsg^¼ü¬÷øþΆÿFþa ¹ ð4ÿ¾üþþ<ýúÒø&úlý&DtõûP¬…~üúð|ÿ ò°õdüú Æ:ù¨œ÷žvÚNú õ^^ù‚úþþ¾ b÷ZrÈgÿ1öPþvÚýÎùÝû øÉšüËÿ2Lÿ4Vû¦ýÎÿ„ýHÜÊBÿWý¼Ê°8þ“úîõþµ÷Fùòˆ%ý€ûÔ÷Ûè¢I,ðú0üúJû,û ĤÓÐØ.ÇBù"ùüÐÃû¡øzýÊúÕ„Ö|†Ìýìû!ýàû³û<ÿJº^º ò¢ÿ\þ:(pýÚúV@ÿ®ú¯ý:`j‘¸„þ¤üÎýþ`ü|ý¥ôL’®nñ\þëúˆüpý&ý~üÅü¯xýïãÓ¬þ+üŽúÞû×ü˜ýoj¨{¬¨C@ÿ×üjü–ýßþÿ}þ”ÿô)RÒˆÿi¶4ÿÜý©ÿbÿòýÄÿÖÿ2ÿÿ |ê¶407nþ?þ!ýnûürýyÿ©¢¶´ ˜gDúûNúLý¾ý^ýÿrÎðF¦þ‚üôþ/ÿ,üÑý>:Þ˜ðjÿþÄþJþøýòþ½ÿþDÓ,³XpËÿ‹þTÿŠ"ÿBghÿÚÿHèÊ_Qfÿþkþwý¦ýÿo¢< þ`ÿ¶ýÐü\ü ü]üVý|(2XÖ>0ÿ¥ÿ"þòû¥ü®þWÿØÿÆhJn6.ÿ ý ðMýVþNŒ2ÿdþ‚°³èþNÿ´nÔïÿÿÄÿ‚BŸþPÿ xØ0DÿiþpþÚÿæý ü`.ÃÆá„Œ’ýývýCýôýzÿDÿ¤ÄÉϾóþ‘þ‚ýaýäýÚýþ4´D88€Ôhÿ*ÿŒþ|þ–ÿ&$ÿ¾þÙÿ¨úýÿ6l2øû’Âþ¶ÿÌÿDÿ:þÂþ„ÿ³Oöz}R*4þÄþþ3ÿ\ˆDðW8aþ´ýÌþ/ÿÿÐþþ\ÿ¸ˆ±A¿¬þÿ£ýªüôü>ý’ÿXNLNžB"þDþxþtþŽþ þâþbªZ Ú~Ÿé‚äþ4ÿ_(þþ þøý ÿhÂÿz禮ÿ¤þúÿüÿŠþôþ^ÿÕjÑ¢Jñpâ­ ‘ìú” †PE÷âþÄ  ùƒãÿõÜþ\ ÈÜA` ð\òþ¿ðDîTŠõžóÞðþ¦ ¦Z8d ùoñX÷âüÊPø‹öu$¯ Šžý"ý˜ÿPúØõšóúúMû^þlì ì ’þ”ùoÿ•þƒûðüdù¯ôþüÛì:¨ ­‘ –`íÿõæÃú‚dÿdú üòý"¸fâÿY¨øðñì:úŠ"‹œ œªþÜN püþ´ýsÿø`ëÈíW÷¶r Ê ô2‚κøÖñÊø&ü]ü\øºöDÿ:ÞÞ ¸¬,q¼ýüôäò÷ýRøÖ÷(ÿL jšÎäþêûÍùÜôâî†ò¢ýEüÇ®Ž ¼†zû-öÀø0þRüÊ÷`öDýžZà¨ Ô zŠýTõdòõ ùÔüÐþDþ < ê6ýâú.ø¾ö\÷{ùHÿÀwÐÿx¸&ü4ÈýlùÈ÷zøøîø¢þ³²œ> .ÀsýŽøÈóAò¦öü|ÿ¶ÖhDhý ûøùHùSøfùäüy2ã¤À]ÿFû#øFøøø{üo'fT>žQÿ¥ü û®øÄø*úoûuÿ¤<oþȳ¸üÿÈý<ûYùeúˆúù6üÖUÀ €|}¸ÿÚü:÷Òó6öRûþ8Ú ¢ºÎü ùyúŽûXøÂø¼ý1”t8î<ÿHûŠúoüVúxø\úŠþØô¼ÖÿfÑÈþúÏ÷Îùäûlü^þ:ú< H9ÛþÁýý)û.úâûüžýëÿ$صó´‘\ÿüüù&øHøžù¬ü­’~(¦˜³ÿPü€ú¦ùªù ûþÿ÷x˜P¬®ƒÿÅýÂüürúûTý\þR8D®n0ÿþaûäù×úÎûhüvþè´ë„q¾áÿîý2üÉûdû-ü®ýþÿ=ÔŽÀ,ýôýãúøE÷Dúxÿ^ ì¤Ï¨EL@8üTúGû;û^ûþ³jÇœ’®Ä¸ÿ¡þ?ûÐø.úîû\þ¹ÚºD:Yüÿèþ„þªü¼ú¯ûúúŒýa]¥HKf8ý|ýæùyû<ùôªö*Ć è>ð¤d û²týˆúJöäòâŽòük î ãø´øÿ{¹TúžæF÷Zü,ð=šÿ nóÂöâôùøŽ¥0ü2óšøÐ¼ ¼á±5ûÖóªôæ Jf÷pí·÷ˆÖ  tv×·ø¢òüðëóÑþŒ’ -€6 n¼û÷qøRù1Æ €ÿ@ùŠü]Qùàøüô– <Ħý8úô&÷×úÈþD  Ü ÿõ øXûòüÞpü¼ýb"ÿ¶’ùW…>þ±þ¢übüÿ8þÂûÀýúÚú(æ° Æ;‚¬þ€û÷øZ÷îøÖøtþ†Ü Q  v:ùøt÷Ûùjª‚còžü~ûðûÿý„¤TIªgý5üâúzùxüÿzÒÿ†Nûýdúüùvü‚ýzþGÿÂÚüþNf9ºÙþîüÀü^üØüÆýÂþ£sš òî @Füþù¾ûÜù,ú0ý¼ŸQ Œtÿ¢ú÷`øVùSüZÿà2öþwþþªþ¯¼Hÿ›ÿ:ýfùú²þ´ÎŽ5€EHüÄùøúvü°¶üIÎà(°ÿxºœÿeý$ûLúÎüžÿÎÿHq6|²,¸¦þFþ—þ¿û@þÙþ.¶»ö|zÿ(ýcü‡úÙûHþ Œf±žþÀýÒüöü\þþ'i8þüüOü|üNü¬Þjò&ÿû¬úKû—ú£ý{"Þ…öö|eÿQÿcÄÿ*ÿþnýïû€ýzÿÊ¿,LÇ2þÈý1üýNý˜þÿ¤ÂÀ²®ÿÿeÿhÿþPýkþ@J‚^à¤ÿ(üŽü5$âÒ;~üôúÿû9ÿ¡àî‹›þÝü~üóý\Øòpmÿyý¾þúÿô=È;ÿÐüÉûóûnþ ¶¦!ä.¾þ¥þ}ÓÿÔþÊþvþ€þ~ÿÐLš,*”ÿÖýwü¤ü þ†ÿ8ŠÜ4Lÿæþ)x€ö”ÿ·ýXþzÿ,`HjÇQòÿJÿNÿrÿžÿÏÿ Þÿf˜dd¤ WÎh.Úþ¾ýþõþ“ÿFµŒÿŽþœþUÿ<Y&*nÿ&ÿ>žÖ×JDD'ÿ„þdþ¦þlÿ|êl þidrÿ<ÿõÿòÿPíÞðÿ¶ÿfÿnÿªÿŠÃÿ&Ø’oÿÀþÿ€ÿ’ÿ%¤âuúÿ*†jLZ$°ÿKÿyÿ¶ÿ­ÿ´ÿœ@}héÿ‰ÿkÿ”ÿ¶ÿtkabber-0.11.1/sounds/default/groupchat_my_message.wav0000644000175000017500000000634411066760706022425 0ustar sergeisergeiRIFFÜ WAVEfmt +"Vdata¸ Le_:ó÷\ -™ÿÞpõHótÿ§†ütì¡ ®û²û- öüR™ ÛóúíÐù ¨ð* è±õ0. õÄìáïŽþÜì -\ªÒþŽüÿ7úJùk÷äôœ÷F6 vN ô5s>ýøúñýÉûÂý¾ÿÄ ¼ ñŸö‹ôÎÿò‚üVŒÿ·ÿx 4.þôûþ–Ë þÀþ0&ºàªøôøÖûHýAÿ` }ÿ¨Ôýlùù÷ú’ÿT©Ê vº³Dü`øòôE÷ÿÄ^¦ +‚þ2ødùºû¢û²ú'ýÄ ö¾b€‡ýÖþüèý?ûVüèà}ŒþÿþÿFÿèý¯þ¥ìLœúÿ“ÿ´ü>ülûòüf z¯ë¼ð 4üÓøÈøFùý4&ë`n ó5‘ý¸ûöú»ù[ø‘ù^þlŽèfâ˜æ/üðúøú€ùHûH’¡Sš4Böþ}þ½ý2ü¦ý¬ÿ·2ê´ÿtþÿùÿüöñE²ÿþ¸þmûðú~þ¢þ¾þŠèf!lÿOÿYü«ù û­ü¾ýÎ&/lÊx~<þ0útøtúÙüœÿŽÂœVB¾€ÿÈüÐûdûpû?ûòýj±Åæ^ìþJýºý#šÿê€zXzÕÞþ þ2þøÿûá8 öÿ5þüôûþaÿ|Ôöî5\þ3ûàûÂûnû‚þ¨Ð*÷,ræýåüýúÐùxþºa¦ê8èÿßþ€ü”ú7üþþ¾4µ$Ú’ÓmýPýìþtÿÿÿRÆîÊÿ2ÿ¾‰ÿ†þ´ÐÂìX>Žÿ^üèûºüfýMÿbqôR(|'þÎüæüæû¿üÐÿâ¸Crqˆþýðü{ü÷ûÖý6ÿ¨UÞ¶bï_Âþ˜üRüÕüˆýÿ¨þ[»¨1ŒÿPÿdþšþxþlÿçÿbÿž1WÀþ_ÿpÏd|Gÿ.ýný¬þøþÆþÖÿÊFd”z˜ìþþ|ýOûûrüOþU”äH˜Öÿ4ý`ûpü!ýþ¢ÿ$gЬ úŠÿ§ýêýöþhþZþjt„¨ÍZ z:þ¸ýÿõÿ«ÀÿÐÿ:òÿõ1ºª¨‡0FðÎáÄ á¬bûü @`ôìø.þZ9 çö¯á/õzþ ¸Ìî‚l 0Xþ-ï—ë¶ÉóPó8ò¸îrþ”tþ÷Îï4öžüЩ4úkøv :° l]ý*üÚ¬þºù¾õ˜ôHü €˜ûøþu  "ÿ)ùHþ8ýUúÒû@øØôýƒ¤ úB0 Ęû–öÎô õúûÅý<úlý~ LÞ:ì~üøêóˆòè÷#ÿÔ<0¤ ¢ Öýùõù´ûÑøžõz÷³ýbN ´ðÝÜòê&ûÚöÚø:úÀùÐûªücþ2Y Š Ä– ÃøÛôÖõdù¦ý.þµþoœJ ! :ŠBþOýöù®ö®óâòmÿö þž¸ùþ<¼2þ¾÷ý÷¢øÖô:ôÔ~V– 6Œf+úÌü´õOñOúDü4ÿ¶öR! —~äù ú„û¼þ›ûäúü»0bÿÛþ:jt`9ØþÎøZùlûp÷À÷õùöýê˜ } ñzZ¢pü®ô`òËôàüS5Ü^Ô¦qì,ý]ý*ýÃþü#ùPú~ÿæÄ r\·õÏí¿øSÈþB1Dá\¾_,ÿåÿ'œúüò¹ô²û°¿;UŠÏ|4ÿúþêýúù©õ¡ø(T¾  ŽÚÒú¼÷ÃóRôÎùÇùû g  µ N PYþYú˜÷óø„ø»öxüUHs2û%ý¾ùLú>û„÷´÷€þ Ü4Æ:h\ÿ ý>û†÷vø5ûÔüýüÿÞ”wXÐ,þEüŸúŽù¾ù”û’ýÓýk<T ´[þÕùdö´ô0÷¢úãF´ÒÙ " žNþ¨û¾ø¤øüøú‚ûÀþÜb¼‚©vRý ûØù]úçú¡ûêý*`P§2Ä‚ÿŒü¢ùÌ÷Tø%ûÊþñ^‡µÖ¯áÿÎübûDûÉùzúáý„‰É€Š\ލHÿHû(ù@ùNùúTþT\šEÆäæý¯û€ø’÷múý¦ÿnõÂÈã‡ÿðý>ýêúéùzú[ûÀþÑ8ÞR]è$¼ÿµý üÍù¶÷¨ù1û„ÿîô"˜‹þÀ!þ>ûçü úüú õ^ø‹ ÿÜ bèÖð1* ßùF,üvùõ¤ñF b¤Ž “úê÷¢û»üXïùùñºü„¸øØžl‘þ Y~èð ò^ú`XþËþjüòÃFý¬ýüLá´ýôIùèýhø*ûöþY¦ ¹q¡ÿüþºõÆòö8þ…ÄúÐ4š¹ÿ˜øL÷Øý[ˆýÄú*ÿ,¸ä²ÿþHô¹êûHöü¯ÿdû÷ÿŒ:¶ Z VüªïS÷ÈøÐ÷f ¦ HþŠÞõúôt°VC P øÕójö!üH¸üŠÿLðzÿ:ÿrþÊý¿ž ÞÍû=ö²ôŒ÷žú¸ÿŒì G¼ „<÷»õ(ö-ùàŠ’ºÿþ¨úiû]ÿ-²;:ühü,úùõú?þê` þ ¹Ôÿý¹ú$ùgú*ÿ®^D7ýBþ zÔìÊBÿ:ýdùhûþôþ"ÎVÕÿ‚bYýÞü(¨6øæüùRñÄûÚÝd  Èÿ”÷ô¡ùEú”þt¾­évT*úF÷à½6~“ýâû‚ùDù¿ýK¡ÿÒ^}ZÛýÊú´ü ùŠøvùâÚ¾¥üãùcb‘ìÿÀÿåý˜üºû¼üü¦¤l–ôþîý6ýB†èü°(ÿ`þìýtrþª À8Øü›ú³ùfø úýüïÿähCòþöûˆújûˆü ÿ3Ê" ÿ>ý3ûúŽÿvüRš^ˆþû¼ûülû‹þ”! ”d:”ÿ¦þýbýÑýÒÿ`Îÿ¦þ`þFýH»r>¾Rÿ@ýäûáüìûðý †ÿ¦¤9X¦ÌÿÔþúü£þBþVüéýÂ&Äì"tÿƒýmü™ý<ÿëòÈÿ¦ýˆýëþL wᚎþ†ü®ûVûAþø®^ª J0ÿFþ´þàþÖÿàÿŒÿÒÿ°ÿ–ÿ`îHÔV»—þÍüŒü‚ü'þÔ Dìúv¸ÿûÿ ÿþ†þþÔþ9ÿGÿÔj»¿/.ÒýbýpýZþî0Rªÿ_ýÚý?0 jžþðûúûVþ„™J½Õ‡ÿùþŠÿbVÊâ›ýÈúüìþRÔ:n®0þNüàûÍý +̦úÿßþ\ÿ1ÿ¾ÿš’‡"$äýòüžýþæþ´µr”Î)»ýÜüxþDÿ?‘¸ïgŒÿðþÿøˆçºÿÜý&þÛþxÿzβuôÿ.V ÿÿÕÿcÿÛþ(ÿÕÿñÿ”^Ô Jÿtkabber-0.11.1/sounds/default/presence_available.wav0000644000175000017500000000640011066760706022015 0ustar sergeisergeiRIFFø WAVEfmt +"VdataÔ üÿòÿìÿüÿ 06Ôÿ°ÿ¢ÿèÿCT5 ôÿäÿþÿôÿêÿÔÿüÿ&Ôñu¢ÿ5ÿˆÿT®Jäÿ+zÎÆT¨ÿÿ¬þ%ÿÏ·*xuÿÿ5ÿjÿøÿ\ÿáÿÌæ²l¤þ5ý•ýDÿ¦„:ÔÊÿTþ]þ“ϼ¸ÿ þƒþŽÿÚ6Ö¶ýDürýµÊœÚ ý]ŽÊÿþºý+ÿ^ÿïÿ¯æÞºf§ÿìþþ ýÇýºþp„ÊÚ·ÿÔýÖýJþ0ÿpÔÿ*îÿ½‚ÂX’‚ýý5ý´ýà„0²»þ•ýªýªýíÿÒêþêþÿúÿÑ’>êÿ€ýøû˜ýTÿ  a—Eÿ,þ$þŽÿ0ÿ"j‘¾þ™Pÿ#ýü+ýÿ¨îÖÈþ(dÿÀÿÿ¹üPü+ýƒÿ `¶æU,ÿÈûÄüUÿ#ÿbÚÜÿ¤ÿ*ÿºÿÈ–Üý„ûûBüÿš¤B…üýçû¥ü8ýšýÍFç"×^Zþþ,ýüý·þŽl¸´Cÿ‚ÿðÿÉþQþÿ|ÿ…ýJþþÿ&â(­ÿÊüüLü|ý44¨^þþìþ£z|þÜûvû`ü­04€Pÿ(ûûû”ý§>Qtøý”ýùÿÛý;ýèüÿ\.ÊÆÿþfýZüžJ*ÿTýüJRJ8]þäüäùfü&ÿȈêÿôþ4ü¾ÿLý€û@DÇ:ú>ú&þ‹qž48øõ˜öhhûªnx,û\û0ý“Úþ´ø¨ûøþÁ }þ´"¾ù«újÜöþêù<ýý« öúà –ô^ ï;ÿä È¿ûBþ6 ÿ$üÖö~üÎþYþçñ‚úÔd õ~ûÌûýý þÞÔ'E¬«Ðÿšüéü’üòþ¢ÿ§D’Bªÿ°üÂû>ûŠþÎ2Œ#X¬»þ„üÎûtü’üâÿgµGp‹V¿üXúûþÞàûrþÿþìý›ýZýàýÎþ0x9”2Pÿ€ýý8ühü®þ^ÑEü÷þþ\ýœû^ûlý¥þ¸Ð [þ~þpýEü1ûˆü6þÆh ÆoáþRûúûú@ýÚÿK\v 4þý ü"ü|ý-ÿÐÿ¾>¾qF2ÿýëüˆû>ûÿL`l‚|sü’ùiûý.ýHËpƽiÿ¢ý:úºúæýÞü–ÿd Ž÷îý üùQøý­8®’¶ÒþÆú@û§ûPü ÿÝ2Üü·âøÿðü§ûú÷ûpþd\I8ðfýÊù?úêù ühŠ4Æò¢lÿPü,úJûÜü,þjäàî”ÂþÄüCù.øû~ÿ(êL/þLû¦únûâû°þ&Wn7–"þcû†ú¢úDýÜpLfýzúªù^ù®úØÿ++ ʦOþ|ú¨ùüdþMýŠ?.Lÿ ýˆù4ù(ýÿ0ªÐо þ‹ú]û—útû¹ÿp€Ü{Ó’ºÿôû„ûDûôûÝý2²Hp|åý†ùVù ùwü÷3ã\k–‰þFúžøZûBýßþ7b$”D¦Òþ×ü ùÞùöü ÿ BÐ^pÿBüÌú€ùÈùÊýnP_¨}ý^ûYúEûŠüZÿPlËvœþ€úq÷Úö[ú®ÿ¤p†ø”IýÅ÷zø|û‚ûÑýâ|b0ìFüÿÄûîøxú(ülý¸t^¯•”þrý…û÷ölýþþr~°þúúþûPúÕú¦œá¾vºVù;ô2÷*ûÀübV ˜ }¹Žü6ú‰ø†ø,øRÿæœ ›Ñjýjú úJþ¦ýåüø\ÿºýÎè ]Äœùüò®úÿüž# c–ý‡üŸûûúïûDþÎýþžô € üùÖÿ¸8ý§ýÓøúøfðj ºpõ4öjûÔËöÌøvu0 Aÿ ÿiõíñR „9ÂüFýøÿ@6,þœ û²ïªîÊ¢ÿnÿÀÿ¢T<‹†ËÿŽÿÿÖþS˜(öÿ> Wþ°þhž¸xV¾ÿþõýþ>þHÿ"yz®ÿhÿsÿƒý†ý´þ¸ÀÐnÚ]þ´ý8ÿgrPÿàmÂÿñþ(ÿ "ÓÿÜÿÿ"ÿdÿ§ÿ#èÿš{ÌôþÛþ6ÿ´þ¥ÿ0<6â‰ÿêÿFÿ ý þ8ÿ@õüÜ|ðÿÜýGýmþ¤þžÿíÆnƒM‰ÿºýŠþTþCÿŽÿªßÄ>èÿè4þ¢<öÿ–ÿÃÿœÿIÿ0¤&*aÿ¸ÿÿQÿîþ–ÿ. Ìÿ¨(èýîüþÿÊþ¨ÿ@í6TJ\þúýñüCýVùnzPÁRÿŒþØý\þ ÿ ÊÔ,’4ÿ ˜ÿxÿµÿ’Àÿªÿ2ÿ"’Ò6°ÿ_ÿ¸ý2ý©ÿ >؆±¡þwýZýøþzÿ‚kÜ€,Çþ.ý„üjÿ®ÿä8"æþdýlýþþ¾ý,àL:’0…ÿŽÿJÿ  ´ÿ[ÿ!ÿtÿ¤ÿ™–\þàÎþHþáý@ý¸ÿî:ÞÞxˆþqübýîýâýÿx7qvî†þüýxýþX@ ÷·ýRýþ w朠 ÿfÿÀþR Øþ²ÿÇûþgþ@Z²ôdߢü¶ýôþÿýþéTÁX<Íÿ`ý8ü¢ýÆý$¾½Ÿ"tþžúOü0ÿÜÿTÝRRä@ÿôýZýsþdÿ\ÿÚÃìüÿ`ÿ? ÿ“ãþ3þ¹Àÿýmÿ`"’Ú=ÿþý±üØÿQJ Ë úDüÚûþýÿÿ¥;@ÃT&þøü¡ýXÿ7ÿÞAÖfHÿþfþüþéþ4ײèÿ_ÿH‚þ þò‘ÿ˜ÿ;zÿ¾þ® ðh޹ü©ý§þ¿ý ÿpìÇU8þþû ýæý³ýxÿpöÏ¿v/þ&ûü*ÿSþV{ `†Vþý¶þ4nèÿ·-ÿ ÿøþßlýþaNÿ!üÿj»Ì¾ÿÉþ’þRý2ýþÞLà ¾¥þúØùÿXÿ~ÿþÜ`Bdý2ù‚ü:ÿ+.c Vò]þ”ü@ý6ÿ7Ñþöý´ÒLÿû™ƒÿRÒ\ûkÿøBú€úiF+ÿîÑ ¸ýþÜûÑ÷Þlÿ6ùöš4´vûsó&IþÌv²þÈ”ÿÞüxû¬FªvþTÙ$´üøü€šÿ@þÞÿ4x\ûþf¦DþÓýäÑÉýú¢üËо4 :rû‘ùVþuý§úý®u]ú?üIóUü©nþ+ÿùTÞýû ñD÷²ÿjf- ýûåû‰hÝÿ (¬Jÿ˜üTþýÈý,0ÿn:1þ’úN°wþÞÿÒÿJ\ÃüÒúüþÞ[t‚Tkùüqþ“þ þÂþ| <úøüâþRüÔû¼ ^þêû¾tú \ÿjÿÉöN^ð\ø=ù–ͦȠ%ôF·ÿêþÚþÉÿ«£ÿtkabber-0.11.1/sounds/default/connected.wav0000644000175000017500000005655411066760706020172 0ustar sergeisergeiRIFFd]WAVEfmt +"Vdata@]Ìÿÿ¸ÿÆÿÏÿÔÿåÿèÿøÿâÿöÿU ·ÂÖ⺟®t¼ÿªÿ€ÿÿøþðþúþÿGÿ›ÿ ÿnÿÿœþRþ6þ:þ.þþšþ\ÿ·ÿ‚ÿ.ÿhÿòÿ˪vN9Üÿžÿ®ÿ¼ÿÆÿ¶ÿªÿÚÿ|„ ¿ÿ˜ÿœÿ„ÿ’ÿôÿ.kŒ¨äì§Ž‹˜ÔäÊ”DpºÜ ^ŽjÿDÿïÿÌ&ì)Žÿ~þŽü–úZù$ù[ùXùÏùûÌü”þûÿ.†h²2T„¨àòÒ™‘byxøÿ-–ö\êV‡·Í’FæµHé¬>oÉÆ…>öþŠýåüæü4ü¬ú’ø<ö’óáïZíXî>ôdýÝ à:0þ ý~þ¾°¯Ê{˜þr’¶¢ÿ0þrþÿäþDýbûdú×ú1üxýšÿTϼ¤ä°ÂñFv°R âÿ.ü,øÝóÙïíRìpí„ïñ(óÀódóôâ÷‡þdC ¬ < , â Æ2¦þ¶þ»ÿ úVÐY^‚öˆÿJþÖýþ¤ýpüfûœûÓüþLlÿýýÜü¢üþàþ¼ } Û Á |  â ; LŠ<ý¶÷ßñŠìèŽä^ãöäè¬ëÀî?ò´øî_@ Z"~NȽ ê6">"à˜þçûúÀùêù³ù˜ùÕù#ú?û ýFÿîÀÓ`.d¼¼’:r¾ÿ†ÿFƒBV¨ ¤  V öê=ÿøˆïâæ1àNÝJßDåîr÷„ÿ,àœUîPp°6 < ×  ã  ü Ìk^t1ÿ0ü«ù÷ ôòòñPôcøÆü|” †‰ÜØ](ú@ ° Ø ± ¬uêrö · úýÂóé¦ÝuÒÈÊ Ë™ÔåÞ÷ô”2zf {.Æì 2 ½ f t }è:Hüøkô|ò8ó‚õÌ÷”øø¾ø:üþ° ä~± Úþ{|ñ¥Dÿ<ý ûhúpüWŠh ¦Çn‰ ÍXü.ò9çÞwÙ6ÛŠâ ì÷-* ¬ T ÒêüþølùôýäË „ðªn,¤ ç *r–šÿVüJø³ò­ì2é”êŽðæ÷`ýtœ`@à0Q¯¸] ë ) ò ó 8 Ò ¤ Ì À § ê„úúñrèRÞFÖ$Ó2ÖŽÞúéöt„ Ö¼Nz ¿ Ú { 8 œ D0À¦þTû~ù¹øÞø*úüaýÊü$ù³ôFóŒö\þô>ðѨ B¥þ9ûúÚù‚ù‹øøúxþª &ªäx ¢.ý>óœèüßìÛ|ÝÆâ>é®ð¸øsÿ˜Tãý¾û„ýÂâ~ .4pow&  2 jä¸ÿú´ó¼ëLæŠæFì„óùÛüD¾—³F4HŒ F r Ì  ÒGP  T êþÿÆù¾ñ´çŽÜîÔ²ÔœÛåëìÍò–ù6 ~æ|” X  hÆ\˜Òýúùö²ó¡ô½øsýDÿpü<÷šô´÷ªÿe´à{Ë TçýDýÄýbýBûêøVøÇùýˆ Ä×ÎŠÉ DtýNôøëKç|çMêìDì>ë:ìÌð˜öŠú©üØþdzœ îe^\ðK2ö ˜ ø r¨Þþ1útórë‘æÁç®í¤ôöù þ¬ ±¹)ØäŽ × f ä › ^ô >   t •8@þÚ÷&ï~åÞ†Ü1âtëvóŽ÷±÷÷|ùnÿú 蘦~âG ¤<»cü:ø2ö–ööøwüÜÿ*€þFù¼õf÷þI…dí ¤Êþfý{üû<ù<÷±örùèþ6ø "ëb L À¾üjôÔíþëî†ðÂïhëRæ åPéðG÷HüüÿHt Î ¹4ßvâ  ’¾|ÂþÏùvóî-ìÜîqô?ù,ûû@ü†þ¾j¢´n ‹ ’ Œ V h Þ  , ê ¬ .\Þèÿ*úBò„è+ßVÛâßNê{ôàùFùøôÄñ¶óZû,*ÑÂ}<ž r öËJ¾ÿ0ü¢ø[öVõ~öpù‚üfý¡û®øøþæ xä¾ ÄÚ–ÿ¬þjþ¿ýŠürú&ø0÷Dù•ýXh ö <¦6$R ú^ü²õò$óÖõ†÷ö$ñzé¢â•ßâ4ê/õþÿšøF-Œ¨¾Â„p Ó ;iêÿ„úôÖíXë¥ì®ñx÷Xûèüîý¶þ’z[´n Ä  Ä ž à  Y û z HDîÚÿXüCöRî¨æ&änéŒóÍûRÿ(þtøâð´ìŽïÃøÐ¢.À(˜ A <¶Rý\ùˆölöyøÆû$þ þTûÊù üòb ©Î ( ªføÿúþ²þëý0üüù¸÷àö$øðû^Š `îÝH Ü ÂŒýH÷ õN÷dú½ûÚøòzé©áöÜkÞBçŒóïþùÄ ÆF?+˜þ\[¸ Ò Ú ôß/ýŠöâðHîÆïnôúÔýÊþ#ýÒûøûòý½ B " Ê j ä *  Ð + -ÕˆÌiáý´ø òJêÃä^å¸ìªöŠþĦÿòøñúë|ìØó 4 {>nH° * ÁCÿ ü"ùñöáöø³úÅûû~ù*úTþÊê ½¸j, ˆ4êÿ‡ÿ6xJÿ.ýìú@ù¤ø´ù8ýVÞ ¾ Š ž n žÍšýúúúþø`#û¼òéàZÚ·Ú¦áÜíÀû\>žš#|4ùå . š €®hýìö~ð í„î¥óBùüúüüœû~ütþXÕ{ ¨ È [ Ú Š ø  ÁtØ–¿ÿ6ü¼÷Mò`ìÁèvêÉñ­ûD®–:ûLò‘ë êzï¦úÁÁê.ìÅ t $n¥þDüÚù¢÷Öö øAú²ûŒû†ú0û$ÿ¬Î {b­ è%'ÿuþÿœÿëþ<ý÷úºø6÷h÷÷ùôþÇn ò ’ À à äÀ@þû´ú6ýŠï…ÿQù´ðòæfÞªÚðÝçdó÷ÿZ , ˆ¤‚ôì Ë V ¬ ÜxÈü¹ö­ñð€ò€÷îûöýqý¶ûUúú©ü|<š  ˜ ) O € ä T –—}p²4Bþ~úˆõâï³ê†è—ëxóêüß¾²\üÂôwîJìðàø¾ zn 0½ ü üýyû8ù„÷âö½÷xùjúVú–ú ý <& ‚ô™ 6 $d¤ÿæÿÈ  äýUû~ùÕøÚùÔü\Å – <  I¦ÿý®üvþ:¢¢þööbí@ähÝŠÛMàDê^ö¾ šæ¬˜¦ ’ 3 ² y ¼¬ºþæøCó^ðøñNöûðýØýàû|ú¦úmüTÿ2 _ p 9 ª ë • ^ y$éa ÿxû÷Jò6î¦ëªì\òû"9Ä2ùêñí?îˆôgþL<,Üê ?˜ý$û6ù÷$÷Ã÷ñøIúÌútúûˆÿ;‚ ü ·  ÊèæÿöÿÿwýBûÆø ÷÷bùiýHÖÐ @ îÒ´]ìýýþÚqÄÿŸ÷¶îÆæ@áçß¶ãìØö» z¯øöþ x º n f ®"¿`ý|øUô¨ò°ôùåü(þâüšú*ù‚ùæûªÿ<û Þ ½ ¡ ¾ZÄæPâýšùõªð/í0ìËîèôÿüöB>QDúÒóðxð6õúü4ª ¦Å“  ¶ý"û°ù†øøZøÖø~ù&úFûÅý8ªô À . ì Œ ˆfPlþ,üúùVø<øsú¼þ²Œ— œ ÞµÈþýHýnÿ5"2ºüJõ‘íÊæ’âFâWæ%î@øú8 à¨6ñ â * Z " ¡o<ûøö‹ôüôã÷ˆû þDþ‚ülú†ùƒúwý€œ¢ I Ø  aàƒ,¢ÞŽu°ÿEüý÷Ióï”ìFí±ñüø@¾ ú¨ýûðõAòpòzöâüÄ  æ  yõ]ÿtûªø¸öÁõÄõ¤ödøRúü þ( ö n y ž†ô‚éÿ~ÿxþ¼ü±úžøR÷±÷úrþc<üf£òþiüõû²ýÜ"¶Šþ¼øœò íHé7è}êÝïz÷†" PA „  ÆúÅbÖý:úÆ÷÷~ø0ûœý¾þ(þIü:úùàùàüù¦ þ „ ÀÚ˜9š¦r¶>ÿóû¬÷<óüïïöðjõ“ûÈëÌRnÿÿùÑõNôïõbúx¡h Æ ¾ É ‚šxªü˜ù\÷Eö9ö&÷òøJûöýȬtª K Œ *zØni»ü‚þpü*ú-øI÷þ÷vú:þørc&2\ŒÿÆÿdU!:Nþ‰û3ø®ôÆñ3ð‚ðÔò3÷5ý_DO d Þ T ”î|S,ÌBÖþÉý"ýðüãüsü–ûlúuùKùdúúütØ`††Ç^<*êk¿œëÿÄýðú¼÷îôAóó¸ô;øÎüÚì`¶ÓzÿúþƒÿÑhÝÒ+Ø×@çÿÖüˆù®ö×ôbôÃõêøý N–»ø×vðfÓ .0ÓÿTþZü"úHø=÷6÷®øžûAÿžìÖZê]CÔˆh0þøûÂù»÷öEõ³õW÷&úþp4Àà „ ül(Xåÿ¬ÿµÿÊÿµÿŒÿFÿxþýCûÞùTùýùãû˜þnÜ’E?iÊp8Ö‹=öÿSþZü"úü÷böÆõyösøNûWþØ€6¦4*”À²<Jß ÿìü·úÜøä÷.ø¼ù=ü:ÿ :—$Œújâ^àlû‚ÕÆÿPþ~üœú ù‚øùáúƒýný¸tV•hæôÿAÿÁþjþ.þþÓýQýbüûÞùùù>úVü ÿñ‚R*\*²$³tÿtþ¾ýWýPý ýþ‚þºþÀþ¨þþ±þ.ÿüÿ&òr¥ƒ7C;0:ÿhþÐý{ýQý0ýøü²ürüNünüäüœýxþiÿ`Bú|ÇÊ€tÎ,’ÿÿÀþ}þ:þêý’ýFýý(ý”ýVþNÿfŽª¢bÖê”î çÐÿàþ0þºýlý;ý(ý0ýVý§ý0þçþªÿd–N|z6Ä0|´ÿæþ)þšý<ýýäüæüý^ýÕý~þLÿ ê¬PÐ$>¶"q¦Øÿ ÿ—þOþ;þLþhþþÆþÿPÿ¦ÿ  ”ï8x¨º‘7¼V€ÿ²þ þ”ýNý ýÿüöüýaýØývþ*ÿÛÿ€ |Ò#Û† xÙÿBÿÂþZþ þÐý¨ý¢ýÑý>þâþ°ÿ–p(³ ;7¥%”ðD˜ÿúþzþþâýËýÒýþýRþÒþqÿÄO­Ô̦f±Iâÿxÿÿ”þ%þÌýŒýnýqý˜ýäýRþÞþ~ÿ$ÆTºëêÈ’Lþ«^Öÿ“ÿPÿÿíþØþ×þêþÿRÿ¨ÿˆúUŽ Œd4Úµ“h,Úÿtÿÿ¢þIþþØýÆýÕý þlþóþÿ.³;<!÷Șd,ëÿ¢ÿSÿ ÿÐþ¢þþlþgþ|þ´þÿšÿ8ÔX·îóРe Îq œÿ0ÿÎþzþ8þþþ#þmþáþvÿ¸8ЬŸf¤2ÈÿlÿÿàþªþþfþVþTþ^þxþ¨þóþZÿÚÿjûvÈæÐŠ$¶Möÿ²ÿ„ÿbÿHÿ8ÿ0ÿ2ÿ<ÿNÿeÿ†ÿ²ÿòÿF­k™œv-ÐnÆÿ‹ÿ\ÿ1ÿÿâþÈþ¾þ¾þÄþÐþäþÿ:ÿ„ÿàÿD¤ìôÀ†Jæÿ¼ÿ–ÿrÿPÿ5ÿ"ÿÿÿ$ÿ8ÿZÿ’ÿäÿJ¼(¹ÌºˆBî˜F÷ÿ®ÿkÿ2ÿÿîþäþëþÿ&ÿZÿ˜ÿáÿ3†Ð!ô¶jÎÿŽÿZÿ.ÿ ÿîþÜþÔþÜþñþÿ2ÿZÿŒÿÊÿf´ø&6(þÄ„JôÿÓÿ´ÿœÿŒÿ†ÿ‹ÿ™ÿ¬ÿÀÿÔÿíÿ:s®ãþبq=âÿµÿ†ÿYÿ2ÿÿ ÿÿÿÿ1ÿNÿzÿ¶ÿüÿD†µÌȬ„T$øÿÐÿªÿ†ÿjÿVÿPÿVÿgÿÿ›ÿºÿàÿIŒÎ,8, ݦj2ýÿÌÿ ÿ{ÿbÿVÿYÿhÿ|ÿ”ÿ®ÿÎÿòÿKxžµ·¢zHÜÿ«ÿ‚ÿbÿHÿ7ÿ0ÿ4ÿDÿ^ÿÿ¡ÿÂÿäÿ0^бËÓÆ¨€R(ãÿÊÿµÿ¥ÿžÿ¤ÿ¸ÿÓÿñÿ $8I\p„–žšˆjG$çÿËÿ°ÿ–ÿ€ÿtÿpÿyÿŒÿ¤ÿ¼ÿÎÿÜÿéÿøÿ "4?B>5( üÿìÿÜÿÊÿºÿ²ÿ²ÿºÿÉÿÛÿìÿúÿ 4Ol„–šŒw\>ùÿÙÿ¾ÿ¬ÿ¤ÿ«ÿ¼ÿÐÿäÿòÿþÿ )<Qaf^K1öÿÚÿºÿ™ÿ}ÿjÿaÿgÿ€ÿ¨ÿÒÿúÿ5IZlz‚†~gF%Þÿºÿœÿ„ÿrÿjÿsÿ–ÿÝÿE°(-öÊœn?äÿ²ÿ†ÿeÿNÿ@ÿ<ÿFÿ\ÿ€ÿ¸ÿ[´.6 ð¬^Úÿªÿ€ÿ]ÿAÿ.ÿ*ÿ3ÿFÿ^ÿ~ÿ¤ÿÑÿ P ì*OV@Ö”Sæÿ»ÿ˜ÿÿuÿrÿxÿ†ÿ™ÿªÿ¾ÿÝÿ J’Ù.4ð¶z=Ïÿ£ÿ€ÿdÿRÿHÿHÿOÿ^ÿnÿ~ÿ”ÿ¼ÿôÿ:„Èõâ¶„T(Üÿ¼ÿŸÿˆÿxÿrÿoÿpÿzÿÿ²ÿáÿ^¢à$Ú«zM ôÿÆÿœÿyÿbÿXÿWÿZÿcÿsÿŒÿ°ÿÞÿZ”¾ÖÙ̱‰X(úÿÏÿ¤ÿ|ÿ\ÿFÿ<ÿ:ÿ@ÿNÿhÿŠÿ´ÿäÿ_ÌçìáȤzLðÿÆÿŸÿÿjÿaÿcÿoÿ€ÿ”ÿ®ÿÏÿøÿ([ˆª½Áµ›vJôÿÌÿ¨ÿˆÿqÿcÿ`ÿeÿoÿ~ÿÿ¦ÿÀÿâÿ0Vt†‡zaB$ ïÿÖÿ¿ÿ¬ÿœÿ•ÿ–ÿžÿªÿºÿÊÿÚÿîÿ ?\s€vaG*öÿÞÿÈÿµÿ¨ÿ¢ÿ¤ÿ¬ÿ¹ÿÇÿÔÿâÿðÿ.FYddXD( ñÿØÿÂÿ®ÿžÿ•ÿ”ÿšÿ¦ÿ¶ÿÇÿØÿéÿúÿ$<VjtsgR8ëÿÖÿÄÿµÿ¬ÿªÿ®ÿ·ÿÄÿÓÿâÿðÿÿÿ$:QdprhW?$ ñÿÙÿÄÿ±ÿ¤ÿœÿ›ÿ ÿªÿ·ÿÅÿÔÿäÿ÷ÿ %>SbgaR=$ øÿãÿÐÿÀÿ´ÿ­ÿ¬ÿ°ÿ¸ÿÄÿÒÿàÿïÿ,DXeicVB.óÿâÿÒÿÃÿºÿ¶ÿ¸ÿ¿ÿËÿØÿäÿñÿþÿ0@JLG:*ôÿæÿÙÿÌÿÂÿ¼ÿ¹ÿ¼ÿÄÿÐÿÜÿéÿõÿ.<GJE:, þÿòÿèÿÞÿÖÿÐÿÎÿÐÿ×ÿáÿíÿøÿ&2>FHC8(øÿíÿâÿØÿÐÿÊÿÈÿÌÿÔÿßÿêÿôÿýÿ "-6:80$üÿñÿçÿÞÿÖÿÑÿÐÿÔÿÜÿçÿòÿüÿ &2<BB<1#úÿîÿãÿÚÿÔÿÒÿÖÿÞÿêÿõÿÿÿ (0660&õÿéÿÝÿÔÿÍÿÌÿÐÿÚÿåÿòÿüÿ þÿþÿÿÿþÿýÿýÿüÿüÿüÿüÿüÿüÿþÿþÿýÿýÿþÿÿÿþÿýÿüÿýÿþÿüÿùÿøÿúÿýÿþÿÿÿþÿûÿúÿûÿþÿÿÿÿÿþÿüÿ÷ÿôÿòÿòÿóÿôÿôÿòÿðÿðÿòÿòÿòÿôÿõÿõÿôÿôÿóÿòÿôÿùÿüÿúÿöÿôÿòÿòÿ÷ÿüÿüÿúÿöÿòÿîÿïÿöÿþÿýÿúÿúÿ&*'#&.4,Óÿ‡ÿFÿ,ÿCÿÿöÿ^ ²›k6øÿèÿÕÿ¼ÿ¡ÿ‚ÿaÿAÿ&ÿÿÿLÿ¨ÿŠÜþì¶t7 ôÿóÿøÿüÿ BblJöÿˆÿ(ÿøþÿGÿ´ÿ*ÖøðÈ•d.îÿ¬ÿnÿ>ÿ&ÿ+ÿ=ÿNÿfÿŒÿ½ÿêÿ  &=XtŒ—…Z&òÿÒÿÊÿ×ÿêÿèÿàÿàÿêÿ27' 6><0"ÿÿâÿÂÿ°ÿºÿÐÿìÿ0<6þÿÜÿÊÿÆÿÅÿÈÿÔÿîÿ üÿÚÿ°ÿŒÿ~ÿ“ÿÂÿôÿ240NTF4 ÖÿÂÿÓÿòÿ8<".<6Áÿ—ÿ”ÿ¼ÿöÿJ‚z2Êÿ„ÿÿ°ÿðÿ0h{`-íÿÒÿàÿ&H ðÿ·ÿtÿNÿaÿŒÿžÿÄÿîÿáÿ¿ÿŠÿ²ÿôÿ(ýÿÕÿØÿÖÿ¸ÿÿdÿ ÿÿ(ÿLÿnÿhÿ™ÿÀÿÂÿÔÿLl¨èáÆ–Ž´­¤x-Öÿ¤ÿwÿKÿBÿ-ÿ@ÿuÿÿÑÿ&öÿ¶ÿxÿVÿLÿ€ÿ´ÿºÿºÿ¢ÿÈÿÔÿxÿ5ÿ¾þ.þEþuþ¯þÿ}ÿ¤úÜ»”z£Ê°r´ÿjÿ!ÿÿ@ÿTÿÿÿÿ:ÿÄÿ_“SÜê ôÞ•Åÿ ÿ¼þ‰þtþ þªþ”þhþ*þ‹þdÿ|¢’ÂçÀ¢b¶ÿ ÿ|þþðýÁýžýŽý:ýýbýþ×þÛÿ,8ÌÚ›jú‚|pN6ž"¥ÿÿ’þ:þSþÐþ_ÿ/<A3ȺJðŒ.Ⱦíÿ˜ÿÿrþNýü:û^ú®ùÈø+øœøÌù—û®ý(ZÙl§øV ep4Íúÿ8ÿßþšþHþXþ_ÿ´rlˆ<ôœDøèŽHðâL’L&ÞŠ^úÑ6ËþŸú÷Öó0ñþîþìíÁð_öÏü D‡üë9Ì;¬êy * ^ °ºöŠêŠÿDþhüËù÷£ôìò¿òêôÄø+þ‹ˆ–DÜ^`6n è ¨ ` ô r(Óþ†ûhøDõ4òCï2ìpé|ç$çÎéÎî¸ô»ûúZ š ~ ÖÊÅ«RÒÖhX`ª¦0ðÿ4{ÀxÔÿÏýLûõøÁ÷§øfûùþãt@„1¢ÿÒýÖüüúüQ¨h ì † @ F ¼¬þvúzödò^îEë<éÌçZç é}î;ömýüùOilþn * Œ PR h ˆ22’ØÀÏÿ#ý.ù˜ó®í®é~éÜí9õýýlš Ü 4 <»*’ú j ôÐ  "¡ü$õ ìåHá8ájã%æäè”íÀôªüxj —\r «BZéàÑÖÿCþVýJýþ>Iž[è:àþÁú÷4öòùÔÔ „ 8 žôú¾öHõhöÎøjüÕ¤ý m»*&' `¸üó¾èNßû×ðÕ¦Û6çqõWÜ 8 ôŽÒü®ùøúÐÿ¦» ÊÎ~A]‚P Ù ÛþFËþ†úzõ1ï è°ã`ãäèjò[ý~ 0™ „ æq^6^î ö <ÄhRptV ð¬÷ î`ädÛÕÒÒ4×ã`ô<j’*Äq2 ¢Éfþîè! þ°ü9þ&àÐÊlú¸ÚüùÔõœóXôùazm Þ õ"ŠúDô$ðdðNõ2ýþ; ¼²î<ž´’xBÖþróçÆÛ¢Ó‡ÏlÐÉ×EätòÔþ9 ´ l ” ì ê “ ‹ ¤ct|J: , T*:úôöíè¶ãDáÆâÐê˜÷¼Úûþœ Ä,>ýîƒn  ’ f Ë ‚  Ž:Nú~óÇí­è˜âßÛq×ÒÙ™ã—ñr ;ðj‚… †bƘN(ÖüþühúûúþÆ " 3“ÆþøˆñNîÐñBû´hûÊn ÕÿIùÛôÊòªò?ô$÷¶ûâ Z(¶ÆT PÿÞõÀévܚҶп×DäòNý®6w£ÿfüÍü –Û ¨Øz D ˆ Û Ý NÈlúòŒéžàŒÙÙáÈï‚× x10g¸èÁÛƒÚ 2 X‡T: ` ¨ Šðôþ±ùäôdðŽë*å*ÝÀÕ6ÓïØúæÆù² ,¢'R7 –Ø~±¦Œüÿÿrà 6º Ì öQûéõ‚ñ[ïæñDùÐAÌ ~ `ä#ùòÙïÑñu÷Nÿ¢šR±@ºæÔj I¹úsðhä Ø„ÏŽÎòÔà í”ù ˜ ­`p Å R è * ? îä,`Ê8 Æ’qÿpùòéèà!Û¼ÜHæLôêÜИ$ L Áˆ® æ j €  œtþûÒ÷²ôîðpìðçFäŽã€ætìÈó„û™ ƒrt.´ jÂ÷þPýûšøöö©÷çú.ê  Ê  >çþˆúøjùðûGÿ~ ~¢æÿ°û+÷†óÛñâò÷þã° ŒmrŽ ”tÖþ¢üãù®ö/óLïúëJê‹êÃì=ð^ôù þÝV, Ì Ôsù € áÚ˜ò¿ç– /ÿfûV÷kóLðjïoñ”õKûnŽî - ¸ 4 äù‚|nŸÜưvW¯ÿýÌúÞø$÷õþòVññ¬ò„õCùŒý•¼Ôªzð®À¼žÿÈþ‚þüþôÿ 9ZAó4jS“ÿ(ýÐûÑûæü€þxS`ÓxnþˆüDûû$üÚýýÿCˆ°v€ „ …· jüøôBñðgðNò,õyø±ûnþ¶t¡ˆJ²ä@š€(¬zŸŠDÿ+þTý\ü4ûúùsøvøDùûfýìjJ8T½rR¸†DíÿÂÿ­ÿ`ÿ¹þ½ý üªûûÂúoúú5ú°ú…ûØüHþ²ÿŒ¬:(znnv”ÿøþŒþFþþ(þþFÿ–0¾#eЈð\ÿþý¨üéü†ý.þÈþ,ÿ@ÿÿÿÿ/ÿtÿ 'ZL”d™ ªþ<üÞùÊ÷&ö8õNõGöæ÷þù‚üBÿ¦h¦VŽR¸Ä’.’‚(Þ80ÿþìüûû`ûjû&üpý ÿÔ ç¦Ö‹HÖZò¶&0"ÿtþ þfý„üèûàûüü˜ûpû7ü¶ý(ÿ*àd²õîhâ«{ÿnÿÛÿ‚úó LDz‚ûÿÿ†þ¨þÿÿÙþˆþWþSþ˜þ!ÿ¨ÿ8âŸø ,n‚å“þþ8þˆý²ü¡ûlúyùBùáù:ûOýºÿ£’ ÷VÄÜ®˜n2é€Ârÿƒý–û1úRùðø4ù úDûæüÿ&?Ž|š²”Ì#¨öúþ6ýüxû†ûüðü0þ´ÿ"¶×Q˜Û42ÿ¸ýgü¢ûKû,ûDûÐûVüµüïüÙü„ü‹ü,ýGþšÿVôgÆöŒf*⺄0”þ³ü4ûúJù¢ø²øÞùüÌþÄR6"D³Ê²Í=И¸ü0öVvf9ÿ¬ýÊû±ù øxöàôôóÇóôêöìù0ýÓÿ¡Pìàüÿž òFNÍþrtÑô–•¦þzû–øÈöâöúø ûLþñ“O»è(†,¼È : `Þ–âü&ùtõ òîŠéæ§äUæ<ì˜õ˜ÿÛÈ 3 ¢ ùâÜ ¯Ç „  â œ Ls‡d6ÿ‹üÑù”öØò6îÂëŠíŒóBüö¾ ´ ³ $ Ê @ 2£Ú¬SrðÄÌ|Üþºüù>ô0ïüêÙçŽæÆçÌê×î0ó¬ùE ð^îý > ìôŠ@ÀöJxHý”ûìûÖþÂ"pH únµüýÿù°öˆôÇôFøWÿ~ª ë ‚ AÅ0ûÌöÎõ¨ø™ýŠZ™ê\XÚmþ€ùô ïÿëvëîšò[ö÷ìõôô˜õ‘øý¼¶ DÞa h š ´ „ - r v È šR>ø!þàú÷|òxîÄë$ê½êtïøÒ ´ ò[ ‚ Ô ú˜Ì*ûüü÷×òîµé…åÑá¬ßá·æTðdú¾”Å æ }³®ž@ s È.úÿ ÿùþÈÿbëÏ"¾`C²<üöüï?íšð8ùlœ ›QF  þ£û¬üæš¹ ï?í c *(ûCö8òâîpëæèùçléÞìêïGò^öfü <hÞÞ¶¹ å Þ+\ê ° Þ ¸  @ 2Á>üÝ÷]ó2î†ç<á ßSä ñOþR¾·m  . X Õ’ßû äˆÿ7ö½ìnäýÞdÝÈÞèá~æÐí?÷aþÈèÿ?Ó ô[žÌ F‘¥ÿLüúüøMù¨ûlÿgâÝ ˜ — 5 R 7ØßåþÂùÿòüì¦ëÁït÷Žÿý¨ Üü<ù<ùôýÀxÿ\ê@ €Êú<óìfæóâ"ã׿!í¥òoô¤ñ>îî¶òêúp˜ `ÄFþŒ Ê x È ± Ü T g ¨ Sïýú+ödò”îëŠè¶çëê°ò²ü8— J©¨ F Â é ’œ€¼P †þŒõ¶ë<â:Ú¹Õ!ÖìÚHâkê>ó±ú¨ÿà $0¨ÌŒ† š}ζÆxhþXü0ü¢þð¤ J a x ßx,þùÜòhî¾îõÅýaš™Üü4øÎôØõ‚û¨&Jâ%", â¬û(ñhçÂß~Û|ÛÔÞHäHé`ì4ïnóÖùWè× ( ":z   º @2n^ïù"  ›ŽÿYü‡ùföëò*ïVìxêÌèyèôìýöê¶ °ž“  Sî$ ‹ qx¤€² f$ý,öØðéëÀærâ­à,âÄåÖêFñýöLûúÿ–‡ €Ç(åî ¤öÿpüûPû0ýz2Œ @ §Ê ø ÎÙ¦€z2ÿÔùîó¶îðìÖï.ö®ü’\ÄüÒø<÷JøhýV5 @\úžLN èýòœçÀÞj؃՘ÕÉØt߀èXòžûŠÄ ‰¡r8\J   > æbüdS ¼ÓTÿúŽõwòïÏë"éÒçéîí´öÿö ¦ð< * S\~îý †´ø0¢ Nÿ(ûŒõÐðì<çiâ§ÞËÜRܪÞ6çÃô`\ðÔʼ ü‘ÿ·ÿ8ÿþþ`ÿŠRd \b~´ `Œ8¾IþŽúõÊïVìKî$õrý€IfþaùÐõîõhúmö ŒmÑ\ú(z´á®÷Bîxä¾ÛÆÕüÒ¸Ñ:ÓêÚÜæÊôt’ êÓìä¶ ¢  n š úZåsP ' ÈyjýøóZï¶íbí’íRí;î¾ñ¸øb °ðhO òÔm_…Z f ô ö Ñ ¢*VÀþTûönïçžÞrÙ[ØÜáåõV¶B ˆ Þÿ üùù;ùúèüÊþ— 0jšU Ž ¸^Âÿ`ýTúxõ`ðfî’ðÑõ5ü¯jÔþXúîöÿõxøäýj˜ ÔHÌ~Èšvàš R°ÿ öýëßÈÒ"ÊfÅÇ@Ñ4äú DrQ,h, ÄT  ¬(Ðçuˆ @ ÞTâüþö=ñ^ì&é8è€èñéÚîÌ÷«ž ¨1Nv Þ²ƒÜ6‚¸ © â Å ªà¶â ÿ¸þHýxú´ôhìæâÈÙïÒ’Ò<Û­ì->ì€H\þý½û:üHýÔþÐ"¬A ÌÞ\ ˆý\ùƒôAïÊëÜìÖòúúV}@VüÚ÷¼õ=÷`ü%î š88|ªà Ä<‹ø¾î äGÙÏ–ÆÜÈâ×”ímL³CF d ~Ö ö 7Rü ` ” ÈPŸtýú÷óLïAí¬ìåì³íŒðbö’þå? °á àà*úè,èâh^à2ŠXQš"ú,ï ãØÐÝÎ{×øèoþºÚþP˜ ÿ&þôùˆømùWüüÿ¢à. …JKè Ý ôÞÿ4û öÏðÚìnìæð¸ø¼ÿÞ€øü øõõ£øLÿzÉžXÖž™VájØ X$ûùð4叨fÌÂf¾ÆRÙýòX F–^œŠ Å»Ä @bnqð 0 h vÒn8þnùZôð<í¨ëëRë`îZõÿë ‚x ÎnFÌ«  å8€<Ø.ÞÐ>ü¬ó–èîÜëÒšÎ4Ô@äZú¼ÖpßÁübúíúý2ˆF6 ¶Ì>® € ( tJþ­ùÇô¦ï¯ìîàóšû:Z¨ÿžû†ø ÷ˆùvþOÜ ¸`DŒú#©î  .hüßòŽçÛ ÎäÃ,¿ÀįÕ#în’bÆ6Ä ¹Q@ ´ØúŠ2 ¼ ™¶4ÊŒü4ølôƒñ³ïÎî²îvï òÀ÷<ÞòíJÈ ÌLþÊíN€Ur:Øå ³¶Ò€¦ý~ôúèâÜ‚ÒXÎÒÔ·åâû×hÄå;þXùê÷Šùäü,ŠÝ à \ò( – r pTCþù~óNîìÀîRõzüˆ.üü ù¬ö"÷ŸúÝ%Ҟ㦲&ä@ø4 ;Ný§ôÅéRÝ8ÐpÄ¢¾­ÃÞÔîH¸ зfê äx ¶ »N&(Œ ¥*ð"Žý·ù'ö:ózñŠððŽï6ðôû×t >HÌ öô, 2SüÀ!R®úœx_ªÜöþgö#ëzßRÕöÏÂÓ©á&öY ‹ \îRŠºú6øbùÈür- ¾ ¶D! 2 ¼®Ðþoú˜õˆðLí îŒòìøðýŽÿAþœûåù.úÕü¦¯ nÞ®"Æ’Í(_( êÒûdó¿èŽÜÐ ÅÑ¿ûÄÜÕVî‚êà"ô* ¬ô? è 8€ôf ¥ 䶬ÿìûDøšõô–óvóó:òò\õüû$K ¶  v4¬œìõWLúÿ(ÜðÖnÖLÿJöë‚ßÖÕóСÔ*âŽöÖ ÷S‘^þÆ÷Põ2÷šûXè ×Äž3a Ì p ¹¼ÜÛÿûõðìöëÔïönûnýxüvú—ùÆúåý Õš àÈØÕ²"åjè× ã÷ü…ôê€ÞtÒÒÇ$ÂŒÅ8ÔmëΧœ‡ Ü5B™ ¼Çðæ  4KSEÿ@üHù¢öõ¤ôäô õ;ôóüó0ø.ÿÄ9 ~¦ › Ú ZÔ’¸ìŠè"@б`Eò¾þnö ìRáÅתҨÕüáÚôj2™ŽØxÿ$ù“öHøÊü9œ8 h’|l³ ¾ \JêÿlûQö ñøì@ì]ïäôúÈüsýAýýáþt&, ì µ2Fî–´ª¢u hÐúÀòäè·ÝøÑjÇ"‰ÆÖŸíù¾È–ˆ‹ ¤Ö< < ÆX & î1‡ýŠú$øÖötöÈö~÷\÷ õ°ó@ô†øÀÿ+#   ® 0vZpúaÔ~¼·ŒÊžÖÎÿÀö¬ìÛámØžÓ`ÖâôÝxÀŸÔpÚý¢öÎóöNû¢¢D þB› 6 ( 2  '6x6ü‘÷.ò'íDëíZñyöúbûÏû¾ü’þ&“5 à¬J@Í2|, zÒÔûhóXéÞ¬Ò·ÈÎÃöÇ‹Öêì¶×Àî Î6 ~=h ‚‰…þ ‚ ñUÿSü`ùÂö‘õöx÷æøùr÷MõGõø†þNå Û È f ² øRî(š²8p+.üA HMUÿÐöêìtâjÙæÔµ×ã~ôgɇì ~ýH÷Rõ0øôýa .Ú8šá „ t F f‚ÏTü3÷tñ‰ìë{í’òè÷ZûæüêýJÿ<¢^^ N ÚN9aþð ¦Å5ú8ò\èLÝÒ\ÈîÃÉËØ¤ï5âüÄŒI F¡ Å FìšÈ v>üºþÉûù÷Èöú÷Êù"ûûÌøàõJõwø þ  l È T ÚJò'žúhÿbÿr€ÑE ô à Jäÿ÷0í ãaÚ ÕÒ×JâóÖÕdñöýüXö%ô÷"ýÈŒ Š „.Æ œ b ¦2‚ÿŽûL÷VòÓíâëüìtðÝôŽø ûúüôþ6­b D h \V–€¾ò„ï ~ìúzò0è¸ÜžÑÐÈ ÅFËPÚ$ðÔ¾j°fÜb*0†Î ìØ¢ ߦnþþÔû(ù`÷*÷Hø´ùšúlújøÈõPõ”ø¾þ£Ö Ô î Ž „RTޮ͜äþHÿ^nø  C b N‘ÿˆö\ì~âøÙeÕÈ×Hâ ó¨J$&t nÊûöõþôù® âø¦j ÿ  B òtÙTü<÷Zñ?ìRêhìñuöÚúéý&X€Ÿt þ ® ˆµép„‡ ôº&ú\ò´èn݈ÒîÉæÆXÌÛÜðz*rn\–¯ ‚&× ní: T IPHõýbû”ù´ø)ù¸ú:üèü4üˆùö&öŠù`ÿüü   T ’Œ4ÿÿÿ Rÿþôÿ؆{ ¶vÓ +¦÷&î¼äÜíÖJØ4áðÈÈŠ` ®"üUöõÇøèÿd ¸œ7‚ B & ¾Œ‹»ÿoû–öñìêìðõkùÕüœÿ6_Ö‚† 8 Ä {ÒZ(kìò ævúØòGéÞ$ÓÖÊVÈÞÍ Ü¼ðÄ_–š²à <Âk röH Ž `÷˜býúúŽùHù¯ùâúLüÎü}ûœøõ>õFùÓÿ“K < b v ÆPÿÀþjÿ 8Šÿ´þ½ÿ¬â o» X¸÷Üí ä`Û&Ö×&àÍï\¥:À† ¦ÔúJõàôÔùÜ} ¸’Ô=v * ~ ¼ N âËõÿvûAö¼ðêëûéøëð.öûóþ¼è”š}Ö|  ¯ Þ„M”þ  ähú£ò.é|Þ ÔæË ÉÎ ÜëðòP±è2²Ü À&¬Œ (\ à ûhøü’úºùRúÊûxý¸þÃþÊüFùÐõ6õöøÔÿ Š d r ƒÐ`ÿ„þ³þìþÆþIþBþ[÷L ¨ð@* >CùÀï®åŠÜçÖÌ×Uà ïkHŒh DûøõöLûˆf n ®^qœ l Ø ~ @ ¼6ÿâúFöñð|ìëúì=ñ<ö¶úŒþð¬f¢ ˆ ù – ´`bÈrXb• >üôbê•ßùÔ¨ÌÖÉŠÏëÝFòj[ž©¤¹t ‡sî z– Ç Úäpïü¤úPúQûáüMþúþ"þVû^÷KôÐôÔùlvß ú : r \\þ0þÔþ4ÿÿ’þ–þ–Œ :R] ‘”ù>ðæEÜ¥ÕÀÕœÝìný¼  . ŽYûö÷ÌüZ* Xì¥Ñ  Ú ) ö ödNœýùô|îxêûé7íºò\ø4ýT‡PܧRó ° X 6ž Ææ—z Öþƒú óÄé€ß×ÕVΨ˰нÝìð€( ìÎ óàÔ â < - yÍÐ^ÿBüªú ûÆüöþ7 hþ*ûáö*ôZõîúÁ” C r í  Ëëýtüòüæý:þÑýFý2þ’(H ÝJh> ÍhúëñbèÖÞ8Ø®×tÞì„ü) ¸&R Túxöò÷IþŸˆüˆJ 3 0  4 ‚ 'ìý¸÷9ò:í$êbê.îÜó˜ùXþ Ú~Ñpäl0 ± * ,ض½ú´[ è$=ùòæéáqسѢϲÔÔàNòP€ø+t¨ ­~là U 2  v´¾~þ\ûÚùøúyý¹ÿÇ„ýù`õdóªõ‚ü ¤ ”Fl üBTþnü®ü›ýÐý’ýšýÿš j Ö¸R¬ ~`2ú©ñûçÞ×FÖ:Ýxê@ú®ä<<  ]ûÒ÷ÈùmáßB@o" j " X ðàPTrüæöðð‰ë´è½énîøôdûŒzªîÚÛu ^ 4 ´ SóÒ † ’´þøÚð×èZà‰ØÒÒÑèÖã†óÄHAÖÖÒ¼ Y'- – ¬ ´ÂžLý–ú*ú`ülÿ¶6bíü·øôôìó9÷lþƒì ‚  röÿÑü@ûûNûZûlû4ü¾þCN 8ÄYtt €àù6ñ¡çÞîØÙàßì2úÎÞ È BZúbøûrŠ *IK‡+± b »î¸#Ìt ûõ3ïwêdè2êŒïhöÉü†Àäw®ú:p Û G ç  ‚ ,<& > nmÿxøwðÎçbßkØÔÔ8ÚÈåóô þú ¦²b æƒÓ\\ ( Ôææ¨þ‘û‘ùèùŒüÂÿóâÿJü*øêô£ô~øœÿ3p l| ü ôØÿüˆú˜úôú^û2üþ8Œ² pæ2µ –˜ù]ñÆçÐÞLÙFÙßë˜ø} À ~’ ü)ûpþïR ¨ˆ–bF„ Ï N „Kd™ ‚úhôrîÖéè=ê/ð¶÷gþ2r˜uy õÊ b U   Ê < ž B ” 2B&ý<öïÙçá&Û;×&×\ÜÝæõùšÈÇX‚ Z1Úº¤ ; î>Hÿ‹ü&ûüîþîlÐ@BüÀ÷xô•ôüø<Hu 6 – bzþ0ûëùûù;ú—ú¦ûàýˆtÔ P”,nú ¢Þÿhù«ñ¿è9àÀÚ‚ÚXàHëNøvÆ t ¿"†ü7ûïýÔÆ e–ª À â Xlïí^ÿù~óœí=éþç³êÌð|ø‰ÿ¤¹Þ*~L}¸0¬ ì ~ † ¬ T ¾ z 8Zý´öïjèÆá-ܼØüØêݼç~õ8¶NÚ¾ Vݹ‡ ( òÿ¾,ý.ú9ùÖúFþâÉ;úût÷uôþô›ùªˆ *  fÆþsûúÖùú¼ú–ülÿúXP œD , µ²ÿxùxñRèØßCÚÙßê–÷å Ä ‡Äùý5ý@*¬ : œÆú 0 t ' „ÇÓ:ÿŠùIó"íŒèIç:êÀðäøbØ  ùÞŠÞy† h † ¡ < ÿ  È hDVûõ¯î„èÒâÞÛÛHß;èõ*Š.¯†® y:šøx  ÞÙ³¤ýlû3ûkýIŒj6üÍ÷´ô õ4ù¶ÿ( 8 Ø  ^ý:úÐøxøÈø úaüÊÿ:# ¯ ;ã ˆ AZ*úBò!éfà¬ÚGÚàëNøqx Ð ÿ+ý¼ü'7 f´“† »  Å>÷¾åŒþIù~ó©íénçê¥ð ù³ä ” ÿp˜rº¦{ ” ð  1 † c º ø@ûõøîkéZä¶ß^ÜøÛÙߣè®õ îæŽ´Ã$ Y¬ÖFDBîþ üŒú(ûôýðPrðx¾üÆ÷gô†ô‚øÀþ6ü ¼ ž fØþ‹úúøÌøxùFû(þª§$ h$|^µ –\»þúø¦ñéœàžÚzÙ—ÞVéWö?RŠsì,Z¾ý Cò¾úU Í J  B„è¼þ¬øÈòæìJèåæåé¡ð\ùÉç «  „žŒæÐÀ  : Ê † a ‡ JTÿ2ù‡óTî™éXåŸáÎÞ8Þá­éöÚ:Ã<’RëÒŽ Z¬fv€ÿ#ý1ü^ý˜teZ©ýYøõÏôøØýÌ ª ÌÀKÄüXùœ÷h÷”øû”þÅQØ Âº< Ž“¼ÿ–ùòxéOáµÛÅÚÜ߆ê€÷\: ÙPz…)Ö Ì–Õœ b ( Ô –Ð$˜têý°ø óVíÀè+çüé²ðxùzð l Ž ¦N¨\„Ú+  h ¦ ø ’ ªè—ÿŠù²óÙîÚê&çšãµàâß·â.êöõÌ.uÐì.ú~Hš†ðÿŠýøûü4þ" ŠŒ^ýÍøŽõùô¹÷Øü–L¢ * HòJýù—÷˜÷/ùhüÓrt æ Ô:XŒ ð aćþôø¬ñJé,ádÛþÙ`ÞIè±ôfÿºÆ&>Ž¡  Ì ð0>ô Š ø °þ;adý"ønò¬ì è¤æÀé ñZún ¦ Æ ˜ ©zDº ¬ þ Í ‚ h ° Bô²ýlø€óvïgìžéˆætãàáŽãÈéŽô„ Ld(ì¸î ¶žö_s»þåýˆþÔfÎ Ö1eøý’ùVö‹õ×÷NüDbª|Ê”8ü¼ø ÷t÷†ùÔü/J z òA¼¶ îÖóÿ<ú2óüêãâÝcÛl߯èZôÖþÄæ8 °‰ow¤ / Ð î Ô Â j Ö‰.ôŒjüõ÷óîí0ê—é#í3ôÖü¥ò D Þ › ÚæÚ¦½r/*ÊÔ€þôùàõ°òðVíêçZåTætëþôîË ÄQ­öP!ÜøÎÊÿþýVý þðÿ   N #ûý–ùÐö öÚ÷ ü@~|nL¢ûñ÷^öN÷`ú´þp¾ P ¼ô¦ € [ Ô^8ÿlúSôîì±å3àæÝhàðçHòüS}ú§„¢ä0 ª ß {  ¯ î ‰ üµ‘fJü¤÷ÌòIîë¾êîæôDý°¬ ¼ " ¾ì%÷&ᥜn°ýÛlþûž÷æô8óTñëíÚéÛædæàéÚñúüê äõ&ø$hŽ,ÿöþ.5œîÎs <€ôNþÞú ø÷ø6ûmÿ4noXÌÿÔûÄøq÷Vø6ûFÿüdb à ¡ ¥’Í I “i˜0ü–ö†ï`èÂâà°áäçDñÔúDä( Ð önÊ™ ü l – `  ƒ £†`àêÿŽü©ø3ôáïGí¦í,ño÷èþï Œ Ø ’ €¦¸–Ð|n-bÖ˜&ÿºûùj÷öõ òîÍêÚé´ìÖóºý[J4Lô ~6DMªÎ(ÿvþ÷þ° Q K ê|‹JÿÜû&ùî÷¥ø~ûÿ)à†ˆÿUûšø¬÷ØøúûtÇíú  Æ * â » ç½û‡Œüv÷ñdê¸äµáÊâ„èñ¾ù:Õ È š êÞ6‹¹ R r x O • ^é˜FZªÿ%üøòópð’îïHòøøþ Ì ‚ ¶³=À2ÿEèdöº8âÀPþ.ü‚úcù{øœö`ó‚ï&ì‚êì¶ñxú€€ <’ îÍÚªÿ¶ÿëÿºÿ@ÿ6ÿ¼ÈˆŒcÐÿü—ù8ø®øûVþ’ã…´ÿGüùšøú(ýï””À É * J À dN¸²üÔ÷,òìÎç.å—å¦é¾ðù´I\  IþÖœ“Zº¼‚òí¸ú”ÿ‰üùŽõÈòñlò„õpúñÿÃö$ ˜öH2Ø3Ð>Fì`£ ¶(÷>ÿ®ýºü(üvûÎùæö=óÁïÞíÝîvóôú%Ê c  ¥ øøÑDÿÿ0ÿôþ¨þÿ\@F VˮڟGÅýtûöùàùZûÇýX(‰Z×þïûÈù@ùÀúºýGv¶. – â Ì B !ÄÜlý^ù­ôrïHêâæÅæ_êîð×ø‰Š ü cÔ[J:Òãz„W<6hOÿ¾ü¦ù†öþóÊòmóö‚ú\ÿ𓨖RéÜNvønwæ.¤k&V"Äþ¬ýýšüÏû&ú~÷óóðªíî4ó>úvdã ” ì ® HÈþnþ`þtþÐþÐÿž®’ö¾ÄÎ^¬¢rÿ2ý9ûàùµùúúý8ÿèhŒ|þ<üÖúôú¸üˆÿÊ–H ‡ôU U ÂJ.µæÿ­ü¼ødôõïÒë é é6ìò ù=¸Ô– nо\H ²HÄQ¤šìùþ“üÏùQ÷¶õfõdöÏø4üÀÿx¾ÆÞÄÄ2=šÝ~¬Í"æ¡tÿDÿaÿ2ÿ¨þœý”ûºø_õ?ò®ðèñöæû Md þ H ðÿ~ýùü$ý×ýÌþ(Þ®D`öÂðê¶P~jþü\û/ûÞûýxþvÿ³ÿÐþ>ýëûUûßû¢ýJîÅæxÚnàÆ òf,–ÿ§üDùxõ\ñºíÅëì ðVõ û¬F×? *Ò®Edh4¶j£Ô΂Áþ§üŠú øf÷*÷øþùªüªÿnƒ–Šf¢î Çà˜p´lÿ)ÿÿðþŽþŽý¿ûù õ¨ò|ñó4÷¡ü>¾ ìÖ `wÿþVþfþ¤þ^ÿœ$âxƒàŒ´z€®ÿãýDüûÂúKûüþHÿšÿêþÔýîü±üpý ÿh›.üM ôîT/Î2þTû0ø¼ô;ñpîCí{îòb÷Xý¸X²D Âôæj"¬ÊqÚB–ÔðÆbÿÚý*ü`úþø‚øÜøðùÂûþŒ¶BîÆ6ˆÞZ(BT­Mí[Ÿÿðþ|þZþiþpþLþ´ý<üÆùôöÞô’ô‘önúÿ~º Gw~þ¦ýQýjý þ(ÿ”%ž²BHÖ/t„Gäÿ†þDýNüòûSüBýJþëþÒþ þý}üžü|ýÿ,/æ|ó6Bî$üh^þ¤ûýøöóñ˜ð*òŒõúþþ1äÎBþÙLS¾\ì'ð`®zžv5ÿìýŠü*û%úÄùúûXüþôÿÐ0ÔÞš<ÄQ&Fb=ãx ƒÄÿóþyþ‚þÊþæþþ¢ý üæù¨÷ö,ö ø|ûaÿîmt ˆy†,ÿ‚þ^þœþ>ÿ@x´Ð«újžºÀ›TÿþýwüDü¬ü’ýŽþ*ÿ&ÿ þþÈýþÿj`FÃZŒŽ9l(ˆ£ÿ„ý8ûÄø6öàólòtò"ô:÷Lûœÿ>€;Ⱦ·^ê\v0¸4¬A<ÿÚýübû­ú©úDûTü½ýhÿ$ž‚¹x ”½ ÀÒ¢>Îd¤ÿLÿÿ>ÿƒÿ‚ÿøþæýnü´úù"øzøLú&ýDð¢t [Øÿ¾þþÞýþÖþõÿD‚‚,l4ª€ÔóáÿÅþÙýMý*ýpý þ¬þòþ¶þ(þ¨ýŒýþÿlÐî¦ Hv˜¤wåÞ|àÿþ üàù³÷Êõœô¬ô/öèø[üçÿרBè2¸¯ôV¤º“<À/“á ÿþ(ý`üåûÔû*üÓüÄýøþT•{ãä°g˜˜‰AÔv*ãÿ¨ÿ’ÿ²ÿòÿíÿ6ÿ þŽüôú†ùÇø.ùÈú*ýÂÿŽ$Æ·`"4ÿ¤þ~þÖþ§ÿÀàÔ‰ö¾Z®ü &ÿ<þý8ý=ýœý1þÂþ ÿäþ†þPþ†þ$ÿ 0ÿh޲äàN_uÿ¢ýÌû úføþö,öZö°÷úàüÉÿ?à~>ŠÕhPu¬Üöê²Yðp¿àÿòþþRýÈüü³ü0ýðý×þÕÿÚÀV„d"Ü—Z2Æt&îÿÆÿ®ÿ²ÿàÿ(T-šÿ¨þ€ýJü<û§úæúüèýáÿ®·Ç—}ÿ²þJþFþ¨þmÿzŠ_ê5D®@Øb¼æÿ ÿ^þùýÜýþ[þµþÞþÆþŒþrþ®þHÿ Ñb§·ÀÞ!¶ÎÿnþêüRûÈùxø³÷×÷ù*û¾ýMa¦³XìÔú/VfTÄ\åR¬ÿ ÿ„þþÖý´ýÃýþbþ×þhÿÐqÔò⼆Gîˇ&Îÿžÿ›ÿ¿ÿ hºÚïÿêþÀýœü¢ûûDû4ü¦ý8ÿ£* ”¾èÿPÿÿ'ÿ„ÿ,à|ÈÖ¼‚(¾RÛA…ÿÉþ8þçýÙýþDþþÌþèþíþ ÿbÿïÿ“4¼6:A[„¨¤R¬ȸÿþ0ýÚû˜ú˜ù ùcùlúüþ¤öÈNÕŒzŒ¥´¼¶–Rø˜2½ÿGÿêþ°þ’þˆþþ±þòþLÿ²ÿ$ P\Hè·˜‚d,àÿšÿ„ÿ¨ÿêÿ;”ØÜŠîÿ%ÿLþ~ý×ü€ü¤üOýVþqÿgrVØ(‡ÿÿúþÿzÿ ²K¶îüêÇœn<÷Œøÿ\ÿâþ‘þfþ^þyþ§þÔþôþÿ>ÿ’ÿˆó@jpa`‚ºäêÀZºìÿÿþüüü3ûÆúðúÃûý¸þ>v4j/¿V !<LRH&ê Pþÿ²ÿrÿ@ÿ%ÿÿÿÿ ÿ6ÿ\ÿ”ÿâÿ@˜Ø÷øçϵ›Z Úÿ¨ÿ¤ÿÎÿb¯ÞÖŒ aÿ­þüýcýýýˆýJþ/ÿ ¸ Øfüÿ¸ÿ¢ÿ·ÿöÿYÈ(e„tT*Ô™DØÿfÿ ÿÑþµþ³þÉþôþ(ÿUÿ{ÿ¬ÿôÿF’Ðø BhlFüŒöÿBÿ€þÄýý“üLügüöüåýÿ àe•x2ïÊÅÐ×ÖÒȰŠ`4Ôÿ­ÿ’ÿ†ÿˆÿÿÿ–ÿ¡ÿ²ÿÌÿöÿ,_‚Ž‹lXB,ñÿÒÿÀÿÈÿîÿMr‰‚V¢ÿ8ÿÐþuþ<þ?þ„þøþ~ÿùÿTˆ‰Y Æÿžÿ˜ÿ±ÿåÿ,z¼âèàÑÀ®Ÿ‘zRÐÿ‘ÿbÿBÿ0ÿ.ÿ:ÿSÿnÿŒÿ³ÿéÿ#Tx‹ŽŒ‘¢¿ÔÑ´„Dõÿ–ÿ.ÿÄþ^þþÔýÜý,þ¸þbÿ„Ôôè™xz~~~xfH&éÿ×ÿÎÿÌÿÐÿØÿÛÿ×ÿÑÿÌÿÌÿÖÿéÿ"<LQNF8&îÿÞÿØÿâÿûÿ<T`Z>Ðÿ’ÿVÿ$ÿÿþþÿPÿ–ÿÞÿCRG(íÿèÿöÿ2Tp~~xnd\RE2üÿÚÿ¼ÿ¦ÿ˜ÿ’ÿ•ÿŸÿ®ÿÂÿØÿðÿ $8DIIHJLT[^WG0ñÿÊÿžÿtÿNÿ2ÿ&ÿ0ÿTÿŠÿÇÿ.JWTI;0*('(**&þÿöÿòÿðÿôÿøÿúÿúÿøÿöÿõÿöÿûÿ ÿÿüÿùÿøÿúÿ øÿîÿæÿßÿÛÿÜÿàÿéÿôÿýÿþÿüÿüÿþÿtkabber-0.11.1/sounds/default/groupchat_their_message.wav0000644000175000017500000001757411066760706023122 0ustar sergeisergeiRIFFtWAVEfmt +"VdataPyÿÉþÿ©ÿvÿÿ7ÿÿ‰ÿžÿ·ÿ~ÿXÿìÿ¬\}ÿ-Ó—ˆ5lNÔm?á^ƒiQcm<-åÃê°Rà7>®ýÿºÿØÿ"ÿ(þ&þ>þ<ý¢ýTýIý†ýsü™üÏü™ûûhûðùÚøÛù{ùyùfùcù.ù¸ù¼úãúÒûòü ýÇýËþÚþ¶ÿhÿŒÿ3|ÿ»þþÑý”üÉû¼ú~úÒùÖùñù<ú6ú}úû°û‘üÌÿ¨¹Q,¯un ÍÌ # É §  à Ï K  c N Œ : ý  u¾¿±PgJbkÿGý ûêùùZùø7÷%ö‰ô´ó-ò òNóYòŽñƒòôŸôhôo÷BøùUûéüËÿʯßXëͤd»ÿüÁÒ6n*‡¥ó¶ZúüûPùN÷×ö§ô¨óòAï.íåêAë‹êìÝì°íðîUñ»ôšõ÷ìúíý \ % u’ñ§ør½yf®£?xÏKîÛ”˜ ï Øƒ6öÕþ!ýYûñøÄõÊô¥ñ³ï¬ì êÓéØêë êê/ìGîPïdðøò—öÄùÇýk» é u ç ½ë}|s Ï ¯B¿p¯üù®öõò7îë é3é³è›æ6å†çÊä®ã?â â@ã å¥çëìöð®ôØøøûÊÿ 3 ]Ž|È"Ì%î(K),J,‡*ì(¿'p%ž#¢ÔEm kÀæCþ^û2öØò’ðÍð_ï$î÷ïKðïîFîìëuëêÞê¹ëìì3îØîGïòªóÞöçö¾ø©ýc˜ –óúS—QÄkÔõrËVî Ì4b±ýÔ÷¨óañqíné€çäåûã¸á9áŠÞaÛƒÚnÙx×LØ»ÚòÜÞ:áµäEèìŸðiõLú1þhê C ‹V$'¿*0Ù2Ž1k1Ý0/:-(¸%‡"–ƒ#- ”TQüø°÷-ôïòIóuó*òÈïEðvîùêŸéöé§ìwëfë•ï’ð*ð?ðIóõ4õCù{û;ý¤mì Ä~F@*W½¤=×Ñ é ÙCýÖøpõNðjêçHã7á â^â¶áâPãÇãJá¦ßàùá!åìæ¥ç€ë³íüïëó!ö;ù„ýp­êy -Ö ­!à%Z*o*e)E(¯'g%’ ùÂ|)à ©ÿQû8ø÷÷Åöíöá÷ÊøÃùé÷2÷_õPóó‚òòÅïRð‘ñ_ñ³ï@ð’òuòbòxó.ö†ø,üÎÿ#Ë ¢LžŒyM:!“ÛEÙÝѧú”õæðbí?é­æåýâÆáZáˆÞõÛúÙÏØþؾØ#ÚcÛÕÞµàÿáuå3é8îñÆóæö£ûºæ2 @frm#ˆ&Ü)Ô*+á+.*Ï(ð%Z#J!a`sʱ’W ýgûµùØùüSüuûœúôùÙøÕööÿõËõQõáõúõžõ(öÆö"÷töñô öD÷®øÚû]þ*ýq %È0Û©ï ´ …º˜­ý>ú«öáñ¦íüê¯èFçØæJèxè@è`é}ê×ê€éêÚê÷ìÉî%ïãñíò‘ô€÷˜øûÛýcþÊþS.üÑ Õ îz–Cì’WÀ›#ÑIlÃ: :ëL<h`þrþ¥ýnýÂHbf„Ñò”˜£ÿ½þ©ürüÿûŒúùø8úÿøÓöDöýö+ùXú¦û|ÿò° ƒ ² ³î÷„§g @ k ñ:ĈýÃ÷¨ôíñîZëçé!é>ç½æ×æ´ä5ãµãëãûâ(äøä æoçxéßëëìð5õMöÕõ‹öÌú ÿX,Aì Ë$ÎÑ`‡À;¶¦(2 ½ á„`<¹þ þÿü*ý&lÃ3P,¿ª±S„`¸ò†Óþ±üIû~ûæüÔûuúÍûˆþ¤ëž»éB.Pžþ‰ývüEú¥÷þõ.õ`òçï.ïIîÙì7ìÂíËï­ð„óÛô´õÅö´÷÷÷CøKúéû¨üäüéýÑþAþŒþOð2þ„þeÿkÿÌþ¨ÿçïT^q r °a'Ì®º Îÿ0þ“ý’þ?þýOýbý?ýnýƒ7‚þ Ÿ £ Ø  õlÔÓ59¸¡øÿ½ýûÔù­ùìù ú¥úvüVÿ ØdGf©g ´ @€‡ûºŤÿŸþšûÿølöËó¸ñ6ð©ïŽîqîvï‚ïMð8ñoñ’ð/ñ;ò òüòõ?÷—øøÎú°ý±üšû ýþþA¹Ú1~ÙÌ ý û Z l 7 ñ }öoìN¥ExÃòÿ<ÿÏ‹¼ æ k|äÙ¨’Ió{N ÿ ÇÌ—ÿ›ý÷ü@û!øóöøþø»ùúû`û ûmûÂüêû·ú•ù;ø©÷Íö<öÃö}öJõ©ó©òZò—òhó†ô ö¢ù½úÅû¿ýtÿx¼_`/.mqB3Ý~èy>ƒþWý þ?þÿj°ªÔ¡•fÿký‘ûõú3ûsûûÝüþßý¹ýþRÿÃÿ°E–m q c 6[ H º Á  [Pà «Æƒ-€þôý¯ý"ýãû‚üâýøþêÿÍÇT*9é¸(}²ñƶþ„ýý‡ûkùf÷™õ#ôâòiò»òóDó®ôBö÷©õAö7ø6ù´ùãùûpüãü…ýOÿ…¿µ<2¼’˜9|b/GÐ"Ãè&ý&üüü¾ûMý"ÿjÿþSþ7ÿœÿš¿Z ’ à  ". <úwF : ”å[µý~û©ú¾÷ÌôÁóÕó ô&ôÔõ#÷]÷à÷£ù†úÉù÷÷üö¦ö\÷p÷Öö½÷TøR÷*ö-ö›÷›ø ùõúóü'þLÿøm k‰~©››ð¨ êYêÞ.5ÿƒýþûûü-ýÞþ¼ÿåÿ‚ˆÿ¥þÆýÇü ûgù½ùšú"ú…úGü¶ýƒýúýÊÿÖÒ[[žó¨ À i } å ²  ç ™[Ž@¯‹ùÿþ<üüJü,û(úÈúýÎýÍþº,_:òˆ×Wwÿfþ>þcý*ü¤úàøÌ÷löÄõ±õEö?ö|öò÷QùÝùßùÖúÁüvýÜü\ü¡üÏýDþ^ÿ …ƒ; Mýÿ •òª?‹ƒn݈ýJû®ûæü§üðü–þÿ´þaÿeˆÀ[‹[ … ú ÉÍDò¬E ~ d #ÌßÿìýÕúø}öAõó¤ðð)ðêïµñöó£õÝõäöƒùúðù.ù¿øyù"úºùyùŒù%ú¿úÊú_û…üUýTýéýUÿ'ŸoŸfÇK®EUøjJÕrYÿ‰þýÄüdüIý¼þûÿ¢__þ_º(þÆüý$ý`üLý ÿŽÿ ­¯òþ.¢“ÈÍU ^ Ì t y·dÄ[“ÿNþ+þÊü¥úkùôùjú¾ùÞùšûvüý¹þà«Ö«ûBÿ/%Üÿ ÿ0þ›üæúOúèùoøÅöîö ÷Ïö"÷–ø·ú$ûßû¼ý±þ˜þ8þdþµÿoôŒê8=%ÌW[þÿGîíLj=šòÿáýÕþTÿuÿAäu(\#2‚  N Ý ´èGÊ÷ ø %ì1fýUûùžö¼ô¿óÑñžïÐî/ïñîcï[ñÓóñôöiøÂúü€üRüÓûHüÆü%üÜûÜü(þ~þ*þÿ5àÿ¶£›Ÿ´°÷ëGk¬ª[ØœÓàfa¡Â¿À0n3‘J(¨s*­ÕN‰¿ÿ õ!éy*±ŠqOM¯ºÁÅg+híÿÊþëþ¨ý–ûPúˆù‰ø‹÷ø|ùûù‰ù¸ù[úaúBûjý¯ÿx‡©Þwª%‡É¡þkýýeü|úùÞøø(öõ!õ!õ"õAöBø@ùËù4ûýÿýyþ'ÿêÿ—+~ÎpÍ·ÖŽ,<ðÿ"W á¼ J ï{\gå›CØ2” º 3 ¶ Ÿ —  ( 5$ÜèVþœûqùƒ÷Võ°óêò òÐðXïmï¿ï²ï”ðQòWôUö@ø°úˆüuýÊýýúü€ý¤ý…ýÄý™þñþµþôþsÿ¡ÿÿÿ)ÿ›þTþFÿÀ¢ÓÙ¡rȗŧ†K`ÐßÓHÿFcs3fš$µÿ8¿z ¯Àaäæ»ÞëÞ=|ÿÛ¾±>™¡ÿ‹þäýOý¼ûÚùéø¸ø½ø<ùúõúûäúgûhûÅûýÿÀçFÍ/9»N<òþýÄülü=û²ù]øá÷÷-öHöDööLö÷þ÷”ø¸ùüûˆý“þ„ÿ:¼éú1£‹DpÿûKèËíÚ‚>¡oÍ—ÿò¯$j7`·y@ ¡ ¿    ó] v . _-+­­—þüû¾ùç÷ö‘ôÐó^óãòÏñiñ‡ñ†ñòñ+ó õ*÷?ùLû ýBþzÿ,àÿÿuÿ4ÿßþ½þwþûý±ýÈýþ8ý™üü%ü û¹û±üÆýTþ-ÿˆlw‹ÞÓ²(× ¦ª²+v€“]ÂVƒÕïæs¸ÞÎ7±ì=# aíã°p€:ŽÿˆÿŒÿÿÔÿ$nÿ…þþSýYü£ûXûZûüýlýaýLýÏýþÕýÜý†þhÿ‚d-ÌBwÓ°ÿêþ4þwýÓüøûÒú€ùÇøŽøøøá÷ƒ÷÷6÷Á÷pøJùßú‰ü¿ýÂþ}ÿÈÿ9äI$×xçF:9QhVŠƒ‹°D”'…Y9Wþj%ƒ¥'/Éâ—}_ÄdW)øußÒ *4ÿ ýÙúÎø=÷øõyõõŸôôó}ó¬óáó/ô õöW÷Þø€úüý‰þ)ŸB½ÿYÿáþnþdþþ˜ýý×üYüšû'ûÍúnúoú®úû¢ûjüˆý9þÿ?çXÐ è¥@®éƒ9~Q;±IÏKRm²qSí+Ë Uù°ëÔ›x”­<Šÿyÿ©ÿÆÿñÿ-¨ÅZ³ÿ&ÿãþ|þäýUý}ý7þŠþ˜þvþ¡þÿÿÚþÄþÂþUÿµúÚ9d£{ÿ»þ}þôý2ýNü^ûnú…ù ù”ø5ø<ø+øÎ÷¾÷øåø¨ùúÈûÄüáýòþ™ÿ˜¤§'g; øÃùm~…ÚÈ—ÿxþä=# 'Ƙ Xd°òß’ï0Ó‘4è¡ ª$•þýƒû:úüøeøû÷O÷’ö.öjöÓö÷o÷ð÷øyù–úÙûûü2þ|ÿ8?ãÿ£ÿYÿëþÃþ>þký‰üñû£û#û¸úÖúåú»ú¢úÅú>ûÈû¦üý(þÿ%š£’gk§Ò¥A™<© þkµò5! ¸ÃÖ­]‚$Ówj˜z£ò×c(4/‘ûZ¸ýÞG¦ÿÿ4ÿ«ÿÓÿ­ÿ©ÿ‰ÿEÿùþ¢þ[þPþÎþgÿ”ÿ–ÿÈÿ%3Áÿ ÿoþøýýèüéûûtúóùMù½ø¡ø²ø¢øø¢øÝøDùúûëûÞü$þ[ÿóÿU¤–^AnFõÿ¦ÿ\ÿšÿ'ph[·){à°ºÊ]6búDÒè !0'âXk°A¬Cù• Kw[ÿfþ¿ýýõû ûËúyúÚù{ùù úLúGúZúlú»úûuüLý þÂþÿÃÿÿ(ÿòþäþÈþIþ“ý÷ü[üËûHûû.û?û&û?û…û½ûüküý¼ýWþBÿ<ãjú6Íä;b©øKÏ?Y!ñ%Õ¶·K†Ì~Ã4ëÿkÿ)ÿ<ÿpÿ±ÿèÿ4W#õÿæÿäÿ(€æÂm8­ƒÎÓlÉÿZÿ6ÿýþÍþ²þvþiþ¶þÿGÿ>ÿEÿnÿuÿ5ÿÓþþXþFþ¸ýÔüøû8û³úGú9úúÀúËúéúîúèúû ûnü#ýîýèþ¥ÿõÿ4v‹q&ÿÿæÿµÿ–ÿYÿQÿÄÿ?obMuà†RÜdRG¹ðPÃä—j@þý²D¢ëeëh¿Ið®3”ÿÿ¶þþ(ý«ü‘üKüîûŸû¦ûÒûçûüüü•üJýçýaþËþ4ÿ’ÿÌÿ²ÿkÿÿýþÕþ6þ ý-ý©ü6ü×ûâûü!ü@ü}ü©üÎüîü<ý³ýHþ ÿõóCUD?„˜¤¤ïtœ|Jø¸ ¦n=GQøˆfXs·ÿJÿ*ÿ]ÿÄÿ:~˜‹]8‘ý9ÖëÂÂï×gQ×5Ðÿ¯ÿ„ÿEÿ"ÿ ÿæþèþÿ<ÿUÿGÿ.ÿ@ÿpÿwÿ\ÿLÿbÿ-ÿwþÈý:ý¼üaüNü‰ü£ü‹ü“ü¬ü¥ü”üÉüMýÀýþSþÚþqÿ¿ÿîÿ& ´ÿƒÿdÿ:ÿÿÿAÿœÿáÿ$Rl‰ÔmöNÄ”vå%|¼©T&аŽR«VÛD¿GÑ„1 £ÿÿÖþ±þKþÀýƒýeýýŸüzü~üŠüªüïü%ýAý’ýþoþÁþóþÿ=ÿdÿVÿÿ÷þÿêþeþáýqýéübü4ü\üŒü·üýTýgýzýÄý1þ§þÿ°ÿ`ûtÌ6G;?B0ô"M9ÐS=H:ýØöçâü×z0àÿ«ÿªÿÃÿëÿ þÿâÿÈÿÃÿc”Ì AjE ÚiÉÿ ÿgÿ3ÿÿúþîþÿÿþäþÒþ¿þ¼þîþ6ÿ\ÿTÿ^ÿ†ÿ]ÿñþ›þQþþÏýÈýÒý¹ý©ýÑýòýéýåýøýþ3þ<þVþ˜þìþ?ÿbÿ`ÿdÿMÿ3ÿ(ÿÿñþÔþäþ-ÿoÿ›ÿÔÿ?o½0 ÷oŠÕ3eaCÃx+Ñx$æº}!¬J!Àÿ{ÿnÿiÿKÿÿûþæþ¡þ_þ.þåýýsýkýqýuýýÀýëýþSþþÊþïþèþèþÿ<ÿCÿ.ÿ:ÿUÿ$ÿÀþWþîý›ýnýtý–ýµýêý<þvþþ¯þíþCÿŒÿ¾ÿ .œÔý ìàÕÄ¡ˆ€iK8æ¼®¯WS‰¾ÛæøûÈŠaF:- $÷ÿøÿ EMp³áêæû ã¿®‰MÄÿÿ_ÿIÿLÿGÿ=ÿ6ÿ,ÿ*ÿ'ÿÿ-ÿkÿ¥ÿ»ÿ»ÿÝÿñÿÈÿ¨ÿvÿ4ÿýþéþäþÓþÕþíþëþÏþ¶þ¦þ£þ¢þŸþ·þëþ'ÿUÿbÿuÿ‹ÿyÿ]ÿTÿHÿ0ÿÿ6ÿoÿ™ÿÄÿ.IxÌ6Ìs¿ÿ(RrhB ºe ½{2öТ\ ÕÿÄÿ«ÿxÿZÿ[ÿ`ÿ[ÿPÿQÿHÿÿüþáþ¼þ¡þ•þŒþ|þhþoþŒþªþÍþòþÿ9ÿEÿ)ÿÿ0ÿWÿeÿeÿ€ÿšÿÿQÿÿàþ¬þ þ²þÀþÎþÿþ@ÿgÿÿžÿÂÿñÿ&U‘å@u{‡Ÿš‰†}^1 æ½±¹ªŒƒ‰„mSQi‹¡¤ÀÃ¥ƒcAûÿåÿÍÿÍÿèÿóÿâÿØÿêÿ .?EHYpjM)úÿÅÿÿgÿPÿ?ÿ>ÿIÿKÿDÿ>ÿAÿMÿQÿNÿ^ÿŒÿ´ÿÃÿÐÿöÿ!&óÿÅÿ–ÿvÿcÿVÿOÿTÿWÿCÿ*ÿÿýþôþõþòþùþ ÿRÿnÿ~ÿ—ÿªÿšÿ‹ÿ“ÿ“ÿŒÿ”ÿ¬ÿÁÿÐÿîÿ <m£Ø :jªé*MhT)þÄ}<ƃV=ïÿÅÿ§ÿšÿ”ÿÿŽÿ–ÿÿžÿ•ÿÿˆÿÿ{ÿpÿ]ÿLÿ7ÿÿÿûþþþ ÿÿ-ÿ;ÿAÿHÿEÿ8ÿ2ÿFÿfÿwÿ|ÿŒÿ¡ÿžÿÿwÿQÿ0ÿ'ÿ7ÿAÿHÿnÿÿ¯ÿ¶ÿÅÿÜÿ÷ÿ:[‡ÀáãëþûêäÝÁœ‡rSM[YC.-2.*0CZgn{vcH*öÿèÿÞÿÜÿ×ÿÔÿÜÿÝÿÝÿèÿðÿíÿìÿùÿÿÿòÿéÿöÿüÿòÿëÿâÿÏÿ»ÿ«ÿœÿ‰ÿ|ÿ€ÿ„ÿ‰ÿ—ÿ¥ÿ¯ÿ¹ÿ½ÿ¼ÿ¼ÿÎÿêÿúÿ0/%ýÿáÿÑÿÂÿ²ÿ¯ÿ´ÿ³ÿ©ÿ˜ÿŒÿ‚ÿ{ÿzÿÿ’ÿ®ÿ½ÿ¾ÿÆÿÔÿÚÿÜÿãÿîÿñÿïÿôÿöÿóÿúÿ %<Qjƒ˜¦³ÆÞðü ý䯥„iQ=0%ðÿáÿÞÿÚÿÔÿÔÿÜÿáÿÜÿÙÿÞÿßÿàÿäÿæÿàÿÓÿÃÿ¯ÿÿ“ÿÿÿ–ÿÿ›ÿ–ÿ˜ÿ•ÿ‹ÿÿŸÿ°ÿ·ÿ¿ÿÐÿÚÿÙÿÕÿÏÿÆÿ¾ÿ»ÿ¼ÿ¼ÿÀÿÇÿÍÿÒÿÖÿÝÿæÿõÿ)6?DNY`caZOA6-'%$!!%%'(# ûÿøÿùÿúÿúÿûÿþÿþÿýÿüÿüÿûÿûÿûÿùÿùÿûÿûÿ÷ÿôÿòÿïÿëÿèÿçÿåÿåÿçÿêÿíÿïÿñÿóÿöÿøÿúÿýÿ ÿÿýÿüÿüÿûÿûÿûÿûÿûÿûÿûÿüÿüÿýÿþÿþÿÿÿÿÿtkabber-0.11.1/chats.tcl0000644000175000017500000011714611074113462014341 0ustar sergeisergei# $Id: chats.tcl 1511 2008-10-11 12:08:18Z sergei $ package require textutil option add *Chat.theyforeground blue widgetDefault option add *Chat.meforeground red3 widgetDefault option add *Chat.highlightforeground red3 widgetDefault option add *Chat.serverlabelforeground green widgetDefault option add *Chat.serverforeground violet widgetDefault option add *Chat.infoforeground blue widgetDefault option add *Chat.errforeground red widgetDefault option add *Chat.inputheight 3 widgetDefault namespace eval chat { set enrichid 0 custom::defgroup Chat [::msgcat::mc "Chat options."] -group Tkabber custom::defvar options(smart_scroll) 0 \ [::msgcat::mc "Enable chat window autoscroll only when last message is shown."] \ -type boolean -group Chat custom::defvar options(stop_scroll) 0 \ [::msgcat::mc "Stop chat window autoscroll."] \ -type boolean -group Chat custom::defvar options(display_status_description) 1 \ [::msgcat::mc "Display description of user status in chat windows."] \ -type boolean -group Chat custom::defvar options(default_message_type) chat \ [::msgcat::mc "Default message type (if not specified explicitly)."] \ -type radio -group Chat \ -values [list normal [::msgcat::mc "Normal"] \ chat [string trim [::msgcat::mc "Chat "]]] custom::defvar options(gen_status_change_msgs) 0 \ [::msgcat::mc "Generate chat messages when chat peer\ changes his/her status and/or status message"] \ -type boolean -group Chat custom::defvar open_chat_list {} [::msgcat::mc "List of users for chat."] \ -group Hidden } set chat_width 50 set chat_height 18 plugins::load [file join plugins chat] proc chat::open_chat_dialog {} { variable open_chat_jid variable open_chat_list variable open_chat_connid if {[lempty [jlib::connections]]} return set gw .open_chat catch { destroy $gw } set connid [lindex [jlib::connections] 0] set open_chat_connid [jlib::connection_jid $connid] Dialog $gw -title [::msgcat::mc "Open chat"] -separator 1 -anchor e \ -default 0 -cancel 1 set gf [$gw getframe] grid columnconfigure $gf 1 -weight 1 set open_chat_jid "" label $gf.ljid -text [::msgcat::mc "JID:"] ecursor_entry [ComboBox $gf.jid -textvariable [namespace current]::open_chat_jid \ -values [linsert $open_chat_list 0 ""] -width 35].e grid $gf.ljid -row 0 -column 0 -sticky e grid $gf.jid -row 0 -column 1 -sticky ew if {[llength [jlib::connections]] > 1} { set connections {} foreach c [jlib::connections] { lappend connections [jlib::connection_jid $c] } label $gf.lconnection -text [::msgcat::mc "Connection:"] ComboBox $gf.connection -textvariable [namespace current]::open_chat_connid \ -values $connections grid $gf.lconnection -row 1 -column 0 -sticky e grid $gf.connection -row 1 -column 1 -sticky ew } $gw add -text [::msgcat::mc "Chat"] -command "[namespace current]::open_chat $gw" $gw add -text [::msgcat::mc "Cancel"] -command "destroy $gw" $gw draw $gf.jid } proc chat::open_chat {gw} { variable open_chat_jid variable open_chat_list variable open_chat_connid destroy $gw foreach c [jlib::connections] { if {[jlib::connection_jid $c] == $open_chat_connid} { set connid $c } } if {![info exists connid]} { set connid [jlib::route $open_chat_jid] } set open_chat_list [update_combo_list $open_chat_list $open_chat_jid 20] open_to_user $connid $open_chat_jid } # chat::close -- # Closes the container chat window for a chat identified # by given chat ID. Has the same effect as if the user closed # the chat's window using the UI. proc chat::close {chatid} { ifacetk::destroy_win [winid $chatid] } proc chat::get_nick {connid jid type} { variable chats set nick $jid switch -- $type { chat { set group [node_and_server_from_jid $jid] set chatid1 [chatid $connid $group] if {[is_groupchat $chatid1]} { set nick [resource_from_jid $jid] } else { set nick [roster::itemconfig $connid \ [roster::find_jid $connid $jid] -name] if {$nick == ""} { if {[node_from_jid $jid] != ""} { set nick [node_from_jid $jid] } else { set nick $jid } } } } groupchat { set nick [resource_from_jid $jid] } } return $nick } proc chat::winid {chatid} { set connid [get_connid $chatid] set jid [get_jid $chatid] set tag [jid_to_tag $jid] return .chat_${connid}_$tag } proc chat::winid_to_chatid {winid} { variable chat_id expr {[info exists chat_id($winid)] ? $chat_id($winid) : ""} } proc chat::chatid {connid jid} { return [list $connid $jid] } proc chat::get_connid {chatid} { return [lindex $chatid 0] } proc chat::get_jid {chatid} { return [lindex $chatid 1] } ############################################################################### proc client:message \ {connid from id type is_subject subject body err thread priority x} { debugmsg chat "MESSAGE: $connid; $from; $id; $type; $is_subject;\ $subject; $body; $err; $thread; $priority; $x" hook::run rewrite_message_hook connid from id type is_subject \ subject body err thread priority x debugmsg chat "REWRITTEN MESSAGE: $connid; $from; $id; $type; $is_subject;\ $subject; $body; $err; $thread; $priority; $x" hook::run process_message_hook $connid $from $id $type $is_subject \ $subject $body $err $thread $priority $x } ############################################################################### proc chat::rewrite_message \ {vconnid vfrom vid vtype vis_subject vsubject \ vbody verr vthread vpriority vx} { upvar 2 $vfrom from upvar 2 $vtype type variable options if {$type == ""} { set type $options(default_message_type) } set from [tolower_node_and_domain $from] } hook::add rewrite_message_hook [namespace current]::chat::rewrite_message 99 ############################################################################### proc chat::process_message_fallback \ {connid from id type is_subject subject body err thread priority x} { variable chats set chatid [chatid $connid $from] switch -- $type { chat { if {$thread != ""} { set chats(thread,$chatid) $thread } set chats(id,$chatid) $id } groupchat { set chatid [chatid $connid [node_and_server_from_jid $from]] if {![is_groupchat $chatid]} return if {$is_subject} { set_subject $chatid $subject if {[cequal $body ""]} { set nick [resource_from_jid $from] if {[cequal $nick ""]} { set body [format [::msgcat::mc "Subject is set to: %s"] $subject] } else { set body [format [::msgcat::mc "/me has set the subject to: %s"] $subject] } } } } error { if {[is_groupchat $chatid]} { if {$is_subject} { set body "subject: " restore_subject $chatid } else { set body "" } append body [error_to_string $err] } else { if {$is_subject && $subject != ""} { set body "[::msgcat::mc {Subject:}] $subject\n$body" } set body "[error_to_string $err]\n$body" } } default { debugmsg chat "MESSAGE: UNSUPPORTED message type '$type'" } } #chat::open_window $chatid $type chat::add_message $chatid $from $type $body $x if {[llength $x] > 0} { message::show_dialog $connid $from $id $type $subject $body $thread $priority $x 0 } } hook::add process_message_hook \ [namespace current]::chat::process_message_fallback 99 ############################################################################### proc chat::window_titles {chatid} { set connid [get_connid $chatid] set jid [get_jid $chatid] set chatname [roster::itemconfig $connid \ [roster::find_jid $connid $jid] -name] if {$chatname != ""} { set tabtitlename $chatname set titlename $chatname } else { set titlename $jid if {[is_groupchat $chatid]} { set tabtitlename [node_from_jid $jid] } else { set tabtitlename [get_nick $connid $jid chat] } if {$tabtitlename == ""} { set tabtitlename $titlename } } return [list $tabtitlename [format [::msgcat::mc "Chat with %s"] $titlename]] } proc chat::reconnect_groupchats {connid} { variable chats global grouproster foreach chatid [opened $connid] { if {[is_groupchat $chatid]} { if {[info exists ::muc::muc_password($chatid)]} { set password $::muc::muc_password($chatid) } else { set password "" } muc::join_group $connid \ [get_jid $chatid] \ [get_our_groupchat_nick $chatid] \ $password } else { set chats(status,$chatid) connected } } } hook::add connected_hook [namespace current]::chat::reconnect_groupchats 99 proc chat::disconnect_groupchats {connid} { variable chats global statusdesc foreach chatid [opened $connid] { if {![winfo exists [chat_win $chatid]]} return set jid [get_jid $chatid] if {$chats(status,$chatid) != "disconnected"} { set chats(status,$chatid) disconnected add_message $chatid $jid error [::msgcat::mc "Disconnected"] {} } set cw [winid $chatid] if {[winfo exists $cw.status.icon]} { $cw.status.icon configure \ -image [ifacetk::roster::get_jid_icon $connid $jid unavailable] \ -helptext "" } if {[winfo exists $cw.status.desc]} { $cw.status.desc configure \ -text "($statusdesc(unavailable))" \ -helptext "" } } } hook::add predisconnected_hook [namespace current]::chat::disconnect_groupchats 99 proc chat::open_window {chatid type args} { global chat_width chat_height variable chats variable chat_id variable options global grouproster global statusdesc set connid [get_connid $chatid] set jid [get_jid $chatid] set jid [tolower_node_and_domain $jid] set chatid [chatid $connid $jid] set cw [winid $chatid] set cleanroster 1 foreach {key val} $args { switch -- $key { -cleanroster { set cleanroster $val } } } if {[winfo exists $cw]} { if {$type == "groupchat" && \ $chats(status,$chatid) == "disconnected" && \ $cleanroster} { set grouproster(users,$chatid) {} } if {!$::usetabbar && \ [info exists ::raise_on_activity] && $::raise_on_activity} { if {$type == "chat"} { wm deiconify $cw } raise $cw } return } hook::run open_chat_pre_hook $chatid $type set chats(type,$chatid) $type set chats(subject,$chatid) "" if {$type == "groupchat"} { set chats(status,$chatid) disconnected } else { set chats(status,$chatid) connected } set chats(exit_status,$chatid) "" add_to_opened $chatid set chat_id($cw) $chatid lassign [chat::window_titles $chatid] chats(tabtitlename,$chatid) \ chats(titlename,$chatid) add_win $cw -title $chats(titlename,$chatid) \ -tabtitle $chats(tabtitlename,$chatid) \ -class Chat -type $type \ -raisecmd "focus [list $cw.input] hook::run raise_chat_tab_hook [list $cw] [list $chatid]" frame $cw.status pack $cw.status -side top -fill x if {[cequal $type chat]} { set status [get_user_status $connid $jid] Label $cw.status.icon \ -image [ifacetk::roster::get_jid_icon $connid $jid $status] \ -helptext [get_user_status_desc $connid $jid] pack $cw.status.icon -side left if {$options(display_status_description)} { Label $cw.status.desc -text "($statusdesc($status))" \ -helptext [get_user_status_desc $connid $jid] pack $cw.status.desc -side left } } if {[cequal $type chat]} { menubutton $cw.status.mb -text $jid \ -anchor w \ -menu $cw.status.mb.menu create_user_menu $cw.status.mb.menu $chatid pack $cw.status.mb -side left } else { menubutton $cw.status.mb -text [::msgcat::mc "Subject:"] \ -direction below \ -menu $cw.status.mb.menu -relief flat create_conference_menu $cw.status.mb.menu $chatid pack $cw.status.mb -side left entry $cw.status.subject \ -xscrollcommand [list [namespace current]::set_subject_tooltip $chatid] pack $cw.status.subject -side left -fill x -expand yes bind $cw.status.subject \ [list chat::change_subject [double% $chatid]] bind $cw.status.subject \ [list chat::restore_subject [double% $chatid]] balloon::setup $cw.status.subject \ -command [list [namespace current]::set_subject_balloon $chatid] } foreach tag [bind Menubutton] { if {[string first 1 $tag] >= 0} { regsub -all 1 $tag 3 new bind $cw.status.mb $new [bind Menubutton $tag] } } PanedWin $cw.pw0 -side right -pad 0 -width 4 pack $cw.pw0 -fill both -expand yes set upw [PanedWinAdd $cw.pw0 -weight 1 -minsize 0] set dow [PanedWinAdd $cw.pw0 -weight 0 -minsize 0] set isw [ScrolledWindow $cw.isw -scrollbar vertical] pack $cw.isw -fill both -expand yes -side bottom -in $dow textUndoable $cw.input -width $chat_width \ -height [option get $cw inputheight Chat] -wrap word $isw setwidget $cw.input [winfo parent $dow] configure -height [winfo reqheight $cw.input] set chats(inputwin,$chatid) $cw.input if {[cequal $type groupchat]} { PanedWin $cw.pw -side bottom -pad 1 -width 4 pack $cw.pw -fill both -expand yes -in $upw set cf [PanedWinAdd $cw.pw -weight 1 -minsize 0] set uw [PanedWinAdd $cw.pw -weight 0 -minsize 0] set chats(userswin,$chatid) $uw.users set rosterwidth [option get . chatRosterWidth [winfo class .]] if {$rosterwidth == ""} { set rosterwidth [winfo pixels . 3c] } ifacetk::roster::create $uw.users -width $rosterwidth \ -popup ifacetk::roster::groupchat_popup_menu \ -singleclick [list [namespace current]::user_singleclick $chatid] \ -doubleclick ::ifacetk::roster::jid_doubleclick \ -draginitcmd [namespace current]::draginitcmd \ -dropovercmd [list [namespace current]::dropovercmd $chatid] \ -dropcmd [list [namespace current]::dropcmd $chatid] pack $uw.users -fill both -side right -expand yes [winfo parent $uw] configure -width $rosterwidth set grouproster(users,$chatid) {} set pack_in $cf } else { set cf $cw set pack_in $upw } set chats(chatwin,$chatid) $cf.chat set csw [ScrolledWindow $cf.csw -scrollbar vertical -auto none] pack $csw -expand yes -fill both -side top -in $pack_in ::richtext::richtext $cf.chat \ -width $chat_width -height $chat_height \ -wrap word ::plugins::chatlog::config $cf.chat \ -theyforeground [query_optiondb $cw theyforeground] \ -meforeground [query_optiondb $cw meforeground] \ -serverlabelforeground [query_optiondb $cw serverlabelforeground] \ -serverforeground [query_optiondb $cw serverforeground] \ -infoforeground [query_optiondb $cw infoforeground] \ -errforeground [query_optiondb $cw errforeground] \ -highlightforeground [query_optiondb $cw highlightforeground] $csw setwidget $cf.chat reverse_scroll $cf.chat focus $cw.input bind $cw.input { } bind $cw.input [double% " chat::send_message [list $cw] [list $chatid] [list $type] break"] regsub -all %W [bind Text ] $cf.chat prior_binding regsub -all %W [bind Text ] $cf.chat next_binding bind $cw.input $prior_binding bind $cw.input $next_binding bind $cw.input $prior_binding bind $cw.input $next_binding bind $cw.input +break bind $cw.input +break bind $cw.input +break bind $cw.input +break bind $cw.input continue bind $cw.input continue bind $cw.input continue bind $cw.input continue bind $cw [list chat::close_window [double% $chatid]] hook::run open_chat_post_hook $chatid $type } ############################################################################### # This proc is used by the "richtext widget" to query the option DB for # it's attributes which are really maintained by the main chat window proc chat::query_optiondb {w option} { option get $w $option Chat } ############################################################################### proc chat::draginitcmd {target x y top} { return {} } ############################################################################### proc chat::dropovercmd {chatid target source event x y op type data} { variable chats set chat_connid [get_connid $chatid] lassign $data jid_connid jid if {$source != ".roster.canvas" || \ ![info exists chats(status,$chatid)] || \ $chats(status,$chatid) == "disconnected" || \ $chat_connid != $jid_connid || \ ![::roster::itemconfig $jid_connid $jid -isuser]} { DropSite::setcursor dot return 0 } else { DropSite::setcursor based_arrow_down return 1 } } ############################################################################### proc chat::dropcmd {chatid target source x y op type data} { set group [get_jid $chatid] lassign $data connid jid set reason [::msgcat::mc "Please join %s" $group] if {[muc::is_compatible $group]} { muc::invite_muc $connid $group $jid $reason } else { muc::invite_xconference $connid $group $jid $reason } } ############################################################################### proc chat::user_singleclick {chatid cjid} { lassign $cjid connid jid set nick [get_nick $connid $jid groupchat] hook::run groupchat_roster_user_singleclick_hook $chatid $nick } ############################################################################### proc chat::bind_window_click {chatid type} { set cw [chat::chat_win $chatid] bind $cw \ [list hook::run chat_window_click_hook [double% $chatid] %W %x %y] } hook::add open_chat_post_hook [namespace current]::chat::bind_window_click ############################################################################### proc chat::close_window {chatid} { variable chats variable chat_id if {![is_opened $chatid]} return remove_from_opened $chatid set connid [get_connid $chatid] set jid [get_jid $chatid] set cw [winid $chatid] unset chat_id($cw) if {[is_groupchat $chatid]} { muc::leave_group $connid $jid [get_our_groupchat_nick $chatid] \ $chats(exit_status,$chatid) set chats(status,$chatid) disconnected client:presence $connid $jid unavailable "" {} foreach jid [get_jids_of_user $connid $jid] { client:presence $connid $jid unavailable "" {} } } destroy $cw hook::run close_chat_post_hook $chatid } ############################################################################## proc chat::trace_room_nickname_change {connid group nick new_nick} { set from $group/$nick set to $group/$new_nick set chatid [::chat::chatid $connid $from] set ix [lsearch -exact [::chat::opened] $chatid] if {$ix < 0} return set msg [format [::msgcat::mc \ "%s has changed nick to %s."] \ $nick $new_nick] ::chat::add_message $chatid "" chat $msg {} set cw [chat_win $chatid] $cw config -state normal $cw delete {end - 1 char} ;# zap trailing newline $cw insert end " " set tooltip [::msgcat::mc "Opens a new chat window\ for the new nick of the room occupant"] ::plugins::urls::render_url $cw url $tooltip {} \ -title [::msgcat::mc "Open new conversation"] \ -command [list [namespace current]::open_to_user $connid $to] $cw insert end \n $cw config -state disabled } hook::add room_nickname_changed_hook chat::trace_room_nickname_change ############################################################################## proc chat::check_connid {connid chatid} { if {[get_connid $chatid] == $connid} { return 1 } else { return 0 } } ############################################################################## proc chat::opened {{connid {}}} { variable chats if {![info exists chats(opened)]} { return {} } elseif {$connid != {}} { return [lfilter [list [namespace current]::check_connid $connid] \ $chats(opened)] } else { return $chats(opened) } } proc chat::is_opened {chatid} { variable chats if {[info exists chats(opened)] && \ ([lsearch -exact $chats(opened) $chatid] >= 0)} { return 1 } else { return 0 } } proc chat::add_to_opened {chatid} { variable chats lappend chats(opened) $chatid set chats(opened) [lsort -unique $chats(opened)] } proc chat::remove_from_opened {chatid} { variable chats set idx [lsearch -exact $chats(opened) $chatid] if {$idx >= 0} { set chats(opened) [lreplace $chats(opened) $idx $idx] } } ############################################################################## proc chat::users_win {chatid} { variable chats return $chats(userswin,$chatid) } proc chat::chat_win {chatid} { variable chats return $chats(chatwin,$chatid) } proc chat::input_win {chatid} { variable chats return $chats(inputwin,$chatid) } ############################################################################## proc chat::is_chat {chatid} { variable chats if {[info exists chats(type,$chatid)]} { return [cequal $chats(type,$chatid) chat] } else { return 1 } } proc chat::is_groupchat {chatid} { variable chats if {[info exists chats(type,$chatid)]} { return [cequal $chats(type,$chatid) groupchat] } else { return 0 } } ############################################################################## proc chat::is_disconnected {chatid} { variable chats if {![info exists chats(status,$chatid)] || \ $chats(status,$chatid) == "disconnected"} { return 1 } else { return 0 } } ############################################################################## proc chat::create_user_menu {m chatid} { menu $m -tearoff 0 set connid [get_connid $chatid] set jid [get_jid $chatid] hook::run chat_create_user_menu_hook $m $connid $jid return $m } proc chat::create_conference_menu {m chatid} { menu $m -tearoff 0 set connid [get_connid $chatid] set jid [get_jid $chatid] hook::run chat_create_conference_menu_hook $m $connid $jid return $m } proc chat::add_separator {m connid jid} { $m add separator } hook::add chat_create_user_menu_hook chat::add_separator 40 hook::add chat_create_user_menu_hook chat::add_separator 42 hook::add chat_create_user_menu_hook chat::add_separator 50 hook::add chat_create_user_menu_hook chat::add_separator 70 hook::add chat_create_user_menu_hook chat::add_separator 85 hook::add chat_create_conference_menu_hook chat::add_separator 40 hook::add chat_create_conference_menu_hook chat::add_separator 42 hook::add chat_create_conference_menu_hook chat::add_separator 50 proc chat::send_message {cw chatid type} { set iw $cw.input set connid [get_connid $chatid] if {[catch { set user [jlib::connection_user $connid] }]} { set user "" } set body [$iw get 1.0 "end -1 chars"] debugmsg chat "SEND_MESSAGE:\ [list $chatid] [list $user] [list $body] [list $type]" set chatw [chat_win $chatid] $chatw mark set start_message "end -1 chars" $chatw mark gravity start_message left hook::run chat_send_message_hook $chatid $user $body $type $iw delete 1.0 end catch {$iw edit reset} } proc chat::add_message {chatid from type body x} { variable chats variable options if {[is_opened $chatid]} { set chatw [chat_win $chatid] if {[lindex [$chatw yview] 1] == 1} { set scroll 1 } else { set scroll 0 } } else { set scroll 1 } hook::run draw_message_hook $chatid $from $type $body $x if {[is_opened $chatid]} { set chatw [chat_win $chatid] if {![$chatw compare "end -1 chars linestart" == "end -1 chars"]} { $chatw insert end "\n" } # In the last condition we work around the underscrolling if the chat # window wasn't maped yet. It's unlikely that mapped chat window will # be exactly 1 pixel tall. if {$body != "" && !$options(stop_scroll) && \ (!$options(smart_scroll) || \ ($options(smart_scroll) && $scroll) || \ [chat::is_our_jid $chatid $from] || \ [winfo height $chatw] == 1)} { after idle [list catch [list $chatw yview moveto 1]] } $chatw configure -state disabled } hook::run draw_message_post_hook $chatid $from $type $body $x } proc chat::add_open_to_user_menu_item {m connid jid} { $m add command -label [::msgcat::mc "Start chat"] \ -command [list chat::open_to_user $connid $jid] } hook::add roster_create_groupchat_user_menu_hook \ [namespace current]::chat::add_open_to_user_menu_item 10 hook::add roster_jid_popup_menu_hook \ [namespace current]::chat::add_open_to_user_menu_item 10 hook::add message_dialog_menu_hook \ [namespace current]::chat::add_open_to_user_menu_item 10 hook::add search_popup_menu_hook \ [namespace current]::chat::add_open_to_user_menu_item 10 proc chat::open_to_user {connid user args} { set msg "" foreach {opt val} $args { switch -- $opt { -message { set msg $val } } } if {$connid == ""} { set connid [jlib::route $user] } set jid [get_jid_of_user $connid $user] if {[cequal $jid ""]} { set jid $user } set jid [tolower_node_and_domain $jid] set chatid [chatid $connid $jid] set cw [winid $chatid] if {![winfo exists $cw]} { chat::open_window $chatid chat } raise_win $cw focus -force $cw.input if {![cequal $msg ""]} { debugmsg chat "SEND_MESSAGE ON OPEN:\ [list $chatid] [jlib::connection_user $connid] [list $msg] chat" set chatw [chat_win $chatid] $chatw mark set start_message "end -1 chars" $chatw mark gravity start_message left hook::run chat_send_message_hook $chatid [jlib::connection_user $connid] \ $msg chat } } ############################################################################### proc chat::change_presence {connid jid type x args} { global grouproster variable chats variable options global statusdesc switch -- $type { error - unavailable { set status $type } available { set status available foreach {key val} $args { switch -- $key { -show { set status [normalize_show $val] } } } } default { return } } set group [node_and_server_from_jid $jid] set chatid [chatid $connid $group] if {[is_opened $chatid]} { if {[is_groupchat $chatid]} { debugmsg chat "ST: $connid $jid $status" if {[resource_from_jid $jid] == ""} { return } set nick [get_nick $connid $jid groupchat] if {[cequal $status unavailable] || [cequal $status error]} { if {$status == "error" && [is_our_jid $chatid $jid]} { add_message $chatid $group error \ [format [::msgcat::mc "Error %s"] \ [get_jid_presence_info status $connid $jid]] {} set chats(status,$chatid) disconnected client:presence $connid $group unavailable "" {} } if {$status == "unavailable" && [is_our_jid $chatid $jid]} { if {[muc::is_compatible $group] || \ ![muc::is_changing_nick $chatid]} { add_message $chatid $group error \ [::msgcat::mc "Disconnected"] {} set chats(status,$chatid) disconnected client:presence $connid $group unavailable "" {} } } debugmsg chat "$jid UNAVAILABLE" muc::process_unavailable $chatid $nick hook::run chat_user_exit $chatid $nick lvarpop grouproster(users,$chatid) \ [lsearch -exact $grouproster(users,$chatid) $jid] catch { unset grouproster(status,$chatid,$jid) } debugmsg chat "GR: $grouproster(users,$chatid)" chat::redraw_roster_after_idle $chatid } else { if {$chats(status,$chatid) == "disconnected" && \ [is_our_jid $chatid $jid]} { set chats(status,$chatid) connected client:presence $connid $group "" "" {} } set userswin [users_win $chatid] if {![lcontain $grouproster(users,$chatid) $jid]} { #roster::addline $userswin jid $nick $jid lappend grouproster(users,$chatid) $jid set grouproster(status,$chatid,$jid) $status muc::process_available $chatid $nick hook::run chat_user_enter $chatid $nick muc::report_available $chatid $nick 1 } else { muc::report_available $chatid $nick 0 } set grouproster(status,$chatid,$jid) $status ifacetk::roster::changeicon $userswin $jid roster/user/$status ifacetk::roster::changeforeground $userswin $jid $status chat::redraw_roster_after_idle $chatid } } } # This case traces both chat and private groupchat conversations: if {$options(gen_status_change_msgs)} { set chatid [chatid $connid $jid] if {[is_opened $chatid]} { set msg [get_nick $connid $jid chat] append msg " " [::get_long_status_desc [::get_user_status $connid $jid]] set desc [::get_user_status_desc $connid $jid] if {$desc != {}} { append msg " ($desc)" } ::chat::add_message $chatid "" chat $msg {} } } set cw [winid [chatid $connid $jid]] if {[winfo exists $cw.status.icon]} { $cw.status.icon configure \ -image [ifacetk::roster::get_jid_icon $connid $jid $status] \ -helptext [get_user_status_desc $connid $jid] } if {[winfo exists $cw.status.desc]} { $cw.status.desc configure -text "($statusdesc([get_user_status $connid $jid]))" \ -helptext [get_user_status_desc $connid $jid] } set user [node_and_server_from_jid $jid] set cw [winid [chatid $connid $user]] if {[winfo exists $cw.status.icon]} { $cw.status.icon configure \ -image [ifacetk::roster::get_jid_icon \ $connid $user [get_user_status $connid $user]] \ -helptext [get_user_status_desc $connid $user] } } hook::add client_presence_hook chat::change_presence 70 ############################################################################### proc chat::redraw_roster {group} { global grouproster set connid [get_connid $group] set userswin [users_win $group] set grouproster(users,$group) [lsort $grouproster(users,$group)] ifacetk::roster::clear $userswin 0 set levels {} foreach jid $grouproster(users,$group) { if {[info exists ::muc::users(role,$connid,$jid)]} { if {$::muc::users(role,$connid,$jid) == ""} { set level a[::msgcat::mc "Users"] lappend levels $level lappend levelusers($level) $jid } else { if {$::muc::users(role,$connid,$jid) != "" && \ $::muc::users(role,$connid,$jid) != "none"} { set level $::muc::users(role,$connid,$jid) switch -- $level { moderator {set level 4[::msgcat::mc "Moderators"]} participant {set level 5[::msgcat::mc "Participants"]} visitor {set level 6[::msgcat::mc "Visitors"]} } lappend levels $level lappend levelusers($level) $jid } #if {$::muc::users(affiliation,$jid) != "" && \ # $::muc::users(affiliation,$jid) != "none"} { # set level $::muc::users(affiliation,$jid) # switch -- $level { # owner {set level 0Owners} # admin {set level 1Admins} # member {set level 2Members} # outcast {set level 9Outcasts} # } # lappend levels $level # lappend levelusers($level) $jid #} } } else { set level 8[::msgcat::mc "Users"] lappend levels $level lappend levelusers($level) $jid } } set levels [lrmdups $levels] foreach level $levels { ifacetk::roster::addline $userswin group \ "[crange $level 1 end] ([llength $levelusers($level)])" \ [crange $level 1 end] [crange $level 1 end] 0 set jid_nicks {} foreach jid $levelusers($level) { lappend jid_nicks [list $jid [get_nick $connid $jid groupchat]] } set jid_nicks [lsort -index 1 -dictionary $jid_nicks] foreach item $jid_nicks { lassign $item jid nick set status $grouproster(status,$group,$jid) ifacetk::roster::addline $userswin jid $nick \ [list $connid $jid] [crange $level 1 end] 0 ifacetk::roster::changeicon $userswin \ [list $connid $jid] roster/user/$status if {$::plugins::nickcolors::options(use_colored_roster_nicks)} { ifacetk::roster::changeforeground $userswin \ [list $connid $jid] $status \ [plugins::nickcolors::get_color $nick] } else { ifacetk::roster::changeforeground $userswin \ [list $connid $jid] $status } } } ifacetk::roster::update_scrollregion $userswin } proc chat::redraw_roster_after_idle {group} { variable afterid if {[info exists afterid($group)]} \ return set afterid($group) [after idle " chat::redraw_roster [list $group] unset [list chat::afterid($group)] "] } proc chat::restore_subject {chatid} { variable chats set sw [winid $chatid].status.subject if {[is_opened $chatid] && [winfo exists $sw]} { $sw delete 0 end $sw insert 0 $chats(subject,$chatid) } } proc chat::set_subject {chatid subject} { variable chats set cw [winid $chatid] if {[is_opened $chatid]} { $cw.status.subject delete 0 end $cw.status.subject insert 0 $subject set chats(subject,$chatid) $subject } } proc chat::change_subject {chatid} { set cw [winid $chatid] set connid [get_connid $chatid] set jid [get_jid $chatid] set subject [$cw.status.subject get] message::send_msg $jid -connection $connid \ -type groupchat -subject $subject } proc chat::set_subject_balloon {chatid} { variable chats set sw [winid $chatid].status.subject if {[info exists chats(subject_tooltip,$chatid)]} { return [list $chatid $chats(subject_tooltip,$chatid) \ -width [winfo width $sw]] } else { return [list $chatid ""] } } proc chat::set_subject_tooltip {chatid lo hi} { variable chats set sw [winid $chatid].status.subject if {![winfo exists $sw]} return if {($lo == 0) && ($hi == 1)} { set chats(subject_tooltip,$chatid) "" } else { set chats(subject_tooltip,$chatid) [$sw get] } } proc chat::is_our_jid {chatid jid} { return [cequal [our_jid $chatid] $jid] } proc chat::our_jid {chatid} { variable chats set connid [get_connid $chatid] set jid [get_jid $chatid] switch -- $chats(type,$chatid) { groupchat { return $jid/[get_our_groupchat_nick $chatid] } chat { set group [node_and_server_from_jid $jid] set groupid [chatid $connid $group] if {[is_groupchat $groupid]} { return $group/[get_our_groupchat_nick $groupid] } else { return [jlib::connection_jid $connid] } } } return "" } ############################################################################### proc chat::add_invite_menu_item {m connid jid} { $m add command -label [::msgcat::mc "Invite to conference..."] \ -command [list chat::invite_dialog $jid 0 -connection $connid] } hook::add chat_create_user_menu_hook \ [namespace current]::chat::add_invite_menu_item 20 hook::add roster_create_groupchat_user_menu_hook \ [namespace current]::chat::add_invite_menu_item 20 hook::add roster_jid_popup_menu_hook \ [namespace current]::chat::add_invite_menu_item 20 hook::add message_dialog_menu_hook \ [namespace current]::chat::add_invite_menu_item 20 hook::add search_popup_menu_hook \ [namespace current]::chat::add_invite_menu_item 20 proc chat::add_invite2_menu_item {m connid jid} { $m add command -label [::msgcat::mc "Invite users..."] \ -command [list chat::invite_dialog2 $jid 0 -connection $connid] } hook::add chat_create_conference_menu_hook \ [namespace current]::chat::add_invite2_menu_item 20 ############################################################################### proc chat::invite_dialog {user {ignore_muc 0} args} { variable chats global invite_gc foreach {opt val} $args { switch -- $opt { -connection { set connid $val } } } if {![info exists connid]} { set connid [jlib::route $user] } set jid [get_jid_of_user $connid $user] if {[cequal $jid ""]} { set jid $user } set gw .invite catch { destroy $gw } if {[catch { set nick [roster::get_label $user] }]} { if {[catch {set nick [roster::get_label \ [node_and_server_from_jid $user]] }]} { if {[catch { set nick [chat::get_nick $connid \ $user groupchat] }]} { set nick $user } } } set titles {} set jids {} foreach chatid [lsort [lfilter [namespace current]::is_groupchat [opened $connid]]] { lappend jids $chatid [get_jid $chatid] lappend titles $chatid [node_from_jid [get_jid $chatid]] } if {[llength $titles] == 0} { MessageDlg ${gw}_err -aspect 50000 -icon info \ -message \ [format [::msgcat::mc "No conferences for %s in progress..."] \ [jlib::connection_jid $connid]] \ -type user \ -buttons ok -default 0 -cancel 0 return } CbDialog $gw [format [::msgcat::mc "Invite %s to conferences"] $nick] \ [list [::msgcat::mc "Invite"] "chat::invitation [list $jid] 0 $ignore_muc destroy $gw" \ [::msgcat::mc "Cancel"] "destroy $gw"] \ invite_gc $titles $jids } proc chat::invite_dialog2 {jid ignore_muc args} { variable chats global invite_gc foreach {opt val} $args { switch -- $opt { -connection { set connid $val } } } if {![info exists connid]} { set connid [jlib::route $jid] } set gw .invite catch { destroy $gw } set title [node_from_jid $jid] set choices {} set balloons {} foreach choice [roster::get_jids $connid] { if {![cequal [roster::itemconfig $connid $choice -category] conference]} { lappend choices [list $connid $choice] [roster::get_label $connid $choice] lappend balloons [list $connid $choice] $choice } } if {[llength $choices] == 0} { MessageDlg ${gw}_err -aspect 50000 -icon info \ -message \ [format [::msgcat::mc "No users in %s roster..."] \ [jlib::connection_jid $connid]] \ -type user \ -buttons ok -default 0 -cancel 0 return } CbDialog $gw [format [::msgcat::mc "Invite users to %s"] $title] \ [list [::msgcat::mc "Invite"] "chat::invitation [list $jid] 1 $ignore_muc destroy $gw" \ [::msgcat::mc "Cancel"] "destroy $gw"] \ invite_gc $choices $balloons } proc chat::invitation {jid usersP ignore_muc {reason ""}} { global invite_gc foreach choice [array names invite_gc] { if {$invite_gc($choice)} { lassign $choice con gc if {$usersP} { set to $gc set group $jid } else { set to $jid set group $gc } if {[cequal $reason ""]} { set reas [::msgcat::mc "Please join %s" $group] } else { set reas $reason } if {!$ignore_muc && [muc::is_compatible $group]} { muc::invite_muc $con $group $to $reas } else { muc::invite_xconference $con $group $to $reas } } } } ############################################################################# proc chat::restore_window {cjid type nick connid jid} { set chatid [chatid $connid $cjid] if {$type == "groupchat"} { set_our_groupchat_nick $chatid $nick } # TODO: Password? open_window $chatid $type set cw [winid $chatid] raise_win $cw } ############################################################################# proc chat::save_session {vsession} { upvar 2 $vsession session global usetabbar variable chats variable chat_id # TODO if {!$usetabbar} return set prio 0 foreach page [.nb pages] { set path [ifacetk::nbpath $page] if {[info exists chat_id($path)]} { set chatid $chat_id($path) set connid [get_connid $chatid] set jid [get_jid $chatid] set type $chats(type,$chatid) if {$type == "groupchat"} { set nick [get_our_groupchat_nick $chatid] } else { set nick "" } set user [jlib::connection_requested_user $connid] set server [jlib::connection_requested_server $connid] set resource [jlib::connection_requested_resource $connid] lappend session [list $prio $user $server $resource \ [list [namespace current]::restore_window $jid $type $nick] \ ] } incr prio } } hook::add save_session_hook [namespace current]::chat::save_session ############################################################################# # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/login.tcl0000644000175000017500000005230211066760706014351 0ustar sergeisergei# $Id: login.tcl 1503 2008-09-25 19:08:54Z sergei $ if {[lcontain [jlib::capabilities transport] tls]} { set use_tls 1 } else { set use_tls 0 } if {[lcontain [jlib::capabilities transport] compress]} { set have_compress 1 } else { set have_compress 0 } if {[lcontain [jlib::capabilities auth] sasl]} { set have_sasl 1 } else { set have_sasl 0 } if {[llength [jlib::capabilities proxy]] > 1} { set have_proxy 1 } else { set have_proxy 0 } if {[lcontain [jlib::capabilities transport] http_poll]} { set have_http_poll 1 } else { set have_http_poll 0 } custom::defgroup Warnings [::msgcat::mc "Warning display options."] \ -group Tkabber if {$use_tls} { custom::defvar tls_warnings 1 [::msgcat::mc "Display SSL warnings."] \ -group Warnings -type boolean } custom::defgroup Login \ [::msgcat::mc "Login options."] \ -group Tkabber custom::defvar loginconf(user) "" \ [::msgcat::mc "User name."] \ -group Login -type string custom::defvar loginconf(server) "localhost" \ [::msgcat::mc "Server name."] \ -group Login -type string custom::defvar loginconf(password) "" \ [::msgcat::mc "Password."] \ -group Login -type password custom::defvar loginconf(resource) "tkabber" \ [::msgcat::mc "Resource."] \ -group Login -type string custom::defvar loginconf(priority) "8" \ [::msgcat::mc "Priority."] \ -group Login -type integer custom::defvar loginconf(connect_forever) 0 \ [::msgcat::mc "Retry to connect forever."] \ -group Login -type boolean custom::defvar loginconf(allowauthplain) 0 \ [::msgcat::mc "Allow plaintext authentication mechanisms (when password\ is transmitted unencrypted)."] \ -group Login -type boolean custom::defvar loginconf(allowgoogletoken) 1 \ [::msgcat::mc "Allow X-GOOGLE-TOKEN authentication mechanisms. It requires\ connection to Google via HTTPS."] \ -group Login -type boolean if {$have_sasl} { custom::defvar loginconf(usesasl) 1 \ [::msgcat::mc "Use SASL authentication."] \ -group Login -type boolean } set values [list plaintext [::msgcat::mc "Plaintext"]] if {$have_compress} { lappend values compressed [::msgcat::mc "Compression"] } if {$use_tls} { lappend values encrypted [::msgcat::mc "Encryption (STARTTLS)"] \ ssl [::msgcat::mc "Encryption (legacy SSL)"] } if {$use_tls || $have_compress} { custom::defvar loginconf(stream_options) plaintext \ [::msgcat::mc "XMPP stream options when connecting to server."] \ -group Login -type options \ -values $values } if {$use_tls} { custom::defvar loginconf(sslcertfile) "" \ [::msgcat::mc "SSL certificate file (optional)."] \ -group Login -type file custom::defvar loginconf(sslcacertstore) "" \ [::msgcat::mc "SSL certification authority file or directory (optional)."] \ -group Login -type file custom::defvar loginconf(sslkeyfile) "" \ [::msgcat::mc "SSL private key file (optional)."] \ -group Login -type file } if {$have_proxy} { set values {} foreach type [jlib::capabilities proxy] { switch -- $type { none {lappend values none [::msgcat::mc "None"]} socks4 {lappend values socks4 [::msgcat::mc "SOCKS4a"]} socks5 {lappend values socks5 [::msgcat::mc "SOCKS5"]} https {lappend values https [::msgcat::mc "HTTPS"]} } } custom::defvar loginconf(proxy) none \ [::msgcat::mc "Proxy type to connect."] \ -group Login -type options \ -values $values custom::defvar loginconf(proxyhost) "localhost" \ [::msgcat::mc "HTTP proxy address."] \ -group Login -type string custom::defvar loginconf(proxyport) 3128 \ [::msgcat::mc "HTTP proxy port."] \ -group Login -type integer custom::defvar loginconf(proxyusername) "" \ [::msgcat::mc "HTTP proxy username."] \ -group Login -type string custom::defvar loginconf(proxypassword) "" \ [::msgcat::mc "HTTP proxy password."] \ -group Login -type password custom::defvar loginconf(proxyuseragent) \ "Mozilla/4.0 (compatible; MSIE 6.0;\ $::tcl_platform(os) $::tcl_platform(osVersion))" \ [::msgcat::mc "User-Agent string."] \ -group Login -type string } custom::defvar loginconf(usealtserver) 0 \ [::msgcat::mc "Use explicitly-specified server address and port."] \ -group Login -type boolean custom::defvar loginconf(altserver) "" \ [::msgcat::mc "Server name or IP-address."] \ -group Login -type string custom::defvar loginconf(altport) "5222" \ [::msgcat::mc "Server port."] \ -group Login -type integer custom::defvar loginconf(replace_opened) 1 \ [::msgcat::mc "Replace opened connections."] \ -group Login -type boolean if {$have_http_poll} { custom::defvar loginconf(usehttppoll) 0 \ [::msgcat::mc "Use HTTP poll connection method."] \ -group Login -type boolean custom::defvar loginconf(pollurl) "" \ [::msgcat::mc "URL to connect to."] \ -group Login -type string custom::defvar loginconf(usepollkeys) 1 \ [::msgcat::mc "Use HTTP poll client security keys (recommended)."] \ -group Login -type boolean custom::defvar loginconf(numberofpollkeys) 100 \ [::msgcat::mc "Number of HTTP poll client security keys to send\ before creating new key sequence."] \ -group Login -type integer custom::defvar loginconf(polltimeout) 0 \ [::msgcat::mc "Timeout for waiting for HTTP poll responses (if set\ to zero, Tkabber will wait forever)."] \ -group Login -type integer custom::defvar loginconf(pollmin) 6000 \ [::msgcat::mc "Minimum poll interval."] \ -group Login -type integer custom::defvar loginconf(pollmax) 60000 \ [::msgcat::mc "Maximum poll interval."] \ -group Login -type integer } custom::defvar reasonlist {} [::msgcat::mc "List of logout reasons."] \ -group Hidden ###################################################################### # connect errors mapping array set connect_error [list \ err_unknown [::msgcat::mc "Unknown error"] \ timeout [::msgcat::mc "Timeout"] \ network-failure [::msgcat::mc "Network failure"] \ err_authorization_required [::msgcat::mc "Proxy authentication required"] \ err_version [::msgcat::mc "Incorrect SOCKS version"] \ err_unsupported_method [::msgcat::mc "Unsupported SOCKS method"] \ err_authentication_unsupported [::msgcat::mc "Unsupported SOCKS authentication method"] \ err_authorization [::msgcat::mc "SOCKS authentication failed"] \ rsp_failure [::msgcat::mc "SOCKS request failed"] \ rsp_errconnect [::msgcat::mc "SOCKS server cannot identify username"] \ rsp_erruserid [::msgcat::mc "SOCKS server username identification failed"] \ rsp_notallowed [::msgcat::mc "SOCKS connection not allowed by ruleset"] \ rsp_netunreachable [::msgcat::mc "Network unreachable"] \ rsp_hostunreachable [::msgcat::mc "Host unreachable"] \ rsp_refused [::msgcat::mc "Connection refused by destination host"] \ rsp_expired [::msgcat::mc "TTL expired"] \ rsp_cmdunsupported [::msgcat::mc "SOCKS command not supported"] \ rsp_addrunsupported [::msgcat::mc "Address type not supported by SOCKS proxy"] \ err_unknown_address_type [::msgcat::mc "Unknown address type"]] # TLS info # # [::msgcat::mc "Certificate has expired"] # [::msgcat::mc "Self signed certificate"] ###################################################################### proc login {logindata} { global connect_error global login_after_time global login_after_id array set lc $logindata set user $lc(user)@$lc(server)/$lc(resource) if {[info exists login_after_id($user)]} { after cancel $login_after_id($user) unset login_after_id($user) } debugmsg login "Starting login" if {[catch {login_connect $logindata} connid] > 0} { # Nasty thing has happened. debugmsg login "Failed to connect: $connid" if {$lc(connect_forever)} { login_retry $logindata } else { if {[winfo exists .connect_err]} { destroy .connect_err } if {[info exists connect_error($connid)]} { set msg $connect_error($connid) } else { set msg $connid } set res [MessageDlg .connect_err -width 600 -icon error \ -message [format [::msgcat::mc "Failed to connect: %s"] $msg] \ -type user -buttons [list abort [::msgcat::mc "Keep trying"]] \ -default 0 -cancel 0] if {$res} { set lc(connect_forever) 1 set logindata [array get lc] login_retry $logindata } } return } # OK, connected. debugmsg login "Connect successful ($user) $connid" set login_after_time 15000 login_login $logindata $connid } proc login_retry {logindata} { global login_after_time global login_after_id if {![info exists login_after_time]} {set login_after_time 15000} if {$login_after_time < 1800000} { # 1800000 == 30 * 60 * 1000 == 30min # the sequence goes: 30s, 1min, 2min, 4min, 8min, 16min, 32min, 32min... set login_after_time [expr {$login_after_time * 2}] } array set lc $logindata set user $lc(user)@$lc(server)/$lc(resource) debugmsg login "Scheduling connect retry for $user in ${login_after_time}ms" if {[info exists login_after_id($user)]} { after cancel $login_after_id($user) } set login_after_id($user) [after $login_after_time [list login $logindata]] } proc client:tls_callback {connid args} { global tls_result tls_warnings global ssl_certificate_fields global tls_warning_info switch -- [lindex $args 0] { info { set_status [lindex $args 4] } verify { if {[cequal [set reason [lindex $args 5]] ""]} { return 1 } set info [::msgcat::mc [string totitle $reason 0 0]] append tls_warning_info($connid) "$info\n" if {!$tls_warnings} { return 1 } append info [::msgcat::mc ". Proceed?\n\n"] foreach {k v} [lindex $args 3] { switch -- $k { subject - issuer { set v [regsub -all {\s*[/,]\s*(\w+=)} $v \n\t\\1] } } if {![cequal $v ""]} { if {[info exists ssl_certificate_fields($k)]} { append info [format "%s: %s\n" \ $ssl_certificate_fields($k) $v] } else { append info [format "%s: %s\n" $k $v] } } } set blocking [fconfigure [set fd [lindex $args 1]] -blocking] fconfigure $fd -blocking 1 set readable [fileevent $fd readable] fileevent $fd readable {} set res [MessageDlg .tls_callback -aspect 50000 -icon warning \ -type user -buttons {yes no} -default 1 \ -cancel 1 \ -message [string trim $info]] fileevent $fd readable $readable fconfigure $fd -blocking $blocking if {$res} { set res 0 } else { set res 1 } return $res } error { set tls_result [join [lrange $args 2 end] " "] } default { } } } proc login_connect {logindata} { global use_tls have_compress have_sasl have_http_poll have_proxy global tls_warning_info array set lc $logindata set connid [jlib::new -user $lc(user) \ -server $lc(server) \ -resource $lc(resource)] set tls_warning_info($connid) "" set args [list -password $lc(password) \ -allowauthplain $lc(allowauthplain) \ -allowgoogletoken $lc(allowgoogletoken)] if {$have_sasl} { lappend args -usesasl $lc(usesasl) } if {$have_proxy} { if {($lc(proxy) != "none")} { lappend args -proxy $lc(proxy) lappend args -proxyhost $lc(proxyhost) lappend args -proxyport $lc(proxyport) lappend args -proxyusername $lc(proxyusername) lappend args -proxypassword $lc(proxypassword) lappend args -proxyuseragent $lc(proxyuseragent) } else { lappend args -proxy "" } } set ascii_server [idna::domain_toascii $lc(server)] if {$have_http_poll && $lc(usehttppoll)} { if {$lc(pollurl) != ""} { set url $lc(pollurl) } else { set url [jlibdns::get_http_poll_url $ascii_server] } return [eval [list jlib::connect $connid \ -transport http_poll \ -polltimeout $lc(polltimeout) \ -pollint $lc(pollmin) \ -pollmin $lc(pollmin) \ -pollmax $lc(pollmax) \ -httpurl $url \ -httpusekeys $lc(usepollkeys) \ -httpnumkeys $lc(numberofpollkeys)] $args] } else { if {$have_compress && $lc(stream_options) == "compressed"} { lappend args -usecompression 1 } if {$lc(usealtserver)} { set hosts {} } else { set hosts [jlibdns::get_addr_port $ascii_server] if {[lempty $hosts]} { set hosts [list [list $ascii_server 5222]] } } set transport tcp set sslopts {} if {$use_tls} { switch -- $lc(stream_options) { ssl { set usestarttls 0 set transport tls # Do some heuristic. # Traditionally legacy SSL port is 5223, # so let's add 1 to all ports from SRV reply set hosts1 {} foreach hp $hosts { lappend hosts1 \ [list [lindex $hp 0] \ [expr {[lindex $hp 1] + 1}]] } set hosts $hosts1 } encrypted { set usestarttls 1 } default { set usestarttls 0 } } set sslopts [list -usestarttls $usestarttls \ -certfile $lc(sslcertfile) \ -cacertstore $lc(sslcacertstore) \ -keyfile $lc(sslkeyfile)] } if {$lc(usealtserver)} { set hosts [list [list [idna::domain_toascii $lc(altserver)] $lc(altport)]] } return [eval [list jlib::connect $connid \ -transport $transport \ -hosts $hosts] \ $sslopts $args] } } ######################################################################## proc login_login {logindata connid} { global loginconf_hist global gr_nick gr_server gra_server array set lc $logindata set loginconf_hist($connid) $logindata set gr_nick $lc(user) set gr_server conference.$lc(server) set gra_server conference.$lc(server) jlib::login $connid [list recv_auth_result $connid $logindata] } ######################################################################## set reconnect_retries 0 proc logout {{connid {}}} { global reconnect_retries global login_after_id debugmsg login "LOGOUT $connid" # TODO foreach user [array names login_after_id] { after cancel $login_after_id($user) unset login_after_id($user) } if {$connid == {}} { foreach connid [jlib::connections] { disconnected $connid } } else { disconnected $connid } set reconnect_retries 0 } proc client:disconnect {connid} { logout $connid } # TODO proc client:reconnect {connid} { global reconnect_retries global loginconf_hist debugmsg login "RECONNECT $connid" disconnected $connid if {[incr reconnect_retries] <= 3} { after 1000 [list login $loginconf_hist($connid)] } } proc connected {connid logindata} { hook::run connected_hook $connid } # TODO proc disconnected {connid} { global curuserstatus userstatusdesc hook::run predisconnected_hook $connid jlib::disconnect $connid roster::clean_connection $connid if {[jlib::connections] == {}} { set_status "Disconnected" set curuserstatus unavailable set userstatusdesc [::msgcat::mc "Not logged in"] hook::run change_our_presence_post_hook unavailable } hook::run disconnected_hook $connid } proc recv_auth_result {connid logindata res args} { array set lc $logindata if {$res == "OK"} { connected $connid $logindata } else { if {[winfo exists .auth_err$connid]} { destroy .auth_err$connid } lassign [error_type_condition [lindex $args 0]] type cond if {($type == "sasl") || ($type == "auth" && $cond == "not-authorized")} { set res [MessageDlg .auth_err$connid -aspect 50000 -icon error \ -message [format \ [::msgcat::mc "Authentication failed: %s\nCreate new account?"] \ [error_to_string [lindex $args 0]]] \ -type user -buttons {yes no} -default 0 -cancel 1] if {!$res} { jlib::send_iq set \ [jlib::wrapper:createtag query \ -vars {xmlns jabber:iq:register} \ -subtags [list [jlib::wrapper:createtag username \ -chdata $lc(user)] \ [jlib::wrapper:createtag password \ -chdata $lc(password)]]] \ -connection $connid \ -command [list recv_register_result $connid $logindata] return } } else { MessageDlg .auth_err$connid -aspect 50000 -icon error \ -message [format \ [::msgcat::mc "Authentication failed: %s"] \ [error_to_string [lindex $args 0]]] \ -type user -buttons {ok} -default 0 -cancel 0 } logout $connid } } proc recv_register_result {connid logindata res args} { if {$res == "OK"} { jlib::disconnect $connid login $logindata } else { if {[winfo exists .auth_err$connid]} { destroy .auth_err$connid } MessageDlg .auth_err$connid -aspect 50000 -icon error \ -message [format [::msgcat::mc "Registration failed: %s"] \ [error_to_string [lindex $args 0]]] \ -type user -buttons ok -default 0 -cancel 0 logout $connid } } # TODO proc change_password_dialog {} { global oldpassword newpassword password set oldpassword "" set newpassword "" set password "" if {[winfo exists .passwordchange]} { destroy .passwordchange } Dialog .passwordchange -title [::msgcat::mc "Change password"] \ -separator 1 -anchor e -default 0 -cancel 1 .passwordchange add -text [::msgcat::mc "OK"] -command { destroy .passwordchange send_change_password } .passwordchange add -text [::msgcat::mc "Cancel"] -command [list destroy .passwordchange] set p [.passwordchange getframe] label $p.loldpass -text [::msgcat::mc "Old password:"] ecursor_entry [entry $p.oldpass -show * -textvariable oldpassword] label $p.lnewpass -text [::msgcat::mc "New password:"] ecursor_entry [entry $p.newpass -show * -textvariable newpassword] label $p.lpassword -text [::msgcat::mc "Repeat new password:"] ecursor_entry [entry $p.password -show * -textvariable password] grid $p.loldpass -row 0 -column 0 -sticky e grid $p.oldpass -row 0 -column 1 -sticky ew grid $p.lnewpass -row 1 -column 0 -sticky e grid $p.newpass -row 1 -column 1 -sticky ew grid $p.lpassword -row 2 -column 0 -sticky e grid $p.password -row 2 -column 1 -sticky ew focus $p.oldpass .passwordchange draw } # TODO proc send_change_password {} { global loginconf global oldpassword newpassword password if {$oldpassword != $loginconf(password)} { MessageDlg .auth_err -aspect 50000 -icon error \ -message [::msgcat::mc "Old password is incorrect"] \ -type user -buttons ok -default 0 -cancel 0 return } if {$newpassword != $password} { MessageDlg .auth_err -aspect 50000 -icon error \ -message [::msgcat::mc "New passwords do not match"] \ -type user -buttons ok -default 0 -cancel 0 return } set connid [jlib::route $loginconf(server)] jlib::send_iq set \ [jlib::wrapper:createtag query \ -vars {xmlns jabber:iq:register} \ -subtags [list [jlib::wrapper:createtag username \ -chdata $loginconf(user)] \ [jlib::wrapper:createtag password \ -chdata $password]]] \ -to $loginconf(server) \ -connection $connid \ -command recv_change_password_result } # TODO proc recv_change_password_result {res args} { global loginconf global newpassword if {$res == "OK"} { MessageDlg .shpasswd_result -aspect 50000 -icon info \ -message [::msgcat::mc "Password is changed"] \ -type user -buttons ok -default 0 -cancel 0 for {set i 1} {[info exists ::loginconf$i]} {incr i} { if {!([info exists ::loginconf${i}(user)] && \ [info exists ::loginconf${i}(server)] && \ [info exists ::loginconf${i}(password)])} { continue } upvar ::loginconf${i}(user) user upvar ::loginconf${i}(server) server upvar ::loginconf${i}(password) password if {[string equal $user $loginconf(user)] && \ [string equal $server $loginconf(server)] && \ [string equal $password $loginconf(password)]} { set password $newpassword } } set loginconf(password) $newpassword } else { MessageDlg .shpasswd_result -aspect 50000 -icon error \ -message [format [::msgcat::mc "Password change failed: %s"] [error_to_string [lindex $args 0]]] \ -type user -buttons ok -default 0 -cancel 0 } } # TODO proc show_logout_dialog {} { global reason reasonlist set lw .logout if {[winfo exists $lw]} { destroy $lw } Dialog $lw -title [::msgcat::mc "Logout with reason"] \ -separator 1 -anchor e -default 0 -cancel 1 set lf [$lw getframe] grid columnconfigure $lf 1 -weight 1 if {[llength $reasonlist]} {set reason [lindex $reasonlist 0]} label $lf.lreason -text [::msgcat::mc "Reason:"] ecursor_entry [ComboBox $lf.reason -textvariable reason \ -values $reasonlist -width 35].e label $lf.lpriority -text [::msgcat::mc "Priority:"] ecursor_entry [entry $lf.priority -textvariable loginconf(priority)] grid $lf.lreason -row 0 -column 0 -sticky e grid $lf.reason -row 0 -column 1 -sticky ew grid $lf.lpriority -row 1 -column 0 -sticky e grid $lf.priority -row 1 -column 1 -sticky ew $lw add -text [::msgcat::mc "Log out"] -command logout_reason $lw add -text [::msgcat::mc "Cancel"] -command "$lw withdraw" $lw draw $lf.reason } proc logout_reason {} { global logoutuserstatus logouttextstatus logoutpriority reason reasonlist set reasonlist [update_combo_list $reasonlist $reason 10] set lw .logout if {[winfo exists $lw]} { destroy $lw } # TODO set logoutpriority $::loginconf(priority) set logouttextstatus $reason set logoutuserstatus unavailable logout } # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/emoticons/0000755000175000017500000000000011076120366014524 5ustar sergeisergeitkabber-0.11.1/emoticons/default/0000755000175000017500000000000011076120366016150 5ustar sergeisergeitkabber-0.11.1/emoticons/default/facehappy.gif0000644000175000017500000000013510615702573020602 0ustar sergeisergeiGIF89a‘ÿÿÿÿÿ!ù,.”™Ç’áb!Zyê½I <¡‰!hnVª~-§+sù)eöv”|jd¾C;tkabber-0.11.1/emoticons/default/facestartled.gif0000644000175000017500000000013710615702573021305 0ustar sergeisergeiGIF89a‘ÿÿÿÿÿ!ù,0”™Ç’áb!Zyê½I <¡‰!hnVª~-žÊJ†VÇöèÉbGÑMðP;tkabber-0.11.1/emoticons/default/faceironic.gif0000644000175000017500000000013610615702573020745 0ustar sergeisergeiGIF89a‘ÿÿÿÿÿ!ù,/”™Ç’áb!Zyê½I <¡‰!hnVª~mX‚§²’°ÚÙo®o<";52ŠŸ ;tkabber-0.11.1/emoticons/default/facestraight.gif0000644000175000017500000000013310615702573021304 0ustar sergeisergeiGIF89a‘ÿÿÿÿÿ!ù,,”™Ç’áb!Zyê½I <¡‰!hnVª~-‡*JI¾cýv^«gà×ð);tkabber-0.11.1/emoticons/default/facegrinning.gif0000644000175000017500000000015110615702573021272 0ustar sergeisergeiGIF89a‘YÿÈÿÿÿÿÿÿ!ù,:œ ™Ç“áb ZyjxR´Iaøi×ù(ªºU€ ¼°ìº3Ïív÷®Ã“å~ÀŽóµŠ©ÓȨ;tkabber-0.11.1/emoticons/default/facewinking.gif0000644000175000017500000000013610615702573021130 0ustar sergeisergeiGIF89a‘ÿÿÿÿÿ!ù,/”™Ç’áb!Zyê½ý}Z*R nÖ£ri+JêèÈ+VŸ&žÏ ™4Š£;tkabber-0.11.1/emoticons/default/beer.gif0000644000175000017500000000125007526004533017554 0ustar sergeisergeiGIF89aöG>/>=%%(+2E\-_2b.e8r9OBTFTH%^S/ZS=iHmQpJyZhY&fZ2z]2~`yj;VVXZ\c^`c\bzqhKggd`g|vvvddlrˆLˆ\™U‰fˆq”ošq…t9—~.®~‡|SŒ|a€ÿÿŸ’´Œ¼–š”J¡Ÿ^§›iÊ’Ú£†…†’”–—˜›œ¤ žŸ§¦¦­¯´±¯°´´©µ¶¸ÃÂËÓ×ÄÔÔÖæâÞèæèúøû!ùG,þ€84:<>>99-GG<@G"$&" 9D9G"$$$"$# EE8G%$$$"$#=@G$$$ :EGG(006&5'#!GGGG %%$€GGG;tkabber-0.11.1/emoticons/default/icondef.xml0000644000175000017500000000253410615702573020311 0ustar sergeisergei Default 0.0.3 Tkabber's emoticons. Alexey Shchepin 2002-08-12 :-) :) facehappy.gif :-( :( facesad.gif :-O facestartled.gif :-| facestraight.gif :-/ :-\ faceironic.gif :-D :D facegrinning.gif ;-) ;) facewinking.gif :-P :P faceyukky.gif :beer: (B) beer.gif tkabber-0.11.1/emoticons/default/facesad.gif0000644000175000017500000000013610615702573020231 0ustar sergeisergeiGIF89a‘Œ­ÿÿÿÿ!ù,/”™Ç’ábAÆ ÂÁøJ”Eb¥ud¦—*¶« Ÿ¨2:ÖøÙðµíY#C56 £;tkabber-0.11.1/emoticons/default/faceyukky.gif0000644000175000017500000000014110615702573020632 0ustar sergeisergeiGIF89a‘Ìÿÿ)Jÿÿÿ!ù,2œ™Ç“áb!Zyê½I <¡‰!hnVª~aûŠÊ,“’à¥w :Æ;¡¬IÃ1k;tkabber-0.11.1/hooks.tcl0000644000175000017500000000214410644426236014361 0ustar sergeisergei# $Id: hooks.tcl 1149 2007-07-09 12:39:58Z sergei $ namespace eval hook {} proc hook::add {hook func {seq 50}} { variable $hook lappend $hook [list $func $seq] set $hook [lsort -real -index 1 [lsort -unique [set $hook]]] } proc hook::set_flag {hook flag} { variable F set idx [lsearch -exact $F(flags,$hook) $flag] set F(flags,$hook) [lreplace $F(flags,$hook) $idx $idx] } proc hook::unset_flag {hook flag} { variable F if {![lcontain $F(flags,$hook) $flag]} { lappend F(flags,$hook) $flag } } proc hook::is_flag {hook flag} { variable F return [expr ![lcontain $F(flags,$hook) $flag]] } proc hook::run {hook args} { variable F variable $hook if {![info exists $hook]} { return } set F(flags,$hook) {} foreach func_prio [set $hook] { set func [lindex $func_prio 0] set code [catch { eval $func $args } state] debugmsg hook "$hook: $func -> $state (code $code)" if {$code} { ::bgerror "Hook $hook failed\nProcedure\ $func returned code $code\n$state" } if {(!$code) && ([cequal $state stop])} { break } } } tkabber-0.11.1/pubsub.tcl0000644000175000017500000013574210752133252014542 0ustar sergeisergei# $Id: pubsub.tcl 1373 2008-02-05 19:19:06Z sergei $ # # Publish-Subscribe Support (XEP-0060) # Personal Eventing via Pubsub Support (XEP-0163) # ########################################################################## # # Publish-subscribe XEP-0060 # namespace eval pubsub { variable ns array set ns [list \ collections "http://jabber.org/protocol/pubsub#collections" \ config-node "http://jabber.org/protocol/pubsub#config-node" \ create-and-configure "http://jabber.org/protocol/pubsub#create-and-configure" \ create-nodes "http://jabber.org/protocol/pubsub#create-nodes" \ delete-any "http://jabber.org/protocol/pubsub#delete-any" \ delete-nodes "http://jabber.org/protocol/pubsub#delete-nodes" \ get-pending "http://jabber.org/protocol/pubsub#get-pending" \ instant-nodes "http://jabber.org/protocol/pubsub#instant-nodes" \ item-ids "http://jabber.org/protocol/pubsub#item-ids" \ leased-subscription "http://jabber.org/protocol/pubsub#leased-subscription" \ meta-data "http://jabber.org/protocol/pubsub#meta-data" \ manage-subscription "http://jabber.org/protocol/pubsub#manage-subscription" \ modify-affiliations "http://jabber.org/protocol/pubsub#modify-affiliations" \ multi-collection "http://jabber.org/protocol/pubsub#multi-collection" \ multi-subscribe "http://jabber.org/protocol/pubsub#multi-subscribe" \ outcast-affiliation "http://jabber.org/protocol/pubsub#outcast-affiliation" \ persistent-items "http://jabber.org/protocol/pubsub#persistent-items" \ presence-notifications "http://jabber.org/protocol/pubsub#presence-notifications" \ publish "http://jabber.org/protocol/pubsub#publish" \ publisher-affiliation "http://jabber.org/protocol/pubsub#publisher-affiliation" \ purge-nodes "http://jabber.org/protocol/pubsub#purge-nodes" \ retract-items "http://jabber.org/protocol/pubsub#retract-items" \ retrieve-affiliations "http://jabber.org/protocol/pubsub#retrieve-affiliations" \ retrieve-default "http://jabber.org/protocol/pubsub#retrieve-default" \ retrieve-items "http://jabber.org/protocol/pubsub#retrieve-items" \ retrieve-subscriptions "http://jabber.org/protocol/pubsub#retrieve-subscriptions" \ subscribe "http://jabber.org/protocol/pubsub#subscribe" \ subscription-options "http://jabber.org/protocol/pubsub#subscription-options" \ subscription-notifications "http://jabber.org/protocol/pubsub#subscription-notifications" \ subscribe_authorization "http://jabber.org/protocol/pubsub#subscribe_authorization" \ subscribe_options "http://jabber.org/protocol/pubsub#subscribe_options" \ node_config "http://jabber.org/protocol/pubsub#node_config" \ event "http://jabber.org/protocol/pubsub#event"] variable m2a variable a2m set aff_list [list [::msgcat::mc "Owner"] owner \ [::msgcat::mc "Publisher"] publisher \ [::msgcat::mc "None"] none \ [::msgcat::mc "Outcast"] outcast] foreach {m a} $aff_list { set m2a($m) $a set a2m($a) $m } variable m2s variable s2m set subsc_list [list [::msgcat::mc "None"] none \ [::msgcat::mc "Pending"] pending \ [::msgcat::mc "Unconfigured"] unconfigured \ [::msgcat::mc "Subscribed"] subscribed] foreach {m s} $subsc_list { set m2s($m) $s set s2m($s) $m } } ########################################################################## # # Entity use cases (5) # ########################################################################## # # Discover features (5.1) is implemented in disco.tcl # Discover nodes (5.2) is implemented in disco.tcl # Discover node information (5.3) is implemented in disco.tcl # Discover node meta-data (5.4) is implemented in disco.tcl # ########################################################################## # # Discover items for a node (5.5) is NOT implemented in disco.tcl # TODO # ########################################################################## # # Retrieve subscriptions (5.6) # # Evaluates command for attribute lists # proc pubsub::retrieve_subscriptions {service args} { debugmsg pubsub [info level 0] set command "" foreach {key val} $args { switch -- $key { -connection { set connid $val} -command { set command $val } } } if {![info exists connid]} { return -code error \ "pubsub::retrieve_subscriptions: -connection is mandatory" } if {$node == ""} { return -code error "pubsub::retrieve_subscriptions: Node is empty" } jlib::send_iq set \ [jlib::wrapper:createtag pubsub \ -vars [list xmlns $::NS(pubsub)] \ -subtags [list [jlib::wrapper:createtag subscriptions]]] \ -to $service \ -connection $connid \ -command [list [namespace current]::retrieve_subscriptions_result $command] } proc pubsub::retrieve_subscriptions_result {command res child} { debugmsg pubsub [info level 0] if {$res != "OK"} { if {$command != ""} { eval $command [list $res $child] } return } set items {} jlib::wrapper:splitxml $child tag vars isempty chdata children foreach ch $children { jlib::wrapper:splitxml $ch tag1 vars1 isempty1 chdata1 children1 if {$tag1 != "subscriptions"} continue foreach item $children1 { jlib::wrapper:splitxml \ $item tag2 vars2 isempty2 chdata2 children2 if {$tag2 == "subscription"} { lappend items $vars2 } } } if {$command != ""} { eval $command [list $res $items] } } ########################################################################## # # Retrieve affiliations (5.6) # # Evaluates command for attribute lists # proc pubsub::retrieve_affiliations {service args} { debugmsg pubsub [info level 0] set command "" foreach {key val} $args { switch -- $key { -connection { set connid $val} -command { set command $val } } } if {![info exists connid]} { return -code error \ "pubsub::retrieve_affiliations: -connection is mandatory" } if {$node == ""} { return -code error "pubsub::retrieve_affiliations: Node is empty" } jlib::send_iq set \ [jlib::wrapper:createtag pubsub \ -vars [list xmlns $::NS(pubsub)] \ -subtags [list [jlib::wrapper:createtag affiliations]]] \ -to $service \ -connection $connid \ -command [list [namespace current]::retrieve_affiliations_result $command] } proc pubsub::retrieve_affiliations_result {command res child} { debugmsg pubsub [info level 0] if {$res != "OK"} { if {$command != ""} { eval $command [list $res $child] } return } set items {} jlib::wrapper:splitxml $child tag vars isempty chdata children foreach ch $children { jlib::wrapper:splitxml $ch tag1 vars1 isempty1 chdata1 children1 if {$tag1 != "affiliations"} continue foreach item $children1 { jlib::wrapper:splitxml \ $item tag2 vars2 isempty2 chdata2 children2 if {$tag2 == "affiliation"} { lappend items $vars2 } } } if {$command != ""} { eval $command [list $res $items] } } ########################################################################## # # Subscriber use cases (6) # ########################################################################## # # Subscribe to pubsub node "node" at service "service" (6.1) # # if node is empty then it's a subscription to root collection node (9.2) # # -jid "jid" is optional (when it's present it's included to sub request) # # -resource "res" is optional (when it's present bare_jid/res is included # to sub request # # if both options are absent then user's bare JID is included to sub # request # # Optional pubsub#subscribe_options parameters # -deliver # -digest # -expire # -include_body # -show-values # -subscription_type # -subscription_depth # proc pubsub::subscribe {service node args} { variable ns debugmsg pubsub [info level 0] set command "" set options {} foreach {key val} $args { switch -- $key { -jid { set jid $val } -resource { set resource $val } -connection { set connid $val} -command { set command $val } -deliver - -digest - -expire - -include_body - -show-values - -subscription_type - -subscription_depth { lappend options [field "pubsub#[string range $opt 1 end]" $val] } } } if {![info exists connid]} { return -code error "pubsub::subscribe: -connection is mandatory" } if {![info exists jid]} { set jid [jlib::connection_bare_jid $connid] } if {[info exists resource]} { append jid "/$resource" } set vars [list jid $jid] if {$node != ""} { lappend vars node $node } if {![lempty $options]} { set options \ [list [jlib::wrapper:createtag options \ -subtags \ [list [jlib::wrapper:createtag x \ -vars [list xmlns $::NS(data) \ type submit] \ -subtags \ [linsert $options 0 \ [form_type $ns(subscribe_options)]]]]]] } jlib::send_iq set \ [jlib::wrapper:createtag pubsub \ -vars [list xmlns $::NS(pubsub)] \ -subtags [concat [list [jlib::wrapper:createtag subscribe \ -vars $vars]] \ $options]] \ -to $service \ -connection $connid \ -command [list [namespace current]::subscribe_result $command] } proc pubsub::subscribe_result {command res child} { debugmsg pubsub [info level 0] if {$res == "OK"} { jlib::wrapper:splitxml $child tag vars isempty chdata children if {[jlib::wrapper:getattr $vars xmlns] == $::NS(pubsub)} { foreach child1 $children { jlib::wrapper:splitxml \ $child1 tag1 vars1 isempty1 chdata1 children1 if {$tag == "subscription"} { set node [jlib::wrapper:getattr $vars1 node] set jid [jlib::wrapper:getattr $vars1 jid] set subid [jlib::wrapper:getattr $vars1 subid] set subscription \ [jlib::wrapper:getattr $vars1 subscription] # TODO: subscription-options if {$command != ""} { eval $command [list $res \ [list $node $jid \ $subid $subscription]] return } } } if {$command != ""} { # Something strange: OK without subscription details eval $command [list $res {}] return } } } if {$command != ""} { eval $command [list $res $child] } } ########################################################################## # # Unsubscribe from pubsub node "node" at service "service" (6.2) # # if node is empty then it's a unsubscription from root collection node (9.2) # # -jid "jid" is optional (when it's present it's included to sub request) # # -resource "res" is optional (when it's present bare_jid/res is included # to sub request # # if both options are absent then user's bare JID is included to sub # request # proc pubsub::unsubscribe {service node args} { debugmsg pubsub [info level 0] set command "" foreach {key val} $args { switch -- $key { -jid { set jid $val } -subid { set subid $val } -resource { set resource $val } -connection { set connid $val} -command { set command $val } } } if {![info exists connid]} { return -code error "pubsub::unsubscribe: -connection is mandatory" } if {![info exists jid]} { set jid [jlib::connection_bare_jid $connid] } if {[info exists resource]} { append jid "/$resource" } set vars [list jid $jid] if {$node != ""} { lappend vars node $node } if {[info exists subid]} { lappend vars subid $subid } jlib::send_iq set \ [jlib::wrapper:createtag pubsub \ -vars [list xmlns $::NS(pubsub)] \ -subtags [list [jlib::wrapper:createtag unsubscribe \ -vars $vars]]] \ -to $service \ -connection $connid \ -command [list [namespace current]::unsubscribe_result $command] } proc pubsub::unsubscribe_result {command res child} { debugmsg pubsub [info level 0] if {$command != ""} { eval $command [list $res $child] } } ########################################################################## # # Configure subscription options (6.3) # proc pubsub::request_subscription_options {service node args} { debugmsg pubsub [info level 0] set command "" foreach {key val} $args { switch -- $key { -jid { set jid $val } -subid { set subid $val } -resource { set resource $val } -connection { set connid $val} -command { set command $val } } } if {![info exists connid]} { return -code error \ "pubsub::request_subscription_options: -connection is mandatory" } if {$node == ""} { return -code error \ "pubsub::request_subscription_options: Node is empty" } if {![info exists jid]} { set jid [jlib::connection_bare_jid $connid] } if {[info exists resource]} { append jid "/$resource" } if {[info exists subid]} { set vars [list node $node subid $subid jid $jid] } else { set vars [list node $node jid $jid] } jlib::send_iq get \ [jlib::wrapper:createtag pubsub \ -vars [list xmlns $::NS(pubsub)] \ -subtags [list [jlib::wrapper:createtag options \ -vars $vars]]] \ -to $service \ -connection $connid \ -command [list [namespace current]::subscription_options_result \ $connid $service $command] } proc pubsub::subscription_options_result {connid service command res child} { debugmsg pubsub [info level 0] if {$res != "OK"} { if {$command != ""} { eval $command [list $res $child] } return } jlib::wrapper:splitxml $child tag vars isempty chdata children foreach ch $children { jlib::wrapper:splitxml $ch tag1 vars1 isempty1 chdata1 children1 if {$tag1 == "options"} { jlib::wrapper:splitxml \ [lindex $children1 0] tag2 vars2 isempty2 chdata2 children2 set node [jlib::wrapper:getattr $vars2 node] set jid [jlib::wrapper:getattr $vars2 jid] set subid [jlib::wrapper:getattr $vars2 subid] break } } data::draw_window $children2 \ [list [namespace current]::send_subscribe_options $connid $service $node $jid $subid $command] } proc pubsub::send_subscribe_options {connid service node jid subid command w restags} { debugmsg pubsub [info level 0] destroy $w.error.msg $w.bbox itemconfigure 0 -state disabled if {$subid != ""} { set vars [list node $node subid $subid jid $jid] } else { set vars [list node $node jid $jid] } jlib::send_iq set [jlib::wrapper:createtag pubsub \ -vars [list xmlns $::NS(pubsub)] \ -subtags [jlib::wrapper:createtag options \ -vars $vars \ -subtags $restags]] \ -to $service \ -connection $connid \ -command [list data::test_error_res $w] } ########################################################################## # # Retrieve items for a node (6.4) # Node must not be empty # Evaluates command with list of items # # -max_items $number (request $number last items) # -items $item_id_list (request specific items) proc pubsub::retrieve_items {service node args} { debugmsg pubsub [info level 0] set command "" set items {} foreach {key val} $args { switch -- $key { -connection { set connid $val } -command { set command $val } -subid { set subid $val } -max_items { set max_items $val } -items { foreach id $val { lappend items [jlib::wrapper:createtag item -vars [list id $id]] } } } } if {![info exists connid]} { return -code error \ "pubsub::retrieve_items: -connection is mandatory" } if {$node == ""} { return -code error "pubsub::retrieve_items: Node is empty" } if {[info exists subid]} { set vars [list node $node subid $subid] } else { set vars [list node $node] } if {[info exists max_items]} { lappend vars max_items $max_items } jlib::send_iq set \ [jlib::wrapper:createtag pubsub \ -vars [list xmlns $::NS(pubsub)] \ -subtags [list [jlib::wrapper:createtag items \ -vars $vars \ -subtags $items]]] \ -to $service \ -connection $connid \ -command [list [namespace current]::get_items_result $command] } proc pubsub::get_items_result {command res child} { debugmsg pubsub [info level 0] if {$res != "OK"} { if {$command != ""} { eval $command [list $res $child] } return } set items {} jlib::wrapper:splitxml $child tag vars isempty chdata children foreach ch $children { jlib::wrapper:splitxml $ch tag1 vars1 isempty1 chdata1 children1 if {$tag1 != "items"} continue foreach item $children1 { jlib::wrapper:splitxml \ $item tag2 vars2 isempty2 chdata2 children2 if {$tag2 == "item"} { lappend items $item } } } if {$command != ""} { eval $command [list $res $items] } } ########################################################################## # # Publisher use cases (7) # ########################################################################## # # Publish item "itemid" to pubsub node "node" at service "service" (7.1) # payload is a LIST of xml tags # node must not be empty proc pubsub::publish_item {service node itemid args} { debugmsg pubsub [info level 0] set command "" set payload {} set transient 0 foreach {key val} $args { switch -- $key { -transient { set transient $val } -payload { set payload $val } -connection { set connid $val} -command { set command $val } } } if {![info exists connid]} { return -code error "pubsub::publish_item: -connection is mandatory" } if {$node == ""} { return -code error "pubsub::publish_item: Node is empty" } if {$itemid == ""} { set vars {} } else { set vars [list id $itemid] } if {$transient} { set item {} } else { set item [list [jlib::wrapper:createtag item \ -vars $vars \ -subtags $payload]] } jlib::send_iq set \ [jlib::wrapper:createtag pubsub \ -vars [list xmlns $::NS(pubsub)] \ -subtags [list [jlib::wrapper:createtag publish \ -vars [list node $node] \ -subtags $item]]] \ -to $service \ -connection $connid \ -command [list [namespace current]::publish_item_result $command] } proc pubsub::publish_item_result {command res child} { debugmsg pubsub [info level 0] if {$command != ""} { eval $command [list $res $child] } } ########################################################################## # # Delete item "itemid" from pubsub node "node" at service "service" (7.2) # node and itemid must not be empty # -notify is a boolean (true, false, 1, 0) proc pubsub::delete_item {service node itemid args} { debugmsg pubsub [info level 0] set command "" set notify 0 foreach {key val} $args { switch -- $key { -notify { set notify $val } -connection { set connid $val} -command { set command $val } } } if {![info exists connid]} { return -code error "pubsub::delete_item: -connection is mandatory" } if {$node == ""} { return -code error "pubsub::delete_item: Node is empty" } if {$itemid == ""} { return -code error "pubsub::delete_item: Item ID is empty" } set vars [list node $node] if {[string is true -strict $notify]} { lappend vars notify true } jlib::send_iq set \ [jlib::wrapper:createtag pubsub \ -vars [list xmlns $::NS(pubsub)] \ -subtags \ [list [jlib::wrapper:createtag retract \ -vars $vars \ -subtags \ [list [jlib::wrapper:createtag item \ -vars [list id $itemid]]]]]] \ -to $service \ -connection $connid \ -command [list [namespace current]::delete_item_result $command] } proc pubsub::delete_item_result {command res child} { debugmsg pubsub [info level 0] if {$command != ""} { eval $command [list $res $child] } } ########################################################################## # # Owner use cases (8) # ########################################################################## # # Create pubsub node "node" at service "service" (8.1) # # 8.1.2 create_node service node -connection connid -command callback # or create_node service node -access_model model -connection connid \ # -command callback # # 8.1.3 create_node service node -connection connid -command callback \ # -title title \ # ........... \ # -body_xslt xslt # # Optional pubsub#node_config parameters # -access_model # -body_xslt # -collection # -dataform_xslt # -deliver_notifications # -deliver_payloads # -itemreply # -children_association_policy # -children_association_whitelist # -children # -children_max # -max_items # -max_payload_size # -node_type # -notify_config # -notify_delete # -notify_retract # -persist_items # -presence_based_delivery # -publish_model # -replyroom # -replyto # -roster_groups_allowed # -send_last_published_item # -subscribe # -title # -type proc pubsub::create_node {service node args} { variable ns debugmsg pubsub [info level 0] set command "" set options {} set fields {} foreach {key val} $args { switch -- $key { -connection { set connid $val} -command { set command $val } -access_model - -body_xslt - -collection - -dataform_xslt - -deliver_notifications - -deliver_payloads - -itemreply - -children_association_policy - -children_association_whitelist - -children - -children_max - -max_items - -max_payload_size - -node_type - -notify_config - -notify_delete - -notify_retract - -persist_items - -presence_based_delivery - -publish_model - -replyroom - -replyto - -roster_groups_allowed - -send_last_published_item - -subscribe - -title - -type { lappend fields [field "pubsub#[string range $opt 1 end]" $val] } } } if {![info exists connid]} { return -code error "pubsub::create_node: -connection is mandatory" } if {$node == ""} { set vars {} } else { set vars [list node $node] } if {![lempty $fields]} { set fields [linsert $fields 0 [form_type $ns(node_config)]] set fields \ [list [jlib::wrapper:createtag x \ -vars [list xmlns $::NS(data) \ type submit] \ -subtags \ [linsert $fields 0 \ [form_type $ns(node_config)]]]] } jlib::send_iq set \ [jlib::wrapper:createtag pubsub \ -vars [list xmlns $::NS(pubsub)] \ -subtags [list [jlib::wrapper:createtag create \ -vars $vars] \ [jlib::wrapper:createtag configure \ -subtags $fields]]] \ -to $service \ -connection $connid \ -command [list [namespace current]::create_node_result \ $node $command] } proc pubsub::form_type {value} { return [jlib::wrapper:createtag field \ -vars [list var FORM_TYPE \ type hidden] -subtags [list [jlib::wrapper:createtag value \ -chdata $value]]] } proc pubsub::field {var value} { return [jlib::wrapper:createtag field \ -vars [list var $var] \ -subtags [list [jlib::wrapper:createtag value \ -chdata $value]]] } proc pubsub::create_node_result {node command res child} { debugmsg pubsub [info level 0] if {$res == "OK" && $node == ""} { # Instant node: get node name from the answer jlib::wrapper:splitxml $child tag vars isempty chdata children if {[jlib::wrapper:getattr $vars xmlns] == $::NS(pubsub)} { foreach child1 $children { jlib::wrapper:splitxml \ $child1 tag1 vars1 isempty1 chdata1 children1 if {$tag == "create"} { set node [jlib::wrapper:getattr $vars1 node] } } } } if {$command != ""} { eval $command [list $node $res $child] } } ########################################################################## # # Configure pubsub node "node" at service "service" (8.2) # node must not be empty # proc pubsub::configure_node {service node args} { debugmsg pubsub [info level 0] set command "" foreach {key val} $args { switch -- $key { -connection { set connid $val} -command { set command $val } } } if {![info exists connid]} { return -code error "pubsub::configure_node: -connection is mandatory" } if {$node == ""} { return -code error \ "pubsub::configure_node: Node is empty" } jlib::send_iq set \ [jlib::wrapper:createtag pubsub \ -vars [list xmlns $::NS(pubsub#owner)] \ -subtags [list [jlib::wrapper:createtag configure \ -vars [list node $node]]] \ -to $service \ -connection $connid \ -command [list [namespace current]::configure_node_result \ $connid $service $command] } proc pubsub::configure_node_result {connid service command res child} { debugmsg pubsub [info level 0] if {$res != "OK"} { if {$command != ""} { eval $command [list $res $child] } return } jlib::wrapper:splitxml $child tag vars isempty chdata children foreach ch $children { jlib::wrapper:splitxml $ch tag1 vars1 isempty1 chdata1 children1 if {$tag1 == "configure"} { set node [jlib::wrapper:getattr $vars1 node] jlib::wrapper:splitxml \ [lindex $children1 0] tag2 vars2 isempty2 chdata2 children2 break } } data::draw_window $children2 \ [list [namespace current]::send_configure_node $connid $service $node $command] } proc pubsub::send_configure_node {connid service node command w restags} { debugmsg pubsub [info level 0] destroy $w.error.msg $w.bbox itemconfigure 0 -state disabled jlib::send_iq set [jlib::wrapper:createtag pubsub \ -vars [list xmlns $::NS(pubsub#owner)] \ -subtags [jlib::wrapper:createtag configure \ -vars [list node $node] \ -subtags $restags]] \ -to $service \ -connection $connid \ -command [list data::test_error_res $w] } ########################################################################## # # Request default configuration options (8.3) # proc pubsub::request_default {service args} { variable ns debugmsg pubsub [info level 0] set command "" set form [jlib::wrapper:createtag default] foreach {key val} $args { switch -- $key { -connection { set connid $val} -command { set command $val } -node_type { set form \ [jlib::wrapper:createtag default \ -subtags [list [jlib::wrapper:createtag x \ -vars [list xmlns $::NS(data) \ type submit] \ -subtags [list [form_type $ns(node_config)] \ [field pubsub#node_type $val]]]]] } } } if {![info exists connid]} { return -code error "pubsub::request_default: -connection is mandatory" } if {$node == ""} { return -code error \ "pubsub::request_default: Node is empty" } jlib::send_iq set \ [jlib::wrapper:createtag pubsub \ -vars [list xmlns $::NS(pubsub#owner)] \ -subtags [list $form] \ -to $service \ -connection $connid \ -command [list [namespace current]::request_default_result \ $connid $service $command] } proc pubsub::request_default_result {connid service command res child} { debugmsg pubsub [info level 0] if {$res != "OK"} { if {$command != ""} { eval $command [list $res $child] } return } jlib::wrapper:splitxml $child tag vars isempty chdata children foreach ch $children { jlib::wrapper:splitxml $ch tag1 vars1 isempty1 chdata1 children1 if {$tag1 == "default"} { jlib::wrapper:splitxml \ [lindex $children1 0] tag2 vars2 isempty2 chdata2 children2 break } } # TODO: Don't send the form data::draw_window $children2 \ [list [namespace current]::send_request_results $connid $service $node $command] } proc pubsub::send_request_results {connid service node command w restags} { debugmsg pubsub [info level 0] destroy $w.error.msg $w.bbox itemconfigure 0 -state disabled jlib::send_iq set [jlib::wrapper:createtag pubsub \ -vars [list xmlns $::NS(pubsub#owner)] \ -subtags [jlib::wrapper:createtag default \ -subtags $restags]] \ -to $service \ -connection $connid \ -command [list data::test_error_res $w] } ########################################################################## # # Delete a node (8.4) # node must not be empty # proc pubsub::delete_node {service node args} { debugmsg pubsub [info level 0] set command "" foreach {key val} $args { switch -- $key { -connection { set connid $val} -command { set command $val } } } if {![info exists connid]} { return -code error "pubsub::delete_node: -connection is mandatory" } if {$node == ""} { return -code error "pubsub::delete_node: Node is empty" } jlib::send_iq set \ [jlib::wrapper:createtag pubsub \ -vars [list xmlns $::NS(pubsub#owner)] \ -subtags [list [jlib::wrapper:createtag delete \ -vars [list node $node]]] \ -to $service \ -connection $connid \ -command [list [namespace current]::delete_node_result $command] } proc pubsub::delete_node_result {command res child} { debugmsg pubsub [info level 0] if {$command != ""} { eval $command [list $res $child] } } ########################################################################## # # Purge all node items (8.5) # node must not be empty # proc pubsub::purge_items {service node args} { debugmsg pubsub [info level 0] set command "" foreach {key val} $args { switch -- $key { -connection { set connid $val} -command { set command $val } } } if {![info exists connid]} { return -code error "pubsub::purge_items: -connection is mandatory" } if {$node == ""} { return -code error "pubsub::purge_items: Node is empty" } jlib::send_iq set \ [jlib::wrapper:createtag pubsub \ -vars [list xmlns $::NS(pubsub#owner)] \ -subtags [list [jlib::wrapper:createtag purge \ -vars [list node $node]]] \ -to $service \ -connection $connid \ -command [list [namespace current]::purge_items_result $command] } proc pubsub::purge_items_result {command res child} { debugmsg pubsub [info level 0] if {$command != ""} { eval $command [list $res $child] } } ########################################################################## # # Manage subscription requests (8.6) # is done in messages.tcl # ########################################################################## # # Request all pending subscription requests (8.6.1) # proc pubsub::request_pending_subscription {service args} { variable ns debugmsg pubsub [info level 0] foreach {key val} $args { switch -- $key { -connection { set connid $val} } } if {![info exists connid]} { return -code error \ "pubsub::request_pending_subscription: -connection is mandatory" } # Let xcommands.tcl do the job xcommands::execute $service $ns(get-pending) -connection $connid } ########################################################################## # # Manage subscriptions (8.7) # # Callback is called with list of entities: # {jid JID subscription SUB subid ID} # proc pubsub::request_subscriptions {service node args} { debugmsg pubsub [info level 0] set command "" foreach {key val} $args { switch -- $key { -connection { set connid $val} -command { set command $val } } } if {![info exists connid]} { return -code error \ "pubsub::request_subscriptions: -connection is mandatory" } if {$node == ""} { return -code error "pubsub::request_subscriptions: Node is empty" } jlib::send_iq set \ [jlib::wrapper:createtag pubsub \ -vars [list xmlns $::NS(pubsub#owner)] \ -subtags [list [jlib::wrapper:createtag subscriptions \ -vars [list node $node]]]] \ -to $service \ -connection $connid \ -command [list [namespace current]::subscriptions_result $command] } proc pubsub::subscriptions_result {command res child} { debugmsg pubsub [info level 0] if {$res != "OK"} { if {$command != ""} { eval $command [list $res $child] } return } set entities {} jlib::wrapper:splitxml $child tag vars isempty chdata children foreach ch $children { jlib::wrapper:splitxml $ch tag1 vars1 isempty1 chdata1 children1 if {$tag1 != "subscriptions"} continue foreach entity $children1 { jlib::wrapper:splitxml \ $entity tag2 vars2 isempty2 chdata2 children2 if {$tag2 == "subscription"} { lappend entities $vars2 } } } if {$command != ""} { eval $command [list $res $entities] } } ########################################################################## proc pubsub::modify_subscriptions {service node entities args} { debugmsg pubsub [info level 0] set command "" foreach {key val} $args { switch -- $key { -connection { set connid $val} -command { set command $val } } } if {![info exists connid]} { return -code error \ "pubsub::modify_subscriptions: -connection is mandatory" } if {$node == ""} { return -code error "pubsub::modify_subscriptions: Node is empty" } set subscriptions {} foreach entity $entities { lappend subscriptions [jlib::wrapper:createtag subscription \ -vars $entity] } jlib::send_iq set \ [jlib::wrapper:createtag pubsub \ -vars [list xmlns $::NS(pubsub#owner)] \ -subtags [list [jlib::wrapper:createtag subscriptions \ -vars [list node $node] \ -subtags $subscriptions]]] \ -to $service \ -connection $connid \ -command [list [namespace current]::modify_subscriptions_result $command] } proc pubsub::modify_subscriptions_result {command res child} { debugmsg pubsub [info level 0] if {$command != ""} { eval $command [list $res $child] } } ########################################################################## # # Retrieve current affiliations (8.8) # Evaluates command with list of entity attributes lists # proc pubsub::request_affiliations {service node args} { debugmsg pubsub [info level 0] set command "" foreach {key val} $args { switch -- $key { -connection { set connid $val} -command { set command $val } } } if {![info exists connid]} { return -code error \ "pubsub::request_affiliations: -connection is mandatory" } if {$node == ""} { return -code error "pubsub::request_affiliations: Node is empty" } jlib::send_iq set \ [jlib::wrapper:createtag pubsub \ -vars [list xmlns $::NS(pubsub#owner)] \ -subtags [list [jlib::wrapper:createtag affiliations]]] \ -to $service \ -connection $connid \ -command [list [namespace current]::affiliations_result $command] } proc pubsub::affiliations_result {command res child} { debugmsg pubsub [info level 0] if {$res != "OK"} { if {$command != ""} { eval $command [list $res $child] } return } set entities {} jlib::wrapper:splitxml $child tag vars isempty chdata children foreach ch $children { jlib::wrapper:splitxml $ch tag1 vars1 isempty1 chdata1 children1 if {$tag1 != "affiliations"} continue foreach entity $children1 { jlib::wrapper:splitxml \ $entity tag2 vars2 isempty2 chdata2 children2 if {$tag2 == "affiliation"} { lappend entities $vars2 } } } if {$command != ""} { eval $command [list $res $entities] } } ########################################################################## proc pubsub::modify_affiliations {service node entities args} { debugmsg pubsub [info level 0] set command "" foreach {key val} $args { switch -- $key { -connection { set connid $val} -command { set command $val } } } if {![info exists connid]} { return -code error \ "pubsub::modify_subscriptions: -connection is mandatory" } if {$node == ""} { return -code error "pubsub::modify_subscriptions: Node is empty" } set affiliations {} foreach entity $entities { lappend affiliations [jlib::wrapper:createtag affiliation \ -vars $entity] } jlib::send_iq set \ [jlib::wrapper:createtag pubsub \ -vars [list xmlns $::NS(pubsub#owner)] \ -subtags [list [jlib::wrapper:createtag affiliations \ -vars [list node $node] \ -subtags $affiliations]]] \ -to $service \ -connection $connid \ -command [list [namespace current]::modify_affiliations_result $command] } proc pubsub::modify_affiliations_result {command res child} { debugmsg pubsub [info level 0] if {$command != ""} { eval $command [list $res $child] } } ########################################################################## # # Modifying entity affiliations # node must not be empty # TODO # proc pubsub::request_entities {service node args} { debugmsg pubsub [info level 0] set command "" foreach {key val} $args { switch -- $key { -connection { set connid $val} -command { set command $val } } } if {![info exists connid]} { return -code error \ "pubsub::request_entities: -connection is mandatory" } if {$node == ""} { return -code error "pubsub::request_entities error: Node is empty" } jlib::send_iq set \ [jlib::wrapper:createtag pubsub \ -vars [list xmlns $::NS(pubsub)] \ -subtags \ [list [jlib::wrapper:createtag entities \ -vars [list node $node]]] \ -to $service \ -connection $connid \ -command [list [namespace current]::receive_entities \ $connid $service $command] } proc pubsub::receive_entities {connid service command res child} { variable winid debugmsg pubsub [info level 0] if {$res != "OK"} { if {$command != ""} { eval $command [list $res $child] } } jlib::wrapper:splitxml $child tag vars isempty chdata children foreach child1 $children { jlib::wrapper:splitxml $child1 tag1 vars1 isempty1 chdata1 children1 if {$tag1 == "entities"} { set node [jlib::wrapper:getattr $vars1 node] set entities $children1 break } } if {![info exists winid]} { set winid 0 } else { incr winid } set w .pubsub_entities$winid if {[winfo exists $w]} { destroy $w } Dialog $w -title [::msgcat::mc "Edit entities affiliations: %s" $node] \ -modal none -separator 1 -anchor e -default 0 -cancel 1 \ -parent . set wf [$w getframe] set sw [ScrolledWindow $wf.sw -scrollbar vertical] set sf [ScrollableFrame $w.fields -constrainedwidth yes] set f [$sf getframe] $sw setwidget $sf fill_list $sf $f $entities list_add_item $sf $f $w add -text [::msgcat::mc "Send"] \ -command [list [namespace current]::send_entities \ $connid $service $node $w $f] $w add -text [::msgcat::mc "Cancel"] -command [list destroy $w] bind $w \ [list after idle [list [namespace current]::cleanup_entities $w $f]] button $w.add -text [::msgcat::mc "Add"] \ -command [list [namespace current]::list_add_item $sf $f] pack $w.add -side bottom -anchor e -in $wf -padx 1m -pady 1m pack $sw -side top -expand yes -fill both bindscroll $f $sf set hf [frame $w.hf] pack $hf -side top set vf [frame $w.vf] pack $vf -side left update idletasks $hf configure -width [expr {[winfo reqwidth $f] + [winfo pixels $f 1c]}] set h [winfo reqheight $f] set sh [winfo screenheight $w] if {$h > $sh - 200} { set h [expr {$sh - 200}] } $vf configure -height $h $w draw } proc pubsub::fill_list {sf f entities} { variable a2m variable s2m variable listdata variable origlistdata debugmsg pubsub [info level 0] grid columnconfigure $f 0 -weight 1 grid columnconfigure $f 1 -weight 1 grid columnconfigure $f 2 -weight 1 grid columnconfigure $f 3 -weight 1 label $f.ljid -text [::msgcat::mc "Jabber ID"] grid $f.ljid -row 0 -column 0 -sticky we -padx 1m bindscroll $f.ljid $sf label $f.lsubid -text [::msgcat::mc "SubID"] grid $f.lsubid -row 0 -column 1 -sticky we -padx 1m bindscroll $f.lsubid $sf label $f.laffiliation -text [::msgcat::mc "Affiliation"] grid $f.laffiliation -row 0 -column 2 -sticky we -padx 1m bindscroll $f.laffiliation $sf label $f.lsubscription -text [::msgcat::mc "Subscription"] grid $f.lsubscription -row 0 -column 3 -sticky we -padx 1m bindscroll $f.lsubscription $sf set row 1 set entities2 {} foreach entity $entities { jlib::wrapper:splitxml $entity tag vars isempty chdata children switch -- $tag { entity { set jid [jlib::wrapper:getattr $vars jid] set subid [jlib::wrapper:getattr $vars subid] set affiliation [jlib::wrapper:getattr $vars affiliation] set subscription [jlib::wrapper:getattr $vars subscription] lappend entities2 [list $jid $subid $affiliation $subscription] } } } foreach entity [lsort -dictionary -index 0 $entities2] { lassign $item jid subid affiliation subscription label $f.jid$row -text $jid \ -textvariable [namespace current]::listdata($f,jid,$row) grid $f.jid$row -row $row -column 0 -sticky w -padx 1m bindscroll $f.jid$row $sf label $f.subid$row -text $subid \ -textvariable [namespace current]::listdata($f,subid,$row) grid $f.subid$row -row $row -column 1 -sticky w -padx 1m bindscroll $f.subid$row $sf ComboBox $f.affiliation$row -text $a2m($affiliation) \ -values [list $a2m(owner) \ $a2m(publisher) \ $a2m(none) \ $a2m(outcast)] \ -editable no \ -width 9 \ -textvariable [namespace current]::listdata($f,affiliation,$row) grid $f.affiliation$row -row $row -column 2 -sticky we -padx 1m bindscroll $f.affiliation$row $sf ComboBox $f.subscription$row -text $s2m($subscription) \ -values [list $s2m(none) \ $s2m(pending) \ $s2m(unconfigured) \ $s2m(subscribed)] \ -editable no \ -width 12 \ -textvariable [namespace current]::listdata($f,subscription,$row) grid $f.subscription$row -row $row -column 3 -sticky we -padx 1m bindscroll $f.subscription$row $sf incr row } set listdata($f,rows) $row array set origlistdata [array get listdata $f,*] } proc pubsub::list_add_item {sf f} { variable a2m variable s2m variable listdata debugmsg pubsub [info level 0] set row $listdata($f,rows) entry $f.jid$row \ -textvariable [namespace current]::listdata($f,jid,$row) grid $f.jid$row -row $row -column 0 -sticky we -padx 1m bindscroll $f.jid$row $sf entry $f.subid$row \ -textvariable [namespace current]::listdata($f,subid,$row) grid $f.subid$row -row $row -column 1 -sticky we -padx 1m bindscroll $f.subid$row $sf ComboBox $f.affiliation$row -text $a2m(none) \ -values [list $a2m(owner) \ $a2m(publisher) \ $a2m(none) \ $a2m(outcast)] \ -editable no \ -width 9 \ -textvariable [namespace current]::listdata($f,affiliation,$row) grid $f.affiliation$row -row $row -column 2 -sticky we -padx 1m bindscroll $f.affiliation$row $sf ComboBox $f.subscription$row -text $s2m(none) \ -values [list $s2m(none) \ $s2m(pending) \ $s2m(unconfigured) \ $s2m(subscribed)] \ -editable no \ -width 12 \ -textvariable [namespace current]::listdata($f,subscription,$row) grid $f.subscription$row -row $row -column 3 -sticky we -padx 1m bindscroll $f.subscription$row $sf incr listdata($f,rows) } proc pubsub::send_entities {connid service node w f} { variable origlistdata variable listdata debugmsg pubsub [info level 0] set entities {} for {set i 1} {$i < $origlistdata($f,rows)} {incr i} { set vars {} if {$listdata($f,affiliation,$i) != $origlistdata($f,affiliation,$i)} { lappend vars affiliation $listdata($f,affiliation,$i) } if {$listdata($f,subscription,$i) != $origlistdata($f,subscription,$i)} { lappend vars subscription $listdata($f,subscription,$i) } if {$vars != {} && $origlistdata($f,jid,$i) != ""} { lappend vars jid $origlistdata($f,jid,$i) lappend entities [jlib::wrapper:createtag entity \ -vars $vars] } } for {} {$i < $listdata($f,rows)} {incr i} { set vars1 {} set vars2 {} set vars3 {} if {$listdata($f,affiliation,$i) != ""} { lappend vars1 affiliation $listdata($f,affiliation,$i) } if {$listdata($f,subscription,$i) != ""} { lappend vars1 subscription $listdata($f,subscription,$i) } if {$listdata($f,jid,$i) != ""} { lappend vars2 jid $listdata($f,jid,$i) } if {$listdata($f,subid,$i) != ""} { lappend vars3 subid $listdata($f,subid,$i) } if {$vars1 != {} && $vars2 != {} && $vars3 != {}} { lappend entities [jlib::wrapper:createtag item \ -vars [concat $vars2 $vars3 $vars1]] } } set connid [chat::get_connid $chatid] set group [chat::get_jid $chatid] if {$entities != {}} { jlib::send_iq set \ [jlib::wrapper:createtag pubsub \ -vars [list xmlns $::NS(pubsub)] \ -subtags [list [jlib::wrapper:createtag entities \ -vars [list node $node] \ -subtags $entities]]] \ -to $service \ -connection $connid # TODO error checking } destroy $w } proc pubsub::cleanup_entities {w f} { variable listdata variable origlistdata debugmsg pubsub [info level 0] array unset listdata $f,* array unset origlistdata $f,* } ########################################################################## # # Collection nodes (9) # ########################################################################## # # Subscribe to a collection node (9.1) # Implemented in # pubsub::subscribe service node id -connection connid \ # -subscription_type {nodes|items} \ # -subscription_depth {1|all} # ########################################################################## # # Root collection node (9.2) # Implemented in pubsub::subscribe and pubsub::unsubscribe with empty node # ########################################################################## # # Create collection node (9.3) # Implemented in # pubsub::create_node service node -connection connid \ # -node_type collection # ########################################################################## # # Create a node associated with a collection (9.4) # Implemented in # pubsub::create_node service node -connection connid \ # -collection collection # ########################################################################## # # Associate an existing node with a collection (9.5) # Implemented in TODO ########################################################################## # # Diassociate an node from a collection (9.6) # Implemented in TODO ########################################################################## # # Framework for handling of Pubsub event notifications. proc pubsub::register_event_notification_handler {xmlns h} { variable handler variable supported_ns set handler($xmlns) $h set supported_ns [array names handler] } proc pubsub::process_event_notification {connid from mid type is_subject subject body \ err thread priority x} { variable ::pubsub::ns variable handler set res "" foreach event $x { jlib::wrapper:splitxml $event tag vars isempty chdata children if {![string equal $tag event]} continue set xmlns [jlib::wrapper:getattr $vars xmlns] if {![string equal $xmlns $ns(event)]} continue foreach item $children { jlib::wrapper:splitxml $item tag1 vars1 isempty1 chdata1 children1 if {![string equal $tag1 items]} continue set node [jlib::wrapper:getattr $vars1 node] if {![info exists handler($node)]} continue set res stop $handler($node) $connid $from $children1 } } return $res } hook::add process_message_hook pubsub::process_event_notification # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/pep.tcl0000644000175000017500000001324210733476425014027 0ustar sergeisergei# $Id: pep.tcl 1331 2007-12-23 15:21:57Z sergei $ # Personal eventing via pubsub XEP-0163 namespace eval pep { custom::defgroup Plugins \ [::msgcat::mc "Plugins options."] \ -group Tkabber custom::defgroup PEP \ [::msgcat::mc "Personal eventing via pubsub plugins options."] \ -group Plugins } ########################################################################## # # PEP Creating a node (5) # -connection is mandatory # -access_model (open, presence (default), roster, whitelist) # -roster_groups_allowed (roster group list if access is roster) # proc pep::create_node {node args} { variable ns debugmsg pep [info level 0] set command "" set access "presence" set groups {} foreach {key val} $args { switch -- $key { -connection { set connid $val} } } if {![info exists connid]} { return -code error "pep::create_node: -connection is mandatory" } if {$node == ""} { return -code error "pep::create_node: node must not be empty" } set service [jlib::connection_bare_jid $connid] eval [list pubsub::create_node $service $node] $args } ########################################################################## # # Publish item to PEP node "node" (8) # payload is a list of xml tags # node must not be empty # itemid may be empty # -connection is mandatory # proc pep::publish_item {node itemid args} { debugmsg pep [info level 0] set command "" foreach {key val} $args { switch -- $key { -connection { set connid $val} } } if {![info exists connid]} { return -code error "pep::publish_item: -connection is mandatory" } if {$node == ""} { return -code error "pep::publish_item: node must not be empty" } set service [jlib::connection_bare_jid $connid] eval [list pubsub::publish_item $service $node $itemid] $args } ########################################################################## # # Delete item from PEP node "node" # node must not be empty # itemid must not be empty # -connection is mandatory # proc pep::delete_item {node itemid args} { debugmsg pep [info level 0] set command "" foreach {key val} $args { switch -- $key { -connection { set connid $val} } } if {![info exists connid]} { return -code error "pep::delete_item: -connection is mandatory" } if {$node == ""} { return -code error "pep::delete_item: node must not be empty" } if {$itemid == ""} { return -code error "pep::delete_item: Item ID must not be empty" } set service [jlib::connection_bare_jid $connid] eval [list pubsub::delete_item $service $node $itemid] $args } ########################################################################## # # Subscribe to PEP node "node" at bare JID "to" (5.2) # node must not be empty # # -jid "jid" is optional (when it's present it's included to sub request) # # -resource "res" is optional (when it's present bare_jid/res is included # to sub request # # if both options are absent then user's bare JID is included to sub # request # proc pep::subscribe {to node args} { debugmsg pep [info level 0] foreach {key val} $args { switch -- $key { -connection { set connid $val} } } if {![info exists connid]} { return -code error "pep::subscribe error: -connection is mandatory" } if {$node == ""} { return -code error "pep::subscribe error: node must not be empty" } eval [list pubsub::subscribe $to $node] $args } ########################################################################## # # Unsubscribe from PEP node "node" at bare JID "to" (undocumented?!) # node must not be empty # # -jid "jid" is optional (when it's present it's included to sub request) # # -resource "res" is optional (when it's present bare_jid/res is included # to sub request # # if both options are absent then user's bare JID is included to sub # request # proc pep::unsubscribe {to node args} { debugmsg pep [info level 0] set command "" foreach {key val} $args { switch -- $key { -connection { set connid $val} } } if {![info exists connid]} { return -code error "pep::unsubscribe error: -connection is mandatory" } if {$node == ""} { return -code error "pep::unsubscribe error: node must not be empty" } eval [list pubsub::unsubscribe $to $node] $args } ########################################################################## # Returns a name of a submenu (of menu $m) for PEP commands to perform on # the roster item for a user with JID $jid. # This command automatically creates this submenu if needed. proc pep::get_roster_menu_pep_submenu {m connid jid} { set pm $m.pep if {![winfo exists $pm]} { menu $pm -tearoff no $m add cascade -menu $pm \ -label [::msgcat::mc "Personal eventing"] } return $pm } ########################################################################## # Returns pathname of a frame comprising a page for PEP info in # the userinfo (vCard) dialog which notebook widget is $notebook. # If that page is not yet exist, it's created. proc pep::get_userinfo_dialog_pep_frame {notebook} { if {[$notebook index PEP] < 0} { return [$notebook insert end PEP \ -text [::msgcat::mc "Personal eventing"]] } else { return [$notebook getframe PEP] } } proc pep::get_main_menu_pep_submenu {} { return [.mainframe getmenu services].pep } proc pep::on_init {} { set m [.mainframe getmenu services] set idx [$m index [::msgcat::mc "Service Discovery"]] set pm [menu $m.pep -tearoff $::ifacetk::options(show_tearoffs)] $m insert [expr {$idx + 2}] cascade -menu $pm \ -label [::msgcat::mc "Personal eventing"] } hook::add finload_hook [namespace current]::pep::on_init # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/INSTALL0000644000175000017500000000001310525610336013546 0ustar sergeisergeiSee README tkabber-0.11.1/private.tcl0000644000175000017500000000277510674777354014737 0ustar sergeisergei# $Id: private.tcl 1237 2007-09-21 17:27:08Z sergei $ # # Private XML Storage (XEP-0049) support # namespace eval private {} proc private::store {query args} { set command "" foreach {key val} $args { switch -- $key { -command { set command $val } -connection { set connid $val } } } if {![info exists connid]} { return -code error "private::store: -connection is mandatory" } jlib::send_iq set \ [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(private)] \ -subtags $query] \ -command [list [namespace current]::store_result $command] \ -connection $connid } proc private::store_result {command res child} { if {$command != ""} { uplevel #0 $command [list $res $child] } } proc private::retrieve {query args} { set command "" foreach {key val} $args { switch -- $key { -command { set command $val } -connection { set connid $val } } } if {![info exists connid]} { return -code error "private::retrieve: -connection is mandatory" } jlib::send_iq get \ [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(private)] \ -subtags $query] \ -command [list [namespace current]::retrieve_result $command] \ -connection $connid } proc private::retrieve_result {command res child} { if {$command == ""} return if {$res != "OK"} { uplevel #0 $command [list $res $child] return } jlib::wrapper:splitxml $child tag vars isempty cdata children uplevel #0 $command [list OK $children] } tkabber-0.11.1/si.tcl0000644000175000017500000002717710653600460013657 0ustar sergeisergei# $Id: si.tcl 1168 2007-07-31 09:30:24Z sergei $ # # Stream Initiation (XEP-0095) implementation # ############################################################################### namespace eval si { set transport(list) {} } set ::NS(si) http://jabber.org/protocol/si ############################################################################### ############################################################################### proc si::newout {connid jid} { variable streams set id [rand 1000000000] while {[info exists streams(out,$connid,$jid,$id)]} { set id [rand 1000000000] } set streamid 0 set stream [namespace current]::0 while {[info exists $stream]} { set stream [namespace current]::[incr streamid] } upvar #0 $stream state set state(connid) $connid set state(jid) $jid set state(id) $id set streams(out,$connid,$jid,$id) $stream return $stream } proc si::freeout {stream} { variable streams upvar #0 $stream state catch { set connid $state(connid) set jid $state(jid) set id $state(id) unset state unset streams(out,$connid,$jid,$id) } } ############################################################################### proc si::newin {connid jid id} { variable streams if {[info exists streams(in,$connid,$jid,$id)]} { return -code error } set streamid 0 set stream [namespace current]::0 while {[info exists $stream]} { set stream [namespace current]::[incr streamid] } upvar #0 $stream state set state(connid) $connid set state(jid) $jid set state(id) $id set streams(in,$connid,$jid,$id) $stream return $stream } proc si::in {connid jid id} { variable streams return $streams(in,$connid,$jid,$id) } proc si::freein {stream} { variable streams upvar #0 $stream state catch { set connid $state(connid) set jid $state(jid) set id $state(id) unset state unset streams(in,$connid,$jid,$id) } } ############################################################################### ############################################################################### proc si::connect {stream chunk_size mimetype profile profile_el command} { variable transport upvar #0 $stream state set trans [lsort -unique -index 1 $transport(list)] set options {} foreach t $trans { set name [lindex $t 0] if {![info exists transport(allowed,$name)] || \ $transport(allowed,$name)} { lappend options $transport(oppos,$name) } } set opttags {} foreach opt $options { lappend opttags [jlib::wrapper:createtag option \ -subtags [list [jlib::wrapper:createtag value \ -chdata $opt]]] } set feature \ [jlib::wrapper:createtag feature \ -vars [list xmlns http://jabber.org/protocol/feature-neg] \ -subtags \ [list [jlib::wrapper:createtag x \ -vars [list xmlns jabber:x:data type form] \ -subtags \ [list [jlib::wrapper:createtag \ field \ -vars [list var stream-method \ type list-single] \ -subtags $opttags]]]]] set_status [::msgcat::mc "Opening SI connection"] jlib::send_iq set \ [jlib::wrapper:createtag si \ -vars [list xmlns $::NS(si) \ id $state(id) \ mime-type $mimetype \ profile $profile] \ -subtags [list $profile_el $feature]] \ -to $state(jid) \ -command [list si::connect_response $stream $chunk_size \ $profile $command] \ -connection $state(connid) } ############################################################################### proc si::connect_response {stream chunk_size profile command res child} { variable transport upvar #0 $stream state if {![info exists state(id)]} { # TODO: It would be good to send some error message to a receiver # (but it is not supported by the protocol). uplevel #0 $command [list [list 0 [::msgcat::mc "File transfer aborted"]]] return } if {$res != "OK"} { uplevel #0 $command [list [list 0 [error_to_string $child]]] return } jlib::wrapper:splitxml $child tag vars isempty chdata children set trans [lsort -unique -index 1 $transport(list)] set options {} foreach t $trans { set name [lindex $t 0] if {![info exists transport(allowed,$name)] || \ $transport(allowed,$name)} { lappend options $transport(oppos,$name) } } set opts {} foreach item $children { jlib::wrapper:splitxml $item tag1 vars1 isempty1 chdata1 children1 set xmlns [jlib::wrapper:getattr $vars1 xmlns] if {[string equal $xmlns $profile]} { # TODO } elseif {[string equal $xmlns \ http://jabber.org/protocol/feature-neg]} { set opts [parse_negotiation_res $item] } } if {[llength $opts] == 1 && [lcontain $options [lindex $opts 0]]} { set name [lindex $opts 0] set state(transport) $name eval $transport(connect,$name) [list $stream $chunk_size $command] return } uplevel #0 $command \ [list [list 0 [::msgcat::mc "Stream method negotiation failed"]]] } ############################################################################### proc si::send_data {stream data command} { variable transport upvar #0 $stream state eval $transport(send,$state(transport)) [list $stream $data $command] } ############################################################################### proc si::close {stream} { variable transport upvar #0 $stream state eval $transport(close,$state(transport)) [list $stream] set_status [::msgcat::mc "SI connection closed"] } ############################################################################### ############################################################################### proc si::set_readable_handler {stream handler} { upvar #0 $stream state set state(readable_handler) $handler } proc si::set_closed_handler {stream handler} { upvar #0 $stream state set state(closed_handler) $handler } ############################################################################### proc si::recv_data {stream data} { upvar #0 $stream state debugmsg si "RECV_DATA [list $state(id) $data]" append state(data) $data eval $state(readable_handler) [list $stream] } ############################################################################### proc si::read_data {stream} { upvar #0 $stream state set data $state(data) set state(data) {} return $data } ############################################################################### proc si::closed {stream} { upvar #0 $stream state if {[info exists state(closed_handler)]} { eval $state(closed_handler) [list $stream] } } ############################################################################### proc si::parse_negotiation {child} { jlib::wrapper:splitxml $child tag vars isempty chdata children set options {} foreach item $children { jlib::wrapper:splitxml $item tag1 vars1 isempty1 chdata1 children1 set xmlns [jlib::wrapper:getattr $vars1 xmlns] if {[string equal $xmlns jabber:x:data]} { foreach item $children1 { jlib::wrapper:splitxml $item \ tag2 vars2 isempty2 chdata2 children2 set var [jlib::wrapper:getattr $vars2 var] if {[string equal $var stream-method]} { foreach item $children2 { jlib::wrapper:splitxml $item \ tag3 vars3 isempty3 chdata3 children3 foreach item $children3 { jlib::wrapper:splitxml $item \ tag4 vars4 isempty4 chdata4 children4 lappend options $chdata4 } } } } } } return $options } proc si::parse_negotiation_res {child} { jlib::wrapper:splitxml $child tag vars isempty chdata children set options {} foreach item $children { jlib::wrapper:splitxml $item tag1 vars1 isempty1 chdata1 children1 set xmlns [jlib::wrapper:getattr $vars1 xmlns] if {[string equal $xmlns jabber:x:data]} { foreach item $children1 { jlib::wrapper:splitxml $item \ tag2 vars2 isempty2 chdata2 children2 set var [jlib::wrapper:getattr $vars2 var] if {[string equal $var stream-method]} { foreach item $children2 { jlib::wrapper:splitxml $item \ tag3 vars3 isempty3 chdata3 children3 lappend options $chdata3 } } } } } return $options } ############################################################################### proc si::set_handler {connid from lang child} { variable profiledata variable transport jlib::wrapper:splitxml $child tag vars isempty chdata children set id [jlib::wrapper:getattr $vars id] set mimetype [jlib::wrapper:getattr $vars mime-type] set profile [jlib::wrapper:getattr $vars profile] set stream {} set profile_res {} if {[info exists profiledata($profile)]} { foreach item $children { jlib::wrapper:splitxml $item tag1 vars1 isempty1 chdata1 children1 set xmlns [jlib::wrapper:getattr $vars1 xmlns] if {[string equal $xmlns $profile]} { set profile_res [$profiledata($profile) \ $connid $from $lang $id $mimetype $item] } elseif {[string equal $xmlns \ http://jabber.org/protocol/feature-neg]} { set options [parse_negotiation $item] set trans [lsort -unique -index 1 $transport(list)] set myoptions {} foreach t $trans { set name [lindex $t 0] if {![info exists transport(allowed,$name)] || \ $transport(allowed,$name)} { lappend myoptions $transport(oppos,$name) } } foreach opt $options { if {[lcontain $myoptions $opt]} { set stream $opt break } } } } if {[lindex $profile_res 0] == "error"} { return $profile_res } if {$stream == {}} { # no-valid-streams return [list error modify bad-request] } set res_childs {} if {$profile_res != {}} { lappend res_childs $profile_res } set opttags \ [list [jlib::wrapper:createtag value \ -chdata $opt]] lappend res_childs \ [jlib::wrapper:createtag feature \ -vars [list xmlns http://jabber.org/protocol/feature-neg] \ -subtags \ [list [jlib::wrapper:createtag x \ -vars [list xmlns jabber:x:data type submit] \ -subtags \ [list [jlib::wrapper:createtag \ field \ -vars [list var stream-method] \ -subtags $opttags]]]]] set res [jlib::wrapper:createtag si \ -vars [list xmlns $::NS(si)] \ -subtags $res_childs] return [list result $res] } else { # bad-profile return [list error modify bad-request] } } iq::register_handler set "" $::NS(si) si::set_handler ############################################################################### ############################################################################### proc si::register_transport {name oppos prio connect send close} { variable transport lappend transport(list) [list $name $prio] set transport(oppos,$name) $oppos set transport(connect,$name) $connect set transport(send,$name) $send set transport(close,$name) $close } ############################################################################### proc si::register_profile {profile handler} { variable profiledata set profiledata($profile) $handler } ############################################################################### proc si::setup_customize {} { variable transport set trans [lsort -unique -index 1 $transport(list)] foreach t $trans { lassign $t name prio custom::defvar transport(allowed,$name) 1 \ [format [::msgcat::mc "Enable SI transport %s."] $name] \ -type boolean -group {Stream Initiation} } } hook::add finload_hook si::setup_customize 40 ############################################################################### namespace eval si { plugins::load [file join plugins si] -uplevel 1 } ############################################################################### tkabber-0.11.1/AUTHORS0000644000175000017500000000027011074045703013572 0ustar sergeisergeiAlexey Shchepin Marshall T. Rose Sergei Golovan Michail Litvak Konstantin Khomoutov tkabber-0.11.1/examples/0000755000175000017500000000000011076120366014342 5ustar sergeisergeitkabber-0.11.1/examples/tclCarbonNotification-1.0.0/0000755000175000017500000000000011076120366021252 5ustar sergeisergeitkabber-0.11.1/examples/tclCarbonNotification-1.0.0/tclCarbonNotification.tcl0000644000175000017500000000112010047501072026220 0ustar sergeisergeipackage require critcl package provide tclCarbonNotification 1.0 lappend critcl::v::compile -framework Carbon critcl::ccode { #include } critcl::cproc tclCarbonNotification {int bounce char* msg} ok { OSErr err; NMRec request; Str255 message; request.nmMark = bounce; if(strlen(msg)) { CopyCStringToPascal(msg,message); request.nmStr = (StringPtr)&message; } else { request.nmStr = NULL; } request.qType = nmType; request.nmSound = NULL; request.nmResp = NULL; err = NMInstall(&request); if (err != noErr) return TCL_ERROR; return TCL_OK; } tkabber-0.11.1/examples/tclCarbonNotification-1.0.0/build.sh0000755000175000017500000000006110047501072022677 0ustar sergeisergei#!/bin/sh critcl -pkg tclCarbonNotification.tcl tkabber-0.11.1/examples/xrdb/0000755000175000017500000000000011076120366015301 5ustar sergeisergeitkabber-0.11.1/examples/xrdb/teopetuk.xrdb0000644000175000017500000001426510762611355020036 0ustar sergeisergei! Main window geometry Tkabber.geometry: 950x700-70+100 !Tkabber.geometry: 180x400-70+100 ! Chat window geometry (in no tabs mode) *Chat.chatgeometry: 550x500 *Chat.groupchatgeometry: 600x500 ! Browser and Headlines window geometry (in no tabs mode) *JBrowser.geometry: 550x500 ! Roster width (tabbed interface only) Tkabber.mainRosterWidth: 110 ! Roster width in groupchat windows Tkabber.chatRosterWidth: 105 ! Scrollbar bed color *troughColor: #cccccc *background: #dddddd *readonlyBackground: #dddddd *foreground: #000000 *disabledForeground: #888888 *errorForeground: firebrick ! Colors, which are used when mouse is over the item *activeBackground: #ebebeb *activeForeground: #000000 ! Colors and border width selected item !*selectBackground: #334080 *selectBackground: #d1eeee *selectForeground: #000000 *selectBorderWidth: 0 *inactiveSelectBackground: #d1eeee ! Color for highlighting found items *highlightSearchBackground: #c1eec1 ! Color for checkboxes *selectColor: #999999 ! Color of traversal highlight rectangle *highlightBackground: #dddddd *highlightColor: #000000 ! Color of insertion cursor *insertBackground: #000000 ! Font for drawing text (except chats and roster font) !*font: -monotype-arial-medium-r-normal-*-13-*-*-*-*-*-koi8-r ! Currently there is only progressbar (at the splash screen) *ProgressBar.foreground: #334080 *ProgressBar*borderWidth: 1 ! Flatten Spinbox, ComboBox and ArrowButton *Spinbox.borderWidth: 1 *Spinbox.background: #eeeeee *Spinbox.disabledBackground: #dddddd *SpinBox.borderWidth: 1 *SpinBox*Entry*highlightBackground: #eeeeee *ComboBox.borderWidth: 1 *ArrowButton.borderWidth: 0 *ArrowButton.highlightThickness: 0 ! Colors for multicolumn listboxes (as in search result window) *Mclistbox.background: #eeeeee *Mclistbox.labelActiveBackground: #ebebeb *Mclistbox.labelBackground: #dddddd ! Type of subitem in roster (1 - display number of resources, ! 2 - display arrow, 3 - display both, 0 - display nothing *Roster.subitemtype: 3 ! Roster background color *Roster.cbackground: #eeeeee ! Inactive JID background color *Roster.jidfill: #eeeeee ! Active JID background color *Roster.jidhlfill: #d1eeee ! Color of border around JID *Roster.jidborder: #eeeeee ! Inctive group background color *Roster.groupfill: #dddddd ! Inactive closed group background color *Roster.groupcfill: #dddddd ! Active group background color *Roster.grouphlfill: #b4cdcd ! Color of border around group *Roster.groupborder: #dddddd ! Indent of group names *Roster.groupindent: 21 ! Indent of JIDs *Roster.jidindent: 42 *Roster.jidmultindent: 42 ! Indent of second order JIDs ! (resources for those who is logged in multiple times) *Roster.subjidindent: 62 ! Indent of group icons (closed or open arrow icon) *Roster.groupiconindent: 2 ! Indent of group icons when subitemtype is 2 or 3 *Roster.subgroupiconindent: 2 ! Indent of regular JID icons (status icon) *Roster.iconindent: 21 ! Indent of second order JID icons *Roster.subiconindent: 42 ! Additional amount of text height *Roster.textuppad: 0 *Roster.textdownpad: 0 ! Vertical distance between adjacent items *Roster.linepad: 2 ! Foregrounds of JID label ! (stalkerforeground is for contacts with pending subscription) *Roster.stalkerforeground: #663333 ! Other colors are selfexplanatory *Roster.unavailableforeground: #515151 *Roster.dndforeground: #515129 *Roster.xaforeground: #0b3760 *Roster.awayforeground: #0b3760 *Roster.availableforeground: dodgerblue4 *Roster.chatforeground: dodgerblue4 ! Colors in chat and groupchat windows *Chat*Text*Label.background: #eeeeee ! Color of other people nicknames !*Chat.theyforeground: firebrick4 *Chat.theyforeground: dodgerblue4 ! Color of my nickname !*Chat.meforeground: dodgerblue4 *Chat.meforeground: firebrick4 *Chat.highlightforeground: firebrick4 ! Colors of server messages *Chat.serverlabelforeground: DarkGreen *Chat.serverforeground: DarkGreen ! Color of info & error messages *Chat.infoforeground: dodgerblue4 *Chat.errforeground: firebrick ! Color of inactive urls in text *urlforeground: dodgerblue4 ! Color of active urls in text *urlactiveforeground: dodgerblue3 ! Colors of erroneous words (when ispell module is using) *Text.errorColor: firebrick4 *Text.comboColor: dodgerblue4 ! Colors of tab labels (when in tabbed mode) ! Usual color *alertColor0: black ! Color when server message is arrived *alertColor1: DarkViolet ! Color when message is arrived *alertColor2: dodgerblue4 ! Color when personally addressed message is arrived *alertColor3: firebrick4 ! Colors for browser and discovery service windows *JBrowser.fill: #000000 *JBrowser.activefill: #000000 *JBrowser.border: #eeeeee *JBrowser.nscolor: #666666 *JBrowser.nsactivecolor: #666666 *JDisco.fill: #000000 *JDisco.activefill: #000000 *JDisco.border: #eeeeee *JDisco.featurecolor: #666666 *JDisco.identitycolor: DarkGreen *JDisco.optioncolor: DarkViolet *Tree*background: #eeeeee *linesfill: #000000 *crossfill: #000000 *Customize.varforeground: dodgerblue4 ! Tooltip options *Balloon*background: #ffeeaa *Balloon*foreground: #000000 *DynamicHelp.background: #ffeeaa *DynamicHelp.foreground: #000000 *Listbox.background: #eeeeee *Listbox.foreground: #000000 *Listbox.borderWidth: 1 *Text.background: #eeeeee *Text.foreground: #000000 *Text.borderWidth: 1 *Entry.background: #eeeeee *Entry.foreground: #000000 *Entry.borderWidth: 1 *NoteBook*Entry.background: #eeeeee *NoteBook*Entry.disabledBackground: #dddddd *NoteBook*Entry.readonlyBackground: #dddddd *NoteBook*Entry.foreground: #000000 *Button.borderWidth: 1 *Menu.activeBorderWidth: 1 *Menu.borderWidth: 1 *Menubutton.borderWidth: 1 *Buttonbox*borderWidth: 0 *Buttonbox*activeBorderWidth: 0 *Scrollbar.width: 8 tkabber-0.11.1/examples/xrdb/badlop-dark.xrdb0000644000175000017500000001737410762611355020362 0ustar sergeisergei! Badlop-Dark.xrdb theme for Tkabber (based on dark2.xrdb) ! Font for drawing text (except chats and roster font) !*font: -monotype-arial-medium-r-normal-*-17-*-*-*-*-*-koi8-r ! Main window geometry ! [tamaño horizontal] ! x[tamaño vertical] ! -[separacion con borde derecho de pantalla] ! +[separación con borde superior de lapantalla] Tkabber.geometry: 700x520-30+170 ! Chat window geometry (in no tabs mode) !*Chat.geometry: 300x500-70+350 ! notabs *Chat.geometry: 300x500-70+350 *Chat.groupchatgeometry: 600x500 *Chat.chatgeometry: 500x500 ! Browser and Headlines window geometry (in no tabs mode) *JBrowser.geometry: 350x350 *JDisco.geometry: 500x500 ! Roster width (tabbed interface only) Tkabber.mainRosterWidth: 150 ! Roster width in groupchat windows Tkabber.chatRosterWidth: 80 ! Scrollbar bed color *troughColor: #424242 *background: #5e5e5e *readonlyBackground: #3f3f3f *foreground: #ffffff ! Colors, which are used when mouse is over the item *activeBackground: #550066 *activeForeground: #ffffff *disabledBackground: #3f3f3f *disabledForeground: #aaaaaa ! Colors and border width selected item *selectBackground: #550066 *selectForeground: #ffffff *selectBorderWidth: 0 *inactiveSelectBackground: #550066 ! Color for checkboxes *selectColor: #4f135b ! Color of traversal highlight rectangle *highlightBackground: #5e5e5e *highlightColor: #000000 ! Color of insertion cursor *insertBackground: #ffffff ! Currently there is only progressbar (at the splash screen) *ProgressBar.foreground: #550066 ! Flatten ComboBox and ArrowButton +++ *Spinbox.borderWidth: 1 *Spinbox.background: #424242 *SpinBox.borderWidth: 1 *SpinBox*Entry*highlightBackground: #424242 *ComboBox.borderWidth: 1 *ArrowButton*borderWidth: 1 *ArrowButton.borderWidth: 0 *ArrowButton.highlightThickness: 0 ! Colors for multicolumn listboxes (as in search result window) *Mclistbox.background: #424242 *Mclistbox.labelActiveBackground: #550066 *Mclistbox.labelBackground: #5e5e5e *Mclistbox.labelForeground: #ffffff *Mclistbox.labelActiveForeground: #ffffff ! Button and Menubutton colors ! Generic button *Button.background: #5e5e5e *Button.activeBackground: #550066 ! Generic menubutton *Menubutton.background: #5e5e5e *Menubutton.activeBackground: #550066 ! Buttons in chat and message windows *Chat*Button.background: #5e5e5e *Chat*Menubutton.background: #5e5e5e *Message*Menubutton.background: #5e5e5e *bbox.Button.background: #5e5e5e ! Menu colors *Menu.background: #5e5e5e *Menu.activeBackground: #550066 ! Main toolbar buttons *mainframe.topf.tb0.bbox.Button.background: #5e5e5e ! Sign/encrypt message buttons *bottom.buttons1.Button.background: #5e5e5e ! Type of subitem in roster (1 - display number of resources, ! 2 - display arrow, 3 - display both, 0 - display nothing *Roster.subitemtype: 3 ! Roster background color *Roster.cbackground: #424242 ! Inactive JID background color *Roster.jidfill: #424242 ! Active JID background color *Roster.jidhlfill: #4f135b ! Color of border around JID *Roster.jidborder: #424242 ! Inctive group background color *Roster.groupfill: #5e5e5e ! Inactive closed group background color *Roster.groupcfill: #5e5e5e ! Active group background color *Roster.grouphlfill: #550066 ! Color of border around group *Roster.groupborder: #5e5e5e ! Indent of group names *Roster.groupindent: 21 ! Indent of JIDs *Roster.jidindent: 42 ! Indent of second order JIDs ! (resources for those who is logged in multiple times) *Roster.subjidindent: 62 ! Indent of group icons (closed or open arrow icon) *Roster.groupiconindent: 2 ! Indent of group icons when subitemtype is 2 or 3 *Roster.subgroupiconindent: 2 ! Indent of regular JID icons (status icon) *Roster.iconindent: 21 ! Indent of second order JID icons *Roster.subiconindent: 42 ! Additional amount of text height *Roster.textuppad: 0 *Roster.textdownpad: 0 ! Vertical distance between adjacent items *Roster.linepad: 2 ! Foregrounds of JID label ! (stalkerforeground is for contacts with pending subscription) *Roster.stalkerforeground: #d2b48c ! Other colors are selfexplanatory *Roster.unavailableforeground: #b8b8b8 *Roster.dndforeground: #ffc1c1 *Roster.xaforeground: #c1cdcd *Roster.awayforeground: #c1cdcd *Roster.availableforeground: #ffffff *Roster.chatforeground: #ffffff ! Colors in chat and groupchat windows *Chat*Text*Label.background: #66685e ! Color of other people nicknames *Chat.theyforeground: #ff7f50 ! Color of my nickname *Chat.meforeground: #add8e6 ! Colors of server messages *Chat.serverlabelforeground: #caff70 *Chat.serverforeground: #ff69b4 ! Color of error messages *Chat.errforeground: #ff6a6a ! Color of inactive urls in text *urlforeground: #add8e6 ! Color of active urls in text *urlactiveforeground: #add8e6 ! Colors of erroneous words (when ispell module is using) *Text.errorColor: #ff7f50 *Text.comboColor: #add8e6 *Chat.inputheight: 3 ! Colors of tab labels (when in tabbed mode) ! Usual color *alertColor0: #ffffff ! Color when server message is arrived *alertColor1: #ff69b4 ! Color when message is arrived *alertColor2: #add8e6 ! Color when personally addressed message is arrived *alertColor3: #ff7f50 ! Colors for browser and discovery service windows *JBrowser.fill: #ffffff *JBrowser.activefill: #ffffff *JBrowser.border: #424242 ! ale *JBrowser.nscolor: #b8b8b8 *JBrowser.nsactivecolor: #b8b8b8 *JBrowser.cbackground: #b8b8b8 ! White *JBrowser.foreground: #b8b8b8 ! Black *JBrowser.levelindent: 24 *JBrowser.indent: 3 *JBrowser.nsindent: 2 *JBrowser.linepad: 2 *JBrowser.toppad: 1 *JBrowser.bottompad: 1 *JBrowser.icontextpad: 2 ! MidnightBlue ! Blue *JDisco.fill: #ffffff *JDisco.activefill: #ffffff *JDisco.border: #424242 *JDisco.featurecolor: #b8b8b8 *JDisco.identitycolor: #b4eeb4 *JDisco.optioncolor: #ff69b4 *Tree*background: #424242 *linesfill: #ffffff *crossfill: #000000 ! ale *JDisco.cbackground: #ffffff *JDisco.foreground: #000000 ! Tooltip options *Balloon*background: #424242 *Balloon*foreground: #ffffff *DynamicHelp.background: #424242 *DynamicHelp.foreground: #ffffff *Baloon.style: delay *Listbox.background: #424242 *Listbox.foreground: #ffffff *Listbox.borderWidth: 1 *Text.background: #424242 *Text.foreground: #ffffff *Text.borderWidth: 1 *Entry.background: #424242 *Entry.foreground: #ffffff *Entry.borderWidth: 1 *NoteBook*Entry.background: #424242 *NoteBook*Entry.disabledBackground: #5e5e5e *NoteBook*Entry.foreground: #ffffff *Button.borderWidth: 1 *Menu.activeBorderWidth: 1 *Menu.borderWidth: 1 *Menubutton.borderWidth: 1 *Buttonbox*borderWidth: 0 *Buttonbox*activeBorderWidth: 0 ! ale *Search.itemBackground: #ffffff ! ale *RawXML.inforeground: #e0c3c3 *RawXML.outforeground: #a3a3ff *RawXML.intagforeground: #e0c3c3 *RawXML.inattrforeground: #e0c3c3 *RawXML.invalueforeground: #d1aef2 *RawXML.incdataforeground: #b2dcff *RawXML.outtagforeground: #efb3ef *RawXML.outattrforeground: #efb3ef *RawXML.outvalueforeground: #c9ffc9 *RawXML.outcdataforeground: #b6b6f9 *RawXML.inputheight: 4 *Scrollbar.width: 8 tkabber-0.11.1/examples/xrdb/warm.xrdb0000644000175000017500000001510510762611355017136 0ustar sergeisergei! Main window geometry Tkabber.geometry: 788x550-70+100 !Tkabber.geometry: 180x400-70+100 ! Chat window geometry (in no tabs mode) *Chat.groupchatgeometry: 600x500 *Chat.chatgeometry: 500x500 ! Browser and Headlines window geometry (in no tabs mode) *JBrowser.geometry: 500x500 *JDisco.geometry: 500x500 ! Roster width (tabbed interface only) Tkabber.mainRosterWidth: 120 ! Roster width in groupchat windows Tkabber.chatRosterWidth: 90 ! Scrollbar bed color *troughColor: #856b3b *background: #d0b073 *foreground: #000000 ! Color of disabled items *disabledBackground: #d0b073 *disabledForeground: #633333 *readonlyBackground: #d0b073 *errorForeground: firebrick ! Colors, which are used when mouse is over the item *activeBackground: #996b3b *activeForeground: #000000 ! Colors and border width selected item *selectBackground: #b38047 *selectForeground: #000000 *selectBorderWidth: 0 *inactiveSelectBackground: #b38047 ! Color for checkboxes *selectColor: #fdc408 ! Color of traversal highlight rectangle *highlightBackground: #d0b073 *highlightColor: #e00000 ! Color of insertion cursor *insertBackground: #000000 ! Font for drawing text (except chats and roster) *font: -monotype-arial-medium-r-normal-*-13-*-*-*-*-*-koi8-r ! Currently there is only progressbar (at the splash screen) *ProgressBar.foreground: #996b3b ! Flatten ComboBox and ArrowButton *Spinbox.borderWidth: 1 *Spinbox.background: #b38047 *SpinBox.borderWidth: 1 *SpinBox*Entry*highlightBackground: #b38047 *ComboBox.borderWidth: 1 *ArrowButton.borderWidth: 0 *ArrowButton.highlightThickness: 0 ! Colors for listboxes and multicolumn listboxes (as in search result window) *Listbox.background: #f0f0cc *Listbox.foreground: #000000 *Listbox.borderWidth: 1 *Mclistbox.background: #f0f0cc *Mclistbox.labelActiveBackground: #b38047 *Mclistbox.labelBackground: #996b3b *Mclistbox.labelForeground: #000000 *Mclistbox.labelActiveForeground: #000000 ! Button and Menubutton colors ! Generic button *Button.background: #996b3b *Button.activeBackground: #b38047 ! Generic menubutton *Menubutton.background: #996b3b *Menubutton.activeBackground: #b38047 ! Buttons in chat and message windows *Chat*Button.background: #d0b073 *Chat*Menubutton.background: #d0b073 *Message*Menubutton.background: #d0b073 *bbox.Button.background: #996b3b ! Menu colors *Menu.background: #996b3b *Menu.activeBackground: #d0b073 ! Main toolbar buttons *mainframe.topf.tb0.bbox.Button.background: #d0b073 ! Sign/encrypt message buttons *bottom.buttons1.Button.background: #d0b073 ! Type of subitem in roster (1 - display number of resources, ! 2 - display arrow, 3 - display both, 0 - display nothing *Roster.subitemtype: 3 ! Roster background color *Roster.cbackground: #f0f0cc ! Inactive JID background color *Roster.jidfill: #f0f0cc ! Active JID background color *Roster.jidhlfill: #b38047 ! Color of border around JID *Roster.jidborder: #f0f0cc ! Inctive group background color *Roster.groupfill: #d0b073 ! Inactive closed group background color *Roster.groupcfill: #d0b073 ! Active group background color *Roster.grouphlfill: #b38047 ! Color of border around group *Roster.groupborder: #d0b073 ! Indent of group names *Roster.groupindent: 21 ! Indent of JIDs *Roster.jidindent: 42 ! Indent of second order JIDs ! (resources for those who is logged in multiple times) *Roster.subjidindent: 62 ! Indent of group icons (closed or open arrow icon) *Roster.groupiconindent: 2 ! Indent of group icons when subitemtype is 2 or 3 *Roster.subgroupiconindent: 2 ! Indent of regular JID icons (status icon) *Roster.iconindent: 21 ! Indent of second order JID icons *Roster.subiconindent: 42 ! Additional amount of text height *Roster.textuppad: 0 *Roster.textdownpad: 0 ! Vertical distance between adjacent items *Roster.linepad: 2 ! Foregrounds of JID label ! (stalkerforeground is for contacts with pending subscription) *Roster.stalkerforeground: #663333 ! Other colors are selfexplanatory *Roster.unavailableforeground: #515151 *Roster.dndforeground: #515129 *Roster.xaforeground: #0b3760 *Roster.awayforeground: #0b3760 *Roster.availableforeground: dodgerblue4 *Roster.chatforeground: dodgerblue4 ! Colors in chat and groupchat windows *Chat*Text*Label.background: #f0f0cc ! Color of other people nicknames *Chat.theyforeground: firebrick4 ! Color of my nickname *Chat.meforeground: dodgerblue4 ! Colors of server messages *Chat.serverlabelforeground: seagreen *Chat.serverforeground: #4b3a70 ! Color of info & error messages *Chat.infoforeground: dodgerblue4 *Chat.errforeground: firebrick4 ! Color of inactive urls in text *urlforeground: dodgerblue4 ! Color of active urls in text *urlactiveforeground: dodgerblue3 ! Colors of erroneous words (when ispell module is using) *Text.errorColor: firebrick *Text.comboColor: dodgerblue4 ! Colors of tab labels (when in tabbed mode) ! Usual color *alertColor0: black ! Color when server message is arrived *alertColor1: mediumpurple4 ! Color when message is arrived *alertColor2: dodgerblue4 ! Color when personally addressed message is arrived *alertColor3: firebrick4 ! Colors for browser and discovery service windows *JBrowser.fill: #000000 *JBrowser.activefill: #000000 *JBrowser.border: #f0f0cc *JBrowser.nscolor: #966666 *JBrowser.nsactivecolor: #966666 *JDisco.fill: #000000 *JDisco.activefill: #000000 *JDisco.border: #f0f0cc *JDisco.featurecolor: #966666 *JDisco.identitycolor: DarkGreen *JDisco.optioncolor: DarkViolet *Tree*background: #f0f0cc *linesfill: #000000 *crossfill: #000000 ! Tooltip options *Balloon*background: #d0b073 *Balloon*foreground: #000000 *DynamicHelp.background: #d0b073 *DynamicHelp.foreground: #000000 *Text.background: #f0f0cc *Text.foreground: #000000 *Text.borderWidth: 1 *Entry.background: #b38047 *Entry.foreground: #000000 *Entry.borderWidth: 1 *NoteBook*Entry.background: #b38047 *NoteBook*Entry.disabledBackground: #d0b073 *NoteBook*Entry.foreground: #000000 *Menu.activeBorderWidth: 1 *Menu.borderWidth: 1 *Menubutton.borderWidth: 1 *ButtonBox*borderWidth: 0 *ButtonBox*activeBorderWidth: 0 *Button.borderWidth: 1 *Customize.varforeground: firebrick4 tkabber-0.11.1/examples/xrdb/black.xrdb0000644000175000017500000000517110666027074017250 0ustar sergeisergei*background: black *foreground: grey *disabledBackground: black *disabledForeground: grey50 *readonlyBackground: #000000 *errorForeground: coral3 *activeBackground: grey30 *activeForeground: grey100 *selectBackground: grey *selectForeground: black *selectBorderWidth: 0 *inactiveSelectBackground: grey *highlightSearchBackground: #c1eec1 *highlightBackground: black *highlightColor: grey *insertBackground: grey *troughColor: black *Spinbox.borderWidth: 1 *Spinbox.background: black *SpinBox.borderWidth: 1 *SpinBox*Entry*highlightBackground: black *ComboBox.borderWidth: 1 *ArrowButton.borderWidth: 0 *ArrowButton.highlightThickness: 0 *Mclistbox.background: black *Mclistbox.labelBackground: black *Mclistbox.labelForeground: grey *Mclistbox.labelActiveBackground: grey30 *Mclistbox.labelActiveForeground: grey100 *Roster.cbackground: Black *Roster.jidfill: Black *Roster.jidhlfill: #382b54 *Roster.jidborder: Black *Roster.groupfill: Gray30 *Roster.groupcfill: Gray30 *Roster.grouphlfill: MediumPurple4 *Roster.groupborder: Black *JBrowser.fill: Grey *JBrowser.activefill: Grey *JBrowser.border: Black *JBrowser.nscolor: LightSteelBlue3 *JBrowser.nsactivecolor: LightSteelBlue3 *linesfill: Grey *crossfill: Grey *JDisco.fill: Grey *JDisco.activefill: Grey *JDisco.border: Black *JDisco.featurecolor: LightSteelBlue3 *JDisco.identitycolor: darkolivegreen3 *JDisco.optioncolor: mediumorchid3 *Tree*background: Black *Roster.stalkerforeground: grey40 *Roster.unavailableforeground: grey40 *Roster.dndforeground: grey45 *Roster.xaforeground: grey50 *Roster.awayforeground: grey50 *Roster.availableforeground: grey55 *Roster.chatforeground: grey55 *Chat*Text*Label.background: black *Chat.theyforeground: cornflowerblue *Chat.meforeground: coral3 *Chat.serverlabelforeground: darkolivegreen3 *Chat.serverforeground: mediumorchid3 *Chat.infoforeground: cornflowerblue *Chat.errforeground: coral3 *urlforeground: cornflowerblue *urlactiveforeground: skyblue *Text.errorColor: coral3 *Text.comboColor: cornflowerblue *ProgressBar.foreground: grey *alertColor0: Grey *alertColor1: mediumorchid3 *alertColor2: cornflowerblue *alertColor3: coral3 *NoteBook*Entry.background: #000000 *NoteBook*Entry.disabledBackground: #000000 *NoteBook*Entry.foreground: grey *Customize.varforeground: cornflowerblue tkabber-0.11.1/examples/xrdb/ice.xrdb0000644000175000017500000001430010762611355016724 0ustar sergeisergei! Main window geometry Tkabber.geometry: 788x550-70+100 !Tkabber.geometry: 180x400-70+100 ! Chat window geometry (in no tabs mode) *Chat.geometry: 500x500 ! Browser and Headlines window geometry (in no tabs mode) *JBrowser.geometry: 500x500 ! Roster width (tabbed interface only) Tkabber.mainRosterWidth: 120 ! Roster width in groupchat windows Tkabber.chatRosterWidth: 90 ! Scrollbar bed color *troughColor: #c1c1cc *background: #d3d3dd *foreground: #000000 *readonlyBackground: #d3d3dd *disabledBackground: #d3d3dd *disabledForeground: #535373 *errorForeground: firebrick4 ! Colors, which are used when mouse is over the item *activeBackground: #c2c2e3 *activeForeground: #000000 ! Colors and border width selected item *selectBackground: #b2b2f1 *selectForeground: #336699 *selectBorderWidth: 1 *inactiveSelectBackground: #b2b2f1 ! Color for checkboxes *selectColor: #ababb5 ! Color of traversal highlight rectangle *highlightBackground: #d3d3dd *highlightColor: #666666 ! Color of insertion cursor *insertBackground: #000000 ! Font for drawing text (except chats and roster font) *font: -monotype-arial-medium-r-normal-*-13-*-*-*-*-*-koi8-r ! Currently there is only progressbar (at the splash screen) *ProgressBar.foreground: #b2b2f1 ! Flatten ComboBox and ArrowButton *Spinbox.borderWidth: 1 *Spinbox.background: #e5e5f7 *SpinBox.borderWidth: 1 *SpinBox*Entry*highlightBackground: #e5e5f7 *ComboBox.borderWidth: 1 *ArrowButton.borderWidth: 0 *ArrowButton.highlightThickness: 0 ! Colors for multicolumn listboxes (as in search result window) *Mclistbox.background: #e5e5f7 *Mclistbox.labelActiveBackground: #c2c2e3 *Mclistbox.labelBackground: #c6c6cf *Mclistbox.labelForeground: #000000 *Mclistbox.labelActiveForeground: #000000 *Button.background: #c6c6cf *Menubutton.background: #c6c6cf *Menu.activeBackground: #c2c2e3 *Chat*Button.background: #d3d3dd *Chat*Menubutton.background: #d3d3dd *Message*Menubutton.background: #d3d3dd *bbox.Button.background: #c6c6cf *mainframe.topf.tb0.bbox.Button.background: #d3d3dd *bottom.buttons1.Button.background: #d3d3dd ! Type of subitem in roster (1 - display number of resources, ! 2 - display arrow, 3 - display both, 0 - display nothing *Roster.subitemtype: 3 ! Roster background color *Roster.cbackground: #e5e5f7 ! Inactive JID background color *Roster.jidfill: #e5e5f7 ! Active JID background color *Roster.jidhlfill: #c2c2e3 ! Color of border around JID *Roster.jidborder: #e5e5f7 ! Inctive group background color *Roster.groupfill: #d3d3dd ! Inactive closed group background color *Roster.groupcfill: #d3d3dd ! Active group background color *Roster.grouphlfill: #c2c2e3 ! Color of border around group *Roster.groupborder: #d3d3dd ! Indent of group names *Roster.groupindent: 21 ! Indent of JIDs *Roster.jidindent: 42 ! Indent of second order JIDs ! (resources for those who is logged in multiple times) *Roster.subjidindent: 62 ! Indent of group icons (closed or open arrow icon) *Roster.groupiconindent: 2 ! Indent of group icons when subitemtype is 2 or 3 *Roster.subgroupiconindent: 2 ! Indent of regular JID icons (status icon) *Roster.iconindent: 21 ! Indent of second order JID icons *Roster.subiconindent: 42 ! Additional amount of text height *Roster.textuppad: 0 *Roster.textdownpad: 0 ! Vertical distance between adjacent items *Roster.linepad: 2 ! Foregrounds of JID label ! (stalkerforeground is for contacts with pending subscription) *Roster.stalkerforeground: #663333 ! Other colors are selfexplanatory *Roster.unavailableforeground: #515151 *Roster.dndforeground: #515129 *Roster.xaforeground: #0b3760 *Roster.awayforeground: #0b3760 *Roster.availableforeground: dodgerblue4 *Roster.chatforeground: dodgerblue4 ! Colors in chat and groupchat windows *Chat*Text*Label.background: #e5e5f7 ! Color of other people nicknames *Chat.theyforeground: firebrick4 ! Color of my nickname *Chat.meforeground: dodgerblue4 ! Colors of server messages *Chat.serverlabelforeground: seagreen *Chat.serverforeground: #4b3a70 ! Color of info & error messages *Chat.infoforeground: dodgerblue4 *Chat.errforeground: firebrick4 ! Color of inactive urls in text *urlforeground: dodgerblue4 ! Color of active urls in text *urlactiveforeground: dodgerblue3 ! Colors of erroneous words (when ispell module is using) *Text.errorColor: firebrick4 *Text.comboColor: dodgerblue4 ! Colors of tab labels (when in tabbed mode) ! Usual color *alertColor0: black ! Color when server message is arrived *alertColor1: mediumpurple4 ! Color when message is arrived *alertColor2: dodgerblue4 ! Color when personally addressed message is arrived *alertColor3: firebrick4 ! Colors for browser and discovery service windows *JBrowser.fill: #000000 *JBrowser.activefill: #000000 *JBrowser.border: #e5e5f7 *JBrowser.nscolor: #666666 *JBrowser.nsactivecolor: #666666 *JDisco.fill: #000000 *JDisco.activefill: #000000 *JDisco.border: #e5e5f7 *JDisco.featurecolor: #666666 *JDisco.identitycolor: DarkGreen *JDisco.optioncolor: DarkViolet *Tree*background: #e5e5f7 *linesfill: #000000 *crossfill: #000000 ! Tooltip options *Balloon*background: #c2c2e3 *Balloon*foreground: #000000 *DynamicHelp.background: #c2c2e3 *DynamicHelp.foreground: #000000 *Listbox.background: #e5e5f7 *Listbox.foreground: #000000 *Listbox.borderWidth: 1 *Text.background: #e5e5f7 *Text.foreground: #000000 *Text.borderWidth: 1 *Entry.background: #e5e5f7 *Entry.foreground: #000000 *Entry.borderWidth: 1 *NoteBook*Entry.background: #e5e5f7 *NoteBook*Entry.disabledBackground: #d3d3dd *NoteBook*Entry.foreground: #000000 *Menu.activeBorderWidth: 1 *Menu.borderWidth: 1 *Menubutton.borderWidth: 1 *ButtonBox*borderWidth: 0 *ButtonBox*activeBorderWidth: 0 *Button.borderWidth: 1 *Customize.varforeground: dodgerblue4 tkabber-0.11.1/examples/xrdb/light.xrdb0000644000175000017500000001427010762611355017301 0ustar sergeisergei! Main window geometry Tkabber.geometry: 788x550-70+100 !Tkabber.geometry: 180x400-70+100 ! Chat window geometry (in no tabs mode) *Chat.geometry: 500x500 ! Browser and Headlines window geometry (in no tabs mode) *JBrowser.geometry: 500x500 ! Roster width (tabbed interface only) Tkabber.mainRosterWidth: 120 ! Roster width in groupchat windows Tkabber.chatRosterWidth: 90 ! Scrollbar bed color *troughColor: #e3e3e3 *background: #f0f0f0 *foreground: #000000 *readonlyBackground: #f0f0f0 *disabledBackground: #f0f0f0 *disabledForeground: #999999 *errorForeground: firebrick4 ! Colors, which are used when mouse is over the item *activeBackground: #c7e1ff *activeForeground: #0000d1 ! Colors and border width selected item *selectBackground: #e8f3ff *selectForeground: #0000d1 *selectBorderWidth: 0 *inactiveSelectBackground: #e8f3ff ! Color for checkboxes *selectColor: #6b99ff ! Color of traversal highlight rectangle *highlightBackground: #f0f0f0 *highlightColor: #6b99ff ! Color of insertion cursor *insertBackground: #000000 ! Font for drawing text (except chats and roster font) *font: -monotype-arial-medium-r-normal-*-13-*-*-*-*-*-koi8-r ! Currently there is only progressbar (at the splash screen) *ProgressBar.foreground: #6b99ff ! Flatten ComboBox and ArrowButton *Spinbox.borderWidth: 1 *Spinbox.background: #f8f8f8 *SpinBox.borderWidth: 1 *SpinBox*Entry*highlightBackground: #f8f8f8 *ComboBox.borderWidth: 1 *ArrowButton.borderWidth: 0 *ArrowButton.highlightThickness: 0 ! Colors for multicolumn listboxes (as in search result window) *Mclistbox.background: #f0f0f0 *Mclistbox.labelActiveBackground: #c7e1ff *Mclistbox.labelBackground: #e1e1e1 *Mclistbox.labelForeground: #000000 *Mclistbox.labelActiveForeground: #0000d1 *Button.background: #e1e1e1 *Menubutton.background: #e1e1e1 *Menu.activeBackground: #c7e1ff *Chat*Button.background: #f0f0f0 *Chat*Menubutton.background: #f0f0f0 *Message*Menubutton.background: #f0f0f0 *bbox.Button.background: #e1e1e1 *mainframe.topf.tb0.bbox.Button.background: #f0f0f0 *bottom.buttons1.Button.background: #f0f0f0 ! Type of subitem in roster (1 - display number of resources, ! 2 - display arrow, 3 - display both, 0 - display nothing *Roster.subitemtype: 3 ! Roster background color *Roster.cbackground: #f8f8f8 ! Inactive JID background color *Roster.jidfill: #f8f8f8 ! Active JID background color *Roster.jidhlfill: #c7e1ff ! Color of border around JID *Roster.jidborder: #f8f8f8 ! Inctive group background color *Roster.groupfill: #f0f0f0 ! Inactive closed group background color *Roster.groupcfill: #f0f0f0 ! Active group background color *Roster.grouphlfill: #c7e1ff ! Color of border around group *Roster.groupborder: #f0f0f0 ! Indent of group names *Roster.groupindent: 21 ! Indent of JIDs *Roster.jidindent: 42 ! Indent of second order JIDs ! (resources for those who is logged in multiple times) *Roster.subjidindent: 62 ! Indent of group icons (closed or open arrow icon) *Roster.groupiconindent: 2 ! Indent of group icons when subitemtype is 2 or 3 *Roster.subgroupiconindent: 2 ! Indent of regular JID icons (status icon) *Roster.iconindent: 21 ! Indent of second order JID icons *Roster.subiconindent: 42 ! Additional amount of text height *Roster.textuppad: 0 *Roster.textdownpad: 0 ! Vertical distance between adjacent items *Roster.linepad: 2 ! Foregrounds of JID label ! (stalkerforeground is for contacts with pending subscription) *Roster.stalkerforeground: #663333 ! Other colors are selfexplanatory *Roster.unavailableforeground: #515151 *Roster.dndforeground: #515129 *Roster.xaforeground: #0b3760 *Roster.awayforeground: #0b3760 *Roster.availableforeground: dodgerblue4 *Roster.chatforeground: dodgerblue4 ! Colors in chat and groupchat windows *Chat*Text*Label.background: #f8f8f8 ! Color of other people nicknames *Chat.theyforeground: firebrick4 ! Color of my nickname *Chat.meforeground: dodgerblue4 ! Colors of server messages *Chat.serverlabelforeground: seagreen *Chat.serverforeground: #4b3a70 ! Color of info & error messages *Chat.infoforeground: dodgerblue4 *Chat.errforeground: firebrick4 ! Color of inactive urls in text *urlforeground: dodgerblue4 ! Color of active urls in text *urlactiveforeground: dodgerblue3 ! Colors of erroneous words (when ispell module is using) *Text.errorColor: firebrick4 *Text.comboColor: dodgerblue4 ! Colors of tab labels (when in tabbed mode) ! Usual color *alertColor0: black ! Color when server message is arrived *alertColor1: mediumpurple4 ! Color when message is arrived *alertColor2: dodgerblue4 ! Color when personally addressed message is arrived *alertColor3: firebrick4 ! Colors for browser and discovery service windows *JBrowser.fill: #000000 *JBrowser.activefill: #000000 *JBrowser.border: #f8f8f8 *JBrowser.nscolor: #2f6099 *JBrowser.nsactivecolor: #2f6099 *JDisco.fill: #000000 *JDisco.activefill: #000000 *JDisco.border: #f8f8f8 *JDisco.featurecolor: #2f6099 *JDisco.identitycolor: DarkGreen *JDisco.optioncolor: DarkViolet *Tree*background: #f8f8f8 *linesfill: #000000 *crossfill: #000000 *Customize.varforeground: dodgerblue4 ! Tooltip options *Balloon*background: #fffae6 *Balloon*foreground: #000000 *DynamicHelp.background: #fffae6 *DynamicHelp.foreground: #000000 *Listbox.background: #f8f8f8 *Listbox.foreground: #000000 *Listbox.borderWidth: 1 *Text.background: #f8f8f8 *Text.foreground: #000000 *Text.borderWidth: 1 *Entry.background: #f8f8f8 *Entry.foreground: #000000 *Entry.borderWidth: 1 *NoteBook*Entry.background: #f8f8f8 *NoteBook*Entry.disabledBackground: #f0f0f0 *NoteBook*Entry.foreground: #000000 *Menu.activeBorderWidth: 1 *Menu.borderWidth: 1 *Menubutton.borderWidth: 1 *ButtonBox*borderWidth: 0 *ButtonBox*activeBorderWidth: 0 *Button.borderWidth: 1 tkabber-0.11.1/examples/xrdb/dark.xrdb0000644000175000017500000001344510762611355017116 0ustar sergeisergei! Main window geometry Tkabber.geometry: 788x550-70+100 !Tkabber.geometry: 180x400-70+100 ! Chat window geometry (in no tabs mode) *Chat.geometry: 500x500 ! Browser and Headlines window geometry (in no tabs mode) *JBrowser.geometry: 500x500 ! Roster width (tabbed interface only) Tkabber.mainRosterWidth: 120 ! Roster width in groupchat windows Tkabber.chatRosterWidth: 90 ! Scrollbar bed color *troughColor: #424242 *background: #5e5e5e *foreground: #ffffff *readonlyBackground: #5e5e5e *disabledBackground: #5e5e5e *disabledForeground: #cccccc *errorForeground: indianred1 ! Colors, which are used when mouse is over the item *activeBackground: #550066 *activeForeground: #ffffff ! Colors and border width selected item *selectBackground: #550066 *selectForeground: #ffffff *selectBorderWidth: 0 *inactiveSelectBackground: #550066 ! Color for checkboxes *selectColor: #4f135b ! Color of traversal highlight rectangle *highlightBackground: #5e5e5e *highlightColor: #000000 ! Color of insertion cursor *insertBackground: #ffffff ! Font for drawing text (except chats and roster font) *font: -monotype-arial-medium-r-normal-*-13-*-*-*-*-*-koi8-r ! Currently there is only progressbar (at the splash screen) *ProgressBar.foreground: #550066 ! Flatten ComboBox and ArrowButton *Spinbox.borderWidth: 1 *Spinbox.background: #424242 *SpinBox.borderWidth: 1 *SpinBox*Entry*highlightBackground: #424242 *ComboBox.borderWidth: 1 *ArrowButton.borderWidth: 0 *ArrowButton.highlightThickness: 0 ! Colors for multicolumn listboxes (as in search result window) *Mclistbox.background: #424242 *Mclistbox.labelActiveBackground: #550066 *Mclistbox.labelBackground: #5e5e5e *Mclistbox.labelForeground: #ffffff *Mclistbox.labelActiveForeground: #ffffff ! Type of subitem in roster (1 - display number of resources, ! 2 - display arrow, 3 - display both, 0 - display nothing *Roster.subitemtype: 3 ! Roster background color *Roster.cbackground: #424242 ! Inactive JID background color *Roster.jidfill: #424242 ! Active JID background color *Roster.jidhlfill: #4f135b ! Color of border around JID *Roster.jidborder: #424242 ! Inctive group background color *Roster.groupfill: #5e5e5e ! Inactive closed group background color *Roster.groupcfill: #5e5e5e ! Active group background color *Roster.grouphlfill: #550066 ! Color of border around group *Roster.groupborder: #5e5e5e ! Indent of group names *Roster.groupindent: 21 ! Indent of JIDs *Roster.jidindent: 42 ! Indent of second order JIDs ! (resources for those who is logged in multiple times) *Roster.subjidindent: 62 ! Indent of group icons (closed or open arrow icon) *Roster.groupiconindent: 2 ! Indent of group icons when subitemtype is 2 or 3 *Roster.subgroupiconindent: 2 ! Indent of regular JID icons (status icon) *Roster.iconindent: 21 ! Indent of second order JID icons *Roster.subiconindent: 42 ! Additional amount of text height *Roster.textuppad: 0 *Roster.textdownpad: 0 ! Vertical distance between adjacent items *Roster.linepad: 2 ! Foregrounds of JID label ! (stalkerforeground is for contacts with pending subscription) *Roster.stalkerforeground: tan ! Other colors are selfexplanatory *Roster.unavailableforeground: grey72 *Roster.dndforeground: rosybrown1 *Roster.xaforeground: azure3 *Roster.awayforeground: azure3 *Roster.availableforeground: #ffffff *Roster.chatforeground: #ffffff ! Colors in chat and groupchat windows *Chat*Text*Label.background: #424242 ! Color of other people nicknames *Chat.theyforeground: coral ! Color of my nickname *Chat.meforeground: lightblue ! Colors of server messages *Chat.serverlabelforeground: darkolivegreen1 *Chat.serverforeground: hotpink ! Color of info & error messages *Chat.infoforeground: lightblue *Chat.errforeground: indianred1 ! Color of inactive urls in text *urlforeground: lightblue ! Color of active urls in text *urlactiveforeground: lightblue1 ! Colors of erroneous words (when ispell module is using) *Text.errorColor: coral *Text.comboColor: lightblue ! Colors of tab labels (when in tabbed mode) ! Usual color *alertColor0: white ! Color when server message is arrived *alertColor1: hotpink ! Color when message is arrived *alertColor2: lightblue ! Color when personally addressed message is arrived *alertColor3: coral ! Colors for browser and discovery service windows *JBrowser.fill: #ffffff *JBrowser.activefill: #ffffff *JBrowser.border: #424242 *JBrowser.nscolor: grey72 *JBrowser.nsactivecolor: grey72 *JDisco.fill: #ffffff *JDisco.activefill: #ffffff *JDisco.border: #424242 *JDisco.featurecolor: grey72 *JDisco.identitycolor: DarkSeaGreen2 *JDisco.optioncolor: HotPink *Tree*background: #424242 *linesfill: #ffffff *crossfill: #ffffff *Customize.varforeground: lightblue ! Tooltip options *Balloon*background: #424242 *Balloon*foreground: #ffffff *DynamicHelp.background: #424242 *DynamicHelp.foreground: #ffffff *Listbox.background: #424242 *Listbox.foreground: #ffffff *Listbox.borderWidth: 1 *Text.background: #424242 *Text.foreground: #ffffff *Text.borderWidth: 1 *Entry.background: #424242 *Entry.foreground: #ffffff *Entry.borderWidth: 1 *NoteBook*Entry.background: #424242 *NoteBook*Entry.disabledBackground: #5e5e5e *NoteBook*Entry.foreground: #ffffff *Button.borderWidth: 1 *Menu.activeBorderWidth: 1 *Menu.borderWidth: 1 *Menubutton.borderWidth: 1 *Buttonbox*borderWidth: 0 *Buttonbox*activeBorderWidth: 0 tkabber-0.11.1/examples/xrdb/green.xrdb0000644000175000017500000001035710702121075017261 0ustar sergeisergei! Main window geometry Tkabber.geometry: 788x550-70+100 !Tkabber.geometry: 200x350-70+100 ! Chat window geometry (in no tabs mode) *Chat.geometry: 500x500 ! Browser and Headlines window geometry (in no tabs mode) *JBrowser.geometry: 500x500 ! Roster width (tabbed interface only) Tkabber.mainRosterWidth: 120 ! Roster width in groupchat windows Tkabber.chatRosterWidth: 90 *background: ForestGreen *foreground: LawnGreen *readonlyBackground: ForestGreen *disabledBackground: ForestGreen *disabledForeground: PaleGreen3 *activeBackground: PaleGreen3 *activeForeground: DarkOliveGreen *selectBackground: LawnGreen *selectForeground: ForestGreen *inactiveSelectBackground: LawnGreen *highlightBackground: ForestGreen *highlightForeground: LawnGreen *selectColor: PaleGreen3 *selectBorderWidth: 0 *insertBackground: LawnGreen *troughColor: ForestGreen *errorForeground: orange *font: -monotype-arial-medium-r-normal-*-13-*-*-*-*-*-koi8-r *ProgressBar.foreground: PaleGreen2 *Spinbox.borderWidth: 1 *Spinbox.background: ForestGreen *SpinBox.borderWidth: 1 *SpinBox*Entry*highlightBackground: ForestGreen *ComboBox.borderWidth: 1 *ArrowButton.borderWidth: 0 *ArrowButton.highlightThickness: 0 *Mclistbox.background: ForestGreen *Mclistbox.labelActiveBackground: PaleGreen3 *Mclistbox.labelBackground: ForestGreen *Mclistbox.labelForeground: LawnGreen *Mclistbox.labelActiveForeground: DarkOliveGreen *Roster.subitemtype: 3 *Roster.cbackground: ForestGreen *Roster.jidfill: ForestGreen *Roster.jidhlfill: ForestGreen *Roster.jidborder: ForestGreen *Roster.groupfill: DarkGreen *Roster.groupcfill: DarkGreen *Roster.grouphlfill: DarkGreen *Roster.groupborder: DarkGreen *Roster.groupindent: 21 *Roster.jidindent: 42 *Roster.subjidindent: 62 *Roster.groupiconindent: 2 *Roster.subgroupiconindent: 2 *Roster.iconindent: 21 *Roster.subiconindent: 42 *Roster.textuppad: 0 *Roster.textdownpad: 0 *Roster.linepad: 2 *Roster.stalkerforeground: LimeGreen *Roster.unavailableforeground: PaleGreen2 *Roster.dndforeground: PaleGreen3 *Roster.xaforeground: PaleGreen1 *Roster.awayforeground: PaleGreen *Roster.availableforeground: LawnGreen *Roster.chatforeground: LawnGreen *Chat*Text*Label.background: ForestGreen *Chat.theyforeground: DarkSeaGreen2 *Chat.meforeground: DarkOliveGreen2 *Chat.serverlabelforeground: DarkSeaGreen3 *Chat.serverforeground: DarkSeaGreen3 *Chat.infoforeground: DarkSeaGreen2 *Chat.errforeground: orange *urlforeground: DarkOliveGreen2 *urlactiveforeground: Green *Text.errorColor: orange *Text.comboColor: Yellow *alertColor0: PaleGreen3 *alertColor1: PaleGreen2 *alertColor2: PaleGreen3 *alertColor3: LawnGreen *JBrowser.fill: LawnGreen *JBrowser.activefill: White *JBrowser.border: Pink *JBrowser.nscolor: MediumSeaGreen *JBrowser.nsactivecolor: Blue *JDisco.fill: LawnGreen *JDisco.activefill: White *JDisco.border: Pink *JDisco.featurecolor: MediumSeaGreen *JDisco.identitycolor: MediumSeaGreen *JDisco.optioncolor: MediumSeaGreen *Tree*background: ForestGreen *linesfill: LawnGreen *crossfill: LawnGreen *Balloon*background: ForestGreen *Balloon*foreground: PaleGreen *DynamicHelp.background: ForestGreen *DynamicHelp.foreground: PaleGreen *Listbox.background: ForestGreen *Listbox.foreground: PaleGreen *Listbox.borderWidth: 1 *Text.background: ForestGreen *Text.foreground: PaleGreen *Text.borderWidth: 1 *Entry.background: ForestGreen *Entry.foreground: LawnGreen *Entry.borderWidth: 1 *NoteBook*Entry.background: ForestGreen *NoteBook*Entry.disabledBackground: ForestGreen *NoteBook*Entry.foreground: LawnGreen *Button.borderWidth: 1 *Menu.activeBorderWidth: 1 *Menu.borderWidth: 1 *Menubutton.borderWidth: 1 *Buttonbox*borderWidth: 0 *Buttonbox*activeBorderWidth: 0 *Customize.varforeground: DarkOliveGreen2 tkabber-0.11.1/examples/xrdb/dark2.xrdb0000644000175000017500000001430310762611355017172 0ustar sergeisergei! Main window geometry Tkabber.geometry: 788x550-70+100 !Tkabber.geometry: 180x400-70+100 ! Chat window geometry (in no tabs mode) *Chat.geometry: 500x500 ! Browser and Headlines window geometry (in no tabs mode) *JBrowser.geometry: 500x500 ! Roster width (tabbed interface only) Tkabber.mainRosterWidth: 110 ! Roster width in groupchat windows Tkabber.chatRosterWidth: 100 ! Scrollbar bed color *troughColor: #2c2c2c *background: #3f3f3f *foreground: #bfbfae *readonlyBackground: #3f3f3f *disabledForeground: #a9a999 *errorForeground: #f99393 *disabledBackground: #3f3f3f ! Colors, which are used when mouse is over the item *activeBackground: #616151 *activeForeground: #ffffff ! Colors and border width selected item *selectBackground: #4c4c3f *selectForeground: #bfbfae *selectBorderWidth: 0 *inactiveSelectBackground: #4c4c3f ! Color for checkboxes *selectColor: #616151 ! Color of traversal highlight rectangle *highlightBackground: #3f3f3f *highlightColor: #000000 ! Color of insertion cursor *insertBackground: #bfbfae ! Font for drawing text (except chats and roster font) *font: -monotype-arial-medium-r-normal-*-13-*-*-*-*-*-koi8-r ! Currently there is only progressbar (at the splash screen) *ProgressBar.foreground: #616151 ! Flatten ComboBox and ArrowButton *Spinbox.borderWidth: 1 *Spinbox.background: #66685e *SpinBox.borderWidth: 1 *SpinBox*Entry*highlightBackground: #66685e *ComboBox.borderWidth: 1 *ArrowButton.borderWidth: 0 *ArrowButton.highlightThickness: 0 ! Colors for multicolumn listboxes (as in search result window) *Mclistbox.background: #66685e *Mclistbox.labelActiveBackground: #616151 *Mclistbox.labelBackground: #3f3f3f *Mclistbox.labelForeground: #bfbfae *Mclistbox.labelActiveForeground: #ffffff ! Type of subitem in roster (1 - display number of resources, ! 2 - display arrow, 3 - display both, 0 - display nothing *Roster.subitemtype: 3 ! Roster background color *Roster.cbackground: #66685e ! Inactive JID background color *Roster.jidfill: #66685e ! Active JID background color *Roster.jidhlfill: #4c4c3f ! Color of border around JID *Roster.jidborder: #66685e ! Inactive group background color *Roster.groupfill: #575747 ! Inactive closed group background color *Roster.groupcfill: #575747 ! Active group background color *Roster.grouphlfill: #4c4c3f ! Color of border around group *Roster.groupborder: #575747 ! Indent of group names *Roster.groupindent: 21 ! Indent of JIDs *Roster.jidindent: 42 ! Indent of second order JIDs ! (resources for those who is logged in multiple times) *Roster.subjidindent: 62 ! Indent of group icons (closed or open arrow icon) *Roster.groupiconindent: 2 ! Indent of group icons when subitemtype is 2 or 3 *Roster.subgroupiconindent: 2 ! Indent of regular JID icons (status icon) *Roster.iconindent: 21 ! Indent of second order JID icons *Roster.subiconindent: 42 ! Additional amount of text height *Roster.textuppad: 0 *Roster.textdownpad: 0 ! Vertical distance between adjacent items *Roster.linepad: 2 ! Foregrounds of JID label ! (stalkerforeground is for contacts with pending subscription) *Roster.stalkerforeground: tan ! Other colors are selfexplanatory *Roster.unavailableforeground: #b5b5a6 *Roster.dndforeground: #ccb5a6 *Roster.xaforeground: #bfbfae *Roster.awayforeground: #bfbfae *Roster.availableforeground: #ccccbb *Roster.chatforeground: #ccccbb ! Colors in chat and groupchat windows *Chat*Text*Label.background: #66685e ! Color of other people nicknames *Chat.theyforeground: #f99393 ! Color of my nickname *Chat.meforeground: #add8cc ! Colors of server messages *Chat.serverlabelforeground: #bbe8bb *Chat.serverforeground: #e899b5 ! Color of info & error messages *Chat.infoforeground: #add8cc *Chat.errforeground: #f99393 ! Color of inactive urls in text *urlforeground: #add8cc ! Color of active urls in text *urlactiveforeground: #c0ede0 ! Colors of erroneous words (when ispell module is using) *Text.errorColor: #f99393 *Text.comboColor: #add8cc *Customize.varforeground: #add8cc ! Colors of tab labels (when in tabbed mode) ! Usual color *alertColor0: #bfbfae ! Color when server message is arrived *alertColor1: #e899b5 ! Color when message is arrived *alertColor2: #add8cc ! Color when personally addressed message is arrived *alertColor3: #f99393 ! Colors for Raw XML window *RawXML.inforeground: #f99393 *RawXML.outforeground: #add8cc *RawXML.intagforeground: #f99393 *RawXML.inattrforeground: #f99393 *RawXML.invalueforeground: #e899b5 *RawXML.incdataforeground: #add8cc *RawXML.outtagforeground: #e899b5 *RawXML.outattrforeground: #e899b5 *RawXML.outvalueforeground: #bbe8bb *RawXML.outcdataforeground: #add8cc ! Colors for browser and discovery service windows *JBrowser.fill: #bfbfae *JBrowser.activefill: #bfbfae *JBrowser.border: #66685e *JBrowser.nscolor: #cfdfbe *JBrowser.nsactivecolor: #cfdfbe *JDisco.fill: #bfbfae *JDisco.activefill: #bfbfae *JDisco.border: #66685e *JDisco.featurecolor: #cfdfbe *JDisco.identitycolor: #bbe8bb *JDisco.optioncolor: #e899b5 *Tree*background: #66685e *linesfill: #bfbfae *crossfill: #bfbfae ! Tooltip options *Balloon*background: #bfbfae *Balloon*foreground: #000000 *DynamicHelp.background: #bfbfae *DynamicHelp.foreground: #000000 *Listbox.background: #66685e *Listbox.foreground: #bfbfae *Listbox.borderWidth: 1 *Text.background: #66685e *Text.foreground: #bfbfae *Text.borderWidth: 1 *Entry.background: #66685e *Entry.foreground: #bfbfae *Entry.borderWidth: 1 *NoteBook*Entry.background: #66685e *NoteBook*Entry.disabledBackground: #3f3f3f *NoteBook*Entry.foreground: #bfbfae *Button.borderWidth: 1 *Menu.activeBorderWidth: 1 *Menu.borderWidth: 1 *Menubutton.borderWidth: 1 *Buttonbox*borderWidth: 0 *Buttonbox*activeBorderWidth: 0 *Scrollbar.width: 8 tkabber-0.11.1/examples/xrdb/ocean-deep.xrdb0000644000175000017500000002563410762611355020200 0ustar sergeisergei! Ocean Deep theme for Tkabber ! (c) 2004 Badlop ! 2004-06-26 ! Based on Ocean Deep colour theme for Vim ! --------------------------------------------------------------- GEOMETRY ---- ! Main window geometry ! [horizontal size] ! x[vertical size] ! -[separation with right screen edge] ! +[separation with upper screen edge] Tkabber.geometry: 700x520-30+170 ! Roster width (tabbed interface only) Tkabber.mainRosterWidth: 150 ! Roster width in groupchat windows Tkabber.chatRosterWidth: 80 ! Chat window geometry (in no tabs mode) *Chat.geometry: 300x500-70+350 *Chat.groupchatgeometry: 600x500 *Chat.chatgeometry: 500x500 ! Other windows geometry (in no tabs mode) *JBrowser.geometry: 350x350 *JDisco.geometry: 500x500 *Customize.geometry: 600x500 *RawXML.geometry: 500x500 *Messages.geometry: 600x500 ! ------------------------------------------------------------ MAIN WINDOW ---- ! Font for drawing text (except chats and roster font) !*font: -monotype-arial-medium-r-normal-*-17-*-*-*-*-*-koi8-r ! Main font color *foreground: #d5faff ! Color of insertion cursor *insertBackground: #ffbbbb ! Background of all windows and tabs *background: #103040 ! Menu colors (main Tkabber menus...) *Menu.background: #01476a *Menu.activeBackground: #01656a ! ---------------------------------------------------------------- WIDGETS ---- ! ------------------------------------------- PROGRESS BAR ---- ! Scrollbar bed color *troughColor: #0F4866 *Scrollbar.width: 8 ! Currently there is only progressbar (at the splash screen) *ProgressBar.foreground: #0F4866 ! ------------------------------------------- RADIO BUTTON ---- ! Colors and border width selected item (in radialbutton) *selectBackground: #005a56 *selectForeground: #fffeff *selectBorderWidth: 0 *inactiveSelectBackground: #005a56 *errorForeground: #ff7f50 ! ---------------------------------------------- CHECK BOX ---- ! Checkbox background *selectColor: #0c232a ! ----------------------------------------------- TEXT BOX ---- ! Disabled Text boxes *disabledBackground: #103040 *disabledForeground: #85aaaf ! Textbox entry (like user: in Login window) *Entry.background: #0c232e *Entry.foreground: #fffefe *Entry.disabledBackground: #103040 *Entry.readonlyBackground: #103040 *Entry.borderWidth: 1 ! Textbox like in VCard editor *NoteBook*Entry.background: #0c232e *NoteBook*Entry.disabledBackground: #103040 *NoteBook*Entry.foreground: #fffffe ! ----------------------------------------------- LIST BOX ---- !* Colors for multicolumn listboxes (as in search result window) *Mclistbox.background: #0c232e *Mclistbox.labelActiveBackground: #1d5875 *Mclistbox.labelBackground: #0F4866 *Mclistbox.labelForeground: #d5faff *Mclistbox.labelActiveForeground: #d5faff ! ---------------------------------------------- TOOL TIPS ---- ! Tooltip options *Balloon*background: #0c232e *Balloon*foreground: #fffbfb *DynamicHelp.background: #0c232e *DynamicHelp.foreground: #ffffff *Baloon.style: delay ! Listbox widget (like in Customize->Chat->vcard-items) *Listbox.background: #0c232e *Listbox.foreground: #ffffff *Listbox.borderWidth: 1 ! ------------------------------------------------ BUTTONS ---- *Button.borderWidth: 1 *Menu.activeBorderWidth: 1 *Menu.borderWidth: 1 *Menubutton.borderWidth: 1 *Buttonbox*borderWidth: 0 *Buttonbox*activeBorderWidth: 0 *Search.itemBackground: #ffffff !* Flatten ComboBox and ArrowButton +++ *Spinbox.borderWidth: 1 *Spinbox.background: #0c232e *SpinBox.borderWidth: 1 *SpinBox*Entry*highlightBackground: #0c232e *ComboBox.borderWidth: 1 *ArrowButton*borderWidth: 1 *ArrowButton.borderWidth: 0 *ArrowButton.highlightThickness: 0 ! Button and Menubutton colors ! Generic button *Button.background: #0F4866 ! Button background when mouse is over it *Button.activeBackground: #1d5875 ! Generic menubutton (like in Login window->Profiles) *Menubutton.background: #0F4864 *Menubutton.activeBackground: #1d5875 ! Buttons in chat and message windows *Chat*Button.background: #103040 ! Button with JID in Chat window *Chat*Menubutton.background: #0f4864 *Message*Menubutton.background: #0f4863 ! Common button background *bbox.Button.background: #0f4865 ! ----------------------------------------------------------------- TOOLBAR ---- ! Main toolbar buttons *mainframe.topf.tb0.bbox.Button.background: #103040 ! Sign/encrypt message buttons *bottom.buttons1.Button.background: #103040 ! ----------------------------------------------------------------- ROSTER ---- ! Type of subitem in roster (1 - display number of resources, ! 2 - display arrow, 3 - display both, 0 - display nothing *Roster.subitemtype: 3 ! --------------------------------------------------- JIDS ---- ! Roster background color *Roster.cbackground: #0c232e ! Inactive JID background color *Roster.jidfill: #0c232b ! Active JID background color *Roster.jidhlfill: #004567 ! Color of border around JID *Roster.jidborder: #0c232c ! ------------------------------------------------- GROUPS ---- ! Inactive group background color *Roster.groupfill: #18515F ! Inactive closed group background color *Roster.groupcfill: #1b485f ! Active group background color *Roster.grouphlfill: #03557d ! Color of border around group *Roster.groupborder: #103041 ! ---------------------------------------------- POSITIONS ---- ! Indent of group names *Roster.groupindent: 21 ! Indent of JIDs *Roster.jidindent: 42 ! Indent of second order JIDs ! (resources for those who is logged in multiple times) *Roster.subjidindent: 62 ! Indent of group icons (closed or open arrow icon) *Roster.groupiconindent: 2 ! Indent of group icons when subitemtype is 2 or 3 *Roster.subgroupiconindent: 2 ! Indent of regular JID icons (status icon) *Roster.iconindent: 21 ! Indent of second order JID icons *Roster.subiconindent: 42 ! Additional amount of text height *Roster.textuppad: 0 *Roster.textdownpad: 0 ! Vertical distance between adjacent items *Roster.linepad: 2 ! ----------------------------------------------- PRESENCE ---- ! Foregrounds of JID label ! (stalkerforeground is for contacts with pending subscription) *Roster.stalkerforeground: #d2b48c ! Other colors are selfexplanatory *Roster.unavailableforeground: #b8b8b8 *Roster.dndforeground: #ffc1c1 *Roster.xaforeground: #c1cdcd *Roster.awayforeground: #c1cdcd *Roster.availableforeground: #ffffff *Roster.chatforeground: #ffffff ! ------------------------------------------------------------------- TABS ---- ! Colors used when mouse is over the item (a tab header) *activeBackground: #1d5875 *activeForeground: #d7f2ff ! Colors of tab labels font (when in tabbed mode) *NoteBook*Entry.readonlyBackground: #1e3837 ! Usual color *alertColor0: #ffffff ! Color when server message is arrived *alertColor1: #ff69b4 ! Color when message is arrived *alertColor2: #add8e6 ! Color when personally addressed message is arrived *alertColor3: #ff7f50 ! ------------------------------------------------------------------- CHAT ---- ! Text in chats, messages *Text.background: #0c232e *Text.foreground: #fbfffe *Text.borderWidth: 1 ! Colors in chat and groupchat windows *Chat*Text*Label.background: #66685e ! Color of other people nicknames *Chat.theyforeground: #ff7f50 ! Color of my nickname *Chat.meforeground: #add8e6 ! Colors of server messages (--- foo leave the room) *Chat.serverlabelforeground: #caff70 *Chat.serverforeground: #ff69b4 ! Color of info & error messages *Chat.infoforeground: #add8e6 *Chat.errforeground: #ff6a6a ! Color of inactive urls in text *urlforeground: #add8e6 ! Color of active urls in text *urlactiveforeground: #add8e6 ! Colors of erroneous words (when ispell module is using) *Text.errorColor: #ff7f50 *Text.comboColor: #add8e6 *Chat.inputheight: 3 ! -------------------------------------------------------------- DISCOVERY ---- ! Colors for browser and discovery service windows ! Window background *Tree*background: #0c232e ! lines in the tree *linesfill: #d5fafa ! [+] and [-] tree symbols *crossfill: #d5fafa ! ---------------------------------------------- J BROWSER ---- ! Jabber Browser ! Nodes names font color ('Public Conferencing'...) *JBrowser.fill: #ffffff ! Nodes atributes font color ('Search', 'Register'...) *JBrowser.nscolor: #b8b8b8 *JBrowser.levelindent: 24 *JBrowser.indent: 3 *JBrowser.nsindent: 2 *JBrowser.linepad: 2 *JBrowser.toppad: 1 *JBrowser.bottompad: 1 *JBrowser.icontextpad: 2 ! -------------------------------------------- J DISCOVERY ---- ! Jabber Discovery ! Subnodes *JDisco.fill: #ffffff ! Features available *JDisco.featurecolor: #b8b8b8 ! Identity name *JDisco.identitycolor: #b4eeb4 *JDisco.optioncolor: #ff69b4 ! ------------------------------------------------------------------ MORE ---- ! ---------------------------------------------------------------------- ---- *Customize.varforeground: #D5FAFA *Customize.groupnameforeground: #D5FAFA *RawXML.inforeground: #e0c3c3 *RawXML.outforeground: #a3a3ff *RawXML.intagforeground: #e0c3c3 *RawXML.inattrforeground: #e0c3c3 *RawXML.invalueforeground: #d1aef2 *RawXML.incdataforeground: #b2dcff *RawXML.outtagforeground: #efb3ef *RawXML.outattrforeground: #efb3ef *RawXML.outvalueforeground: #c9ffc9 *RawXML.outcdataforeground: #b6b6f9 *RawXML.inputheight: 4 !* Color of traversal highlight rectangle *highlightBackground: #103040 *highlightColor: #d5faff ! ------------------------------------------------------------------- ---- ---- tkabber-0.11.1/examples/xrdb/lighthouse.xrdb0000644000175000017500000001442310762611355020345 0ustar sergeisergei! Main window geometry Tkabber.geometry: 800x600-70+100 !Tkabber.geometry: 236x879-70+0 ! Chat window geometry (in no tabs mode) *Chat.geometry: 500x500 ! Browser and Headlines window geometry (in no tabs mode) *JBrowser.geometry: 500x500 ! Roster width (tabbed interface only) Tkabber.mainRosterWidth: 110 ! Roster width in groupchat windows Tkabber.chatRosterWidth: 105 ! Scrollbar bed color *troughColor: #ddddd0 *background: #eeeee0 *foreground: #000000 *readonlyBackground: #eeeee0 *disabledForeground: #747474 *disabledBackground: #d6d6d6 ! Colors, which are used when mouse is over the item *activeBackground: #fffff0 *activeForeground: #000000 ! Colors and border width selected item *selectBackground: #5f7ca8 *selectForeground: #f5f5f5 *selectBorderWidth: 0 *inactiveSelectBackground: #5f7ca8 ! Color for checkboxes *selectColor: #5f7ca8 ! Color of traversal highlight rectangle *highlightBackground: #eeeee0 *highlightColor: #000000 ! Color of insertion cursor *insertBackground: #000000 ! Font for drawing text (except chats and roster font) !*font: -gnu-unifont-*-*-*-*-*-*-*-*-*-*-iso10646-1 *font: -*-verdana-medium-r-normal-*-12-*-*-*-*-*-iso10646-1 ! Currently there is only progressbar (at the splash screen) *ProgressBar.foreground: #334080 ! Flatten Spinbox, ComboBox and ArrowButton *Spinbox.borderWidth: 1 *Spinbox.background: #f5f5f5 *SpinBox.borderWidth: 1 *SpinBox*Entry*highlightBackground: #ddddd0 *ComboBox.borderWidth: 1 *ArrowButton.borderWidth: 0 *ArrowButton.highlightThickness: 0 ! Colors for multicolumn listboxes (as in search result window) *Mclistbox.background: #f5f5f5 *Mclistbox.labelActiveBackground: #fffff0 *Mclistbox.labelBackground: #ddddd0 ! Type of subitem in roster (1 - display number of resources, ! 2 - display arrow, 3 - display both, 0 - display nothing *Roster.subitemtype: 3 ! Roster background color *Roster.cbackground: #f5f5f5 ! JID background color *Roster.jidfill: #f5f5f5 ! Active JID background color *Roster.jidhlfill: #ddddd0 ! Color of border around JID *Roster.jidborder: #f5f5f5 ! group background color *Roster.groupfill: #ccccc0 ! closed group background color *Roster.groupcfill: #e9e9e9 ! Active group background color *Roster.grouphlfill: #bbbbb0 ! Color of border around group *Roster.groupborder: #eeeee0 ! Indent of group names *Roster.groupindent: 21 ! Indent of JIDs *Roster.jidindent: 42 ! Indent of second order JIDs ! (resources for those who is logged in multiple times) *Roster.subjidindent: 62 ! Indent of group icons (closed or open arrow icon) *Roster.groupiconindent: 2 ! Indent of group icons when subitemtype is 2 or 3 *Roster.subgroupiconindent: 2 ! Indent of regular JID icons (status icon) *Roster.iconindent: 21 ! Indent of second order JID icons *Roster.subiconindent: 42 ! Additional amount of text height *Roster.textuppad: 0 *Roster.textdownpad: 0 ! Vertical distance between adjacent items *Roster.linepad: 2 ! Foregrounds of JID label ! (stalkerforeground is for contacts with pending subscription) *Roster.stalkerforeground: #663333 ! Other colors are selfexplanatory *Roster.unavailableforeground: #515151 *Roster.dndforeground: #515129 *Roster.xaforeground: #0b3760 *Roster.awayforeground: #0b3760 *Roster.availableforeground: dodgerblue4 *Roster.chatforeground: dodgerblue4 ! Colors in chat and groupchat windows *Chat*Text.background: #f5f5f5 ! Color of other people nicknames *Chat.theyforeground: firebrick4 ! Color of my nickname *Chat.meforeground: dodgerblue4 ! Colors of server messages *Chat.serverlabelforeground: seagreen *Chat.serverforeground: #4b3a70 ! Color of error messages *Chat.errforeground: firebrick ! Color of inactive urls in text *urlforeground: dodgerblue4 ! Color of active urls in text *urlactiveforeground: dodgerblue3 ! Colors of erroneous words (when ispell module is using) *Text.errorColor: firebrick4 *Text.comboColor: dodgerblue4 ! Colors of tab labels (when in tabbed mode) ! Usual color *alertColor0: black ! Color when server message is arrived *alertColor1: mediumpurple4 ! Color when message is arrived *alertColor2: dodgerblue4 ! Color when personally addressed message is arrived *alertColor3: firebrick4 ! Colors for browser and discovery service windows *JBrowser.fill: #000000 *JBrowser.activefill: #f5f5f5 *JBrowser.border: #eeeee0 *JBrowser.nscolor: #747474 *JBrowser.nsactivecolor: #747474 *JDisco.fill: #000000 *JDisco.activefill: #f5f5f5 *JDisco.border: #eeeee0 *JDisco.featurecolor: #747474 *JDisco.identitycolor: DarkGreen *JDisco.optioncolor: DarkViolet *Tree*background: #f5f5f5 ! Tooltip options *Balloon*background: #ffeeaa *Balloon*foreground: #000000 *DynamicHelp.background: #ffeeaa *DynamicHelp.foreground: #000000 *Listbox.background: #f5f5f5 *Listbox.foreground: #000000 *Listbox.borderWidth: 1 *Text.background: #f5f5f5 *Text.foreground: #000000 *Text.borderWidth: 1 *Entry.background: #f5f5f5 *Entry.foreground: #000000 *Entry.borderWidth: 1 *NoteBook*Entry.background: #f5f5f5 *NoteBook*Entry.disabledBackground: #e9e9e9 *NoteBook*Entry.foreground: #000000 *Button.borderWidth: 1 *Button.background: #ddddd0 *Button.activeBackground: #fffff0 ! Main toolbar buttons *mainframe.topf.tb0.bbox.Button.background: #eeeee0 *mainframe.topf.tb1.bbox.Button.background: #eeeee0 *mainframe.topf.tb2.bbox.Button.background: #eeeee0 *mainframe.topf.tb3.bbox.Button.background: #eeeee0 *mainframe.topf.tb4.bbox.Button.background: #eeeee0 *mainframe.topf.tb5.bbox.Button.background: #eeeee0 ! Sign/encrypt message buttons *bottom.buttons1.Button.background: #eeeee0 *Chat*Button.background: #eeeee0 *Menu.activeBorderWidth: 1 *Menu.borderWidth: 1 *Menubutton.borderWidth: 1 *Menu.activeBackground: #5f7ca8 *Menu.activeForeground: #f5f5f5 *Menubutton.activeBackground: #fffff0 *Menubutton.activeForeground: #000000 *Buttonbox*borderWidth: 0 *Buttonbox*activeBorderWidth: 0 tkabber-0.11.1/examples/configs/0000755000175000017500000000000011076120366015772 5ustar sergeisergeitkabber-0.11.1/examples/configs/mtr-config.tcl0000644000175000017500000003236410556440255020557 0ustar sergeisergei# MTR's config file for tkabber (now with Aqua support!) set ssj::options(one-passphrase) 1 set ssj::options(sign-traffic) 1 set ssj::options(encrypt-traffic) 1 set use_ispell 1 set debug_lvls [list zerobot] set debug_winP 1 set show_splash_window 1 proc debugmsg {module msg} { global debug_lvls w global debug_fd debug_winP if {![info exists debug_fd]} { catch { file rename -force -- ~/.tkabber/tkabber.log \ ~/.tkabber/tkabber0.log } set debug_fd [open ~/.tkabber/tkabber.log \ { WRONLY CREAT TRUNC APPEND }] fconfigure $debug_fd -buffering line } puts $debug_fd [format "%s %-12.12s %s" \ [clock format [clock seconds] -format "%m/%d %T"] \ $module $msg] if {([lsearch -exact $debug_lvls $module] < 0) || (!$debug_winP)} { return } set dw $w.debug if {![winfo exists $dw]} { add_win $dw -title Debug -tabtitle debug -class Chat [ScrolledWindow $dw.sw] setwidget \ [text $dw.body -yscrollcommand [list $dw.scroll set]] pack $dw.sw -side bottom -fill both -expand yes $dw.body tag configure module \ -foreground [option get $dw theyforeground Chat] $dw.body tag configure proc \ -foreground [option get $dw meforeground Chat] $dw.body tag configure error \ -foreground [option get $dw errforeground Chat] } $dw.body insert end [format "%-12.12s" $module] module " " set tag normal switch -- $module { jlib { if {[set x [string first "(jlib::" $msg]] > 0} { set tag error } if {[set y [string first ")" $msg]] > 0} { $dw.body insert end \ [string range $msg [expr $x+7] [expr $y-1]] proc \ "\n" set msg [string trimleft \ [string range $msg [expr $y+1] end]] } } default { } } $dw.body insert end [string trimright $msg] $tag $dw.body insert end "\n" if {!$chat::options(stop_scroll)} { $dw.body see end } } if {$aquaP} { set load_default_xrdb 1 set font {Monoco 12 normal} option add *font $font userDefault } else { set load_default_xrdb 0 option readfile ~/src/tkabber/tkabber/examples/ice.xrdb userDefault option add *font fixed userDefault } switch -- [winfo screenwidth .]x[winfo screenheight .] { 1440x900 - 1440x879 { option add Tkabber.geometry =710x481+730+21 userDefault } 1400x1050 - 1280x1024 { option add Tkabber.geometry =788x550-0+0 userDefault } 1024x768 - default { option add Tkabber.geometry =630x412-0+0 userDefault } } proc config_postload {} { # the emoticon module plugins::emoticons::load_dir ~/.tkabber/emoticons/rythmbox # the georoster module source ~/src/tkabber/tkabber-plugins/georoster/georoster.tcl # source ~/.tkabber/proprietary/georoster-prop.tcl namespace eval georoster { variable mapnum 1 variable mapwidth variable mapheight variable options set options(showcities) none switch -- [winfo screenwidth .]x[winfo screenheight .] { 1440x900 { set mapwidth 812 set mapheight 422 } 1400x1050 - 1280x1024 { set mapwidth 975 set mapheight 506 } 1024x768 - default { set mapwidth 650 set mapheight 338 set options(mapfile) \ ~/src/tkabber/tkabber-plugins/georoster/bwmap4.gif proc lo {x y} {expr {($x*2 - 649)*18/65 + 10}} proc la {x y} {expr {(371 - $y*2)*9/40}} proc x {lo la} {expr {(649+(($lo-10)*65/18))/2}} proc y {lo la} {expr {(371-($la * 40/9))/2}} } } variable M_PI 3.14159265358979323846 variable M_PI_2 [expr $M_PI/2.0] variable deg_to_rad [expr $M_PI/180.0] variable TWO_PI [expr $M_PI*2.0] variable M_DEG [expr 180/$M_PI] variable M_INVDEG [expr $M_PI/180] variable del_lon [expr $TWO_PI/$mapwidth] variable del_lat [expr $M_PI/$mapheight] variable lon_array for {set i 0} {$i < $mapwidth} {incr i} { set lon_array($i) [expr (($i+0.5)*$del_lon-$M_PI)] } variable lat_array for {set i 0} {$i < $mapheight} {incr i} { set lat_array($i) [expr ($M_PI_2 - ($i+0.5)*$del_lat)] } proc sp2px {lo la} { variable M_PI variable M_PI_2 variable TWO_PI variable del_lon variable del_lat variable mapwidth variable mapheight if {$lo > $M_PI} { set lo [expr $lo-$TWO_PI] } elseif {$lo < -$M_PI} { set lo [expr $lo+$TWO_PI] } set x [expr round(($lo+$M_PI)/$del_lon + 0.5)] if {$x >= $mapwidth} { incr x -$mapwidth } elseif {$x < 0} { incr x $mapwidth } set y [expr round(($M_PI_2-$la)/$del_lat + 0.5)] if {$y >= $mapheight} { set y [expr $mapheight-1] } return [list $x $y] } proc refresh {} { variable mapcmd variable mapnum variable mapwidth variable mapheight if {![winfo exists .georoster.c]} { return [after [expr 60*1000] [namespace current]::refresh] } set file [file join [glob ~] .tkabber georoster_${mapnum}.gif] if {[catch { exec xplanet -geometry =${mapwidth}x${mapheight} \ -projection rectangular \ -num_times 1 \ -output $file & } result]} { set_status "unable to create new georoster image: $result" } else { after [expr 60*1000] \ [list [namespace current]::refresh_aux $file] } } proc refresh_aux {file} { variable mapimage image delete $mapimage set mapimage [image create photo -file $file] catch { file delete -- $file } [set c .georoster.c] delete map $c create image 0 0 -image $mapimage -anchor nw -tag map $c configure -scrollregion [list 0 0 [image width $mapimage] \ [image height $mapimage]] proc x {lo la} { variable M_INVDEG lindex [sp2px [expr $lo*$M_INVDEG] [expr $la*$M_INVDEG]] 0 } proc y {lo la} { variable M_INVDEG lindex [sp2px [expr $lo*$M_INVDEG] [expr $la*$M_INVDEG]] 1 } proc lo {x y} { variable lon_array variable M_DEG if {[set x [expr int($x)]] < 0} { set x 0 } elseif {![info exists lon_array($x)]} { return 180 } return [expr $lon_array($x)*$M_DEG] } proc la {x y} { variable lat_array variable M_DEG if {[set y [expr int($y)]] < 0} { set y 0 } elseif {![info exists lat_array($x)]} { return -90 } return [expr $lat_array($y)*$M_DEG] } redraw $c after [expr 10*60*1000] [list [namespace current]::refresh] } } # special key bindings (due to KDE) bind . {ifacetk::tab_move .nb -1} bind . {ifacetk::tab_move .nb 1} bind . {ifacetk::current_tab_move .nb -1} bind . {ifacetk::current_tab_move .nb 1} bind . { if {[.nb raise] != ""} { eval destroy [pack slaves [.nb getframe [.nb raise]]] .nb delete [.nb raise] 1 ifacetk::tab_move .nb 0 } } } hook::add postload_hook config_postload 9 proc roster_user_popup_info {info connid user} { set text [set $info] if {([set x [string first "(" $text]] > 0) \ && ([string compare [string index $text end] ")"] == 0) \ && ([string first "\n" [string range $text $x end]] > 0)} { set start [string range $text 0 [expr $x-1]] if {[set y [string last ":" $start]] > 0} { set start [string range $start 0 [expr $y-1]] } set $info $start append $info "\n " append $info [string map [list "\n" "\n "] \ [string range $text [expr $x+1] end-1]] } } hook::add roster_user_popup_info_hook \ [namespace current]::roster_user_popup_info 1 namespace eval jbot { proc open_chat_post {chatid type} { global usetabbar if {[cequal [chat::get_nick [chat::get_connid $chatid] [chat::get_jid $chatid] $type]/$type \ jbot/chat]} { set cw [chat::winid $chatid] pack forget $cw.csw pack $cw.csw -expand yes -fill both -side left destroy $cw.status $cw.input $cw.pw0 if {$usetabbar} { .nb itemconfigure [crange [win_id tab $cw] 1 end] \ -text jbot \ -raisecmd "hook::run raise_chat_tab_hook [list $cw] [list $chatid]" } return stop } } proc draw_message {chatid from type body x} { if {[cequal [chat::get_nick [chat::get_connid $chatid] $from $type]/$type jbot/chat]} { set cw [chat::chat_win $chatid] foreach line [split [string trimright $body] "\n"] { if {[cequal [string index $line 15] " "]} { $cw insert end [string range $line 0 15] me set line [string range $line 16 end] if {([set d [string first " " $line]] > 0) \ && (([string first ": " $line] > $d) || ([string first "last message repeated" \ $line] > $d))} { $cw insert end [string range $line 0 $d] they set line [string range $line [expr $d+1] end] } } if {[set d [string first ": " $line]] > 0} { $cw insert end [string range $line 0 $d] me set line [string range $line [expr $d+1] end] } $cw insert end "$line\n" "" } return stop } } proc normalize_chat_id \ {vconnid vfrom vid vtype vis_subject vsubject vbody verr vthread vpriority vx} { upvar 2 $vconnid connid upvar 2 $vfrom from upvar 2 $vtype type if {![cequal $type chat]} return if {[cequal [chat::get_nick $connid $from $type] jbot]} { set from [node_and_server_from_jid $from]/syslog } } hook::add open_chat_post_hook [namespace current]::open_chat_post 1 hook::add draw_message_hook [namespace current]::draw_message 1 hook::add rewrite_message_hook [namespace current]::normalize_chat_id 1 } hook::add finload_hook georoster::refresh 100 proc config_connload {connid} { return foreach g [list xmpp] { join_group ${g}@ietf.xmpp.org -nick mrose -connection $connid } join_group wgchairs@conference.psg.com -nick mrose -connection $connid } hook::add connected_hook config_connload 1000 if {![catch { package require tclCarbonNotification }]} { proc config_tab_set_updated {path updated level} { switch -- $level { message { switch -glob -- $path { .chat_*_jbot* - .headlines_* { } default { tclCarbonNotification 1 "" } } } mesg_to_user { tclCarbonNotification 1 "" } default { } } } hook::add tab_set_updated config_tab_set_updated 10 } if {(![file exists [set file .jsendrc.tcl]]) \ && (![file exists [set file ~/.jsendrc.tcl]])} { return } source $file namespace eval zerobot { proc examine_message {connid from id type is_subject subject body err thread priority x} { global userstatus switch -- $userstatus { away - xa { if {([string length [set body [checkP $from $type $subject \ $body $x]]] > 0) \ && ([catch { notify $from $body } result])} { debugmsg zerobot "notify: $result" } } default { reset } } } hook::add process_message_hook [namespace current]::examine_message 10 } tkabber-0.11.1/examples/configs/teo-config.tcl0000644000175000017500000001526610523213543020536 0ustar sergeisergei# TeopeTuK config file for Tkabber # Loading X resources option readfile ~/.tkabber/teopetuk.xrdb userDefault #option readfile ~/.tkabber/light.xrdb userDefault # Loading non-raising buttons #source ~/.tkabber/button.tcl # Setting Balloon style option add *Balloon.style delay userDefault # Set message locale explicitly #msgcat::mclocale ru #set font "-monotype-arial unicode-medium-r-*-*-14-*-90-100-*-*-iso10646-1" set font "-monotype-arial-medium-r-*-*-13-*-100-100-*-*-iso10646-1" set usetabbar 1 set autologin 0 set ssj::options(sign-traffic) 0 set ssj::options(encrypt-traffic) 0 set pixmaps_theme gabber #set pixmaps_theme psi # Login settings, common for all profiles set loginconf(usedigest) 1 set loginconf(httpproxy) sun set loginconf(httpproxyport) 3128 set loginconf(priority) 0 # Every 10 minutes send empty message to the server # to avoid proxy disconnect set keep_alive 1 set keep_alive_interval 10 # Login profiles setup set loginconf1(profile) "teopetuk@jabber.ru" set loginconf1(user) teopetuk set loginconf1(password) "" set loginconf1(server) jabber.ru set loginconf1(resource) tkabber set loginconf1(usealtserver) 0 set loginconf1(altserver) "" set loginconf1(useproxy) 1 set loginconf2(profile) "teopetuk@amessage.info" set loginconf2(user) teopetuk set loginconf2(password) "" set loginconf2(server) amessage.info set loginconf2(resource) tkabber set loginconf2(usealtserver) 0 set loginconf2(altserver) "" set loginconf2(useproxy) 1 # Set default profile array set loginconf [array get loginconf2] # Set default conference nicks set defaultnick(talks@conference.jabber.ru) teo set defaultnick(debian@conference.jabber.ru) teo #set defaultnick(talks@conference.jabber.ru) "\u0473\u0463\u0461" #set defaultnick(talks@conference.jupiter.golovan.ru) "\u0473\u0463\u0461" #set defaultnick(talks@conference.jupiter.golovan.ru) "\u03c4\u03b5\u03bf" # Check spelling using ispell module set use_ispell 1 # Set procedure for launching browser proc browseurl {url} { exec galeon -w $url & } #hook::add connected_hook {join_group talks@conference.jupiter.golovan.ru teo} 100 proc postload {} { # Set initial roster options set roster::show_only_online 1 set roster::show_transport_icons 1 set roster::show_transport_user_icons 1 set roster::roster(collapsed,Agents) 1 #set roster::aliases(teopetuk@amessage.info) {258151@aim.jabber.ru} #set roster::aliases(teo@jupiter.golovan.ru) {petr@golovan.ru} #set roster::use_aliases 0 # Set search behaviour set search::show_all 1 # Set sound module options set sound::options(sound) 1 set sound::options(theme) "~/.tkabber/sounds" set sound::options(external_play_program) "esdplay" # Set autoaway module options set plugins::autoaway::options(awaytime) [expr 5*60*1000] set plugins::autoaway::options(xatime) [expr 15*60*1000] # Set ispell module options set plugins::ispell::options(dictionary) engrus set plugins::ispell::options(dictionary_encoding) koi8-r # Define the set of emoticons (empty set) set plugins::emoticons::options(theme) "" } # Debug window handling (mostly taken from MTR config file) #set debug_lvls [list presence ssj warning] set debug_lvls [list jlib plugins] set debug_winP 0 proc menuload {menudesc} { set newmenu [lindex $menudesc end] lappend newmenu [list checkbutton "Debug window" {} {} {} -variable debug_winP -command debug_window_update] lappend newmenu [list cascad Debug {} {} 1 [debug_buttons]] return [lreplace $menudesc end end $newmenu] } proc debug_buttons {} { global debug_levels debug_lvls set buttons {} foreach l [list avatar browser chat completion \ conference filetransfer filters iq \ jlib logger login message \ nick plugins presence register \ roster search ssj tkabber \ userinfo warning] { if {[lsearch -exact $debug_lvls $l] >= 0} { set debug_levels($l) 1 } else { set debug_levels($l) 0 } lappend buttons [list checkbutton $l {} {} {} \ -variable debug_levels($l) -command debug_update] } return $buttons } proc debug_window_update {} { global w debug_winP usetabbar if {!$debug_winP && [winfo exists $w.debug]} { if {$usetabbar} { foreach tab [.nb pages] { if {[lsearch -exact [pack slaves [.nb getframe $tab]] $w.debug] >= 0} { eval destroy [pack slaves [.nb getframe $tab]] .nb delete $tab 1 tab_move .nb 0 } } } else { destroy $w.debug } } } proc debug_update {} { global debug_levels debug_lvls set debug_lvls {} foreach {k v} [array get debug_levels] { if {$v} { lappend debug_lvls $k } } } proc debugmsg {module msg} { global debug_lvls w global debug_fd debug_winP if {![info exists debug_fd]} { catch { file rename -force -- ~/.tkabber/tkabber.log \ ~/.tkabber/tkabber0.log } set debug_fd [open ~/.tkabber/tkabber.log \ { WRONLY CREAT TRUNC APPEND }] fconfigure $debug_fd -buffering line } puts $debug_fd [format "%s %-12.12s %s" \ [clock format [clock seconds] -format "%m/%d %T"] \ $module $msg] if {([lsearch -exact $debug_lvls $module] < 0) || (!$debug_winP)} { return } set dw $w.debug if {![winfo exists $dw]} { add_win $dw -title Debug -tabtitle debug [ScrolledWindow $dw.sw] setwidget \ [text $dw.body -yscrollcommand [list $dw.scroll set]] pack $dw.sw -side bottom -fill both -expand yes $dw.body tag configure module -foreground red3 $dw.body tag configure proc -foreground blue $dw.body tag configure error -foreground red } $dw.body insert end [format "%s: %-12.12s" [clock format [clock seconds] -format "%m/%d %T"] \ $module] module " " set tag normal switch -- $module { jlib { if {[set x [string first "(jlib::" $msg]] > 0} { set tag error } if {[set y [string first ")" $msg]] > 0} { $dw.body insert end \ [string range $msg [expr $x+7] [expr $y-1]] proc \ "\n" set msg [string trimleft \ [string range $msg [expr $y+1] end]] } } default { } } $dw.body insert end [string trimright $msg] $tag $dw.body insert end "\n\n" } tkabber-0.11.1/examples/configs/badlop-config-home.tcl0000644000175000017500000000274610522702230022130 0ustar sergeisergei# Language #::msgcat::mclocale en # Now we will load Badlop's configuration file, if available. # It will set a bunch of options. # It's not a good idea to modify 'badlop-config.tcl' # as it will be updated often to add more and more options. # If you want to change any of them, copy the corresponding line (or lines) from that file, # insert it on the following section ('finload_hook') so your personal options # will always be securely saved on your own config file. if {[file exists $rootdir/examples/configs/badlop-config.tcl]} { source $rootdir/examples/configs/badlop-config.tcl } # Configure here your own options hook::add finload_hook { # Set here your Jabber account information # 1. User: # set ::loginconf(user) ******** # 2. Server: # set ::loginconf(server) ******** # 3. Password: # set ::loginconf(password) ******** # You can modify the resource, for example put 'home', or 'laptop/work' # set ::loginconf(resource) TkabberP # If you have installed all the needed to run SSL, you can activate it # set ::loginconf(usessl) 0 # For example, if you do not want sound, uncomment this line # set sound::options(sound) 0 # set ::BROWSER c:/Mozilla/mozillafirebird.exe # option add *font -monotype-arial-medium-r-*-*-11-*-100-100-*-*-iso10646-1 # set font -monotype-arial-medium-r-*-*-11-*-100-100-*-*-iso10646-1 } tkabber-0.11.1/examples/configs/config.tcl0000644000175000017500000000335710523213543017747 0ustar sergeisergei# $Id: config.tcl 785 2006-11-04 22:42:43Z sergei $ # Sample config file for Tkabber # login settings set loginconf(user) aleksey set loginconf(password) secret set loginconf(resource) tkabber set loginconf(server) jabber.ru # Also instead of above login settings you can setup few different profiles: #set loginconf1(profile) "Local test login" #set loginconf1(user) test #set loginconf1(password) test #set loginconf1(resource) tkabber #set loginconf1(server) localhost #set loginconf2(profile) "aleksey@jabber.ru" #set loginconf2(user) aleksey #set loginconf2(password) secret #set loginconf2(resource) tkabber #set loginconf2(server) jabber.ru # And by default use first profile: #array set loginconf [array get loginconf1] # For different you can set different default nicks: #set defaultnick(cool@conference.jabber.org) mY_cOOl_NIcK # You can choose different set of icons: #set pixmaps_theme gabber #set pixmaps_theme psi # Use this to load X resources #option readfile ~/.tkabber/teopetuk.xrdb userDefault # Popup balloons on roster and browser can work in two styles: "delay" & # "follow". #option add *Balloon.style follow userDefault # Define 'browseurl' to browse urls with your favorite browser. # For konqueror: #proc browseurl {url} { # exec konqueror $url & #} # For galeon: #proc browseurl {url} { # exec galeon -n $url & #} # This function called after loading of tkabber's modules (maybe removed in the # future) proc postload {} { # To setup your avatar uncomment this: #avatar::load_file ~/.tkabber/myface.gif # If you download some emoticons theme, and untar it e.g. in # ~/.tkabber/cool-emoticon-theme, then you can load it as follow: #plugins::emoticons::load_dir ~/.tkabber/cool-emoticon-theme } tkabber-0.11.1/examples/configs/badlop-config.tcl0000644000175000017500000002522110523213543021200 0ustar sergeisergei# Badlop's config file for Tkabber 20031201 # - based on MTR and TeopeTuK config files (available on 'examples/' directory) # - includes references to Tkabber documentation (available on 'doc/' directory) # - contributions: # Marcansoft for Linux options # Report any error or suggestion to badlop@ono.com # Configuration ------------------------------------------------------------------ PRELOAD # 2. Configuration # 2.1 Pre-load # 2.1.1 Tabbed Interface # set usetabbar 1 # 2.1.2 Primary Look-and-Feel set pixmaps_theme gush set load_default_xrdb 0 option readfile $rootdir/examples/xrdb/badlop-dark.xrdb userDefault # option add *font fixed userDefault switch -- [winfo screenwidth .]x[winfo screenheight .] { 1400x1050 - 1280x1024 { option add Tkabber.geometry =788x550-0+0 userDefault } 1024x768 { option add Tkabber.geometry =700x520-30+170 userDefault # sets font of most of labels in widgets, option add *font -monotype-arial-medium-r-*-*-11-*-100-100-*-*-iso10646-1 # sets font of chat and roster text set font -monotype-arial-medium-r-*-*-11-*-100-100-*-*-iso10646-1 } 800x600 { option add Tkabber.geometry =600x420-30+100 userDefault # sets font of most of labels in widgets, option add *font -monotype-arial-medium-r-*-*-9-*-100-100-*-*-iso10646-1 # sets font of chat and roster text set font -monotype-arial-medium-r-*-*-9-*-100-100-*-*-iso10646-1 } default { #option add Tkabber.geometry =630x412-0+0 userDefault } } # 2.1.3 Cryptography by default # set ssj::options(one-passphrase) 1 # set ssj::options(sign-traffic) 1 # set ssj::options(encrypt-traffic) 1 # 2.1.4 Using of external TclXML library # set use_external_tclxml 1 # 2.1.5 Use ispell to check spelling # set use_ispell 1 # 2.1.6 Debugging Output # set debug_lvls {jlib warning} # set debug_lvls [list message presence ssj warning] # set debug_lvls [list zerobot] # set debug_lvls [list jlib plugins] # set debug_winP 0 # 2.1.7 Splash window # set show_splash_window 1 # 2.1.8 Periodically send empty string to server # set keep_alive 0 # set keep_alive_interval 10 # 2.1.9 I18n/L10n # ::msgcat::mclocale es # Other non documented: # Remove the four button bar at the top of the roster # hook::add finload_hook {.mainframe showtoolbar 0 0} # Define here the route to your prefered web browser # if {$tcl_platform(platform) == "unix"} { # # Linux users # proc browseurl {url} { # exec mozilla $url &} # } else { # # Windows users # proc browseurl {url} { # exec "c:/Mozilla/MozillaFirebird.exe" $url & # } # } # global BROWSER # if {$tcl_platform(platform) == "unix"} { # # Linux users # set ::BROWSER mozilla # } else { # # Windows users # set ::BROWSER explorer # } # proc browseurl {url} { # exec $::BROWSER $url & # } # show SSL warnings # set ::tls_warnings 0 # Join groupchats automatically at the start (other available option: -nick ) #proc connload {connid} { # join_group jabber@conference.jabber.org -connection $connid } #hook::add connected_hook connload 1000 # 2.2 Post-load ------------------------------------------------------------------ POSTLOAD proc postload {} { # 2.2.1 Look-and-Feel # set raise_new_tab 0 # 2.2.2 The Autoaway Module # set plugins::autoaway::options(awaytime) [expr 2*60*1000] # set plugins::autoaway::options(xatime) [expr 15*60*1000] # set plugins::autoaway::options(status) "Idle" # set plugins::autoaway::options(drop_priority) 0 # 2.2.3 The Avatar Module # if {[file exists ~/.tkabber/avatar.gif]} { # avatar::load_file ~/.tkabber/avatar.gif # } else { # avatar::load_file $::rootdir/pixmaps/default/tkabber/mainlogo.gif # } # set avatar::options(announce) 1 # set avatar::options(share) 1 # 2.2.4 The Chat Module (chat, normal) # set chat::options(default_message_type) chat # set chat::options(stop_scroll) 0 # set chat::options(smart_scroll) 1 # set chat::options(display_status_description) 1 # Examples: # [%R] -- [20:37] # [%T] -- [20:37:12] # [%a %b %d %H:%M:%S %Z %Y] -- [Thu Jan 01 03:00:00 MSK 1970] # set plugins::options(timestamp_format) {[%R]} # 2.2.5 The Clientinfo Module # set plugins::clientinfo::options(autoask) 1 # 2.2.6 The Conferenceinfo Module # set plugins::conferenceinfo::options(autoask) 1 # set plugins::conferenceinfo::options(interval) 300 # set plugins::conferenceinfo::options(err_interval) 3600 # 2.2.7 The Cryptographic Module # set ssj::options(encrypt,fred@example.com) 1 # 2.2.8 The Emoticons Module # plugins::emoticons::load_dir $::rootdir/emoticons/rhymbox-1.0 # 2.2.9 The File Transfer Module # if {$::tcl_platform(platform) == "unix"} { # Linux users # set ft::options(download_dir) "~" # } else { # Windows users # set ft::options(download_dir) "c:/" # } # 2.2.10 The Groupchat Module # global gra_group gra_server # global gr_nick gr_group gr_server gr_v2 # global defaultnick # set defaultnick(talks@conference.jabber.org) teo # 2.2.11 The Ispell Module # set plugins::ispell::options(executable) ispell/bin/ispell.exe # set plugins::ispell::options(executable) /usr/bin/ispell # set plugins::ispell::options(dictionary) spanish # set plugins::ispell::options(check_every_symbol) 0 # set plugins::ispell::options(dictionary_encoding) koi8-r # 2.2.12 The Jidlink Module # set jidlink::transport(allowed,dtcp-passive) 0 # 2.2.13 The Logger Module # set logger::options(logdir) ~/.tkabber/logs # set logger::options(log_chat) 1 # set logger::options(log_groupchat) 1 # 2.2.14 The Login Module global loginconf autologin loginconf1 loginconf2 # Jabber account: set loginconf1(profile) Default # set loginconf1(user) ++++++++ # set loginconf1(password) ++++++++ # set loginconf1(server) ++++++++ # Other Jabber account: set loginconf2(profile) Secondary # set loginconf2(user) -------- # set loginconf2(password) -------- # set loginconf2(server) -------- # set loginconf(usedigest) 1 # set loginconf(resource) TkabberP # set loginconf(port) 5222 # set loginconf(priority) 3 # set loginconf(usessl) 0 # set loginconf(sslport) 5223 # set loginconf(useproxy) 0 # set loginconf(httpproxy) localhost # set loginconf(httpproxyport) 3128 # set loginconf(replace_opened) 0 # array set loginconf [array get loginconf1] set autologin 0 # 2.2.15 The Message Module # set message::options(headlines,cache) 1 # set message::options(headlines,multiple) 1 # 2.2.16 The Raw XML Input Module # set plugins::rawxml::options(pretty_print) 1 # set plugins::rawxml::options(indent) 2 # 2.2.17 The Roster Module # set roster::show_only_online 1 # set roster::show_transport_icons 1 # set roster::show_transport_user_icons 1 # set roster::roster(collapsed,Transports) 1 # set roster::roster(collapsed,Conferences) 1 # set roster::roster(collapsed,Undefined) 1 # set roster::options(show_subscription) 1 # set roster::options(show_conference_user_info) 1 # set roster::use_aliases 0 # set roster::aliases(perico@servidor.org) \ # {perico@servidor2.com} # 2.2.18 The Sound Module # set sound::options(sound) 1 # set sound::options(mute) 0 # set sound::options(mute_groupchat_delayed) 1 # set sound::options(mute_chat_delayed) 1 # set sound::options(delay) 200 set sound::options(theme) "psi" # if {$::tcl_platform(platform) == "unix"} { # Linux users # If no sound is available, use one of the following: #set sound::options(external_play_program) /usr/bin/play #set sound::options(external_play_program) artsplay # } else { # Windows users # set sound::options(external_play_program) plwav.exe # } # Others non documented: # .. The XHTML Module # set plugins::xhtml::options(enable) 1 # plugins::emoticons::load_dir ~/.tkabber/cool-emoticon-theme # Set theme for chess plugin # set plugins::chess::theme 1 # special key bindings (due to KDE) bind . {ifacetk::tab_move .nb -1} bind . {ifacetk::tab_move .nb 1} bind . {ifacetk::current_tab_move .nb -1} bind . {ifacetk::current_tab_move .nb 1} bind . { if {[.nb raise] != ""} { eval destroy [pack slaves [.nb getframe [.nb raise]]] .nb delete [.nb raise] 1 ifacetk::tab_move .nb 0 } } # Change presence indicator #bind . {set userstatus chat} bind . {set userstatus available} #bind . {set userstatus away} bind . {set userstatus xa} bind . {set userstatus dnd} #bind . {set userstatus invisible} # Set search behaviour # set search::show_all 1 # Georoster plugin # MTR's config file for tkabber # If you want to use Georoster, uncomment the lines that start with a '#'. # The lines that start with ' #' are not necessary. # source ~/.tkabber/tkabber-plugins/georoster/georoster.tcl # automatically open GeoRoster window # set georoster::options(automatic) 0 # show cities on map (none, markers, or all) # set georoster::options(showcities) all # file defining city names & locations, localized for XX #set georoster::options(citiesfile) ~/.tkabber/tkabber-plugins/georoster/earth.XX # file defining ISO 3166 country codes #set georoster::options(3166file) iso3166 # default country to use, if unspecified in vCard #set georoster::options(default_country) us # file defining region/locality names & locations, for country XX #set georoster::options(coords,XX) ~/.tkabber/tkabber-plugins/georoster/XX.coords # file containing gif to use as background for map # set georoster::options(mapfile) ~/.tkabber/tkabber-plugins/georoster/colormap.jpg # procedures to map from x/y to lo/la, and back again #proc georoster::lo {x y} #proc georoster::la {x y} #proc georoster::x {lo la} #proc georoster::y {lo la} # hook to locate a given jid: #proc XX {jid update} { # if {$success} { # eval $update [list $la $lo] # return stop # } #} #hook::add georoster:locate_hook [namespace current]::XX } tkabber-0.11.1/examples/tools/0000755000175000017500000000000011076120366015502 5ustar sergeisergeitkabber-0.11.1/examples/tools/rssbot0000644000175000017500000000047607633107273016756 0ustar sergeisergei#!/bin/sh # # PROVIDE: rssbot # REQUIRE: DAEMON . /etc/rc.subr name="rssbot" rcvar=$name command="/usr/pkg/libexec/rssbot.tcl" command_interpreter=tclsh pidfile="/var/run/${name}.pid" command_args="-from ${name}/`hostname -s` -pidfile $pidfile -logfile /tmp/${name}.log &" load_rc_config $name run_rc_command "$1" tkabber-0.11.1/examples/tools/tkabber_setstatus0000755000175000017500000000062310503024614021153 0ustar sergeisergei#!/usr/bin/wish set tkabbers {} foreach w [winfo interps] { if {[string equal -length 7 $w "tkabber"]} { lappend tkabbers $w } } if {$argc == 0} { set argv {{}} } if {$argc > 1} { set argv [list $argv] } if {[lsearch -exact $argv "XMMS playing: %s"] >= 0} { set argv {{}} } foreach i $tkabbers { catch { send -async $i "set textstatus $argv set userstatus \$userstatus" } } exit tkabber-0.11.1/examples/tools/howto.txt0000644000175000017500000000616107633107273017415 0ustar sergeisergei[ howto.txt - Thu Mar 6 10:02:15 2003 - a few explanations - /mtr ] 0. make sure that you have copied the jabberlib-tclxml/ to the library area for your tcl installation, typical names might be: /usr/local/lib/tcl/jabberlib-tclxml/ /usr/pkg/lib/tcl/jabberlib-tclxml/ 1. all of these scripts look for a file called ".jsendrc.tcl" in the current directory, and then in the home directory. if present, this file can be used to define a tcl list called "args" that contains default key/value pairs. e.g., % cat > ~/.jsendrc.tcl set args {-from fred@example.com/bedrock -password wilma} ^D % chmod 0600 ~/.jsendrc.tcl 2. the jsend.tcl script is used from the shell to send jabber messages. it operates in two modes: one-shot and following. here's an example of the one-shot mode: % jsend.tcl barney@example.com -body "hello world." in contrast, following mode is similar to the "tail" command: % jsend.tcl barney@example.com -follow /var/log/syslog & 3. the jsend.tcl script has a lot of options, type % jsend.tcl -help to see them all. the command syntax is: % jsend.tcl "recipient" -k1 v1 -k2 v2 ... for example, by default, the jsend.tcl script will want to use tls to talk to its jabber server, if you want to use plaintext instead, use % jsend.tcl barney@example.com -tls false if you use "-" for the recipient, then the jsend.tcl script will send to every subscriber on the roster of the user that it's logged in as, e.g., % jsend.tcl - -from fred@example.com -body "hello world." will send "hello world." to everyone on fred's roster. 4. you may want to run the jsend.tcl script at system startup. the jbot script can be put in /etc/rc.d/ on netbsd systems. you'll need to: - edit it to reflect where you've installed the jsend.tcl script; and, - decide whether to put the jabber login information in the rc script or in the command line arguments you can use the jbot script as the basis for writing your own startup script on bsd-derived systems. 5. the rssbot.tcl script runs as an rss/jabber gateway. the gateway accepts commands from the subscribers on the roster of the user that it's logged in as. the commands allow each subscriber to manage which RSS/RDF files are monitored, and so on. 6. to find out about the options available in the rssbot.tcl script, type % rssbot.tcl -help the command syntax for the rssbot.tcl script is: % rssbot.tcl -k1 v1 -k2 2 7. you probably want to run the rssbot.tcl script at system startup. the rssbot script can be put in /etc/rc.d/ on netbsd systems. 8. neither the jsend.tcl nor rssbot.tcl scripts manage their roster. you'll need to login to a jabber server and configure their roster accordingly. why? because the roster acts as an access control mechanism for each script. if you want random folks to arbitrarily access these services, modify the scripts to taste. ####### tkabber-0.11.1/examples/tools/rssbot.tcl0000644000175000017500000010145711015465607017535 0ustar sergeisergei#!/bin/sh # the following restarts using tclsh \ PATH=/usr/bin:/bin:/usr/pkg/bin:/usr/local/bin:/sbin:/usr/sbin \ LD_LIBRARY_PATH=/usr/pkg/lib:/usr/lib:/usr/local/lib \ export PATH LD_LIBRARY_PATH; exec tclsh "$0" "$@" package require jabberlib -exact 0.10.1 package require http 2 package require mime package require tls package require uri proc jlib::sendit {stayP to args} { global env variable lib variable roster variable sendit_result array set options [list -to $to \ -from "" \ -password "" \ -host "" \ -port "" \ -activity "" \ -type headline \ -subject "" \ -body "" \ -description "" \ -url "" \ -tls true] array set options $args if {![string compare $options(-host) ""]} { set options(-host) [info hostname] } set params [list from] foreach k $params { if {[string first @ $options(-$k)] < 0} { if {[set x [string first / $options(-$k)]] >= 0} { set options(-$k) [string replace $options(-$k) $x $x \ @$options(-host)/] } else { append options(-$k) @$options(-host) } } if {([string first @ $options(-$k)] == 0) \ && ([info exists env(USER)])} { set options(-$k) $env(USER)$options(-$k) } } foreach k [list tls] { switch -- [string tolower $options(-$k)] { 1 - 0 {} false - no - off { set options(-$k) 0 } true - yes - on { set options(-$k) 1 } default { error "invalid value for -$k: $options(-$k)" } } } array set aprops [lindex [mime::parseaddress $options(-from)] 0] if {[set x [string first / $aprops(domain)]] >= 0} { set aprops(resource) [string range $aprops(domain) [expr $x+1] end] set aprops(domain) [string range $aprops(domain) 0 [expr $x-1]] } else { set aprops(resource) "rssbot" } set options(-xlist) {} if {[string compare $options(-url)$options(-description) ""]} { lappend options(-xlist) \ [jlib::wrapper:createtag x \ -vars [list xmlns jabber:x:oob] \ -subtags [list [jlib::wrapper:createtag url \ -chdata $options(-url)] \ [jlib::wrapper:createtag desc \ -chdata $options(-description)]]] } set lib(lastwhat) $options(-activity) if {[catch { clock scan $options(-time) } lib(lastwhen)]} { set lib(lastwhen) [clock seconds] } set params {} foreach k [list body subject type xlist] { if {[string compare $options(-$k) ""]} { lappend params -$k $options(-$k) } } if {[llength [jlib::connections] <= 0} { set connid [jlib::new -user $aprops(local) \ -server $aprops(domain) \ -resource $aprops(resource)] if {$options(-tls)} { set transport tls if {[string compare $options(-port) ""]} { set port $options(-port) } else { set port 5223 } } else { set transport tcp if {[string compare $options(-port) ""]} { set port $options(-port) } else { set port 5222 } } jlib::connect $connid \ -transport $transport \ -host [idna::domain_toascii $aprops(domain)] \ -port $port \ -password $options(-password) jlib::login $connid [namespace current]::sendit_aux vwait [namespace current]::sendit_result if {[string compare [lindex $sendit_result 0] OK]} { error [lindex [stanzaerror::error_to_list [lindex $sendit_result 1]] } roster_get -command [namespace current]::roster_get_aux vwait [namespace current]::sendit_result } else { set connid [lindex [jlib::connections] 0] } if {$stayP > 1} { jlib::send_presence -stat Online \ -connection $connid return 1 } foreach to $options(-to) { switch -- [eval [list jlib::send_msg $to -connection $connid] $params] { -1 - -2 { if {$stayP} { set cmd [list ::LOG] } else { set cmd [list error] } eval $cmd [list "error writing to socket, continuing..."] return 0 } default { } } } if {!$stayP} { jlib::disconnect $connid } return 1 } proc jlib::sendit_aux {result args} { variable sendit_result set sendit_result [list $result $args] } proc jlib::roster_get_aux {what} { variable sendit_result set sendit_result $what } proc client:message {connid from id type is_subject subject body err thread priority x} { ::LOG "client:message $from $body" if {![regexp {(.*@.*)/.*} $from x jid]} { set jid $from } switch -- $type { normal - chat { } "" { set type chat } default { ::LOG "$from ignoring $type" return } } if {[catch { rssbot::message $jid $body } answer]} { ::LOG "$jid/$body: $answer" set answer "internal error, sorry! ($answer)" } if {[catch { jlib::sendit 1 "" \ -to $from \ -activity "$jid: $body" \ -type $type \ -subject $subject \ -body $answer } result]} { ::LOG "$from: $result" } } proc client:presence {connid from type x args} { ::LOG "client:presence $args" if {![regexp {(.*@.*)/.*} $from x jid]} { set jid $from } switch -- $type { available - unavailable { } "" { set type available } default { ::LOG "$from ignoring $type" return } } rssbot::presence $jid $type } proc client:iqreply {connid from userid id type lang child} { jlib::wrapper:splitxml $child tag vars isempty chdata children set xmlns [jlib::wrapper:getattr $vars xmlns] ::LOG "client:iqreply $from $userid $id $type $lang $xmlns" set result result set now [clock seconds] switch -- $type/$xmlns { get/jabber:iq:browse { foreach ns [list browse last time version] { lappend tags [jlib::wrapper:createtag ns -chdata $ns] } set xmldata [jlib::wrapper:createtag user \ -vars [list xmlns $xmlns type client] \ -subtags $tags] } get/jabber:iq:last { set xmldata [jlib::wrapper:createtag query \ -vars [list xmlns $xmlns \ seconds \ [expr $now-$jlib::lib(lastwhen)]] \ -chdata $jlib::lib(lastwhat)] } get/jabber:iq:time { set gmtP true foreach {k f} [list utc "%Y%m%dT%T" \ tz "%Z" \ display "%a %b %d %H:%M:%S %Z %Y"] { lappend tags [jlib::wrapper:createtag $k \ -chdata [clock format $now \ -format $f \ -gmt $gmtP]] set gmtP false } set xmldata [jlib::wrapper:createtag query \ -vars [list xmlns $xmlns] \ -subtags $tags] } get/jabber:iq:version { global argv0 tcl_platform foreach {k v} [list name [file tail [file rootname $argv0]] \ version "1.0 (Tcl [info patchlevel])" \ os "$tcl_platform(os) $tcl_platform(osVersion)"] { lappend tags [jlib::wrapper:createtag $k -chdata $v] set gmtP false } set xmldata [jlib::wrapper:createtag query \ -vars [list xmlns $xmlns] \ -subtags $tags] } default { set result error set xmldata [jlib::wrapper:createtag error \ -vars [list code 501] \ -chdata "not implemented"] } } jlib::send_iq $result $xmldata -to $from -id $id -connection $connid } proc client:roster_push {args} {} proc client:roster_item {args} {} proc client:reconnect {connid} { rssbot::reconnect } proc client:disconnect {connid} { rssbot::reconnect } namespace eval rssbot {} # state variables # mtime - modified time # ntime - expiration time # # # articles(source,url) [list mtime ... ntime ... args { ... } source "..."] # sources(site) [list mtime ... ntime ...] # subscribers(jid) [list mtime ... sites { ... } status "..."] # proc rssbot::begin {argv} { global doneP variable iqP variable loopID variable parser variable articles variable sources variable subscribers proc [namespace current]::reconnect {} \ [list [namespace current]::reconnect_aux $argv] if {[catch { set loopID "" [set parser [xml::parser]] configure \ -elementstartcommand [list [namespace current]::element \ begin] \ -elementendcommand [list [namespace current]::element \ end] \ -characterdatacommand [list [namespace current]::pcdata] \ -errorcommand [list [namespace current]::error] array set articles {} array set sources {} array set subscribers {} eval [list jlib::sendit 2 ""] $argv set iqP 0 foreach array [list articles sources subscribers] { incr iqP jlib::send_iq get \ [jlib::wrapper:createtag query \ -vars [list xmlns jabber:iq:private] \ -subtags [list [jlib::wrapper:createtag $array \ -vars [list xmlns rssbot.$array]]]] \ -connection [jlib::route ""] \ -command [list [namespace current]::iq_private 0] } while {$iqP > 0} { vwait [namespace current]::iqP } loop $argv } result]} { set doneP 1 bgerror $result } } proc rssbot::loop {argv} { variable loopID set loopID "" if {[catch { loop_aux $argv } result]} { bgerror $result } set loopID [after [expr 5*60*1000] [list [namespace current]::loop $argv]] } proc rssbot::loop_aux {argv} { variable articles variable sources variable subscribers array set updateP [list articles 0 sources 0 subscribers 0] set sites {} foreach jid [array names subscribers] { array set props $subscribers($jid) if {![string compare $props(status) available]} { foreach site $props(sites) { if {[lsearch -exact $sites $site] < 0} { lappend sites $site } } } } set now [clock seconds] foreach site $sites { catch { array unset sprops } array set sprops [list ntime 0] catch { array set sprops $sources($site) } if {$sprops(ntime) > $now} { continue } if {[catch { ::http::geturl $site } httpT]} { ::LOG "$site: $httpT" continue } switch -exact -- [set status [::http::status $httpT]] { ok { if {![string match 2* [set ncode [::http::ncode $httpT]]]} { ::LOG "$site: returns code $ncode" } else { catch { unset state } upvar #0 $httpT state catch { unset array meta } array set meta $state(meta) if {![info exists meta(Last-Modified)]} { set mtime $now } elseif {[catch { clock scan $meta(Last-Modified) } t]} { ::LOG "$site: invalid Last-Modified meta-data $meta(Last-Modified)" set mtime $now } else { set mtime $t } foreach {k v} [process $site $mtime [expr $now+(5*60)] \ $now [::http::data $httpT]] { if {$v} { set updateP($k) 1 } } } } timeout - default { ::LOG "$site: $status" } } ::http::cleanup $httpT } foreach jid [array names subscribers] { catch { array unset props } array set props $subscribers($jid) if {[catch { set props(mtime) } mtime]} { set mtime 0 } set xtime 0 foreach site $props(sites) { foreach article [array names articles] { catch { array unset aprops } array set aprops $articles($article) if {$aprops(ntime) <= $now} { unset articles($article) set updateP(articles) 1 continue } if {[string first "$site," $article]} { continue } if {$aprops(mtime) <= $mtime} { continue } if {[catch { eval [list jlib::sendit 1 $jid] $argv \ $aprops(args) } result]} { ::LOG "$jid: $result" } else { if {$xtime < $aprops(mtime)} { set xtime $aprops(mtime) } set jlib::lib(lastwhat) $aprops(source) set jlib::lib(lastwhen) $aprops(mtime) } } } if {$xtime > $mtime} { set updateP(subscribers) 1 set props(mtime) $xtime set subscribers($jid) [array get props] } } foreach array [list articles sources subscribers] { if {$updateP($array)} { jlib::send_iq set \ [jlib::wrapper:createtag query \ -vars [list xmlns jabber:iq:private] \ -subtags [list [jlib::wrapper:createtag $array \ -vars [list xmlns rssbot.$array] \ -chdata [array get $array]]]] \ -connection [jlib::route ""] \ -command [list [namespace current]::iq_private 1] } } } proc rssbot::process {site mtime ntime now data} { variable info variable parser variable stack variable sources array set info [list site $site ctime $mtime now $now articleP 0] set stack {} if {[catch { $parser parse $data } result]} { ::LOG "$site: $result" } else { set sources($site) [list mtime $mtime ntime $ntime] } return [list articles $info(articleP) sources $info(articleP)] } proc rssbot::element {tag name {av {}} args} { variable info variable stack variable articles switch -- $tag { begin { set parent [lindex [lindex $stack end] 0] lappend stack [list $name $av] switch -- $parent/$name { channel/title { array set info [list subject ""] } channel/item - rdf:RDF/item - RDF/item { array set info [list description "" \ body "" \ url "" \ date ""] } } } end { set stack [lreplace $stack end end] set parent [lindex [lindex $stack end] 0] switch -- $parent/$name { channel/item - rdf:RDF/item - RDF/item { } default { return } } if {[string compare $info(date) ""]} { if {![string compare [string range $info(date) 22 22] ":"]} { set info(date) [string replace $info(date) 22 22] } if {[catch { clock scan $info(date) } info(mtime)]} { ::LOG "$info(site): invalid dc:date $info(date)" set info(mtime) $info(ctime) } } else { set info(mtime) $info(ctime) } if {![string compare [set url $info(url)] ""]} { ::LOG "$info(site): missing URL in item" return } set ntime [expr $info(mtime)+(2*24*60*60)] if {$ntime <= $info(now)} { return } set site $info(site) if {[info exists articles($site,$url)]} { return } if {![string compare $info(body) ""]} { set info(body) [string trim "$info(description)\n$info(url)"] } set args {} foreach k [list subject body description url] { lappend args -$k [string trim $info($k)] } set articles($site,$url) \ [list mtime $info(mtime) \ ntime $ntime \ source [string trim $info(subject)] \ args $args] set info(articleP) 1 } } } proc rssbot::pcdata {text} { variable info variable stack if {![string compare [string trim $text] ""]} { return } set name [lindex [lindex $stack end] 0] set parent [lindex [lindex $stack end-1] 0] switch -- $parent/$name { channel/title { append info(subject) $text } item/title { append info(description) $text } item/link { append info(url) $text } item/description { append info(body) $text } item/dc:date - item/date { append info(date) $text } } } proc rssbot::error {args} { return -code error [join $args " "] } proc rssbot::message {jid request} { variable loopID variable articles variable sources variable subscribers if {[catch { split [string trim $request] } args]} { return $args } set answer "" set updateP 0 set arrayL [list subscribers] set fmt "%a %b %d %H:%M:%S %Z %Y" switch -glob -- [set arg0 [string tolower [lindex $args 0]]] { he* { set answer {commands are: subscribe URL unsubscribe [URL ...] reset [DATE-TIME] list dump [URL ...] flush help} } sub* { if {[llength $args] <= 1} { return "usage: subscribe URL ..." } array set props [list mtime 0 sites {} status available] if {([catch { array set props $subscribers($jid) }]) \ && ([lsearch -exact $jlib::roster(users) $jid] < 0)} { return "not authorized" } set s "" foreach arg [lrange $args 1 end] { if {![string compare $arg ""]} { append answer $s "invalid source: empty URL" } elseif {[lsearch -exact $props(sites) $arg] >= 0} { append answer $s "already subscribed to $arg" } elseif {[catch { uri::split $arg } result]} { append answer $s "invalid source: $arg ($result)" } else { lappend props(sites) $arg set updateP 1 append answer $s "added subscription to $arg" } set s "\n" } } unsub* { if {![info exists subscribers($jid)]} { return "no subscriptions" } array set props $subscribers($jid) if {[llength $args] <= 1} { set props(sites) {} set updateP 1 set s "" foreach site $props(sites) { append answer $s "cancelled subscription to $site" set s "\n" } } else { set s "" foreach arg [lrange $args 1 end] { if {[set x [lsearch -exact $props(sites) $arg]] < 0} { append answer $s "not subscribed to $arg" } else { set props(sites) [lreplace $props(sites) $x $x] set updateP 1 append answer $s "cancelled subscription to $arg" } set s "\n" } } } reset { if {![info exists subscribers($jid)]} { return "no subscriptions" } array set props $subscribers($jid) append answer "subscription history reset" if {[llength $args] <= 1} { set props(mtime) 0 } elseif {[catch { clock scan [concat [lrange $args 1 end]] \ -base [clock seconds] } m]} { return "invalid date-time: [concat [lrange $args 1 end]] ($m)" } else { set props(mtime) $m append answer " to [clock format $m -format $fmt]" } set updateP 1 } list { if {![info exists subscribers($jid)]} { return "no subscriptions" } array set props $subscribers($jid) set s "" foreach site $props(sites) { append answer $s $site set s "\n" } } dump { if {![info exists subscribers($jid)]} { return [jlib::wrapper:createtag subscriber \ -vars [list jid $jid]] } array set props $subscribers($jid) set tags {} if {[info exists props(mtime)]} { set chdata [clock format $props(mtime) -format $fmt] } else { set chdata never } lappend tags [jlib::wrapper:createtag updated -chdata $chdata] foreach site $props(sites) { if {([llength $args] > 1) && ([lsearch -exact [lrange $args 1 end] $site] \ < 0)} { continue } catch { unset array sprops } array set sprops $sources($site) set stags {} lappend stags [jlib::wrapper:createtag url -chdata $site] lappend stags [jlib::wrapper:createtag modified \ -chdata [clock format $sprops(mtime) \ -format $fmt]] lappend stags [jlib::wrapper:createtag expires \ -chdata [clock format $sprops(ntime) \ -format $fmt]] set atags {} foreach article [array names articles] { if {[string first "$site," $article]} { continue } set url [string range $article [string length $site,] end] catch { array unset aprops } array set aprops $articles($article) set atag {} lappend atag [jlib::wrapper:createtag url -chdata $url] lappend atag [jlib::wrapper:createtag modified \ -chdata [clock format $aprops(mtime) \ -format $fmt]] lappend atag [jlib::wrapper:createtag expires \ -chdata [clock format $aprops(ntime) \ -format $fmt]] lappend atag [jlib::wrapper:createtag args \ -chdata $aprops(args)] lappend atags [jlib::wrapper:createtag article \ -subtags $atag] } lappend stags [jlib::wrapper:createtag articles \ -subtags $atags] lappend tags [jlib::wrapper:createtag site \ -subtags $stags] } set answer [jlib::wrapper:createxml \ [jlib::wrapper:createtag subscriber \ -vars [list jid $jid] \ -subtags [list [jlib::wrapper:createtag \ sites -subtags $tags]]]] } flush { if {![info exists subscribers($jid)]} { return "no subscriptions" } array set props $subscribers($jid) foreach array [set arrayL [list articles sources]] { lappend arrayL $array array unset $array array set $array {} } set updateP 1 append answer "cache flushed" } default { append answer "unknown request: $arg0\n" append answer "try \"help\" instead" } } if {$updateP} { set subscribers($jid) [array get props] foreach array $arrayL { jlib::send_iq set \ [jlib::wrapper:createtag query \ -vars [list xmlns jabber:iq:private] \ -subtags [list [jlib::wrapper:createtag $array \ -vars [list xmlns rssbot.$array] \ -chdata [array get $array]]]] \ -connection [jlib::route ""] \ -command [list [namespace current]::iq_private 1] } if {[string compare $loopID ""]} { set script [lindex [after info $loopID] 0] after cancel $loopID set loopID [after idle $script] } } return $answer } proc rssbot::presence {jid status} { variable loopID variable articles variable sources variable subscribers if {![info exists subscribers($jid)]} { ::LOG "$jid not subscribed?!?" return } array set props $subscribers($jid) if {[string compare $props(status) $status]} { set props(status) $status set subscribers($jid) [array get props] jlib::send_iq set \ [jlib::wrapper:createtag query \ -vars [list xmlns jabber:iq:private] \ -subtags [list [jlib::wrapper:createtag subscribers \ -vars [list xmlns rssbot.subscribers] \ -chdata [array get subscribers]]]] \ -connection [jlib::route ""] \ -command [list [namespace current]::iq_private 1] if {(![string compare $status available]) \ && ([string compare $loopID ""])} { set script [lindex [after info $loopID] 0] after cancel $loopID set loopID [after idle $script] } } } proc rssbot::reconnect_aux {argv} { while {1} { after [expr 60*1000] if {![catch { eval [list jlib::sendit 2 ""] $argv } result]} { break } ::LOG $result } } proc rssbot::iq_private {setP status child} { global doneP variable iqP variable articles variable sources variable subscribers if {[set code [catch { if {[string compare $status OK]} { error "iq_private: [lindex $child 0]" } if {$setP} { return } jlib::wrapper:splitxml $child tag vars isempty chdata children set xmlns [jlib::wrapper:getattr $vars xmlns] jlib::wrapper:splitxml [lindex $children 0] tag vars isempty chdata \ children set xmlns [jlib::wrapper:getattr $vars xmlns] if {[catch { llength $chdata }]} { error "iq_private: bad data: $chdata" } if {$isempty} { set chdata {} } switch -- $xmlns { rssbot.articles - rssbot.sources - rssbot.subscribers { array set [string range $xmlns 7 end] $chdata } default { error "iq_private: unexpected namespace: $xmlns" } } incr iqP -1 } result]]} { if {$code == 2} { return } set doneP 1 set iqP 0 bgerror $result } } set debugP 0 set logFile "" proc ::LOG {message} { global debugP logFile if {$debugP > 0} { puts stderr $message } if {([string first "DEBUG " $message] == 0) \ || (![string compare $logFile ""]) \ || ([catch { set fd [open $logFile { WRONLY CREAT APPEND }] }])} { return } regsub -all "\n" $message " " message set now [clock seconds] if {[set x [string first . [set host [info hostname]]]] > 0} { set host [string range $host 0 [expr $x-1]] } catch { puts -nonewline $fd \ [format "%s %2d %s %s personal\[%d\]: %s\n" \ [clock format $now -format %b] \ [string trimleft [clock format $now -format %d] 0] \ [clock format $now -format %T] $host \ [expr [pid]%65535] $message] } catch { close $fd } } proc ::bgerror {err} { global errorInfo ::LOG "$err\n$errorInfo" } set status 1 array set jlib::lib [list lastwhen [clock seconds] lastwhat ""] if {(([set x [lsearch -exact $argv -help]] >= 0) \ || ([set x [lsearch -exact $argv --help]] >= 0)) \ && (![expr $x%2])} { puts stdout "usage: rssbot.tcl ?options...? -pidfile file -from jid -password string -tls boolean (e.g., 'true') The file .jsendrc.tcl is consulted, e.g., set args {-from fred@example.com/bedrock -password wilma} for default values." set status 0 } elseif {[expr $argc%2]} { puts stderr "usage: rssbot.tcl ?-key value?..." } elseif {[catch { if {([file exists [set file .jsendrc.tcl]]) \ || ([file exists [set file ~/.jsendrc.tcl]])} { set args {} source $file array set at [list -permissions 600] array set at [file attributes $file] if {([set x [lsearch -exact $args "-password"]] > 0) \ && (![expr $x%2]) \ && (![string match *00 $at(-permissions)])} { error "file should be mode 0600" } if {[llength $args] > 0} { set argv [eval [list linsert $argv 0] $args] } } } result]} { puts stderr "error in $file: $result" } else { if {([set x [lsearch -exact $argv -debug]] >= 0) && (![expr $x%2])} { switch -- [string tolower [lindex $argv [expr $x+1]]] { 1 - true - yes - on { set debugP 1 } } } if {([set x [lsearch -exact $argv -logfile]] >= 0) && (![expr $x%2])} { set logFile [lindex $argv [expr $x+1]] } set keep_alive 1 set keep_alive_interval 5 if {([set x [lsearch -exact $argv "-pidfile"]] >= 0) && (![expr $x%2])} { set fd [open [set pf [lindex $argv [expr $x+1]]] \ { WRONLY CREAT TRUNC }] puts $fd [pid] close $fd } after idle [list rssbot::begin $argv] set doneP 0 vwait doneP catch { file delete -- $pf } set status 0 } exit $status tkabber-0.11.1/examples/tools/jbot0000644000175000017500000000055307633107273016374 0ustar sergeisergei#!/bin/sh # # PROVIDE: jbot # REQUIRE: syslogd . /etc/rc.subr name="jbot" rcvar=$name command="/usr/pkg/bin/jsend.tcl" command_interpreter=tclsh pidfile="/var/run/${name}.pid" command_args="-pidfile $pidfile &" # the first argument is the destination (or, if "-", use the roster) jbot_flags="- -follow /var/log/jbot" load_rc_config $name run_rc_command "$1" tkabber-0.11.1/examples/tools/jsend.tcl0000644000175000017500000003741711015465607017330 0ustar sergeisergei#!/bin/sh # the next line restarts using the correct interpreter \ exec tclsh "$0" "$0" "$@" package require -exact jabberlib 0.10.1 package require mime package require sha1 package require tls proc jlib::sendit {stayP to args} { global env variable lib variable roster variable sendit_result array set options [list -to $to \ -from "" \ -password "" \ -host "" \ -port "" \ -activity "" \ -type chat \ -subject "" \ -body "" \ -xhtml "" \ -description "" \ -url "" \ -tls true] array set options $args if {![string compare $options(-host) ""]} { set options(-host) [info hostname] } set params [list from] if {[string compare $options(-to) "-"]} { lappend params to } foreach k $params { if {[string first @ $options(-$k)] < 0} { if {[set x [string first / $options(-$k)]] >= 0} { set options(-$k) [string replace $options(-$k) $x $x \ @$options(-host)/] } else { append options(-$k) @$options(-host) } } if {([string first @ $options(-$k)] == 0) \ && ([info exists env(USER)])} { set options(-$k) $env(USER)$options(-$k) } } if {[string compare $options(-to) "-"]} { set options(-to) [list $options(-to)] } foreach k [list tls] { switch -- [string tolower $options(-$k)] { 1 - 0 {} false - no - off { set options(-$k) 0 } true - yes - on { set options(-$k) 1 } default { error "invalid value for -$k: $options(-$k)" } } } array set aprops [lindex [mime::parseaddress $options(-from)] 0] if {[set x [string first / $aprops(domain)]] >= 0} { set aprops(resource) [string range $aprops(domain) [expr $x+1] end] set aprops(domain) [string range $aprops(domain) 0 [expr $x-1]] } else { set aprops(resource) "jsend" } if {(![string compare $options(-body) ""]) && ($stayP < 2)} { set options(-body) [read -nonewline stdin] } set options(-xlist) {} if {[string compare $options(-url)$options(-description) ""]} { lappend options(-xlist) \ [jlib::wrapper:createtag x \ -vars [list xmlns jabber:x:oob] \ -subtags [list [jlib::wrapper:createtag url \ -chdata $options(-url)] \ [jlib::wrapper:createtag desc \ -chdata $options(-description)]]] } if {([string compare $options(-xhtml) ""]) \ && ([string compare $options(-body) ""]) \ && ($stayP < 1)} { lappend options(-xlist) \ [jlib::wrapper:createtag html \ -vars [list xmlns http://jabber.org/protocol/xhtml-im] \ -subtags [list [jlib::wrapper:createtag body \ -vars [list xmlns \ http://www.w3.org/1999/xhtml] \ -subtags [jsend::parse_xhtml $options(-xhtml)]]]] } if {![string compare $options(-type) announce]} { set options(-type) normal set announce [sha1::sha1 \ [clock seconds]$options(-subject)$options(-body)] lappend options(-xlist) \ [jlib::wrapper:createtag x \ -vars [list xmlns \ http://2entwine.com/protocol/gush-announce-1_0] \ -subtags [list [jlib::wrapper:createtag id \ -chdata $announce]]] } set lib(lastwhat) $options(-activity) if {[catch { clock scan $options(-time) } lib(lastwhen)]} { set lib(lastwhen) [clock seconds] } set params {} foreach k [list body subject type xlist] { if {[string compare $options(-$k) ""]} { lappend params -$k $options(-$k) } } if {[llength [jlib::connections]] <= 0} { set connid [jlib::new -user $aprops(local) \ -server $aprops(domain) \ -resource $aprops(resource)] if {$options(-tls)} { set transport tls if {[string compare $options(-port) ""]} { set port $options(-port) } else { set port 5223 } } else { set transport tcp if {[string compare $options(-port) ""]} { set port $options(-port) } else { set port 5222 } } jlib::connect $connid \ -transport $transport \ -host [idna::domain_toascii $aprops(domain)] \ -port $port \ -password $options(-password) jlib::login $connid [namespace current]::sendit_aux vwait [namespace current]::sendit_result if {[string compare [lindex $sendit_result 0] OK]} { error [lindex $sendit_result 1] } roster_get -command [namespace current]::roster_get_aux vwait [namespace current]::sendit_result } else { set connid [lindex [jlib::connections] 0] } if {![string compare $options(-to) "-"]} { set options(-to) $roster(users) } if {$stayP > 1} { jlib::send_presence -stat Online \ -connection $connid if {![string compare $options(-type) groupchat]} { set nick $aprops(local)@$aprops(domain)/@aprops(resource) set nick [string range [sha1::sha1 $nick+[clock seconds]] 0 7] foreach to $options(-to) { jlib::send_presence -to $to/$nick \ -connection $connid } } return 1 } foreach to $options(-to) { switch -- [eval [list jlib::send_msg $to -connection $connid] $params] { -1 - -2 { if {$stayP} { set cmd [list ::LOG] } else { set cmd [list error] } eval $cmd [list "error writing to socket, continuing..."] return 0 } default { } } } if {!$stayP} { set jsend::stayP 0 jlib::disconnect $connid } return 1 } proc jlib::sendit_aux {result args} { variable sendit_result set sendit_result [list $result $args] } proc jlib::roster_get_aux {what args} { variable sendit_result set sendit_result $what } proc client:message {args} { # ::LOG "client:message $args" } proc client:presence {args} { # ::LOG "client:presence $args" } proc client:iqreply {connid from userid id type lang child} { jlib::wrapper:splitxml $child tag vars isempty chdata children set xmlns [jlib::wrapper:getattr $vars xmlns] ::LOG "client:iqreply $from $userid $id $type $lang $xmlns" set result result set now [clock seconds] switch -- $type/$xmlns { get/jabber:iq:browse { foreach ns [list browse last time version] { lappend tags [jlib::wrapper:createtag ns -chdata $ns] } set xmldata [jlib::wrapper:createtag user \ -vars [list xmlns $xmlns type client] \ -subtags $tags] } get/jabber:iq:last { set xmldata [jlib::wrapper:createtag query \ -vars [list xmlns $xmlns \ seconds \ [expr $now-$jlib::lib(lastwhen)]] \ -chdata $jlib::lib(lastwhat)] } get/jabber:iq:time { set gmtP true foreach {k f} [list utc "%Y%m%dT%T" \ tz "%Z" \ display "%a %b %d %H:%M:%S %Z %Y"] { lappend tags [jlib::wrapper:createtag $k \ -chdata [clock format $now \ -format $f \ -gmt $gmtP]] set gmtP false } set xmldata [jlib::wrapper:createtag query \ -vars [list xmlns $xmlns] \ -subtags $tags] } get/jabber:iq:version { global argv0 tcl_platform foreach {k v} [list name [file tail [file rootname $argv0]] \ version "1.0 (Tcl [info patchlevel])" \ os "$tcl_platform(os) $tcl_platform(osVersion)"] { lappend tags [jlib::wrapper:createtag $k -chdata $v] set gmtP false } set xmldata [jlib::wrapper:createtag query \ -vars [list xmlns $xmlns] \ -subtags $tags] } default { set result error set xmldata [jlib::wrapper:createtag error \ -vars [list code 501] \ -chdata "not implemented"] } } jlib::send_iq $result $xmldata -to $from -id $id -connection $connid } proc client:roster_push {args} {} proc client:roster_item {args} {} proc client:reconnect {connid} { jsend::reconnect } proc client:disconnect {connid} { jsend::reconnect } proc client:status {args} { ::LOG "client:status $args" } namespace eval jsend { variable stayP 1 } proc jsend::follow {file argv} { proc [namespace current]::reconnect {} \ [list [namespace current]::reconnect_aux $argv] if {[catch { eval [list jlib::sendit 2] $argv } result]} { ::bgerror $result return } set buffer "" set fd "" set newP 1 array set st [list dev 0 ino 0 size 0] for {set i 0} {1} {incr i} { if {[expr $i%5] == 0} { if {[catch { file stat $file st2 } result]} { ::LOG $result break } if {($st(dev) != $st2(dev)) \ || ($st(ino) != $st2(ino)) \ || ($st(size) > $st2(size))} { if {$newP} { catch { close $fd } } fconfigure [set fd [open $file { RDONLY }]] -blocking off unset st array set st [array get st2] if {(!$newP) && (![string compare $st(type) file])} { seek $fd 0 end } if {!$newP} { set newP 0 } if {[string length $buffer] > 0} { if {[catch { eval [list jlib::sendit 1] $argv \ [parse $buffer] \ [list -body $buffer] } result]} { ::LOG $result break } elseif {$result} { set buffer "" } } } } if {[fblocked $fd]} { } elseif {[catch { set len [string length [set line [read $fd]]] append buffer $line } result]} { ::LOG $result break } elseif {[set x [string first "\n" $buffer]] < 0} { } else { set body [string range $buffer 0 [expr {$x-1}]] while {[catch { eval [list jlib::sendit 1] $argv [parse $body] \ [list -body $body] } result]} { ::LOG $result } if {$result} { set buffer [string range $buffer [expr $x+1] end] } } after 1000 "set alarmP 1" vwait alarmP } } proc jsend::parse {line} { set args {} if {![string equal [string index $line 15] " "]} { return $args } catch { lappend args -time [clock scan [string range $line 0 14]] } set line [string range $line 16 end] if {([set d [string first " " $line]] > 0) \ && ([string first ": " $line] > $d)} { lappend args -activity [string trim [string range $line $d end]] } return $args } proc jsend::reconnect_aux {argv} { variable stayP while {$stayP} { after [expr 60*1000] if {![catch { eval [list jlib::sendit 2] $argv } result]} { break } ::LOG $result } } proc jsend::parse_xhtml {text} { variable xhtml set wrap [jlib::wrapper:new [list [namespace current]::wrap_xhtml start] \ [list [namespace current]::wrap_xhtml end] \ [list [namespace current]::wrap_xhtml parse]] jlib::wrapper:parser $wrap parse "$text" jlib::wrapper:reset $wrap return $xhtml } proc jsend::wrap_xhtml {mode args} { variable xhtml if {![string compare $mode parse]} { set xhtml $args } } proc ::LOG {text} { # puts stderr $text } proc ::debugmsg {args} { # ::LOG "debugmsg: $args" } proc ::bgerror {err} { global errorInfo ::LOG "$err\n$errorInfo" } set status 1 array set jlib::lib [list lastwhen [clock seconds] lastwhat ""] if {![string compare [file tail [lindex $argv 0]] "jsend.tcl"]} { incr argc -1 set argv [lrange $argv 1 end] } if {(([set x [lsearch -exact $argv -help]] >= 0) \ || ([set x [lsearch -exact $argv --help]] >= 0)) \ && (($x == 0) || ([expr $x%2]))} { puts stdout "usage: jsend.tcl recipient ?options...? -follow file -pidfile file -from jid -password string -type string (e.g., 'chat') -subject string -body string -xhtml string -description string -url string -tls boolean (e.g., 'true') If recipient is '-', roster is used. If both '-body' and '-follow' are absent, the standard input is used. The file .jsendrc.tcl is consulted, e.g., set args {-from fred@example.com/bedrock -password wilma} for default values." set status 0 } elseif {($argc < 1) || (![expr $argc%2])} { puts stderr "usage: jsend.tcl recipent ?-key value?..." } elseif {[catch { if {([file exists [set file .jsendrc.tcl]]) \ || ([file exists [set file ~/.jsendrc.tcl]])} { set args {} source $file array set at [list -permissions 600] array set at [file attributes $file] if {([set x [lsearch -exact $args "-password"]] > 0) \ && (![expr $x%2]) \ && (![string match *00 $at(-permissions)])} { error "file should be mode 0600" } if {[llength $args] > 0} { set argv [eval [list linsert $argv 1] $args] } } } result]} { puts stderr "error in $file: $result" } elseif {([set x [lsearch -exact $argv "-follow"]] > 0) && ([expr $x%2])} { set keep_alive 1 set keep_alive_interval 3 if {([set y [lsearch -exact $argv "-pidfile"]] > 0) && ([expr $y%2])} { set fd [open [set pf [lindex $argv [expr $y+1]]] \ { WRONLY CREAT TRUNC }] puts $fd [pid] close $fd } jsend::follow [lindex $argv [expr $x+1]] $argv catch { file delete -- $pf } } elseif {[catch { eval [list jlib::sendit 0] $argv } result]} { puts stderr $result } else { set status 0 } exit $status # vim:ft=tcl:ts=8:sw=4:sts=4:noet tkabber-0.11.1/iq.tcl0000644000175000017500000000530310764041216013641 0ustar sergeisergei# $Id: iq.tcl 1385 2008-03-06 19:14:22Z sergei $ namespace eval iq { variable options custom::defgroup IQ [::msgcat::mc "Info/Query options."] -group Tkabber custom::defvar options(show_iq_requests) 0 \ [::msgcat::mc "Show IQ requests in the status line."] \ -group IQ -type boolean custom::defvar options(shorten_iq_namespaces) 1 \ [::msgcat::mc "Strip leading \"http://jabber.org/protocol/\" from IQ namespaces in the status line."] \ -group IQ -type boolean } proc iq::register_handler {type tag xmlns h} { variable handler variable supported_ns set handler($type,$tag,$xmlns) $h lappend supported_ns $xmlns set supported_ns [lrmdups $supported_ns] } proc iq::process_iq {connid from useid id type lang child} { variable handler variable options jlib::wrapper:splitxml $child tag vars isempty chdata children set xmlns [jlib::wrapper:getattr $vars xmlns] if {[info exists handler($type,$tag,$xmlns)]} { set h $handler($type,$tag,$xmlns) } elseif {[info exists handler($type,,$xmlns)]} { set h $handler($type,,$xmlns) } if {$options(show_iq_requests) && \ ($from != "" && \ !([string equal -nocase $from [jlib::connection_server $connid]] || \ [string equal -nocase $from [jlib::connection_bare_jid $connid]] || \ [string equal -nocase $from [jlib::connection_jid $connid]]))} { set xmlns_short $xmlns if {$options(shorten_iq_namespaces) && [string first "http://jabber.org/protocol/" $xmlns_short] == 0} { set xmlns_short [string range $xmlns_short 27 end] } set_status [format [::msgcat::mc "%s request from %s"] $xmlns_short $from] } if {[info exists h]} { set res [eval $h [list $connid $from $lang $child]] if {$res != {}} { switch -- [lindex $res 0] { result { debugmsg iq "IQREPLY: SENDING RESULT: $from; $useid; $id; $child" jlib::send_iq result [lindex $res 1] \ -to $from \ -connection $connid \ -id $id } error { debugmsg iq "IQREPLY: SENDING ERROR: $from; $useid; $id; $child" jlib::send_iq error \ [eval stanzaerror::error [lrange $res 1 end] -xml {$child}] \ -to $from \ -connection $connid \ -id $id } ignore { # Do nothing, swallow the request } } } } else { debugmsg iq "IQREPLY: SENDING 503: $from; $useid; $id; $child" jlib::send_iq error \ [stanzaerror::error cancel service-unavailable -xml $child] \ -to $from \ -connection $connid \ -id $id } } proc client:iqreply {connid from useid id type lang child} { debugmsg iq "IQREPLY: $from; $useid; $id; $type; $lang; $child" iq::process_iq $connid $from $useid $id $type $lang $child } plugins::load [file join plugins iq] tkabber-0.11.1/custom.tcl0000644000175000017500000005242710752133252014552 0ustar sergeisergei# $Id: custom.tcl 1373 2008-02-05 19:19:06Z sergei $ option add *Customize.varforeground blue widgetDefault option add *Customize.groupnameforeground blue widgetDefault namespace eval custom { # Filename for saving options set options(customfile) [file join $::configdir custom.tcl] # -1: stored values haven't been restored yet (only config changes vars) # 0: stored values are being restored now # 1: stored values have been restored (changes may be stored) set custom_loaded -1 } proc custom::defgroup {id doc args} { variable group if {![info exists group(members,$id)]} { set group(members,$id) {} } if {![info exists group(subgroups,$id)]} { set group(subgroups,$id) {} } set group(doc,$id) $doc set group(tag,$id) $id if {![info exists group(parents,$id)]} { set group(parents,$id) {} } foreach {attr val} $args { switch -- $attr { -tag {set group(tag,$id) $val} -group { lappend group(subgroups,$val) [list group $id] set group(subgroups,$val) [lrmdups $group(subgroups,$val)] lappend group(parents,$id) $val set group(parents,$id) [lrmdups $group(parents,$id)] #set group(members,$val) [lrmdups $group(members,$val)] } -type { set group(type,$id) $val } } } } proc custom::defvar {vname value doc args} { variable var variable group set fullname [uplevel 1 {namespace current}]::$vname if {![info exists $fullname]} { set $fullname $value } else { set var(config,$fullname) $value } trace variable $fullname w \ [list [namespace current]::on_var_change $fullname] set var(default,$fullname) $value set var(doc,$fullname) $doc set var(type,$fullname) string set var(state,$fullname) "" eval { configvar $fullname } $args } proc custom::on_var_change {varname args} { variable options variable var variable custom_loaded switch -- $custom_loaded { -1 { set var(config,$varname) [set $varname] } 0 { } 1 { # Store variable if it has been changed by # any procedure which is not in ::custom namespace if {[namespace qualifiers [caller]] != [namespace current]} { # Don't store loginconf here # (storing all loginconf except password may be # confusing) if {![regexp {^(::)+loginconf\(.*\)} $varname]} { store_vars $varname } } } } } proc custom::add_radio_options {vname values} { variable var set fullname [uplevel 1 {namespace current}]::$vname if {![info exists $fullname]} { return } set var(values,$fullname) [concat $var(values,$fullname) $values] } proc custom::configvar {fullname args} { variable var variable group if {![info exists $fullname]} { error "No such variable: $fullname" } foreach {attr val} $args { switch -- $attr { -type { set var(type,$fullname) $val } -group { lappend group(members,$val) [list var $fullname] #set group(members,$val) [lrmdups $group(members,$val)] } -values { set var(values,$fullname) $val } -layout { set var(layout,$fullname) $val } } } switch -- $var(type,$fullname) { radio { set q 0 foreach {v d} $var(values,$fullname) { if {$v == [set $fullname]} { set q 1 } } if {!$q} { set $fullname $var(default,$fullname) } } } foreach {attr val} $args { switch -- $attr { -command { trace variable $fullname w $val } } } } custom::defgroup Tkabber \ [::msgcat::mc "Customization of the One True Jabber Client."] custom::defgroup Hidden "Hidden group" -group Tkabber -tag "Hidden group" \ -type hidden ############################################################################### proc custom::open_window {gid} { set w .customize if {[winfo exists $w]} { raise_win $w goto $gid focus $w.fields return } add_win $w -title [::msgcat::mc "Customize"] \ -tabtitle [::msgcat::mc "Customize"] \ -class Customize \ -raise 1 #-raisecmd "focus [list $w.input]" set sw [ScrolledWindow $w.sw] set t [text $w.fields -wrap word -background [$w cget -background]] $sw setwidget $t frame $w.navigate button $w.navigate.back -text <- \ -command [list [namespace current]::history_move 1] button $w.navigate.forward -text -> \ -command [list [namespace current]::history_move -1] button $w.navigate.toplevel -text Tkabber \ -command [list [namespace current]::goto Tkabber] label $w.navigate.lab -text [::msgcat::mc "Group:"] Entry $w.navigate.entry -textvariable [namespace current]::curgroup \ -command [list [namespace current]::go] button $w.navigate.browse -text [::msgcat::mc "Open"] \ -command [list [namespace current]::go] pack $w.navigate.back $w.navigate.forward \ $w.navigate.toplevel $w.navigate.lab -side left pack $w.navigate.entry -side left -expand yes -fill x pack $w.navigate.browse -side left pack $w.navigate -side top -fill x pack $sw -side top -fill both -expand yes $t tag configure var -underline no \ -foreground [option get $w varforeground Customize] $t tag configure groupname -underline no \ -foreground [option get $w groupnameforeground Customize] bind $t [list $t yview scroll 1 unit] bind $t [list $t yview scroll -1 unit] bind $t [list $t yview scroll 1 page] bind $t [list $t yview scroll -1 page] variable history set history(pos) 0 set history(list) {} variable curgroup $gid hook::run open_custom_post_hook $w update idletasks goto $gid focus $t } proc custom::go {} { variable curgroup goto $curgroup } proc custom::goto {gid} { history_add $gid fill_group .customize.fields $gid 0 } proc custom::fill_group {t gid offset} { variable group variable var variable curgroup set curgroup $gid $t configure -state normal $t delete 1.0 end if {![info exists group(members,$gid)]} { $t configure -state disabled return } set i 0 if {[info exists group(parents,$gid)] && $group(parents,$gid) != {}} { foreach parent $group(parents,$gid) { set b [button $t.gr$i -text $group(tag,$parent) \ -cursor left_ptr \ -command [list [namespace current]::goto $parent]] $t window create end -window $b $t insert end " " bindscroll $b $t incr i } if {[llength $group(parents,$gid)] == 1} { $t insert end [::msgcat::mc "Parent group"] } else { $t insert end [::msgcat::mc "Parent groups"] } $t insert end "\n\n" } set butwidth 0 foreach member [concat $group(members,$gid) \ [lsort -dictionary -index 1 $group(subgroups,$gid)]] { lassign $member type data switch -- $type { group { if {[info exists group(type,$data)] && \ [cequal $group(type,$data) "hidden"]} { continue } $t insert end "\n" set b [button $t.gr$i -text "$group(tag,$data)" \ -width $butwidth \ -cursor left_ptr \ -command [list [namespace current]::goto $data]] $t window create end -window $b if {$butwidth < [string length "$group(tag,$data)"]} { set butwidth [string length "$group(tag,$data)"] for {set j 0} {$j <= $i} {incr j} { if {[winfo exists $t.gr$j]} { $t.gr$j configure -width $butwidth } } } bindscroll $b $t $t insert end " $group(doc,$data)" bindtags $b [lreplace [bindtags $b] 1 0 $t] $t insert end "\n" } var { $t insert end $data var ": " fill_var $t $data $i $t insert end "\n" } } incr i } $t configure -state disabled $t yview moveto $offset } proc custom::fill_var {t varname idx} { variable var variable tmp switch -- $var(type,$varname) { string { catch {unset tmp($varname)} trace variable [namespace current]::tmp($varname) w \ [list [namespace current]::on_edit $varname] set tmp($varname) [set $varname] set e [entry $t.entry$idx \ -textvariable [namespace current]::tmp($varname)] $t window create end -window $e bindscroll $e $t $t insert end "\n" } password { catch {unset tmp($varname)} trace variable [namespace current]::tmp($varname) w \ [list [namespace current]::on_edit $varname] set tmp($varname) [set $varname] set e [entry $t.entry$idx -show * \ -textvariable [namespace current]::tmp($varname)] $t window create end -window $e bindscroll $e $t $t insert end "\n" } boolean { catch {unset tmp($varname)} trace variable [namespace current]::tmp($varname) w \ [list [namespace current]::on_edit $varname] set tmp($varname) [set $varname] set cb [checkbutton $t.cb$idx -cursor left_ptr \ -variable [namespace current]::tmp($varname)] $t window create end -window $cb bindscroll $cb $t $t insert end "\n" } integer { catch {unset tmp($varname)} trace variable [namespace current]::tmp($varname) w \ [list [namespace current]::on_edit $varname] set tmp($varname) [set $varname] set e [Spinbox $t.spin$idx -1000000000 1000000000 1 \ [namespace current]::tmp($varname)] $t window create end -window $e bindscroll $e $t $t insert end "\n" } options { catch {unset tmp($varname)} catch {unset var(temp,$varname)} trace variable [namespace current]::tmp($varname) w \ [list [namespace current]::on_edit $varname] trace variable [namespace current]::var(temp,$varname) w \ [list [namespace current]::on_change $t $varname] set var(temp,$varname) [set $varname] set tmp($varname) [set $varname] set options {} foreach {val text} $var(values,$varname) { lappend options $text } set opt [eval [list OptionMenu $t.opt$idx \ [namespace current]::var(temp,$varname)] \ $options] $t.opt$idx configure -cursor left_ptr $t window create end -window $t.opt$idx bindscroll $t.opt$idx $t $t insert end "\n" } list { if {![info exists var(values,$varname)]} return catch {unset tmp($varname)} trace variable [namespace current]::tmp($varname) w \ [list [namespace current]::on_edit $varname] set tmp($varname) [set $varname] set fr [frame $t.fr$idx -cursor left_ptr] trace variable [namespace current]::tmp($varname) w \ [list [namespace current]::on_change $fr.lb $varname] set sw [ScrolledWindow $fr.sw] set lb [listbox $fr.lb -cursor left_ptr \ -selectmode extended -height 3 -exportselection false] eval [list $lb] insert end $var(values,$varname) $sw setwidget $lb pack $sw foreach i $tmp($varname) { $lb selection set $i } bind $lb <> \ "set [namespace current]::tmp($varname) \[$lb curselection\]" $t window create end -window $fr -align top $t insert end "\n" } radio { catch {unset tmp($varname)} trace variable [namespace current]::tmp($varname) w \ [list [namespace current]::on_edit $varname] set tmp($varname) [set $varname] if {[info exists var(layout,$varname)] && \ [string first v $var(layout,$varname)] == 0} { set anchor w set side top } else { set anchor n set side left } set fr [frame $t.fr$idx -cursor left_ptr] set i 0 foreach {val displ} $var(values,$varname) { set rb [radiobutton $fr.rb$i -cursor left_ptr \ -text $displ -value $val \ -variable [namespace current]::tmp($varname)] pack $rb -anchor $anchor -side $side bindscroll $rb $t incr i } $t window create end -window $fr -align top bindscroll $fr $t $t insert end "\n" } font { catch {unset tmp($varname)} trace variable [namespace current]::tmp($varname) w \ [list [namespace current]::on_edit $varname] set tmp($varname) [set $varname] set fr [frame $t.fr$idx -cursor left_ptr] trace variable [namespace current]::tmp($varname) w \ [list [namespace current]::on_change $fr.selectfont $varname] set sf [SelectFont $fr.selectfont -type toolbar \ -font $tmp($varname) \ -command [list [namespace current]::on_set_font \ $fr.selectfont $varname]] pack $sf bindscroll $sf $t $t window create end -window $fr bindscroll $fr $t $t insert end "\n" } file { catch {unset tmp($varname)} trace variable [namespace current]::tmp($varname) w \ [list [namespace current]::on_edit $varname] set tmp($varname) [set $varname] set e [entry $t.entry$idx -width 30 \ -textvariable [namespace current]::tmp($varname)] set browse \ [button $t.browse$idx -text [::msgcat::mc "Browse..."] \ -cursor left_ptr \ -command [list [namespace current]::get_filename $varname]] $t window create end -window $e $t window create end -window $browse bindscroll $e $t bindscroll $browse $t $t insert end "\n" } default { $t insert end "\n" } } set b [menubutton $t.stb$idx -text [::msgcat::mc "State"] \ -cursor left_ptr \ -menu $t.stb$idx.statemenu -relief $::tk_relief] create_state_menu $b.statemenu $varname $t window create end -window $b bindscroll $b $t set l [label $t.stl$idx \ -textvariable [namespace current]::var(state,$varname)] $t insert end " " $t window create end -window $l bindscroll $l $t $t insert end "\n" $t insert end "$var(doc,$varname)\n" } proc custom::get_filename {varname} { variable tmp set args {} if {$tmp($varname) == ""} { lappend args -initialdir $::configdir } else { lappend args -initialdir [file dirname $tmp($varname)] \ -initialfile [file tail $tmp($varname)] } set filename [eval tk_getOpenFile $args] if {$filename != ""} { set tmp($varname) $filename } } proc custom::on_change {w varname args} { variable var variable tmp if {![winfo exists $w]} { return } switch -- $var(type,$varname) { font { $w configure -font $tmp($varname) } list { $w selection clear 0 end foreach i $tmp($varname) { $w selection set $i } } options { foreach {val text} $var(values,$varname) { if {$text == $var(temp,$varname) && \ (![info exists tmp($varname)] || \ $tmp($varname) != $val)} { set tmp($varname) $val break } } } } } proc custom::on_set_font {sf varname} { variable tmp set tmp($varname) [$sf cget -font] } proc custom::on_edit {varname args} { variable var variable tmp variable saved switch -- $var(type,$varname) { options { foreach {val text} $var(values,$varname) { if {$tmp($varname) == $val && \ (![info exists var(temp,$varname)] || \ $var(temp,$varname) != $text)} { set var(temp,$varname) $text break } } } } set is_default [cequal [set $varname] $var(default,$varname)] if {[info exists var(config,$varname)]} { set is_config [cequal [set $varname] $var(config,$varname)] } else { set is_config -1 } set is_current [cequal [set $varname] $tmp($varname)] if {[info exists saved($varname)]} { set is_saved [cequal [set $varname] $saved($varname)] } else { set is_saved -1 } if {!$is_current} { set st [::msgcat::mc "value is changed, but the option is not set."] } else { switch -glob -- $is_default,$is_config,$is_saved { 0,0,1 - 0,-1,1 {set st [::msgcat::mc "the option is set and saved."]} *,*,0 - 0,0,-1 - 0,-1,-1 {set st [::msgcat::mc "the option is set, but not saved."]} *,1,* {set st [::msgcat::mc "the option is taken from config file."]} 1,*,* {set st [::msgcat::mc "the option is set to its default value."]} } } set var(state,$varname) $st } proc custom::create_state_menu {m varname} { variable var variable saved if {[winfo exists $m]} { destroy $m } menu $m -tearoff 0 $m add command -label [::msgcat::mc "Set for current session only"] \ -command [list [namespace current]::set_for_current_sess $varname] $m add command -label [::msgcat::mc "Set for current and future sessions"] \ -command [list [namespace current]::save_var $varname] $m add command -label [::msgcat::mc "Reset to current value"] \ -command [list [namespace current]::reset_to_current $varname] $m add command -label [::msgcat::mc "Reset to saved value"] \ -command [list [namespace current]::reset_to_saved $varname] \ -state [expr {[info exists saved($varname)] ? "normal" : "disabled"}] $m add command -label [::msgcat::mc "Reset to value from config file"] \ -command [list [namespace current]::reset_to_config $varname] \ -state [expr {[info exists var(config,$varname)] ? "normal" : "disabled"}] $m add command -label [::msgcat::mc "Reset to default value"] \ -command [list [namespace current]::reset_to_default $varname] return $m } proc custom::set_for_current_sess {varname} { variable var variable tmp variable saved set $varname $tmp($varname) on_edit $varname } proc custom::reset_to_current {varname} { variable var variable tmp variable saved set tmp($varname) [set $varname] on_edit $varname } proc custom::reset_to_saved {varname} { variable var variable tmp variable saved if {![info exists saved($varname)]} return set tmp($varname) $saved($varname) set $varname $saved($varname) on_edit $varname } proc custom::reset_to_config {varname} { variable var variable tmp variable saved if {![info exists var(config,$varname)]} return set tmp($varname) $var(config,$varname) set $varname $var(config,$varname) on_edit $varname } proc custom::reset_to_default {varname} { variable var variable tmp variable saved set tmp($varname) $var(default,$varname) set $varname $var(default,$varname) on_edit $varname } proc custom::save_var {varname} { variable var variable tmp variable saved set saved($varname) $tmp($varname) set $varname $tmp($varname) store on_edit $varname } proc custom::store {} { variable var variable saved variable options set fd [open $options(customfile) w] fconfigure $fd -encoding utf-8 foreach varname [array names saved] { if {[info exists var(config,$varname)]} { if {$saved($varname) != $var(config,$varname)} { puts $fd [list [list $varname $saved($varname)]] } } else { if {![info exists var(default,$varname)] || \ $saved($varname) != $var(default,$varname)} { puts $fd [list [list $varname $saved($varname)]] } } } close $fd catch {file attributes [file join $::configdir custom.tcl] -permissions 00600} } proc custom::store_vars {args} { variable saved foreach varname $args { set saved($varname) [set $varname] } store } proc custom::restore {} { variable var variable saved variable options variable custom_loaded set custom_loaded 0 if {![file readable $options(customfile)]} { set custom_loaded 1 return } set fd [open $options(customfile) r] fconfigure $fd -encoding utf-8 set opts [read $fd] close $fd foreach opt $opts { lassign $opt varname value set saved($varname) $value catch {set $varname $value} } set custom_loaded 1 } hook::add postload_hook custom::restore 60 proc custom::update_page_offset {} { variable history if {[llength $history(list)] == 0} return lassign [.customize.fields yview] offset lassign [lindex $history(list) $history(pos)] page set history(list) [lreplace $history(list) $history(pos) $history(pos) \ [list $page $offset]] } proc custom::history_move {shift} { variable history variable curgroup set newpos [expr {$history(pos) + $shift}] if {$newpos < 0} { return } if {$newpos >= [llength $history(list)]} { return } update_page_offset lassign [lindex $history(list) $newpos] newgroup offset set history(pos) $newpos history_set_buttons set curgroup $newgroup fill_group .customize.fields $newgroup $offset } proc custom::history_add {gid} { variable history update_page_offset set history(list) [lreplace $history(list) 0 [expr {$history(pos) - 1}]] lvarpush history(list) [list $gid 0] set history(pos) 0 history_set_buttons debugmsg custom [array get history] } proc custom::history_set_buttons {} { variable history if {$history(pos) == 0} { .customize.navigate.forward configure -state disabled } else { .customize.navigate.forward configure -state normal } if {$history(pos) + 1 == [llength $history(list)]} { .customize.navigate.back configure -state disabled } else { .customize.navigate.back configure -state normal } } ############################################################################## proc custom::restore_window {gid args} { open_window $gid } proc custom::save_session {vsession} { upvar 2 $vsession session global usetabbar variable history # We don't need JID at all, so make it empty (special case) set user "" set server "" set resource "" # TODO if {!$usetabbar} return set prio 0 foreach page [.nb pages] { set path [ifacetk::nbpath $page] if {[string equal $path .customize]} { lassign [lindex $history(list) $history(pos)] gid lappend session [list $prio $user $server $resource \ [list [namespace current]::restore_window $gid] \ ] } incr prio } } hook::add save_session_hook [namespace current]::custom::save_session # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/register.tcl0000644000175000017500000001207210752133252015054 0ustar sergeisergei# $Id: register.tcl 1373 2008-02-05 19:19:06Z sergei $ namespace eval register { set winid 0 } proc register::open {jid args} { variable winid foreach {key val} $args { switch -- $key { -connection { set connid $val } } } if {![info exists connid]} { return -code error "register::open: -connection required" } set w .register$winid toplevel $w wm group $w . set title [format [::msgcat::mc "Register in %s"] $jid] wm title $w $title wm iconname $w $title wm transient $w . if {$::tcl_platform(platform) == "macintosh"} { catch { unsupported1 style $w floating sideTitlebar } } elseif {$::aquaP} { ::tk::unsupported::MacWindowStyle style $w dBoxProc } wm resizable $w 0 0 set hf [frame $w.error] set vf [frame $w.vf] set sep [Separator::create $w.sep -orient horizontal] set sw [ScrolledWindow $w.sw] set sf [ScrollableFrame $w.fields -constrainedwidth yes] set f [$sf getframe] $sf configure -height 10 $sw setwidget $sf bindscroll $f $sf set bbox [ButtonBox $w.bbox -spacing 0 -padx 10 -default 0] $bbox add -text [::msgcat::mc "Register"] \ -command [list register::register $w $f $connid $jid] \ -state disabled $bbox add -text [::msgcat::mc "Unregister"] \ -command [list register::unregister $w $connid $jid] \ -state disabled $bbox add -text [::msgcat::mc "Cancel"] -command [list destroy $w] bind $w "ButtonBox::invoke $bbox default" bind $w "ButtonBox::invoke $bbox 2" pack $bbox -padx 2m -pady 2m -anchor e -side bottom pack $sep -side bottom -fill x -pady 1m pack $hf -side top pack $vf -side left -pady 2m pack $sw -side top -expand yes -fill both -padx 2m -pady 2m bind $f [list data::cleanup $f] wm withdraw $w jlib::send_iq get \ [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(register)]] \ -to $jid \ -connection $connid \ -command [list register::recv_fields $w $f $connid $jid] incr winid } proc register::recv_fields {w f connid jid res child} { debugmsg register "$res $child" switch -- $res { ERR { destroy $w MessageDlg ${w}_err -aspect 50000 -icon error \ -message [format [::msgcat::mc "Registration: %s"] \ [error_to_string $child]] \ -type user -buttons ok -default 0 -cancel 0 } OK { jlib::wrapper:splitxml $child tag vars isempty chdata children if {[jlib::wrapper:getattr $vars xmlns] == $::NS(register)} { set focus [data::fill_fields $f $children] } $w.bbox itemconfigure 0 -state normal if {$jid != [jlib::connection_server $connid]} { $w.bbox itemconfigure 1 -state normal } update idletasks $w.error configure -width [expr {[winfo reqwidth $f] + [winfo pixels $f 1c]}] set h [winfo reqheight $f] set sh [winfo screenheight $w] if {$h > $sh - 200} { set h [expr {$sh - 200}] } $w.vf configure -height $h wm deiconify $w if {$focus != ""} { focus $focus } } default { destroy $w } } } proc register::register {w f connid jid} { variable data destroy $w.error.msg $w.bbox itemconfigure 0 -state disabled $w.bbox itemconfigure 1 -state disabled set restags [data::get_tags $f] jlib::send_iq set [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(register)] \ -subtags $restags] \ -to $jid \ -connection $connid \ -command [list register::recv_result $w $connid $jid] } proc register::unregister {w connid jid} { variable data destroy $w.error.msg $w.bbox itemconfigure 0 -state disabled $w.bbox itemconfigure 1 -state disabled jlib::send_iq set [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(register)] \ -subtags [list [jlib::wrapper:createtag remove]]] \ -to $jid \ -connection $connid \ -command [list register::recv_result $w $connid $jid] } proc register::recv_result {w connid jid res child} { variable data debugmsg register "$res $child" if {![cequal $res OK]} { $w.bbox itemconfigure 0 -state normal if {$jid != [jlib::connection_server $connid]} { $w.bbox itemconfigure 1 -state normal } set m [message $w.error.msg \ -aspect 50000 \ -text [error_to_string $child] \ -pady 2m] $m configure -foreground [option get $m errorForeground Message] pack $m return } set result [::msgcat::mc "Registration is successful!"] label $w.result -text $result pack $w.result -expand yes -fill both -after $w.sw -anchor nw \ -padx 1c -pady 1c pack forget $w.sw pack forget $w.bbox set bbox [ButtonBox $w.bbox1 -spacing 0 -padx 10 -default 0] $bbox add -text [::msgcat::mc "Close"] -command [list destroy $w] bind $w "ButtonBox::invoke $w.bbox1 default" bind $w "ButtonBox::invoke $w.bbox1 0" pack $bbox -padx 2m -pady 2m -anchor e -side bottom -before $w.sep } hook::add postload_hook \ [list disco::browser::register_feature_handler $::NS(register) register::open \ -desc [list * [::msgcat::mc "Register"]]] tkabber-0.11.1/privacy.tcl0000644000175000017500000013000411013755300014674 0ustar sergeisergei# $Id: privacy.tcl 1425 2008-05-18 07:29:04Z sergei $ # # Privacy lists support (RFC 3921, section 10) # namespace eval privacy { variable options variable seq 0 array set req_messages \ [list ignore [::msgcat::mc "Requesting ignore list: %s"] \ invisible [::msgcat::mc "Requesting invisible list: %s"] \ visible [::msgcat::mc "Requesting visible list: %s"] \ conference [::msgcat::mc "Requesting conference list: %s"]] array set send_messages \ [list ignore [::msgcat::mc "Sending ignore list: %s"] \ invisible [::msgcat::mc "Sending invisible list: %s"] \ visible [::msgcat::mc "Sending visible list: %s"] \ conference [::msgcat::mc "Sending conference list: %s"] \ subscription [::msgcat::mc "Changing accept messages from roster only: %s"]] array set edit_messages \ [list ignore [::msgcat::mc "Edit ignore list"] \ invisible [::msgcat::mc "Edit invisible list"] \ visible [::msgcat::mc "Edit visible list"] \ conference [::msgcat::mc "Edit conference list"]] array set menu_messages \ [list ignore [::msgcat::mc "Ignore list"] \ invisible [::msgcat::mc "Invisible list"] \ visible [::msgcat::mc "Visible list"]] variable accept_from_roster 0 custom::defgroup Privacy \ [::msgcat::mc "Blocking communication (XMPP privacy lists) options."] \ -group Tkabber custom::defvar options(activate_at_startup) 1 \ [::msgcat::mc "Activate visible/invisible/ignore/conference lists\ before sending initial presence."] \ -type boolean -group Privacy } ############################################################################### # # Manual rules editing block # proc privacy::request_lists {args} { foreach {opt val} $args { switch -- $opt { -connection { set connid $val } } } if {![info exists connid]} { set connid [first_supported] } if {$connid == ""} return jlib::send_iq get \ [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(privacy)]] \ -command [list [namespace current]::open_dialog $connid] \ -connection $connid } proc privacy::on_destroy_dialog {w W} { variable data if {$w != $W} return catch { array unset data } } proc privacy::open_dialog {connid res child} { if {[cequal $res ERR]} { MessageDlg .privacy_err -aspect 50000 -icon error \ -message [::msgcat::mc "Requesting privacy rules: %s" \ [error_to_string $child]] \ -type user -buttons ok -default 0 -cancel 0 return } set w .privacy if {[winfo exists $w]} { destroy $w } Dialog $w -title [::msgcat::mc "Privacy lists"] \ -modal none -separator 1 -anchor e \ -default 0 -cancel 1 bind $w [list [namespace current]::on_destroy_dialog $w %W] $w add -text [::msgcat::mc "Send"] \ -command [list [namespace current]::send_lists $connid $w] $w add -text [::msgcat::mc "Cancel"] -command [list destroy $w] set f [$w getframe] set hf [frame $w.hf] pack $hf -side bottom set tools [frame $f.tools] pack $tools -side bottom -fill x -padx 1m set sw [ScrolledWindow $w.sw -scrollbar vertical] set sf [ScrollableFrame $w.fields -constrainedwidth yes] pack $sw -side bottom -expand yes -fill both -in $f -pady 1m -padx 1m set lf [$sf getframe] $sw setwidget $sf set addlist [button $tools.addlist \ -text [::msgcat::mc "Add list"] \ -command [list [namespace current]::add_list \ $connid $tools $lf "" {}]] pack $addlist -side right -padx 1m set default [radiobutton $tools.default \ -text [::msgcat::mc "No default list"] \ -variable [namespace current]::data(default) \ -value "\u0000"] pack $default -side left -padx 1m set active [radiobutton $tools.active \ -text [::msgcat::mc "No active list"] \ -variable [namespace current]::data(active) \ -value "\u0000"] pack $active -side left -padx 1m jlib::wrapper:splitxml $child tag vars isempty chdata children fill_lists $connid $hf $lf $children $w draw } proc privacy::fill_lists {connid hf f items} { variable data grid [label $f.n -text [::msgcat::mc "List name"] -width 20] \ -row 0 -column 0 -sticky we -padx 1m grid [label $f.d -text [::msgcat::mc "Default"]] \ -row 0 -column 1 -sticky we -padx 1m grid [label $f.a -text [::msgcat::mc "Active"]] \ -row 0 -column 2 -sticky we -padx 1m grid columnconfigure $f 0 -weight 1 grid columnconfigure $f 1 -weight 1 grid columnconfigure $f 2 -weight 1 grid columnconfigure $f 3 -weight 1 grid columnconfigure $f 4 -weight 1 set data(active) "\u0000" set data(default) "\u0000" set data(nlists) 0 set i 0 foreach item $items { jlib::wrapper:splitxml $item tag vars isempty chdata children switch -- x$tag { xdefault { set data(default) [jlib::wrapper:getattr $vars name] } xactive { set data(active) [jlib::wrapper:getattr $vars name] } xlist { set name [jlib::wrapper:getattr $vars name] add_list $connid $hf $f $name $children } } } } proc privacy::remove_list {lf ln} { variable data destroy $lf.name$ln destroy $lf.active$ln destroy $lf.default$ln destroy $lf.edit$ln destroy $lf.remove$ln set data(nitems,$ln) 0 set data(newname,$ln) "" } proc privacy::::on_change_list_name {lf i args} { variable data set name $data(newname,$i) if {$data(default) == $data(name,$i)} { set data(default) $name } if {$data(active) == $data(name,$i)} { set data(active) $name } if {[winfo exists $lf.default$i] && [winfo exists $lf.active$i]} { $lf.default$i configure -value $name $lf.active$i configure -value $name } if {$name != ""} { set data(name,$i) $name } } proc privacy::add_list {connid hf lf name children} { variable data set i $data(nlists) if {$name == ""} { set name "list$i" send_new_list $connid $name } set data(name,$i) $name set data(newname,$i) $name trace variable [namespace current]::data(newname,$i) w \ [list [namespace current]::on_change_list_name $lf $i] set lname [label $lf.name$i \ -text $name \ -textvariable [namespace current]::data(name,$i)] set default [radiobutton $lf.default$i \ -variable [namespace current]::data(default) \ -value $name] set active [radiobutton $lf.active$i \ -variable [namespace current]::data(active) \ -value $name] set remove [button $lf.remove$i \ -text [::msgcat::mc "Remove list"] \ -command [list [namespace current]::remove_list $lf $i]] set edit [button $lf.edit$i \ -text [::msgcat::mc "Edit list"] \ -command [list [namespace current]::edit_list $connid $lf $i]] set row [expr {$i + 1}] grid $lname -row $row -column 0 -stick w -padx 1m grid $default -row $row -column 1 -stick we -padx 1m grid $active -row $row -column 2 -stick we -padx 1m grid $edit -row $row -column 3 -stick we -padx 1m grid $remove -row $row -column 4 -stick we -padx 1m update idletasks $hf configure \ -width [expr {[winfo reqwidth $lf] + [winfo pixels $lf 1c]}] incr data(nlists) } proc privacy::edit_list {connid lf ln} { variable data set name $data(name,$ln) jlib::send_iq get \ [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(privacy)] \ -subtags [list [jlib::wrapper:createtag list \ -vars [list name $name]]]] \ -command [list [namespace current]::edit_list_dialog $connid $ln $name] \ -connection $connid } proc privacy::edit_list_dialog {connid ln name res child} { if {[cequal $res ERR]} { MessageDlg .privacy_list_err -aspect 50000 -icon error \ -message [::msgcat::mc "Requesting privacy list: %s" \ [error_to_string $child]] \ -type user -buttons ok -default 0 -cancel 0 set child [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(privacy)] \ -subtags [list [jlib::wrapper:createtag list \ -vars [list name $name]]]] } set w .privacy_list if {[winfo exists $w]} { destroy $w } Dialog $w -title [::msgcat::mc "Edit privacy list"] \ -separator 1 -anchor e \ -default 0 -cancel 1 $w add -text [::msgcat::mc "Send"] \ -command [list [namespace current]::send_list $connid $ln $w] $w add -text [::msgcat::mc "Cancel"] -command [list destroy $w] set f [$w getframe] set tools [frame $f.tools] pack $tools -side bottom -fill x set hf [frame $w.hf] pack $hf -side bottom set sw [ScrolledWindow $w.sw -scrollbar vertical] set sf [ScrollableFrame $w.fields -constrainedwidth yes] set lf [$sf getframe] pack $sw -side top -expand yes -fill both -in $f -pady 1m $sw setwidget $sf set additem [button $tools.aditem \ -text [::msgcat::mc "Add item"] \ -command \ [list [namespace current]::add_item \ $lf.items "none" "" "allow" 1 1 1 1]] pack $additem -side right -padx 1m jlib::wrapper:splitxml $child tag vars isempty chdata children fill_edit_lists $lf $children update idletasks $hf configure \ -width [expr {[winfo reqwidth $lf] + [winfo pixels $lf 1c]}] $w draw } proc privacy::fill_edit_lists {f items} { variable data foreach item $items { if {$item != ""} { jlib::wrapper:splitxml $item tag vars isempty chdata children if {$tag == "list"} { set name [jlib::wrapper:getattr $vars name] fill_edit_list $f $name $children break } } } } proc privacy::compare {item1 item2} { jlib::wrapper:splitxml $item1 tag vars isempty chdata children set order1 [jlib::wrapper:getattr $vars order] jlib::wrapper:splitxml $item2 tag vars isempty chdata children set order2 [jlib::wrapper:getattr $vars order] return [expr {$order1 > $order2}] } proc privacy::fill_edit_list {fr name items} { variable data set data(listname) $name set data(listnewname) $name set fname [frame $fr.name] pack $fname -side top -fill x label $fname.lname -text [string trimright [::msgcat::mc "Name: "]] entry $fname.name \ -textvariable [namespace current]::data(listnewname) pack $fname.lname -side left -anchor w pack $fname.name -side left -fill x -expand yes set f [frame $fr.items] pack $f -side top -fill both -expand yes label $f.ltype -text [::msgcat::mc "Type"] label $f.lvalue -text [::msgcat::mc "Value"] label $f.laction -text [::msgcat::mc "Action"] label $f.lmessage -text [::msgcat::mc "Message"] label $f.lpresencein -text [::msgcat::mc "Presence-in"] label $f.lpresenceout -text [::msgcat::mc "Presence-out"] label $f.liq -text [::msgcat::mc "IQ"] grid $f.ltype -row 0 -column 0 -sticky we -padx 0.5m grid $f.lvalue -row 0 -column 1 -sticky we -padx 0.5m grid $f.laction -row 0 -column 2 -sticky we -padx 0.5m grid $f.lmessage -row 0 -column 3 -sticky we -padx 0.5m grid $f.lpresencein -row 0 -column 4 -sticky we -padx 0.5m grid $f.lpresenceout -row 0 -column 5 -sticky we -padx 0.5m grid $f.liq -row 0 -column 6 -sticky we -padx 0.5m grid columnconfig $f 1 -weight 1 set data(listnitems) 0 foreach item [lsort -command [namespace current]::compare $items] { jlib::wrapper:splitxml $item tag vars isempty chdata children set type [jlib::wrapper:getattr $vars type] if {$type == ""} { set type none } set value [jlib::wrapper:getattr $vars value] set action [jlib::wrapper:getattr $vars action] set all 1 array set tmp [list message 0 presence-in 0 presence-out 0 iq 0] foreach child $children { jlib::wrapper:splitxml $child tag1 vars1 isempty1 chdata1 children1 switch -- $tag1 { message - presence-in - presence-out - iq { set tmp($tag1) 1 set all 0 } } } if {$all} { array set tmp [list message 1 presence-in 1 presence-out 1 iq 1] } add_item $f $type $value $action \ $tmp(message) $tmp(presence-in) $tmp(presence-out) $tmp(iq) } } proc privacy::add_item {f type value action message presencein presenceout iq} { variable data set i $data(listnitems) entry $f.value$i \ -textvariable [namespace current]::data(value,$i) ComboBox $f.type$i \ -values {none jid group subscription} \ -editable no \ -width 12 \ -textvariable [namespace current]::data(type,$i) ComboBox $f.action$i \ -values {allow deny} \ -editable no \ -width 5 \ -textvariable [namespace current]::data(action,$i) checkbutton $f.message$i \ -variable [namespace current]::data(message,$i) \ -command [list [namespace current]::update_checkbuttons $i] checkbutton $f.presencein$i \ -variable [namespace current]::data(presencein,$i) \ -command [list [namespace current]::update_checkbuttons $i] checkbutton $f.presenceout$i \ -variable [namespace current]::data(presenceout,$i) \ -command [list [namespace current]::update_checkbuttons $i] checkbutton $f.iq$i \ -variable [namespace current]::data(iq,$i) \ -command [list [namespace current]::update_checkbuttons $i] button $f.moveup$i -text [::msgcat::mc "Up"] \ -command [list [namespace current]::move_item_up $f $i] button $f.movedown$i -text [::msgcat::mc "Down"] \ -command [list [namespace current]::move_item_down $f $i] button $f.remove$i -text [::msgcat::mc "Remove"] \ -command [list [namespace current]::remove_item $f $i] set data(type,$i) $type set data(value,$i) $value set data(action,$i) $action set data(message,$i) $message set data(presencein,$i) $presencein set data(presenceout,$i) $presenceout set data(iq,$i) $iq set row [expr {$i + 1}] grid $f.type$i -row $row -column 0 -sticky ew -padx 0.5m grid $f.value$i -row $row -column 1 -sticky ew -padx 0.5m grid $f.action$i -row $row -column 2 -sticky ew -padx 0.5m grid $f.message$i -row $row -column 3 -sticky ew -padx 0.5m grid $f.presencein$i -row $row -column 4 -sticky ew -padx 0.5m grid $f.presenceout$i -row $row -column 5 -sticky ew -padx 0.5m grid $f.iq$i -row $row -column 6 -sticky ew -padx 0.5m grid $f.moveup$i -row $row -column 7 -sticky ew -padx 0.5m grid $f.movedown$i -row $row -column 8 -sticky ew -padx 0.5m grid $f.remove$i -row $row -column 9 -sticky ew -padx 0.5m incr data(listnitems) update_button_states $f } proc privacy::update_checkbuttons {i} { variable data if {!$data(message,$i) && !$data(presencein,$i) && \ !$data(presenceout,$i) && !$data(iq,$i)} { set data(message,$i) 1 set data(presencein,$i) 1 set data(presenceout,$i) 1 set data(iq,$i) 1 } } proc privacy::update_button_states {f} { variable data set numrows 0 set row 0 for {set i 0} {$i < $data(listnitems)} {incr i} { if {$data(type,$i) != "remove"} { $f.remove$i configure -state normal incr numrows set row $i } } if {$numrows == 1} { $f.remove$row configure -state disabled } } proc privacy::move_item_up {f i} { variable data set j $i incr j -1 while {$j >= 0 && $data(type,$j) == "remove"} { incr j -1 } if {$j >= 0} { switch_items $f $i $j } } proc privacy::move_item_down {f i} { variable data set j $i incr j 1 while {$j < $data(listnitems) && $data(type,$j) == "remove"} { incr j 1 } if {$j < $data(listnitems)} { switch_items $f $i $j } } proc privacy::switch_items {f i j} { variable data set type $data(type,$i) set value $data(value,$i) set action $data(action,$i) set message $data(message,$i) set presencein $data(presencein,$i) set presenceout $data(presenceout,$i) set iq $data(iq,$i) set data(type,$i) $data(type,$j) set data(value,$i) $data(value,$j) set data(action,$i) $data(action,$j) set data(message,$i) $data(message,$j) set data(presencein,$i) $data(presencein,$j) set data(presenceout,$i) $data(presenceout,$j) set data(iq,$i) $data(iq,$j) set data(type,$j) $type set data(value,$j) $value set data(action,$j) $action set data(message,$j) $message set data(presencein,$j) $presencein set data(presenceout,$j) $presenceout set data(iq,$j) $iq } proc privacy::remove_item {f i} { variable data destroy $f.type$i destroy $f.value$i destroy $f.action$i destroy $f.message$i destroy $f.presencein$i destroy $f.presenceout$i destroy $f.iq$i destroy $f.moveup$i destroy $f.movedown$i destroy $f.remove$i set data(type,$i) remove set data(value,$i) "" set data(action,$i) allow update_button_states $f } proc privacy::send_list_iq {name items args} { set cmd jlib::noop foreach {opt val} $args { switch -- $opt { -command { set cmd $val } -connection { set connid $val } } } if {![info exists connid]} { return -code error "Option -connection is mandatory" } jlib::send_iq set \ [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(privacy)] \ -subtags [list [jlib::wrapper:createtag list \ -vars [list name $name] \ -subtags $items]]] \ -command $cmd \ -connection $connid } proc privacy::send_new_list {connid name} { send_list_iq $name \ [list [jlib::wrapper:createtag item \ -vars [list action allow order 0]]] \ -connection $connid } proc privacy::send_list {connid ln w} { variable data set name $data(listnewname) send_list_iq $name [list_items] -connection $connid if {$name != $data(listname)} { if {$data(default) == $data(listname)} { send_default_or_active_list $name default -connection $connid } send_list_iq $data(listname) {} -connection $connid set data(newname,$ln) $name } destroy $w } proc privacy::send_lists {connid w} { variable data for {set i 0} {$i < $data(nlists)} {incr i} { if {$data(newname,$i) == ""} { send_list_iq $data(name,$i) {} -connection $connid } } send_default_or_active_list $data(active) active -connection $connid send_default_or_active_list $data(default) default -connection $connid destroy $w } proc privacy::list_items {} { variable data set items {} for {set i 0} {$i < $data(listnitems)} {incr i} { if {$data(type,$i) == "remove"} continue set vars [list action $data(action,$i) order $i] if {$data(type,$i) != "none"} { lappend vars type $data(type,$i) value $data(value,$i) } set children {} if {$data(message,$i)} { lappend children [jlib::wrapper:createtag message] } if {$data(presencein,$i)} { lappend children [jlib::wrapper:createtag presence-in] } if {$data(presenceout,$i)} { lappend children [jlib::wrapper:createtag presence-out] } if {$data(iq,$i)} { lappend children [jlib::wrapper:createtag iq] } if {[llength $children] == 4} { set children {} } lappend items [jlib::wrapper:createtag item \ -vars $vars \ -subtags $children] } return $items } ############################################################################### proc privacy::send_default_or_active_list {name tag args} { set cmd jlib::noop foreach {opt val} $args { switch -- $opt { -command { set cmd $val } -connection { set connid $val } } } if {![info exists connid]} { return -code error "Option -connection is mandatory" } if {$name != "\u0000"} { set vars [list name $name] } else { set vars {} } jlib::send_iq set \ [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(privacy)] \ -subtags [list [jlib::wrapper:createtag $tag \ -vars $vars]]] \ -command $cmd \ -connection $connid } ############################################################################### # # Visible, invisible, ignore, conference list block # proc privacy::edit_special_list {name args} { foreach {opt val} $args { switch -- $opt { -connection { set connid $val } } } if {![info exists connid]} { set connid [first_supported] } if {$connid == ""} return jlib::send_iq get \ [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(privacy)] \ -subtags [list [jlib::wrapper:createtag list \ -vars [list name "$name-list"]]]] \ -command [list [namespace current]::edit_special_list_dialog $connid $name] \ -connection $connid } proc privacy::edit_special_list_dialog {connid name res child} { variable req_messages variable edit_messages if {[cequal $res ERR]} { if {[error_type_condition $child] != {cancel item-not-found}} { MessageDlg .privacy_list_err -aspect 50000 -icon error \ -message [format $req_messages($name) [error_to_string $child]] \ -type user -buttons ok -default 0 -cancel 0 return } set child [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(privacy)] \ -subtags [list [jlib::wrapper:createtag list \ -vars [list name "$name-list"]]]] } set w .privacy_list if {[winfo exists $w]} { destroy $w } Dialog $w -title $edit_messages($name) \ -modal none -separator 1 -anchor e \ -default 0 -cancel 1 $w add -text [::msgcat::mc "Send"] \ -command [list [namespace current]::edit_special_list_enddialog \ $connid $w $name] $w add -text [::msgcat::mc "Cancel"] -command [list destroy $w] set f [$w getframe] set tools [frame $f.tools] pack $tools -side bottom -fill x set sw [ScrolledWindow $w.sw] set lf [listbox $w.fields] pack $sw -side top -expand yes -fill both -in $f -pady 1m -padx 1m $sw setwidget $lf bind $lf <3> [list [namespace current]::select_and_popup_menu %W %x %y] set addentry [entry $tools.addentry] set additem [button $tools.additem \ -text [::msgcat::mc "Add JID"] \ -command \ [list [namespace current]::add_special_jid_entry $lf $addentry]] pack $additem -side right -padx 1m pack $addentry -side left -padx 1m -fill x -expand yes jlib::wrapper:splitxml $child tag vars isempty chdata children fill_edit_special_lists $lf $children #update idletasks #$tools configure -width [winfo reqwidth $lf] DropSite::register $lf -dropcmd [list [namespace current]::dropcmd] \ -droptypes {JID} $w draw } proc privacy::edit_special_list_enddialog {connid w name} { $w itemconfigure 0 -state disabled send_special_list $connid $name [$w.fields get 0 end] destroy $w } proc privacy::send_special_list {connid name items} { variable seq variable special_list variable cboxes if {![is_supported $connid]} { return } if {![info exists special_list($connid,$name)]} { set special_list($connid,$name) {} } set newitems {} foreach jid $items { if {[lsearch -exact $special_list($connid,$name) $jid] < 0} { lappend newitems $jid } } set olditems {} foreach jid $special_list($connid,$name) { if {[lsearch -exact $items $jid] < 0} { lappend olditems $jid } } switch -- $name { ignore { set children {} set action deny foreach jid $newitems { send_custom_presence $jid unavailable -connection $connid } set postitems $olditems } invisible { set children [list [jlib::wrapper:createtag presence-out]] set action deny foreach jid $newitems { send_custom_presence $jid unavailable -connection $connid } set postitems $olditems } visible { # TODO: invisibility set children [list [jlib::wrapper:createtag presence-out]] set action allow set postitems $newitems } conference { set children {} set action allow set postitems {} } } set items1 {} set i 0 foreach item $items { lappend items1 [jlib::wrapper:createtag item \ -vars [list type jid \ value $item \ action $action \ order $i] \ -subtags $children] incr i } set s [incr seq] send_list_iq "$name-list" $items1 \ -command [list [namespace current]::get_answer $s] \ -connection $connid # We have to vwait because all privacy lists should be updated # before sending next stanzas lassign [wait_for_answer $s] res child update_tkabber_lists $connid $name $items $postitems $res $child } # subscription-list is responsible for blocking all messages # not from the roster. proc privacy::send_subscription_list {connid} { variable seq variable accept_from_roster_only if {![is_supported $connid]} { return } if {$accept_from_roster_only} { set items [list [jlib::wrapper:createtag item \ -vars [list type subscription \ value none \ action deny \ order 0]]] } else { set items {} } set s [incr seq] # If items aren't empty, we'll never send unavailable presence to # all users to whom directed presence was sent. Bug? send_list_iq "subscription-list" $items \ -command [list [namespace current]::get_answer $s] \ -connection $connid # We have to vwait because all privacy lists should be updated # before sending next stanzas lassign [wait_for_answer $s] res child update_tkabber_lists $connid subscription $items {} $res $child } proc privacy::on_accept_from_roster_only_change {args} { foreach {opt val} $args { switch -- $opt { -connection { set connid $val } } } if {![info exists connid]} { set connid [first_supported] } if {$connid == ""} return send_subscription_list $connid } proc privacy::update_tkabber_lists {connid name items postitems res child} { global userstatus textstatus statusdesc variable send_messages variable special_list variable cboxes if {$res == "DISCONNECT"} return switch -- $name { subscription { # Subscription list doesn't contain JIDs } default { # Workaround for servers without privacy list support/push if {$res == "OK"} { set special_list($connid,$name) $items } array unset cboxes $connid,$name,* foreach jid $special_list($connid,$name) { set cboxes($connid,$name,$jid) 1 } } } if {$res == "ERR"} { MessageDlg .privacy_list_err -aspect 50000 -icon error \ -message [format $send_messages($name) [error_to_string $child]] \ -type user -buttons ok -default 0 -cancel 0 return } switch -- $name { ignore - conference - subscription { # Some inefficiency here. We load three lists twice. join_lists $connid "i-am-visible-list" \ {ignore-list invisible-list conference-list subscription-list} \ {allow {} {}} join_lists $connid "i-am-invisible-list" \ {ignore-list visible-list conference-list subscription-list} \ [list deny {} [list [jlib::wrapper:createtag presence-out]]] } invisible { join_lists $connid "i-am-visible-list" \ {ignore-list invisible-list conference-list subscription-list} \ {allow {} {}} } visible { join_lists $connid "i-am-invisible-list" \ {ignore-list visible-list conference-list subscription-list} \ [list deny {} [list [jlib::wrapper:createtag presence-out]]] } } # ejabberd behaves correctly and applies privacy lists before # routing any subsequent packet, so we haven't to wait for iq reply # before sending presence. What about other servers? if {$userstatus == "invisible"} { set status available } else { set status $userstatus } if {$textstatus == ""} { set tstatus $statusdesc($status) } else { set tstatus $textstatus } foreach jid $postitems { send_presence $status -to $jid -stat $tstatus -connection $connid } } proc privacy::join_lists {connid name lists fallbacks args} { variable litems set items {} set i 0 # Appending myself to the list to make sure we can communicate # between own resources lappend items [jlib::wrapper:createtag item \ -vars [list type jid \ value [jlib::connection_bare_jid $connid] \ action allow \ order $i]] incr i foreach ln $lists { jlib::send_iq get \ [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(privacy)] \ -subtags [list [jlib::wrapper:createtag list \ -vars [list name $ln]]]] \ -command [list [namespace current]::get_items $connid] \ -connection $connid vwait [namespace current]::litems($connid) foreach item $litems($connid) { jlib::wrapper:splitxml $item tag vars isempty chdata children catch { array unset tmp } array set tmp $vars set tmp(order) $i lappend items [jlib::wrapper:createtag $tag \ -vars [array get tmp] \ -subtags $children] incr i } } unset litems($connid) foreach {action vars subtags} $fallbacks { lappend items [jlib::wrapper:createtag item \ -vars [concat [list action $action order $i] $vars] \ -subtags $subtags] } eval { send_list_iq $name $items -connection $connid } $args } proc privacy::get_items {connid res child} { variable litems if {$res != "OK"} { set litems($connid) {} return } jlib::wrapper:splitxml $child tag vars isempty chdata children jlib::wrapper:splitxml [lindex $children 0] tag vars isempty chdata children if {$tag == "list"} { set litems($connid) $children } else { set litems($connid) {} } } proc privacy::dropcmd {target source X Y op type data} { add_special_jid $target [lindex $data 1] } proc privacy::select_and_popup_menu {f x y} { set index [$f index @$x,$y] $f selection clear 0 end $f selection set $index if {[winfo exists [set m .privacy_list_popupmenu]]} { destroy $m } menu $m -tearoff 0 $m add command -label [::msgcat::mc "Remove from list"] \ -command [list $f delete $index] tk_popup $m [winfo pointerx .] [winfo pointery .] } proc privacy::fill_edit_special_lists {f items} { foreach item $items { if {$item != ""} { jlib::wrapper:splitxml $item tag vars isempty chdata children if {$tag == "list"} { set name [jlib::wrapper:getattr $vars name] fill_edit_special_list $f $name $children break } } } } proc privacy::fill_edit_special_list {fr name items} { set values {} foreach item $items { jlib::wrapper:splitxml $item tag vars isempty chdata children set type [jlib::wrapper:getattr $vars type] if {$type != "jid"} { continue } lappend values [jlib::wrapper:getattr $vars value] } eval [list $fr insert end] [lrmdups [lsort -dictionary $values]] } proc privacy::add_special_jid_entry {f entry} { set item [$entry get] $entry delete 0 end add_special_jid $f $item } proc privacy::add_special_jid {f item} { set values [$f get 0 end] lappend values $item set values [lrmdups [lsort -dictionary $values]] set index [lsearch -exact $values $item] $f delete 0 end eval [list $f insert end] $values $f selection set $index } ############################################################################### # # During connect try to activate "i-am-visible-list" privacy list # If it's not found then create and activate it # If activation or creation fails then terminate connect with error message # proc privacy::activate_privacy_list {depth connid} { variable seq variable options set_status [::msgcat::mc "Waiting for activating privacy list"] debugmsg privacy "requested privacy list activation" set s [incr seq] send_default_or_active_list "i-am-visible-list" active \ -command [list [namespace current]::get_answer $s] \ -connection $connid lassign [wait_for_answer $s] res child switch -- $res { "OK" { set_status [::msgcat::mc "Privacy list is activated"] set_supported $connid } "ERR" { switch -- [lindex [error_type_condition $child] 1] { feature-not-implemented { # Privacy lists aren't implemented # Give up set_status \ [::msgcat::mc "Privacy lists are not implemented"] } service-unavailable - recipient-unavailable { # Privacy lists are unavailable # Give up set_status \ [::msgcat::mc "Privacy lists are unavailable"] } item-not-found { if {$depth >= 1} { # After successfully (!) created list it # mustn't be possible # TODO: error message return } # There's no required privacy list # Create it set_status \ [::msgcat::mc "Creating default privacy list"] set s [incr seq] join_lists $connid "i-am-visible-list" \ {ignore-list invisible-list conference-list subscription-list} \ {allow {} {}} \ -command [list [namespace current]::get_answer $s] lassign [wait_for_answer $s] res child switch -- $res { "OK" { # Activate newly created list set_supported $connid return [activate_privacy_list [expr {$depth + 1}] \ $connid] } "ERR" { # Disconnect with error message set_status \ [::msgcat::mc "Privacy list is not created"] NonmodalMessageDlg .privacy_list_error$connid \ -aspect 50000 -icon error \ -title [::msgcat::mc "Privacy lists error"] \ -message \ [::msgcat::mc \ "Creating default privacy list failed:\ %s\n\nTry to reconnect. If problem\ persists, you may want to disable privacy\ list activation at start" \ [error_to_string $child]] logout $connid # Break connected_hook return stop } default { # "DISCONNECT" set_status \ [::msgcat::mc "Privacy list is not created"] # Break connected_hook return stop } } } default { # Something wrong # Disconnect with error message set_status \ [::msgcat::mc "Privacy list is not activated"] NonmodalMessageDlg .privacy_list_error$connid \ -aspect 50000 -icon error \ -title [::msgcat::mc "Privacy lists error"] \ -message \ [::msgcat::mc \ "Activating privacy list failed:\ %s\n\nTry to reconnect. If problem\ persists, you may want to disable privacy\ list activation at start" \ [error_to_string $child]] logout $connid # Break connected_hook return stop } } } default { # "DISCONNECT" set_status [::msgcat::mc "Privacy list is not activated"] # Break connected_hook return stop } } } ########################################################################## proc privacy::activate_privacy_list_at_startup {connid} { variable options if {$options(activate_at_startup)} { activate_privacy_list 0 $connid } } hook::add connected_hook \ [namespace current]::privacy::activate_privacy_list_at_startup 1 ########################################################################## proc privacy::get_answer {seq res child} { variable answer debugmsg privacy "got privacy list answer $seq $res $child" set answer($seq) [list $res $child] } proc privacy::wait_for_answer {seq} { variable answer vwait [namespace current]::answer($seq) set res $answer($seq) unset answer($seq) return $res } ############################################################################### proc privacy::is_supported {connid} { variable supported expr {[info exists supported($connid)] && $supported($connid)} } proc privacy::set_supported {connid} { variable supported set supported($connid) 1 } proc privacy::clear_supported {connid} { variable supported if {$connid == ""} { catch { array unset supported * } } else { catch { array unset supported $connid } } } hook::add disconnected_hook [namespace current]::privacy::clear_supported ############################################################################### proc privacy::create_menu {m connid jid} { variable menu_messages variable special_list variable cboxes set rjid [roster::find_jid $connid $jid] if {$rjid == ""} { set rjid [node_and_server_from_jid $jid] } if {![is_supported $connid] || \ [chat::is_groupchat [chat::chatid $connid $rjid]]} { set state disabled } else { set state normal } set mm [menu $m.privacy_menu -tearoff 0] foreach name {invisible ignore} { if {![info exists special_list($connid,$name)]} { set special_list($connid,$name) {} } if {[lsearch -exact $special_list($connid,$name) $rjid] >= 0} { set cboxes($connid,$name,$rjid) 1 } $mm add checkbutton -label $menu_messages($name) \ -variable [namespace current]::cboxes($connid,$name,$rjid) \ -command [list [namespace current]::update_special_list \ $connid $name $rjid] } $m add cascade -label [::msgcat::mc "Privacy rules"] \ -menu $mm \ -state $state } hook::add chat_create_user_menu_hook \ [namespace current]::privacy::create_menu 79 hook::add roster_service_popup_menu_hook \ [namespace current]::privacy::create_menu 79 hook::add roster_jid_popup_menu_hook \ [namespace current]::privacy::create_menu 79 ############################################################################### proc privacy::update_special_list {connid name jid} { variable cboxes if {[info exists cboxes($connid,$name,$jid)] && $cboxes($connid,$name,$jid)} { add_to_special_list $connid $name $jid } else { remove_from_special_list $connid $name $jid } } ############################################################################### proc privacy::add_to_special_list {connid name jid} { variable special_list if {![info exists special_list($connid,$name)]} { set special_list($connid,$name) {} } set idx [lsearch -exact $special_list($connid,$name) $jid] if {$idx < 0} { send_special_list $connid $name \ [linsert $special_list($connid,$name) 0 $jid] } } ############################################################################### proc privacy::remove_from_special_list {connid name jid} { variable special_list if {![info exists special_list($connid,$name)]} { set special_list($connid,$name) {} } set idx [lsearch -exact $special_list($connid,$name) $jid] if {$idx >= 0} { send_special_list $connid $name \ [lreplace $special_list($connid,$name) $idx $idx] } } ############################################################################### proc privacy::process_iq {connid from lang child} { if {$from != "" && \ !([string equal -nocase $from [jlib::connection_server $connid]] || \ [string equal -nocase $from [jlib::connection_bare_jid $connid]] || \ [string equal -nocase $from [jlib::connection_jid $connid]])} { return {error cancel not-allowed} } jlib::wrapper:splitxml $child tag vars isempty chdata children foreach ch $children { jlib::wrapper:splitxml $ch tag1 vars1 isempty1 chdata1 children1 switch -- $tag1 { list { switch -- [jlib::wrapper:getattr $vars1 name] { invisible-list { reload_special_list $connid invisible } visible-list { reload_special_list $connid visible } ignore-list { reload_special_list $connid ignore } conference-list { reload_special_list $connid conference } subscription-list { reload_subscription_list $connid } } } } } return {result {}} } iq::register_handler set query $::NS(privacy) \ [namespace current]::privacy::process_iq ############################################################################### proc privacy::clear_list_vars {connid} { variable special_list variable cboxes if {$connid == ""} { catch { array unset special_list * } catch { array unset cboxes * } } else { catch { array unset special_list $connid,* } catch { array unset cboxes $connid,* } } } hook::add disconnected_hook [namespace current]::privacy::clear_list_vars ############################################################################### # Conference list should be loaded before any join group attempt is made proc privacy::get_conference_list {connid} { variable seq set s [incr seq] jlib::send_iq get \ [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(privacy)] \ -subtags [list [jlib::wrapper:createtag list \ -vars [list name "conference-list"]]]] \ -command [list [namespace current]::get_answer $s] \ -connection $connid lassign [wait_for_answer $s] res child if {($res == "OK") || \ ($res == "ERR" && \ [lindex [error_type_condition $child] 1] == "item-not-found")} { set_supported $connid } store_special_list $connid conference $res $child } hook::add connected_hook [namespace current]::privacy::get_conference_list 2 ############################################################################### proc privacy::get_list_vars {connid} { foreach name {invisible visible ignore} { reload_special_list $connid $name } reload_subscription_list $connid } hook::add connected_hook [namespace current]::privacy::get_list_vars ############################################################################### proc privacy::reload_special_list {connid name} { jlib::send_iq get \ [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(privacy)] \ -subtags [list [jlib::wrapper:createtag list \ -vars [list name "$name-list"]]]] \ -command [list [namespace current]::store_special_list $connid $name] \ -connection $connid } proc privacy::store_special_list {connid name res child} { variable special_list variable cboxes set special_list($connid,$name) {} array unset cboxes $connid,$name,* if {$res != "OK"} return jlib::wrapper:splitxml $child tag vars isempty chdata children jlib::wrapper:splitxml [lindex $children 0] tag vars isempty chdata children if {$tag != "list"} return foreach item $children { jlib::wrapper:splitxml $item tag1 vars1 isempty1 chdata1 children1 if {[jlib::wrapper:getattr $vars1 type] == "jid" && \ [set jid [jlib::wrapper:getattr $vars1 value]] != ""} { lappend special_list($connid,$name) $jid set cboxes($connid,$name,$jid) 1 } } } ############################################################################### proc privacy::reload_subscription_list {connid} { jlib::send_iq get \ [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(privacy)] \ -subtags [list [jlib::wrapper:createtag list \ -vars [list name "subscription-list"]]]] \ -command [list [namespace current]::store_subscription_list $connid] \ -connection $connid } proc privacy::store_subscription_list {connid res child} { variable accept_from_roster_only set accept_from_roster_only 0 if {$res != "OK"} return jlib::wrapper:splitxml $child tag vars isempty chdata children jlib::wrapper:splitxml [lindex $children 0] tag vars isempty chdata children if {$tag != "list"} return foreach item $children { jlib::wrapper:splitxml $item tag1 vars1 isempty1 chdata1 children1 if {[jlib::wrapper:getattr $vars1 type] == "subscription" && \ [jlib::wrapper:getattr $vars1 value] == "none" && \ [jlib::wrapper:getattr $vars1 action] == "deny"} { set accept_from_roster_only 1 } } } ############################################################################### proc privacy::first_supported {} { foreach connid [jlib::connections] { if {[is_supported $connid]} { return $connid } } return "" } ############################################################################### proc privacy::enable_menu {connid} { if {[first_supported] == ""} return set m [.mainframe getmenu privacy] if {$::ifacetk::options(show_tearoffs)} { set start 1 } else { set start 0 } for {set i $start} {$i <= [$m index end]} {incr i} { catch {$m entryconfigure $i -state normal} } } proc privacy::disable_menu {connid} { if {[first_supported] != ""} return set m [.mainframe getmenu privacy] if {$::ifacetk::options(show_tearoffs)} { set start 1 } else { set start 0 } for {set i $start} {$i <= [$m index end]} {incr i} { catch {$m entryconfigure $i -state disabled} } $m entryconfigure [$m index [::msgcat::mc "Activate lists at startup"]] \ -state normal } hook::add connected_hook [namespace current]::privacy::enable_menu hook::add disconnected_hook [namespace current]::privacy::disable_menu hook::add finload_hook [list [namespace current]::privacy::disable_menu {}] ############################################################################### # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/tkabber.tcl0000755000175000017500000001441611076120361014646 0ustar sergeisergei#!/bin/sh # the next line restarts using the correct interpreter \ exec wish "$0" -name tkabber "$@" # $Id: tkabber.tcl 1517 2008-10-17 14:28:01Z sergei $ set interface tk namespace eval ifacetk {} set aquaP 0 catch { switch -- [tk windowingsystem] { classic - aqua { set aquaP 1 set tk_highlightthickness 0 set tk_relief sunken set tk_borderwidth 0 set tk_modify Cmd set tk_close Cmd-W rename ::bind ::bind_orig proc ::bind {args} { if {[llength $args] < 2} { return [eval ::bind_orig $args] } if {[string first "= 0} { puts "$level: $msg" } } proc fullpath {args} { global rootdir return [eval file join [list $rootdir] $args] } proc load_source {args} { set fullpath [eval fullpath $args] debugmsg tkabber "Loading $fullpath" uplevel #0 [list source $fullpath] } load_source configdir.tcl # from now on Tkabber config directory should be referenced via $::configdir proc get_snapshot {changelog} { set snapshot "" if {[catch { open $changelog } fd]} { return $snapshot } while {[gets $fd line] >= 0} { if {[regexp {(\d\d\d\d)-(\d\d)-(\d\d)} $line -> year month day]} { set snapshot "-$year$month$day" break } } close $fd return $snapshot } set tkabber_version "0.11.1" set toolkit_version "Tcl/Tk [info patchlevel]" proc rescmd {id res ls} { puts "RESULT: $id $res $ls" } proc quit {{status 0}} { hook::run quit_hook catch { bind $::ifacetk::mf {} } destroy . exit $status } namespace eval ifacetk {} namespace eval ssj {} load_source hooks.tcl # Give the starkit a chance to initialize things before # the bulk of the Tkabber code is loaded: if {[info commands starkit_init] != ""} starkit_init hook::add quit_hook logout 10 hook::add quit_hook { foreach chan [file channels] { if {[string first sock $chan] != -1} { catch { close $chan } res debugmsg tkabber "closed $chan '$res'" } } } 100 load_source default.tcl hook::add postload_hook postload hook::add finload_hook finload if {[info exists env(TKABBER_SITE_CONFIG)] && \ [file exists $env(TKABBER_SITE_CONFIG)]} { source $env(TKABBER_SITE_CONFIG) } if {[file exists [file join $configdir config.tcl]]} { source [file join $configdir config.tcl] } package require BWidget if {![info exists load_default_xrdb] || $load_default_xrdb} { option readfile [fullpath ifacetk default.xrdb] 21 switch -- $tcl_platform(platform) { unix { option readfile [fullpath ifacetk unix.xrdb] 21 } } } load_source trans.tcl ::trans::load [file join $rootdir trans] ::msgcat::mcload [file join $rootdir msgs] foreach pr [::msgcat::mcpreferences] { set f [file join $rootdir msgs "$pr.rc"] if {[file exists $f]} { option read $f break } } foreach pr [::msgcat::mcpreferences] { set f [file join $::BWIDGET::LIBRARY "lang" "$pr.rc"] if {[file exists $f]} { option read $f break } } unset pr f if {[catch { package require Tclx }]} { load_source Tclx.tcl } package require jabberlib 0.10.1 load_source xmppmime.tcl foreach {opt val} $argv { switch -- $opt { -mime {set mime_file $val} -user {set loginconf(user) $val} -password {set loginconf(password) $val} -resource {set loginconf(resource) $val} -port {set loginconf(port) $val} -autologin {set autologin $val} -chat {xmppmime::send_event [list chat $val]} -message {xmppmime::send_event [list message $val]} -conference {xmppmime::send_event [list groupchat $val]} -splash {set show_splash_window $val} } } if {[info exists mime_file]} { xmppmime::load $mime_file } if {[xmppmime::is_done]} exit load_source splash.tcl proc ::LOG {text} { debugmsg jlib $text } proc ::HTTP_LOG {text} { debugmsg http $text } if {[catch { package require Img }]} { debugmsg tkabber \ "unable to load the Img package, so no PNG/JPEG image support! The IMG package is available at http://www.xs4all.nl/~nijtmans/img.html" } load_source ifacetk idefault.tcl load_source custom.tcl load_source utils.tcl load_source plugins.tcl load_source pixmaps.tcl load_source balloon.tcl load_source presence.tcl load_source iq.tcl load_source disco.tcl load_source roster.tcl load_source itemedit.tcl load_source messages.tcl load_source chats.tcl load_source joingrdialog.tcl load_source muc.tcl load_source login.tcl load_source userinfo.tcl load_source datagathering.tcl load_source negotiate.tcl load_source mclistbox mclistbox.tcl load_source search.tcl load_source register.tcl load_source si.tcl load_source filetransfer.tcl load_source filters.tcl load_source privacy.tcl load_source gpgme.tcl load_source pubsub.tcl load_source pep.tcl load_source private.tcl load_source richtext.tcl load_source ifacetk bwidget_workarounds.tcl load_source ifacetk iface.tcl plugins::load [file join plugins general] plugins::load [file join plugins roster] plugins::load [file join plugins search] plugins::load [file join plugins richtext] plugins::load [file join plugins pep] plugins::load [file join plugins $tcl_platform(platform)] if {[info exists env(TKABBER_SITE_PLUGINS)] && \ [file isdirectory $env(TKABBER_SITE_PLUGINS)]} { plugins::load_dir $env(TKABBER_SITE_PLUGINS) } plugins::load_dir [file join $configdir plugins] hook::run postload_hook load_source iface.tcl hook::run finload_hook # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/negotiate.tcl0000644000175000017500000000646510764041216015221 0ustar sergeisergei# $Id: negotiate.tcl 1385 2008-03-06 19:14:22Z sergei $ namespace eval negotiate { set ::NS(negotiate) http://jabber.org/protocol/feature-neg set seq 0 } proc negotiate::get_handler {type connid from lang child} { variable handler debugmsg negotiate "$type: [list $from $child]" jlib::wrapper:splitxml $child tag vars isempty cdata children set error 1 set fields {} foreach form $children { jlib::wrapper:splitxml $form tag1 vars1 isempty1 cdata1 children1 if {$tag1 == "x" && \ [jlib::wrapper:getattr $vars1 xmlns] == $::NS(data) && \ [jlib::wrapper:getattr $vars1 type] == "submit"} { foreach field $children1 { jlib::wrapper:splitxml $field \ tag2 vars2 isempty2 cdata2 children2 if {$tag2 != "field"} continue set feature [jlib::wrapper:getattr $vars2 var] if {![info exists handler($feature)]} continue set error 0 # TODO set opts [eval $handler($feature) \ [list $type $connid $from $lang $children2]] lappend fields $opts } } } if {$error} { return [list error cancel feature-not-implemented] } else { set res [jlib::wrapper:createtag feature \ -vars [list xmlns $::NS(negotiate)] \ -subtags [list [jlib::wrapper:createtag x \ -vars [list xmlns $::NS(data) \ type result] \ -subtags $fields]]] return [list result $res] } } iq::register_handler get feature $::NS(negotiate) \ [list [namespace current]::negotiate::get_handler get] iq::register_handler set feature $::NS(negotiate) \ [list [namespace current]::negotiate::get_handler set] proc negotiate::register_handler {feature h} { variable handler set handler($feature) $h } proc negotiate::send_request {connid to feature} { variable seq variable tmp set i [incr seq] set fieldtags {} if {$feature != ""} { lappend fieldtags [jlib::wrapper:createtag field \ -vars [list var $feature]] } jlib::send_iq get \ [jlib::wrapper:createtag feature \ -vars [list xmlns $::NS(negotiate)] \ -subtags [list [jlib::wrapper:createtag x \ -vars [list xmlns $::NS(data) \ type submit] \ -subtags $fieldtags]]] \ -to $to \ -command [list negotiate::recv_request_response $connid $to $i] \ -connection $connid vwait [namespace current]::tmp($i) set res $tmp($i) unset tmp($i) return $res } proc negotiate::recv_request_response {connid jid seq res child} { variable tmp if {$res != "OK"} { set tmp($seq) [list $res $child] return } jlib::wrapper:splitxml $child tag vars isempty chdata children if {$tag == "feature"} { jlib::wrapper:splitxml \ [lindex $children 0] tag1 vars1 isempty1 chdata1 children1 data::draw_window $children1 \ [list [namespace current]::send_negotiation_form $connid $jid] } set tmp($seq) [list OK {}] } proc negotiate::send_negotiation_form {connid jid w restags} { catch { destroy $w.error.msg } $w.bbox itemconfigure 0 -state disabled jlib::send_iq set [jlib::wrapper:createtag feature \ -vars [list xmlns $::NS(negotiate)] \ -subtags [jlib::wrapper:createtag x \ -vars [list xmlns $::NS(data) \ type submit] \ -subtags $restags]] \ -to $jid \ -connection $connid \ -command [list data::test_error_res $w] } tkabber-0.11.1/trans.tcl0000644000175000017500000000300310531642213014346 0ustar sergeisergei# $Id: trans.tcl 802 2006-11-24 19:14:19Z sergei $ # Message translation namespace eval ::trans { variable trans array set trans {} } # Load message file. It must be in UTF-8 encoding. proc ::trans::loadfile {filepath} { set fd [open $filepath "r"] fconfigure $fd -encoding utf-8 uplevel #0 [read $fd] close $fd } # Load all message files in the directory. proc ::trans::load {dirpath} { foreach filepath [glob -nocomplain -directory $dirpath *.msg] { loadfile $filepath } } # Set translated message. proc ::trans::trset {lang msgfrom {msgto ""}} { variable trans if {$msgto != ""} { set trans($lang,$msgfrom) $msgto } } # ::trans::trans lang msg # ::trans::trans msg # Translate message 'msg' to language 'lang'. If there is only one # argument (no lang), then return unchanged message. proc ::trans::trans {args} { switch -- [llength $args] { 0 { return -code error "::trans::trans: Too few arguments" } 1 { # Dummy call for searching translations in the source. return [lindex $args 0] } 2 { lassign $args lang msg variable trans set langlist [split [string tolower $lang] -] set shortlang [lindex $langlist 0] set longlang [join $langlist _] if {[info exists trans($longlang,$msg)]} { return $trans($longlang,$msg) } elseif {[info exists trans($shortlang,$msg)]} { return $trans($shortlang,$msg) } else { return $msg } } default { return -code error "::trans::trans: Too many arguments" } } } tkabber-0.11.1/datagathering.tcl0000644000175000017500000004631211015004476016034 0ustar sergeisergei# $Id: datagathering.tcl 1442 2008-05-21 11:36:30Z sergei $ # # Data Forms (XEP-0004) support # namespace eval data { set winid 0 # Registration & search fields (see XEP-0077 & XEP-0055) array set field_labels [list \ username [::msgcat::mc "Username:"] \ nick [::msgcat::mc "Nickname:"] \ password [::msgcat::mc "Password:"] \ name [::msgcat::mc "Full Name:"] \ first [::msgcat::mc "First Name:"] \ last [::msgcat::mc "Last Name:"] \ email [::msgcat::mc "E-mail:"] \ address [::msgcat::mc "Address:"] \ city [::msgcat::mc "City:"] \ state [::msgcat::mc "State:"] \ zip [::msgcat::mc "Zip:"] \ phone [::msgcat::mc "Phone:"] \ url [::msgcat::mc "URL:"] \ date [::msgcat::mc "Date:"] \ misc [::msgcat::mc "Misc:"] \ text [::msgcat::mc "Text:"] \ key [::msgcat::mc "Key:"]] disco::register_feature jabber:x:data } proc data::fill_fields {g items} { variable data variable field_labels set row 0 set data(varlist,$g) {} grid columnconfig $g 1 -weight 1 -minsize 0 foreach item $items { jlib::wrapper:splitxml $item tag vars isempty chdata children set xmlns [jlib::wrapper:getattr $vars xmlns] if {$xmlns == "jabber:x:data" || $xmlns == "jabber:iq:data"} { return [fill_fields_x $g $children] } } set focus "" set fields {} foreach item $items { jlib::wrapper:splitxml $item tag vars isempty chdata children switch -- $tag { instructions { message $g.instructions$row -text $chdata -width 10c grid $g.instructions$row -row $row -column 0 -columnspan 2 \ -sticky w -pady 2m incr row } registered - x {} default { lappend fields $tag $chdata } } } foreach {tag chdata} $fields { lappend data(varlist,$g) $tag if {[info exists field_labels($tag)]} { label $g.l$row -text $field_labels($tag) } else { label $g.l$row -text $tag } switch -- $tag { key { entry $g.$row \ -textvariable [namespace current]::data(var,$tag,$g) \ -state disabled } password { entry $g.$row \ -textvariable [namespace current]::data(var,$tag,$g) \ -show * if {$focus == ""} { set focus $g.$row } } default { entry $g.$row \ -textvariable [namespace current]::data(var,$tag,$g) if {$focus == ""} { set focus $g.$row } } } if {$chdata != {}} { set data(var,$tag,$g) $chdata } grid $g.l$row -row $row -column 0 -sticky e grid $g.$row -row $row -column 1 -sticky we incr row } return $focus } proc data::cleanup {g} { variable data array unset data *,$g } proc data::get_tags {g} { variable data if {[info exists data(x,$g)]} { return [get_tags_x $g] } set restags {} if {[info exists data(varlist,$g)]} { foreach var $data(varlist,$g) { lappend restags [jlib::wrapper:createtag $var \ -chdata $data(var,$var,$g)] } } return $restags } proc data::get_reported_fields {g} { variable data return $data(varlist,$g) } ############################################################################### # x:data processing ############################################################################### # create field tag proc ::data::createfieldtag {type args} { array set params $args switch -- $type { instructions - title { if {[info exists params(-value)]} { return [jlib::wrapper:createtag $type \ -chdata $params(-value)] } else { error "You must define -value" } } fixed - hidden - list-single - list-multi - text-single - text-multi - text-private - jid-multi - jid-single - boolean { set vars [list type $type] if {[info exists params(-var)]} { lappend vars var $params(-var) } elseif {![string equal $type fixed]} { error "You must define -var" } if {[info exists params(-label)]} { lappend vars label $params(-label) } set subtags {} if {[info exists params(-descr)]} { lappend subtags [jlib::wrapper:createtag descr \ -chdata $params(-descr)] } if {[info exists params(-required)] && $params(-required)} { lappend subtags [jlib::wrapper:createtag required] } if {[lcontain {jid-multi text-multi list-multi hidden fixed} $type]} { if {[info exists params(-values)]} { foreach value $params(-values) { lappend subtags [jlib::wrapper:createtag value \ -chdata $value] } } elseif {[lcontain {jid-multi hidden fixed} $type]} { error "You must define -values" } } else { if {[info exists params(-value)]} { lappend subtags [jlib::wrapper:createtag value \ -chdata $params(-value)] } } if {[lcontain {list-multi list-single} $type]} { if {[info exists params(-options)]} { foreach option $params(-options) { lassign $option name label lappend subtags \ [jlib::wrapper:createtag option \ -vars [list label $label] \ -subtags \ [list [jlib::wrapper:createtag value \ -chdata $name]]] } } else { error "You must define -options" } } return [jlib::wrapper:createtag field \ -vars $vars \ -subtags $subtags] } default { error "Unknown type $type" } } } # parse_result proc data::parse_xdata_results {items args} { set report_hidden 0 foreach {key val} $args { switch -- $key { -hidden { set report_hidden $val } } } set result {} foreach item $items { jlib::wrapper:splitxml $item tag vars isempty chdata children if {$tag != "field"} { continue } set type [jlib::wrapper:getattr $vars type] if {!$report_hidden && $type == "hidden"} { continue } set var [jlib::wrapper:getattr $vars var] if {$var == ""} { continue } set label [jlib::wrapper:getattr $vars label] set values {} foreach child $children { jlib::wrapper:splitxml $child tag1 vars1 isempty1 chdata1 children1 if {$tag1 == "value"} { lappend values $chdata1 } } lappend result [list $var $type $label $values] } return $result } proc data::add_label {g row label {required 0}} { if {$label != ""} { if {$required} { set prefix * } else { set prefix "" } if {![string is punct [string index $label end]]} { set suffix : } else { set suffix "" } label $g.label$row -text ${prefix}${label}$suffix grid $g.label$row -row $row -column 0 -sticky en } } proc data::render_media {g row media_list} { foreach item $media_list { jlib::wrapper:splitxml $item tag vars isempty chdata children set unsupported 1 foreach child $children { jlib::wrapper:splitxml $child tag1 vars1 isempty1 chdata1 children1 switch -- $tag1 { uri { render_url $g.mediauri$row $chdata1 $chdata1 -bg [get_conf $g -bg] grid $g.mediauri$row -row $row -column 1 -sticky ew set unsupported 0 incr row } data { set type [jlib::wrapper:getattr $vars1 type] switch -glob -- $type { image/* { if {![catch {image create photo -data [base64::decode $chdata1]} img]} { label $g.mediaimg$row -image $img bind $g.mediaimg$row [list image delete $img] grid $g.mediaimg$row -row $row -column 1 -sticky ew set unsupported 0 incr row } } default { # TODO: implement other types } } } } } if {$unsupported} { # No supported media item return -code error "No supported types for a media element" } } return $row } proc data::fill_fields_x {g items} { variable data set data(x,$g) 1 set row 0 set data(allvarlist,$g) {} set focus "" foreach item $items { jlib::wrapper:splitxml $item tag vars isempty chdata children switch -- $tag { instructions { #add_label $g $row [::msgcat::mc "Instructions"] message $g.instructions$row -text $chdata -width 15c grid $g.instructions$row -row $row -column 0 \ -columnspan 2 -sticky w -pady 2m incr row } field { set widget [fill_field_x $g $row $tag $vars $chdata $children] if {$focus == ""} { set focus $widget } incr row } title { set top [winfo toplevel $g] if {$top != "."} { wm title $top $chdata wm iconname $top $chdata } } default { debugmsg filetransfer "XDATA: unknown tag $tag" } } } # FIX THIS set data(varlist,$g) $data(allvarlist,$g) return $focus } proc data::fill_field_x {g row tag vars chdata children} { variable data set required 0 set desc {} set options {} set vals {} set var [jlib::wrapper:getattr $vars var] set type [jlib::wrapper:getattr $vars type] if {$type == ""} { set type text-single } set label [jlib::wrapper:getattr $vars label] set data(var,$var,$g) "" set widget "" set media_list {} foreach item $children { jlib::wrapper:splitxml $item tag1 vars1 isempty1 chdata1 children1 switch -- $tag1 { required {set required 1} value { set data(var,$var,$g) $chdata1 lappend vals $chdata1 } desc {set desc $chdata1} option { set lab [jlib::wrapper:getattr $vars1 label] foreach item $children1 { jlib::wrapper:splitxml $item \ tag2 vars2 isempty2 chdata2 children2 switch -- $tag2 { value {set val $chdata2} } } lappend options $lab $val } media { if {[jlib::wrapper:getattr $vars1 xmlns] == $::NS(media-element)} { lappend media_list $item } } } } switch -- $type { jid-single - text-single - text-private { add_label $g $row $label $required set row [render_media $g $row $media_list] entry $g.entry$row \ -textvariable [namespace current]::data(var,$var,$g) if {$type == "text-private"} { $g.entry$row configure -show * } grid $g.entry$row -row $row -column 1 -sticky we set widget $g.entry$row if {$desc != ""} { balloon::setup $g.entry$row -text $desc } } jid-multi - text-multi { add_label $g $row $label $required set row [render_media $g $row $media_list] set sw [ScrolledWindow $g.textsw$row -scrollbar vertical] textUndoable $g.text$row -height 6 -width 50 $sw setwidget $g.text$row bind $g.text$row { } bind $g.text$row "[bind Text ]\nbreak" set data(var,$var,$g) [join $vals \n] catch { $g.text$row insert end $data(var,$var,$g) } grid $sw -row $row -column 1 -sticky we set data(text,$var,$g) $g.text$row set widget $g.text$row if {$desc != ""} { balloon::setup $g.text$row -text $desc } } boolean { switch -- $data(var,$var,$g) { 1 - 0 { set onvalue 1 set offvalue 0 } true - false { set onvalue true set offvalue false } default { set onvalue 1 set offvalue 0 set data(var,$var,$g) 0 } } add_label $g $row $label $required set row [render_media $g $row $media_list] checkbutton $g.cb$row \ -variable [namespace current]::data(var,$var,$g) \ -onvalue $onvalue -offvalue $offvalue grid $g.cb$row -row $row -column 1 -sticky w set widget $g.cb$row if {$desc != ""} { balloon::setup $g.cb$row -text $desc } } fixed { add_label $g $row $label $required set row [render_media $g $row $media_list] catch { message $g.m$row -text [join $vals \n] -width 10c } grid $g.m$row -row $row -column 1 -sticky w set dont_report 1 if {$desc != ""} { balloon::setup $g.m$row -text $desc } } list-single { add_label $g $row $label $required set row [render_media $g $row $media_list] set height 0 foreach {lab val} $options { lappend data(combol$row,$var,$g) $lab incr height if {[string equal $data(var,$var,$g) $val]} { set data(combov$row,$var,$g) $lab } } if {$height > 10} { set height 10 } set cb [ComboBox $g.combo$row \ -height $height \ -editable no \ -values $data(combol$row,$var,$g) \ -textvariable \ [namespace current]::data(combov$row,$var,$g)] grid $cb -row $row -column 1 -sticky we trace variable [namespace current]::data(combov$row,$var,$g) w \ [list data::trace_combo $options \ [namespace current]::data(var,$var,$g)] set widget $g.combo$row if {$desc != ""} { balloon::setup $g.combo$row -text $desc } } list-multi { add_label $g $row $label $required set row [render_media $g $row $media_list] set sw [ScrolledWindow $g.sw$row] set l [listbox $g.lb$row -height 6 \ -selectmode multiple -exportselection no] $sw setwidget $l foreach {lab val} $options { $l insert end $lab if {[lcontain $vals $val]} { $l selection set end } } grid $sw -row $row -column 1 -sticky we set data(multi,$var,$g) 1 trace_listmulti $l $options \ data::data(var,$var,$g) bind $l <> \ [list data::trace_listmulti %W $options \ [namespace current]::data(var,$var,$g)] set widget $sw if {$desc != ""} { balloon::setup $g.lb$row -text $desc } } hidden {} default { debugmsg filetransfer "XDATA: unknown field type '$type'" } } if {![info exists dont_report]} { lappend data(allvarlist,$g) $var } return $widget } proc data::trace_combo {assoc dst name1 name2 op} { foreach {lab val} $assoc { if {[string equal $lab [set ${name1}($name2)]]} { set $dst $val } } } proc data::trace_listmulti {l assoc dst} { set $dst {} foreach idx [$l curselection] { #debugmsg filetransfer [lindex $assoc [expr $idx * 2 + 1]] lappend $dst [lindex $assoc [expr $idx * 2 + 1]] } } proc data::get_tags_x {g} { variable data set restags {} foreach var $data(varlist,$g) { if {[info exists data(multi,$var,$g)]} { set vartags {} foreach val $data(var,$var,$g) { lappend vartags [jlib::wrapper:createtag value \ -chdata $val] } } elseif {[info exists data(text,$var,$g)]} { set data(var,$var,$g) [$data(text,$var,$g) get 1.0 "end -1c"] set vartags {} foreach val [split $data(var,$var,$g) \n] { lappend vartags [jlib::wrapper:createtag value \ -chdata $val] } } else { set vartags [list [jlib::wrapper:createtag value \ -chdata $data(var,$var,$g)]] } lappend restags [jlib::wrapper:createtag field \ -vars [list var $var] \ -subtags $vartags] } set restag [list [jlib::wrapper:createtag x \ -vars [list xmlns jabber:x:data type submit] \ -subtags $restags]] return $restag } ############################################################################### proc data::draw_window {items send_cmd {cancel_cmd destroy}} { variable winid set w .datagathering$winid incr winid if {[winfo exists $w]} { destroy $w } toplevel $w -class XData wm group $w . wm title $w "" wm iconname $w "" wm transient $w . wm withdraw $w set geometry [option get $w geometry XData] if {$geometry != ""} { wm geometry $w $geometry } set sw [ScrolledWindow $w.sw] set sf [ScrollableFrame $w.fields -constrainedwidth yes] set f [$sf getframe] $sf configure -height 10 $sw setwidget $sf if {[catch {data::fill_fields $f $items} focus]} { destroy $w return -code error $focus } set bbox [ButtonBox $w.bbox -spacing 10 -padx 10 -default 0] pack $bbox -side bottom -anchor e -padx 2m -pady 2m $bbox add -text [::msgcat::mc "Send"] \ -command [list eval $send_cmd [list $w] \[data::get_tags $f\]] $bbox add -text [::msgcat::mc "Cancel"] \ -command [list eval $cancel_cmd [list $w]] bind $w [list ButtonBox::invoke $bbox default] bind $w [list ButtonBox::invoke $bbox 1] bind $f [list [namespace current]::cleanup $f] bindscroll $f $sf pack [Separator $w.sep] -side bottom -fill x -pady 1m set hf [frame $w.error] pack $hf -side top set vf [frame $w.vf] pack $vf -side left -pady 2m pack $sw -side top -expand yes -fill both -padx 2m -pady 2m update idletasks $hf configure -width [expr {[winfo reqwidth $f] + [winfo pixels $f 1c]}] set h [winfo reqheight $f] set sh [winfo screenheight $w] if {$h > $sh - 200} { set h [expr {$sh - 200}] } $vf configure -height $h wm deiconify $w if {$focus != ""} { focus $focus } return $w } ############################################################################### proc data::request_data {xmlns jid node args} { foreach {key val} $args { switch -- $key { -connection { set connid $val } } } if {![info exists connid]} { return -code error "data::request_data error: -connection required" } set vars [list xmlns $xmlns] if {$node != ""} { lappend vars node $node } jlib::send_iq get \ [jlib::wrapper:createtag query \ -vars $vars] \ -to $jid \ -connection $connid \ -command [list [namespace current]::receive_data $connid $xmlns $jid $node] } proc data::receive_data {connid xmlns jid node res child} { if {[string equal $res DISCONNECT]} { return } if {[string equal $res ERR]} { set ew .data_err if {[winfo exists $ew]} { destroy $ew } MessageDlg $ew -aspect 50000 -icon error \ -message [::msgcat::mc "Error requesting data: %s" \ [error_to_string $child]] \ -type user -buttons ok -default 0 -cancel 0 return } switch -- $xmlns { jabber:iq:data { set children [list $child] } default { jlib::wrapper:splitxml $child tag vars isempty chdata children } } data::draw_window $children \ [list [namespace current]::send_data $connid $xmlns $jid $node] \ [list [namespace current]::cancel_data $connid $xmlns $jid $node] } proc data::cancel_data {connid xmlns jid node w} { send_data $connid $xmlns $jid $node $w \ [list [jlib::wrapper:createtag x \ -vars [list xmlns jabber:x:data \ type cancel]]] } proc data::send_data {connid xmlns jid node w restags} { switch -- $xmlns { jabber:iq:data { set child [lindex $restags 0] jlib::wrapper:splitxml $child tag vars isempty chdata children array set arr $vars set arr(xmlns) $xmlns set vars [array get arr] } default { set children $restags set vars [list xmlns $xmlns] } } if {$node != ""} { lappend vars node $node } destroy $w.error.msg $w.bbox itemconfigure 0 -state disabled jlib::send_iq set [jlib::wrapper:createtag query \ -vars $vars \ -subtags $children] \ -to $jid \ -connection $connid \ -command [list [namespace current]::test_error_res $w] } proc data::test_error_res {w res child} { if {[string equal $res OK]} { destroy $w return } $sw.bbox itemconfigure 0 -state normal set m [message $w.error.msg \ -aspect 50000 \ -text [error_to_string $child] \ -pady 2m] $m configure -foreground [option get $m errorForeground Message] pack $m } disco::browser::register_feature_handler jabber:iq:data \ [list [namespace current]::data::request_data jabber:iq:data] -node 1 \ -desc [list * [::msgcat::mc "Data form"]] disco::browser::register_feature_handler ejabberd:config \ [list [namespace current]::data::request_data ejabberd:config] -node 1 \ -desc [list * [::msgcat::mc "Configure service"]] tkabber-0.11.1/jabberlib/0000755000175000017500000000000011076120366014440 5ustar sergeisergeitkabber-0.11.1/jabberlib/jlibcomponent.tcl0000644000175000017500000001037511054503013020003 0ustar sergeisergei# jlibcomponent.tcl -- # # This file is part of the jabberlib. It provides support for the # jabber:component:accept protocol (XEP-0114). # # Copyright (c) 2005 Sergei Golovan # # $Id: jlibcomponent.tcl 1488 2008-08-25 10:14:35Z sergei $ # # SYNOPSIS # jlibcomponent::new connid args # creates handshake token # args: -sessionid sessionid # -secret secret # -command callback # # token configure args # configures token parameters # args: the same as in jlibcomponent::new # # token handshake args # starts handshake procedure # args: the same as in jlibcomponent::new # # token free # frees token resourses # # Note that this package is not loaded automatically with jabberlib. # You have to require it explicitly. # ########################################################################## package require sha1 package provide jlibcomponent 1.0 ########################################################################## namespace eval jlibcomponent { variable uid 0 } ########################################################################## proc jlibcomponent::new {connid args} { variable uid set token [namespace current]::[incr uid] variable $token upvar 0 $token state ::LOG "(jlibcomponent::new $connid) $token" set state(-connid) $connid proc $token {cmd args} \ "eval {[namespace current]::\$cmd} {$token} \$args" eval [list configure $token] $args jlib::register_element $state(-connid) handshake \ [namespace code [list parse $token]] jlib::register_element $state(-connid) error \ [namespace code [list parse $token]] return $token } ########################################################################## proc jlibcomponent::free {token} { variable $token upvar 0 $token state ::LOG "(jlibcomponent::free $token)" jlib::unregister_element $state(-connid) handshake jlib::unregister_element $state(-connid) error catch { unset state } catch { rename $token "" } } ########################################################################## proc jlibcomponent::configure {token args} { variable $token upvar 0 $token state foreach {key val} $args { switch -- $key { -sessionid - -secret - -command { set state($key) $val } default { return -code error "Illegal option \"$key\"" } } } } ########################################################################## proc jlibcomponent::parse {token xmldata} { variable $token upvar 0 $token state jlib::wrapper:splitxml $xmldata tag vars isempty cdata children switch -- $tag { handshake { finish $token OK {} } error { if {[wrapper:getattr $vars xmlns] = $::NS(stream)} { finish $token ERR [streamerror:message $xmldata] } } } } ########################################################################## proc jlibcomponent::handshake {token args} { variable $token upvar 0 $token state ::LOG "(jlibcomponent::handshake $token)" eval [list configure $token] $args foreach key [list -sessionid \ -secret] { if {![info exists state($key)]} { return -code error "Handshake error: missing option \"$key\"" } } set secret [encoding convertto utf-8 $state(-sessionid)] append secret [encoding convertto utf-8 $state(-secret)] set digest [sha1::sha1 $secret] set data [jlib::wrapper:createtag handshake -chdata $digest] jlib::client status [::msgcat::mc "Waiting for handshake results"] outmsg [jlib::wrapper:createxml $data] -connection $state(-connid) } ########################################################################## proc jlibcomponent::finish {token res msg} { variable $token upvar 0 $token state ::LOG "(jlibcomponent::finish $token) $res" if {$res != "OK"} { jlib::client status [::msgcat::mc "Handshake failed"] } else { jlib::client status [::msgcat::mc "Handshake successful"] } # Unregister elements after handshake jlib::unregister_element $state(-connid) handshake jlib::unregister_element $state(-connid) error if {[info exists state(-command)]} { uplevel #0 $state(-command) [list $res $msg] } } ########################################################################## tkabber-0.11.1/jabberlib/jlibdns.tcl0000644000175000017500000001075710701637340016602 0ustar sergeisergei# jlibdns.tcl -- # # This file is part of the jabberlib. It provides support for # Jabber Client SRV DNS records (RFC 3920) and # DNS TXT Resource Record Format (XEP-0156). # # Copyright (c) 2006 Sergei Golovan # # $Id: jlibdns.tcl 1244 2007-10-06 07:53:04Z sergei $ # # SYNOPSIS # jlibdns::get_addr_port domain # RETURNS list of {hostname port} pairs # # SYNOPSIS # jlibdns::get_http_poll_url domain # RETURNS URL for HTTP-poll connect method (XEP-0025) # ########################################################################## package require dns package require idna if {$::tcl_platform(platform) == "windows"} { package require registry } package provide jlibdns 1.0 ########################################################################## namespace eval jlibdns {} ########################################################################## proc jlibdns::get_addr_port {domain} { set name _xmpp-client._tcp.[idna::domain_toascii $domain] if {[catch { resolve $name SRV } res]} { return {} } set results {} foreach reply $res { array unset rr1 array set rr1 $reply if {![info exists rr1(rdata)]} continue array unset rr if {[catch { array set rr $rr1(rdata) }]} continue if {$rr(target) == "."} continue if {[info exists rr(priority)] && [check $rr(priority)] && \ [info exists rr(weight)] && [check $rr(weight)] && \ [info exists rr(port)] && [check $rr(port)] && \ [info exists rr(target)]} { if {$rr(weight) == 0} { set n 0 } else { set n [expr {($rr(weight) + 1) * rand()}] } lappend results [list [expr {$rr(priority) * 65536 - $n}] \ $rr(target) $rr(port)] } } set replies {} foreach hp [lsort -real -index 0 $results] { lappend replies [list [lindex $hp 1] [lindex $hp 2]] } return $replies } proc jlibdns::check {val} { if {[string is integer -strict $val] && $val >= 0 && $val < 65536} { return 1 } else { return 0 } } ########################################################################## proc jlibdns::get_http_poll_url {domain} { set name _xmppconnect.[idna::domain_toascii $domain] if {![catch { resolve $name TXT } res]} { foreach reply $res { array set rr $reply if {[regexp {_xmpp-client-httppoll=(.*)} $rr(rdata) -> url]} { return $url } } } return "" } ########################################################################## proc jlibdns::resolve {name type} { set nameservers [get_nameservers] foreach ns $nameservers { set token [dns::resolve $name -type $type -nameserver $ns] dns::wait $token set status [dns::status $token] if {$status == "ok"} { set res [dns::result $token] dns::cleanup $token return $res } else { set err [dns::error $token] dns::cleanup $token } } return -code error "DNS error: $err" } ########################################################################## proc jlibdns::get_nameservers {} { global tcl_platform switch -- $tcl_platform(platform) { unix { set resolv "/etc/resolv.conf" if {![file readable $resolv]} { return {127.0.0.1} } else { set fd [open $resolv] set lines [split [read $fd] "\r\n"] close $fd set ns {} foreach line $lines { if {[regexp {^nameserver\s+(\S+)} $line -> ip]} { lappend ns $ip } } if {$ns == {}} { return {127.0.0.1} } else { return $ns } } } windows { set services_key \ "HKEY_LOCAL_MACHINE\\system\\CurrentControlSet\\Services" set win9x_key "$services_key\\VxD\\MSTCP" set winnt_key "$services_key\\TcpIp\\Parameters" set interfaces_key "$winnt_key\\Interfaces" # Windows 9x if {![catch { registry get $win9x_key "NameServer" } ns]} { return [join [split $ns ,] " "] } # Windows NT/2000/XP if {![catch { registry get $winnt_key "NameServer" } ns] && \ $ns != {}} { return [join [split $ns ,] " "] } if {![catch { registry get $winnt_key "DhcpNameServer" } ns] && \ $ns != {}} { return $ns } foreach key [registry keys $interfaces_key] { if {![catch { registry get "$interfaces_key\\$key" \ "NameServer" } ns] && $ns != {}} { return [join [split $ns ,] " "] } if {![catch { registry get "$interfaces_key\\$key" \ "DhcpNameServer" } ns] && $ns != {}} { return $ns } } return {} } } } ########################################################################## tkabber-0.11.1/jabberlib/socks4.tcl0000644000175000017500000001537310710423253016356 0ustar sergeisergei# socks4.tcl --- # # Package for using the SOCKS4a method for connecting TCP sockets. # Only client side. # # Copyright (c) 2007 Mats Bengtsson # Modifications Copyright (c) 2007 Sergei Golovan # # This source file is distributed under the BSD license. # # $Id: socks4.tcl 1282 2007-10-26 17:40:59Z sergei $ package require autoconnect 0.2 package provide autoconnect::socks4 1.0 namespace eval socks4 { namespace export connect variable const array set const { ver \x04 cmd_connect \x01 cmd_bind \x02 rsp_granted \x5a rsp_failure \x5b rsp_errconnect \x5c rsp_erruserid \x5d } # Practical when mapping errors to error codes. variable iconst array set iconst { 4 ver 1 cmd_connect 2 cmd_bind 90 rsp_granted 91 rsp_failure 92 rsp_errconnect 93 rsp_erruserid } variable debug 0 autoconnect::register socks4 [namespace current]::connect } # socks4::connect -- # # Negotiates with a SOCKS server. # # Arguments: # sock: an open socket token to the SOCKS server # addr: the peer address, not SOCKS server # port: the peer's port number # args: # -command tclProc {token status} # -username userid # -timeout millisecs (default 60000) # # Results: # The connect socket or error if no -command, else empty string. # # Side effects: # Socket is prepared for data transfer. # If -command specified, the callback tclProc is called with # status OK and socket or ERROR and error message. proc socks4::connect {sock addr port args} { variable const set token [namespace current]::$sock variable $token upvar 0 $token state array set state { -command "" -timeout 60000 -username "" async 0 bnd_addr "" bnd_port "" status "" } array set state [list \ addr $addr \ port $port \ sock $sock] array set state $args if {[string length $state(-command)]} { set state(async) 1 } # Network byte-ordered port (2 binary-bytes, short) set bport [binary format S $port] # This corresponds to IP address 0.0.0.x, with x nonzero. set bip \x00\x00\x00\x01 set bdata "$const(ver)$const(cmd_connect)$bport$bip" append bdata "$state(-username)\x00$addr\x00" fconfigure $sock -translation binary -blocking 0 fileevent $sock writable {} if {[catch { puts -nonewline $sock $bdata flush $sock } err]} { catch {close $sock} if {$state(async)} { after idle [list $state(-command) ERROR network-failure] Free $token return } else { Free $token return -code error network-failure } } # Setup timeout timer. set state(timeoutid) \ [after $state(-timeout) [namespace current]::Timeout $token] fileevent $sock readable \ [list [namespace current]::Response $token] if {$state(async)} { return } else { # We should not return from this proc until finished! vwait $token\(status) set status $state(status) set sock $state(sock) Free $token if {[string equal $status OK]} { return $sock } else { catch {close $sock} return -code error $sock } } } # socks4::Response -- # # Receive the reply from a proxy and finish the negotiations. # # Arguments: # token A connection token. # # Result: # An empty string. # # Side effects: # The negotiation is finished with either success or error. proc socks4::Response {token} { variable $token upvar 0 $token state variable const variable iconst Debug 2 "socks4::response" set sock $state(sock) fileevent $sock readable {} # Read and parse status. if {[catch {read $sock 2} data] || [eof $sock]} { Finish $token network-failure return } binary scan $data cc null status if {![string equal $null 0]} { Finish $token err_version return } if {![info exists iconst($status)]} { Finish $token err_unknown return } elseif {![string equal $iconst($status) rsp_granted]} { Finish $token $iconst($status) return } # Read and parse port (2 bytes) and ip (4 bytes). if {[catch {read $sock 6} data] || [eof $sock]} { Finish $token network-failure return } binary scan $data ccccS i0 i1 i2 i3 port set addr "" foreach n [list $i0 $i1 $i2 $i3] { # Translate to unsigned! append addr [expr ( $n + 0x100 ) % 0x100] if {$n <= 2} { append addr . } } # Translate to unsigned! set port [expr ( $port + 0x10000 ) % 0x10000] set state(bnd_port) $port set state(bnd_addr) $addr Finish $token return } # socks4::Timeout -- # # This proc is called in case of timeout. # # Arguments: # token A connection token. # # Result: # An empty string. # # Side effects: # A proxy negotiation is finished with error. proc socks4::Timeout {token} { Finish $token timeout return } # socks4::Free -- # # Frees a connection token. # # Arguments: # token A connection token. # # Result: # An empty string. # # Side effects: # A connection token and its state informationa are destroyed. proc socks4::Free {token} { variable $token upvar 0 $token state catch {after cancel $state(timeoutid)} catch {unset state} return } # socks4::Finish -- # # Finishes a negotiation process. # # Arguments: # token A connection token. # errormsg (optional) error message. # # Result: # An empty string. # # Side effects: # If connection is asynchronous then a callback is executed. # Otherwise state(status) is set to allow https::connect to return # with either success or error. proc socks4::Finish {token {errormsg ""}} { variable $token upvar 0 $token state Debug 2 "socks4::Finish token=$token, errormsg=$errormsg" catch {after cancel $state(timeoutid)} if {$state(async)} { # In case of asynchronous connection we do the cleanup. if {[string length $errormsg]} { catch {close $state(sock)} uplevel #0 $state(-command) [list ERROR $errormsg] } else { uplevel #0 $state(-command) [list OK $state(sock)] } Free $token } else { # Otherwise we trigger state(status). if {[string length $errormsg]} { catch {close $state(sock)} set state(sock) $errormsg set state(status) ERROR } else { set state(status) OK } } return } # https::Debug -- # # Prints debug information. # # Arguments: # num A debug level. # str A debug message. # # Result: # An empty string. # # Side effects: # A debug message is printed to the console if the value of # https::debug variable is not less than num. proc socks4::Debug {num str} { variable debug if {$num <= $debug} { puts $str } } # Test if {0} { set s [socket 192.168.0.1 1080] set t [socks4::connect $s jabber.ru 5222 -username sergei] } tkabber-0.11.1/jabberlib/wrapper.tcl0000644000175000017500000003024111034654147016627 0ustar sergeisergei###################################################################### # # wrapper.tcl # # This file defines wrapper procedures. These # procedures are called by functions in jabberlib, and # they in turn call the TclXML library functions. # # $Header$ # # ###################################################################### # # Here is a list of the procedures defined here: # if {0} { proc wrapper:new {streamstartcmd streamendcmd parsecmd} proc wrapper:free {id} proc wrapper:parser {id args} proc wrapper:reset {id} proc wrapper:elementstart {id tagname varlist args} proc wrapper:elementend {id tagname args} proc wrapper:chdata {id chardata} proc wrapper:xmlerror {id args} proc wrapper:xmlcrypt {text} proc wrapper:createxml {xmldata} proc wrapper:createtag {tagname args} proc wrapper:getattr {varlist attrname} proc wrapper:isattr {varlist attrname} proc wrapper:splitxml {xmldata vtag vvars visempty vchdata vchildren} proc wrapper:streamheader {args} proc wrapper:streamtrailer {} } # # ###################################################################### # set wrapper(list) "" set wrapper(freeid) 0 ###################################################################### proc wrapper:new {streamstartcmd streamendcmd parsecmd} { variable wrapper set id "wrap#$wrapper(freeid)" incr wrapper(freeid) lappend wrapper(list) $id set wrapper($id,streamstartcmd) $streamstartcmd set wrapper($id,streamendcmd) $streamendcmd set wrapper($id,parsecmd) $parsecmd set wrapper($id,parser) \ [::xml::parser "_parser_$id" \ -namespace \ -final 0 \ -elementstartcommand "[namespace current]::wrapper:elementstart [list $id]" \ -elementendcommand "[namespace current]::wrapper:elementend [list $id]" \ -characterdatacommand "[namespace current]::wrapper:chdata [list $id]" # -errorcommand "[namespace current]::wrapper:xmlerror [list $id]" ] if {[info commands ::$wrapper($id,parser)] == ""} { set wrapper($id,parser) [namespace current]::$wrapper($id,parser) } set wrapper($id,stack) {} return $id } ###################################################################### proc wrapper:free {id} { variable wrapper if {[set ind [lsearch $wrapper(list) $id]] == -1} { return -code error -errorinfo "No such wrapper: \"$id\"" } set wrapper(list) [lreplace $wrapper(list) $ind $ind] $wrapper($id,parser) free array unset wrapper $id,* } ###################################################################### proc wrapper:parser {id args} { variable wrapper if {[lsearch $wrapper(list) $id] == -1} { return -code error -errorinfo "No such wrapper: \"$id\"" } return [uplevel 1 "[list $wrapper($id,parser)] $args"] } ###################################################################### proc wrapper:reset {id} { variable wrapper if {[lsearch $wrapper(list) $id] == -1} { return -code error -errorinfo "No such wrapper: \"$id\"" } $wrapper($id,parser) reset $wrapper($id,parser) configure \ -final 0 \ -elementstartcommand "[namespace current]::wrapper:elementstart [list $id]" \ -elementendcommand "[namespace current]::wrapper:elementend [list $id]" \ -characterdatacommand "[namespace current]::wrapper:chdata [list $id]" # -errorcommand "[namespace current]::wrapper:xmlerror [list $id]" set wrapper($id,stack) {} } ###################################################################### proc wrapper:elementstart {id tagname varlist args} { variable wrapper if {[lsearch $wrapper(list) $id] == -1} { return -code error -errorinfo "No such wrapper: \"$id\"" } set newvarlist {} set xmlns "" foreach {attr val} $args { switch -- $attr { -namespace { set xmlns $val lappend newvarlist xmlns $xmlns } } } set idx [string last : $tagname] if {$idx >= 0} { set xmlns [string range $tagname 0 [expr {$idx - 1}]] set tagname [string range $tagname [expr {$idx + 1}] end] lappend newvarlist xmlns $xmlns } foreach {attr val} $varlist { set l [::split $attr :] if {[llength $l] > 1} { set axmlns [join [lrange $l 0 end-1] :] if {$axmlns == $xmlns} { set attr [lindex $l end] } else { if {$axmlns == "http://www.w3.org/XML/1998/namespace"} { set axmlns xml } set attr $axmlns:[lindex $l end] } } lappend newvarlist $attr $val } if {$wrapper($id,stack) == {}} { set wrapper($id,level1tag) $tagname uplevel #0 "$wrapper($id,streamstartcmd) [list $newvarlist]" } set wrapper($id,stack) \ [linsert $wrapper($id,stack) 0 \ [list $tagname $newvarlist {} "" "" ""]] } ###################################################################### proc wrapper:elementend {id tagname args} { variable wrapper if {[lsearch $wrapper(list) $id] == -1} { return -code error -errorinfo "No such wrapper: \"$id\"" } set new_el [lindex $wrapper($id,stack) 0] set tail [lrange $wrapper($id,stack) 1 end] set len [llength $tail] if {$len > 1} { set head [lindex $tail 0] #set subtail [lrange $tail 1 end] set els [linsert [lindex $head 2] end $new_el] set wrapper($id,stack) \ [lreplace $tail 0 0 \ [lreplace $head 2 2 $els]] } elseif {$len == 1} { uplevel \#0 $wrapper($id,parsecmd) [list $new_el] set wrapper($id,stack) $tail } else { # $len == 0 uplevel \#0 $wrapper($id,streamendcmd) set wrapper($id,stack) $tail } } ###################################################################### proc wrapper:chdata {id chardata} { variable wrapper if {[lsearch $wrapper(list) $id] == -1} { return -code error -errorinfo "No such wrapper: \"$id\"" } set new_el [lindex $wrapper($id,stack) 0] #set tail [lrange $wrapper($id,stack) 1 end] set chdata "[lindex $new_el 3]$chardata" set new_el [lreplace $new_el 3 3 $chdata] set els [lindex $new_el 2] if {$els == {}} { set new_el [lreplace $new_el 4 4 "[lindex $new_el 4]$chardata"] } else { set els [lindex $new_el 2] set last_el [lindex $els end] set last_el [lreplace $last_el 5 5 "[lindex $last_el 5]$chardata"] set els [lreplace $els end end $last_el] set new_el [lreplace $new_el 2 2 $els] } set wrapper($id,stack) [lreplace $wrapper($id,stack) 0 0 $new_el] } ###################################################################### # # Called when there's an error with parsing XML. # proc wrapper:xmlerror {id args} { variable wrapper if {[lsearch $wrapper(list) $id] == -1} { return -code error -errorinfo "No such wrapper: \"$id\"" } LOG "XML Parsing Error: $args" uplevel #0 $wrapper($id,streamendcmd) } ###################################################################### proc wrapper:xmlcrypt {text} { return [string map {& & < < > > \" " ' ' \x00 " " \x01 " " \x02 " " \x03 " " \x04 " " \x05 " " \x06 " " \x07 " " \x08 " " \x0B " " \x0C " " \x0E " " \x0F " " \x10 " " \x11 " " \x12 " " \x13 " " \x14 " " \x15 " " \x16 " " \x17 " " \x18 " " \x19 " " \x1A " " \x1B " " \x1C " " \x1D " " \x1E " " \x1F " "} $text] } ###################################################################### # # This procedure converts (and returns) $xmldata to raw-XML # proc wrapper:createxml {xmldata args} { set xmlns jabber:client set prettyprint 0 set level 0 foreach {opt val} $args { switch -- $opt { -xmlns { set xmlns $val } -level { set level $val } -prettyprint { set prettyprint $val } default { return -code error "Bad option \"$opt\":\ must be one of -xmlns, -level or -prettyprint" } } } set retext "" set tagname [lindex $xmldata 0] set vars [lindex $xmldata 1] set subtags [lindex $xmldata 2] set chdata [lindex $xmldata 3] if {$prettyprint && ($level > 0)} { append retext [string repeat \t $level] } append retext "<$tagname" foreach {attr value} $vars { if {$attr == "xmlns"} { if {$value == $xmlns} { continue } else { set xmlns $value } } append retext " $attr='[wrapper:xmlcrypt $value]'" } set no_chdata [expr {$chdata == ""}] if {$no_chdata && [llength $subtags] == 0} { append retext "/>" if {$prettyprint} { append retext \n } return $retext } append retext ">" if {!$no_chdata} { append retext [wrapper:xmlcrypt $chdata] } elseif {$prettyprint} { append retext \n } foreach subdata $subtags { append retext [wrapper:createxml $subdata -xmlns $xmlns \ -prettyprint $prettyprint -level [expr {$level + 1}]] } if {$prettyprint && $no_chdata && ($level > 0)} { append retext [string repeat \t $level] } append retext "" if {$prettyprint && ($level > 0)} { append retext \n } return $retext } ###################################################################### # # This proc creates (and returns) xmldata of tag $tagname, # with the parameters given. # # Parameters: # -empty 0|1 Is this an empty tag? If $chdata # and $subtags are empty, then whether # to make the tag empty or not is decided # here. (default: 1) # # -vars {attr1 value1 attr2 value2 ..} Vars is a list # consisting of attr/value pairs, as shown. # # -chdata $chdata ChData of tag (default: ""), if you use # this attr multiple times, new chdata will # be appended to old one. # # -subtags $subchilds $subchilds is a list containing xmldatas # of $tagname's subtags. (default: no sub-tags) # proc wrapper:createtag {tagname args} { set isempty 1 set vars "" set chdata "" set subtags "" foreach {attr val} $args { switch -- $attr { -empty {set isempty $val} -vars {set vars $val} -chdata {set chdata $chdata$val} -subtags {set subtags $val} } } set retext [list $tagname $vars $subtags $chdata "" ""] return $retext } ###################################################################### # # This proc returns the value of $attr from varlist # proc wrapper:getattr {varlist attrname} { foreach {attr val} $varlist { if {$attr == $attrname} {return $val} } return "" } ###################################################################### # # This proc returns 1, or 0, depending on the attr exists in varlist or not # proc wrapper:isattr {varlist attrname} { foreach {attr val} $varlist { if {$attr == $attrname} {return 1} } return 0 } ###################################################################### # # This proc splits the xmldata to 5 different variables. # proc wrapper:splitxml {xmldata vtag vvars visempty vchdata vchildren} { set tag [lindex $xmldata 0] set vars [lindex $xmldata 1] set children [lindex $xmldata 2] set chdata [lindex $xmldata 3] uplevel 1 "set [list $vtag] [list $tag] \n \ set [list $vvars] [list $vars] \n \ set [list $visempty] 0 \n \ set [list $vchdata] [list $chdata] \n \ set [list $vchildren] [list $children]" } proc wrapper:get_subchdata {xmldata} { lindex $xmldata 4 } proc wrapper:get_fchdata {xmldata} { lindex $xmldata 5 } ###################################################################### # # This proc returns stream header # proc wrapper:streamheader {to args} { set to [wrapper:xmlcrypt $to] set xmlns_stream [wrapper:xmlcrypt "http://etherx.jabber.org/streams"] set xmlns [wrapper:xmlcrypt "jabber:client"] set lang "" set version "" foreach {opt val} $args { switch -- $opt { -xmlns:stream { set xmlns_stream [wrapper:xmlcrypt $val] } -xmlns { set xmlns [wrapper:xmlcrypt $val] } -xml:lang { set lang " xml:lang='[wrapper:xmlcrypt $val]'" } -version { set version " version='$val'" } } } return "" } ###################################################################### # # This proc returns stream trailer # proc wrapper:streamtrailer {} { return "" } # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/jabberlib/namespaces.tcl0000644000175000017500000000374211011554251017262 0ustar sergeisergei# namespaces.tcl -- # # This file is part of the jabberlib. It lists Jabber # namespaces registered by JSF. # # Copyright (c) 2005 Sergei Golovan # # $Id: namespaces.tcl 1408 2008-05-11 11:29:45Z sergei $ ########################################################################## package provide namespaces 1.0 ########################################################################## namespace eval :: { array set NS [list \ stream "http://etherx.jabber.org/streams" \ tls "urn:ietf:params:xml:ns:xmpp-tls" \ sasl "urn:ietf:params:xml:ns:xmpp-sasl" \ bind "urn:ietf:params:xml:ns:xmpp-bind" \ session "urn:ietf:params:xml:ns:xmpp-session" \ iq-auth "http://jabber.org/features/iq-auth" \ iq-register "http://jabber.org/features/iq-register" \ fcompress "http://jabber.org/features/compress" \ compress "http://jabber.org/protocol/compress" \ component "jabber:component:accept" \ auth "jabber:iq:auth" \ register "jabber:iq:register" \ roster "jabber:iq:roster" \ signed "jabber:x:signed" \ encrypted "jabber:x:encrypted" \ iqavatar "jabber:iq:avatar" \ xavatar "jabber:x:avatar" \ xconference "jabber:x:conference" \ data "jabber:x:data" \ event "jabber:x:event" \ xroster "jabber:x:roster" \ rosterx "http://jabber.org/protocol/rosterx" \ chatstate "http://jabber.org/protocol/chatstates" \ commands "http://jabber.org/protocol/commands" \ privacy "jabber:iq:privacy" \ private "jabber:iq:private" \ delimiter "roster:delimiter" \ bookmarks "storage:bookmarks" \ tkabber:groups "tkabber:bookmarks:groups" \ pubsub "http://jabber.org/protocol/pubsub" \ pubsub#owner "http://jabber.org/protocol/pubsub#owner" \ disco#publish "http://jabber.org/protocol/disco#publish" \ challenge "urn:xmpp:tmp:challenge" \ media-element "urn:xmpp:tmp:media-element" ] } ########################################################################## tkabber-0.11.1/jabberlib/https.tcl0000644000175000017500000003321311043403452016302 0ustar sergeisergei# https.tcl -- # # Package for using the HTTP CONNECT (it is a common method for # tunnelling HTTPS traffic, so the name is https) method for # connecting TCP sockets. Only client side. # # Copyright (c) 2007 Sergei Golovan # # This source file is distributed under the BSD license. # # $Id: https.tcl 1478 2008-07-28 17:51:38Z sergei $ package require base64 package require ntlm 1.0 package require autoconnect 0.2 package provide autoconnect::https 1.0 namespace eval https { namespace export connect variable debug 0 autoconnect::register https [namespace current]::connect } # https::connect -- # # Negotiates with a HTTPS proxy server. # # Arguments: # sock: an open socket token to the proxy server # addr: the peer address, not the proxy server # port: the peer port number # args: # -command tclProc {status socket} # -username userid # -password password # -useragent useragent # -timeout millisecs (default 60000) # # Results: # The connect socket or error if no -command, else empty string. # # Side effects: # Socket is prepared for data transfer. # If -command specified, the callback tclProc is called with # status OK and socket or ERROR and error message. proc https::connect {sock addr port args} { variable auth set token [namespace current]::$sock variable $token upvar 0 $token state Debug 2 "https::connect token=$token, sock=$sock, addr=$addr,\ port=$port, args=$args" array set state { -command "" -timeout 60000 -username "" -password "" -useragent "" async 0 status "" } array set state [list \ addr $addr \ port $port \ sock $sock] array set state $args if {[string length $state(-command)]} { set state(async) 1 } if {[catch {set state(peer) [fconfigure $sock -peername]}]} { catch {close $sock} if {$state(async)} { after idle [list $state(-command) ERROR network-failure] Free $token return } else { Free $token return -code error network-failure } } PutsConnectQuery $token fileevent $sock readable \ [list [namespace current]::Readable $token] # Setup timeout timer. set state(timeoutid) \ [after $state(-timeout) [namespace current]::Timeout $token] if {$state(async)} { return } else { # We should not return from this proc until finished! vwait $token\(status) set status $state(status) set sock $state(sock) Free $token if {[string equal $status OK]} { return $sock } else { catch {close $sock} return -code error $sock } } } # https::Readable -- # # Receive the first reply from a proxy and either finish the # negotiations or prepare to autorization process at the proxy. # # Arguments: # token A connection token. # # Result: # An empty string. # # Side effects: # The negotiation is finished or the next turn is started. proc https::Readable {token} { variable $token upvar 0 $token state Debug 2 "https::Readable token=$token" fileevent $state(sock) readable {} set code [ReadProxyAnswer $token] if {$code >= 200 && $code < 300} { # Success while {[string length [gets $state(sock)]]} {} Finish $token } elseif {$code != 407} { # Failure Finish $token $state(result) } else { # Authorization required set content_length -1 set method basic while {[string length [set header [gets $state(sock)]]]} { switch -- [HttpHeaderName $header] { proxy-authenticate { if {[string equal -length 4 [HttpHeaderBody $header] "NTLM"]} { set method ntlm } } content-length { set content_length [HttpHeaderBody $header] } } } ReadProxyJunk $token $content_length close $state(sock) set state(sock) \ [socket -async [lindex $state(peer) 0] [lindex $state(peer) 2]] fileevent $state(sock) writable \ [list [namespace current]::Authorize $token $method] } return } # https::Authorize -- # # Start the authorization procedure. # # Arguments: # token A connection token. # method (basic or ntlm) authorization method. # # Result: # Empty string. # # Side effects: # Authorization is started. proc https::Authorize {token method} { variable $token upvar 0 $token state Debug 2 "https::Authorize token=$token, method=$method" fileevent $state(sock) writable {} switch -- $method { ntlm { AuthorizeNtlmStep1 $token } default { AuthorizeBasicStep1 $token } } return } # https::AuthorizeBasicStep1 -- # # The first step of basic authorization procedure: send authorization # credentials to a socket. # # Arguments: # token A connection token. # # Result: # Empty string. # # Side effects: # Authorization info is sent to a socket. proc https::AuthorizeBasicStep1 {token} { variable $token upvar 0 $token state Debug 2 "https::AuthorizeBasicStep1 token=$token" set auth \ [string map {\n {}} \ [base64::encode \ [encoding convertto "$state(-username):$state(-password)"]]] PutsConnectQuery $token "Basic $auth" fileevent $state(sock) readable \ [list [namespace current]::AuthorizeBasicStep2 $token] return } # https::AuthorizeBasicStep2 -- # # The second step of basic authorization procedure: receive and # analyze server reply. # # Arguments: # token A connection token. # # Result: # Empty string. # # Side effects: # Server reply is received from a socket. proc https::AuthorizeBasicStep2 {token} { variable $token upvar 0 $token state Debug 2 "https::AuthorizeBasicStep2 token=$token" fileevent $state(sock) readable {} set code [ReadProxyAnswer $token] if {$code >= 200 && $code < 300} { # Success while {[string length [gets $state(sock)]]} { } Finish $token } else { # Failure Finish $token $state(result) } return } # https::AuthorizeNtlmStep1 -- # # The first step of NTLM authorization procedure: send NTLM # message 1 to a socket. # # Arguments: # token A connection token. # # Result: # Empty string. # # Side effects: # Authorization info is sent to a socket. proc https::AuthorizeNtlmStep1 {token} { variable $token upvar 0 $token state Debug 2 "https::AuthorizeNtlmStep1 token=$token" set domain "" set host [info hostname] # if username is domain/username or domain\username # then set domain and username set username $state(-username) regexp {(\w+)[\\/](.*)} $username -> domain username set ntlmtok [NTLM::new -domain $domain \ -host $host \ -username $username \ -password $state(-password)] set message1 [$ntlmtok type1Message] set state(ntlmtok) $ntlmtok PutsConnectQuery $token "NTLM $message1" fileevent $state(sock) readable \ [list [namespace current]::AuthorizeNtlmStep2 $token] return } # https::AuthorizeNtlmStep2 -- # # The first step of basic authorization procedure: send authorization # credentials to a socket. # # Arguments: # token A connection token. # # Result: # Empty string. # # Side effects: # Authorization info is sent to a socket. proc https::AuthorizeNtlmStep2 {token} { variable $token upvar 0 $token state Debug 2 "https::AuthorizeNtlmStep2 token=$token" fileevent $state(sock) readable {} set code [ReadProxyAnswer $token] if {$code >= 200 && $code < 300} { # Success while {[string length [gets $state(sock)]]} { } Finish $token return } elseif {$code != 407} { # Failure Finish $token $state(result) return } set content_length -1 set message2 "" while {![string equal [set header [gets $state(sock)]] ""]} { switch -- [HttpHeaderName $header] { proxy-authenticate { set body [HttpHeaderBody $header] if {[string equal -length 5 $body "NTLM "]} { set message2 [string trim [string range $body 5 end]] } } content-length { set content_length [HttpHeaderBody $header] } } } ReadProxyJunk $token $content_length $state(ntlmtok) parseType2Message -message $message2 set message3 [$state(ntlmtok) type3Message] $state(ntlmtok) free PutsConnectQuery $token "NTLM $message3" fileevent $state(sock) readable \ [list [namespace current]::AuthorizeNtlmStep3 $token] return } # https::AuthorizeNtlmStep3 -- # # The third step of NTLM authorization procedure: receive and # analyze server reply. # # Arguments: # token A connection token. # # Result: # Empty string. # # Side effects: # Server reply is received from a socket. proc https::AuthorizeNtlmStep3 {token} { variable $token upvar 0 $token state Debug 2 "https::AuthorizeNtlmStep3 token=$token" fileevent $state(sock) readable {} set code [ReadProxyAnswer $token] if {$code >= 200 && $code < 300} { # Success while {[string length [gets $state(sock)]]} { } Finish $token } else { # Failure Finish $token $state(result) } return } # https::PutsConnectQuery -- # # Sends CONNECT query to a proxy server. # # Arguments: # token A connection token. # auth (optional) A proxy authorization string. # # Result: # Empty string. # # Side effects: # Some info is sent to a proxy. proc https::PutsConnectQuery {token {auth ""}} { variable $token upvar 0 $token state Debug 2 "https::PutsConnectQuery token=$token auth=$auth" fconfigure $state(sock) -buffering line -translation auto puts $state(sock) "CONNECT $state(addr):$state(port) HTTP/1.1" puts $state(sock) "Proxy-Connection: keep-alive" if {[string length $state(-useragent)]} { puts $state(sock) "User-Agent: $state(-useragent)" } if {[string length $auth]} { puts $state(sock) "Proxy-Authorization: $auth" } puts $state(sock) "" return } # https::ReadProxyAnswer -- # # Reads the first line of a proxy answer with a result code. # # Arguments: # token A connection token. # # Result: # The HTTP result code. # # Side effects: # Status line is read form a socket. # Variable state(result) is set to a just read line. proc https::ReadProxyAnswer {token} { variable $token upvar 0 $token state Debug 2 "https::ReadProxyAnswer token=$token" fconfigure $state(sock) -buffering line -translation auto set state(result) [gets $state(sock)] set code [lindex [split $state(result) { }] 1] if {[string is integer -strict $code]} { return $code } else { # Invalid code return 0 } } # https::ReadProxyJunk -- # # Reads the body part of a proxy answer. # # Arguments: # token A connection token. # # Result: # Empty string. # # Side effects: # Some info is read from a socket and discarded. proc https::ReadProxyJunk {token length} { variable $token upvar 0 $token state Debug 2 "https::ReadProxyJunk token=$token, length=$length" fconfigure $state(sock) -buffering none -translation binary if {$length != -1} { read $state(sock) $length } else { read $state(sock) } return } # https::HttpHeaderName -- # # Returns HTTP header name (converted to lowercase). # # Arguments: # header A HTTP header. # # Result: # A header name. # # Side effects # None. proc https::HttpHeaderName {header} { set hlist [split $header ":"] return [string tolower [lindex $hlist 0]] } # https::HttpHeaderBody -- # # Returns HTTP header body. # # Arguments: # header A HTTP header. # # Result: # A header body. # # Side effects # None. proc https::HttpHeaderBody {header} { set hlist [split $header ":"] set body [join [lrange $hlist 1 end] ":"] return [string trim $body] } # https::Timeout -- # # This proc is called in case of timeout. # # Arguments: # token A connection token. # # Result: # An empty string. # # Side effects: # A proxy negotiation is finished with error. proc https::Timeout {token} { Finish $token timeout return } # https::Free -- # # Frees a connection token. # # Arguments: # token A connection token. # # Result: # An empty string. # # Side effects: # A connection token and its state informationa are destroyed. proc https::Free {token} { variable $token upvar 0 $token state catch {after cancel $state(timeoutid)} catch {unset state} return } # https::Finish -- # # Finishes a negotiation process. # # Arguments: # token A connection token. # errormsg (optional) error message. # # Result: # An empty string. # # Side effects: # If connection is asynchronous then a callback is executed. # Otherwise state(status) is set to allow https::connect to return # with either success or error. proc https::Finish {token {errormsg ""}} { variable $token upvar 0 $token state Debug 2 "https::Finish token=$token, errormsg=$errormsg" catch {after cancel $state(timeoutid)} if {$state(async)} { if {[string length $errormsg]} { catch {close $state(sock)} uplevel #0 $state(-command) [list ERROR $errormsg] } else { uplevel #0 $state(-command) [list OK $state(sock)] } Free $token } else { if {[string length $errormsg]} { catch {close $state(sock)} set state(sock) $errormsg set state(status) ERROR } else { set state(status) OK } } return } # https::Debug -- # # Prints debug information. # # Arguments: # num A debug level. # str A debug message. # # Result: # An empty string. # # Side effects: # A debug message is printed to the console if the value of # https::debug variable is not less than num. proc https::Debug {num str} { variable debug if {$num <= $debug} { puts $str } return } # Test if {0} { set s [socket 192.168.0.1 3128] set t [https::connect $s google.com 443] puts $t close $t set s [socket 192.168.0.1 3128] set t [https::connect $s google.com 80] puts $t close $t } # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/jabberlib/socks5.tcl0000644000175000017500000006127010710423253016354 0ustar sergeisergei# socks5.tcl --- # # Package for using the SOCKS5 method for connecting TCP sockets. # Some code plus idee from Kerem 'Waster_' HADIMLI. # Made from RFC 1928. # # Copyright (c) 2000 Kerem 'Waster_' HADIMLI (minor parts) # Copyright (c) 2003-2007 Mats Bengtsson # Modifications Copyright (c) 2007 Sergei Golovan # # This source file is distributed under the BSD license. # # $Id: socks5.tcl 1282 2007-10-26 17:40:59Z sergei $ # # TODO: GSSAPI authentication which is a MUST is missing. # Only CMD CONNECT implemented. # Do not report English text in callback but rather error keys like # rsp_notallowed etc. Client done, server to go. package require autoconnect 0.2 package provide autoconnect::socks5 1.0 namespace eval socks5 { namespace export connect # Constants: # ver: Socks version # nomatchingmethod: No matching methods # cmd_connect: Connect command # rsv: Reserved # atyp_*: Address type # auth_*: Authorication version variable const array set const { ver \x05 auth_no \x00 auth_gssapi \x01 auth_userpass \x02 nomatchingmethod \xFF cmd_connect \x01 cmd_bind \x02 rsv \x00 atyp_ipv4 \x01 atyp_domainname \x03 atyp_ipv6 \x04 rsp_succeeded \x00 rsp_failure \x01 rsp_notallowed \x02 rsp_netunreachable \x03 rsp_hostunreachable \x04 rsp_refused \x05 rsp_expired \x06 rsp_cmdunsupported \x07 rsp_addrunsupported \x08 } # Practical when mapping errors to error codes. variable iconst array set iconst { 0 rsp_succeeded 1 rsp_failure 2 rsp_notallowed 3 rsp_netunreachable 4 rsp_hostunreachable 5 rsp_refused 6 rsp_expired 7 rsp_cmdunsupported 8 rsp_addrunsupported } variable ipv4_num_re {([0-9]{1,3}\.){3}[0-9]{1,3}} variable ipv6_num_re {([0-9a-fA-F]{4}:){7}[0-9a-fA-F]{4}} variable msg array set msg { 1 "General SOCKS server failure" 2 "Connection not allowed by ruleset" 3 "Network unreachable" 4 "Host unreachable" 5 "Connection refused" 6 "TTL expired" 7 "Command not supported" 8 "Address type not supported" } variable debug 0 autoconnect::register socks5 [namespace current]::connect } # socks5::connect -- # # Negotiates with a SOCKS server. # # Arguments: # sock: an open socket token to the SOCKS server # addr: the peer address, not SOCKS server # port: the peer's port number # args: # -command tclProc {status socket} # -username username # -password password # -timeout millisecs (default 60000) # # Results: # The connect socket or error if no -command, else empty string. # # Side effects: # Socket is prepared for data transfer. # If -command specified, the callback tclProc is called with # status OK and socket or ERROR and error message. proc socks5::connect {sock addr port args} { variable msg variable const Debug 2 "socks5::init $addr $port $args" # Initialize the state variable, an array. We'll return the # name of this array as the token for the transaction. set token [namespace current]::$sock variable $token upvar 0 $token state array set state { -password "" -timeout 60000 -username "" async 0 auth 0 bnd_addr "" bnd_port "" state "" status "" } array set state [list \ addr $addr \ port $port \ sock $sock] array set state $args if {[string length $state(-username)] || \ [string length $state(-password)]} { set state(auth) 1 } if {[info exists state(-command)] && [string length $state(-command)]} { set state(async) 1 } if {$state(auth)} { set methods "$const(auth_no)$const(auth_userpass)" } else { set methods "$const(auth_no)" } set nmethods [binary format c [string length $methods]] fconfigure $sock -translation {binary binary} -blocking 0 fileevent $sock writable {} Debug 2 "\tsend: ver nmethods methods" # Request authorization methods if {[catch { puts -nonewline $sock "$const(ver)$nmethods$methods" flush $sock } err]} { catch {close $sock} if {$state(async)} { after idle [list $state(-command) ERROR network-failure] Free $token return } else { Free $token return -code error $err } } # Setup timeout timer. set state(timeoutid) \ [after $state(-timeout) [namespace current]::Timeout $token] fileevent $sock readable \ [list [namespace current]::ResponseMethod $token] if {$state(async)} { return } else { # We should not return from this proc until finished! vwait $token\(status) set status $state(status) set sock $state(sock) Free $token if {[string equal $status OK]} { return $sock } else { catch {close $sock} return -code error $sock } } } # socks5::ResponseMethod -- # # Receive the reply from a proxy and choose authorization method. # # Arguments: # token A connection token. # # Result: # An empty string. # # Side effects: # The negotiation is finished with error or continues with chosen # method. proc socks5::ResponseMethod {token} { variable $token variable const upvar 0 $token state Debug 2 "socks5::ResponseMethod" set sock $state(sock) if {[catch {read $sock 2} data] || [eof $sock]} { Finish $token network-failure return } set serv_ver "" set method $const(nomatchingmethod) binary scan $data cc serv_ver smethod Debug 2 "\tserv_ver=$serv_ver, smethod=$smethod" if {![string equal $serv_ver 5]} { Finish $token err_version return } if {[string equal $smethod 0]} { # Now, request address and port. Request $token } elseif {[string equal $smethod 2]} { # User/Pass authorization required if {$state(auth) == 0} { Finish $token err_authorization_required return } # Username & Password length (binary 1 byte) set ulen [binary format c [string length $state(-username)]] set plen [binary format c [string length $state(-password)]] Debug 2 "\tsend: auth_userpass ulen -username plen -password" if {[catch { puts -nonewline $sock \ "$const(auth_userpass)$ulen$state(-username)$plen$state(-password)" flush $sock } err]} { Finish $token network-failure return } fileevent $sock readable \ [list [namespace current]::ResponseAuth $token] } else { Finish $token err_unsupported_method } return } # socks5::ResponseAuth -- # # Receive the authorization reply from a proxy. # # Arguments: # token A connection token. # # Result: # An empty string. # # Side effects: # The negotiation is finished with error or continues with address and # port request. proc socks5::ResponseAuth {token} { variable $token upvar 0 $token state Debug 2 "socks5::ResponseAuth" set sock $state(sock) if {[catch {read $sock 2} data] || [eof $sock]} { Finish $token network-failure return } set auth_ver -1 set status -1 binary scan $data cc auth_ver status Debug 2 "\tauth_ver=$auth_ver, status=$status" if {![string equal $auth_ver 1]} { Finish $token err_authentication_unsupported return } if {![string equal $status 0]} { Finish $token err_authorization return } # Now, request address and port. Request $token return } # socks5::Request -- # # Request connect to specified address and port. # # Arguments: # token A connection token. # # Result: # An empty string. # # Side effects: # The negotiation is finished with error or continues with address and # port request. proc socks5::Request {token} { variable $token variable const variable ipv4_num_re variable ipv6_num_re upvar 0 $token state Debug 2 "socks5::Request" set sock $state(sock) # Network byte-ordered port (2 binary-bytes, short) set bport [binary format S $state(port)] # Figure out type of address given to us. if {[regexp $ipv4_num_re $state(addr)]} { Debug 2 "\tipv4" # IPv4 numerical address. set atyp_addr_port $const(atyp_ipv4) foreach i [split $state(addr) .] { append atyp_addr_port [binary format c $i] } append atyp_addr_port $bport } elseif {[regexp $ipv6_num_re $state(addr)]} { # todo } else { Debug 2 "\tdomainname" # Domain name. # Domain length (binary 1 byte) set dlen [binary format c [string length $state(addr)]] set atyp_addr_port \ "$const(atyp_domainname)$dlen$state(addr)$bport" } # We send request for connect Debug 2 "\tsend: ver cmd_connect rsv atyp_domainname dlen addr port" set aconst "$const(ver)$const(cmd_connect)$const(rsv)" if {[catch { puts -nonewline $sock "$aconst$atyp_addr_port" flush $sock } err]} { Finish $token network-failure return } fileevent $sock readable \ [list [namespace current]::Response $token] return } # socks5::Response -- # # Receive the final reply from a proxy and finish the negotiations. # # Arguments: # token A connection token. # # Result: # An empty string. # # Side effects: # The negotiation is finished with either success or error. proc socks5::Response {token} { variable $token upvar 0 $token state variable iconst Debug 2 "socks5::Response" set sock $state(sock) fileevent $sock readable {} # Start by reading ver+cmd+rsv. if {[catch {read $sock 3} data] || [eof $sock]} { Finish $token network-failure return } set serv_ver "" set rep "" binary scan $data ccc serv_ver rep rsv if {![string equal $serv_ver 5]} { Finish $token err_version return } if {$rep == 0} { # OK } elseif {[info exists iconst($rep)]} { Finish $token $iconst($rep) return } else { Finish $token err_unknown return } # Now parse the variable length atyp+addr+host. if {[catch {ParseAtypAddr $token addr port} err]} { Finish $token $err return } # Store in our state array. set state(bnd_addr) $addr set state(bnd_port) $port # And finally let the client know that the bytestream is set up. Finish $token return } # socks5::ParseAtypAddr -- # # Receive and parse destination address type and IP or name. # # Arguments: # token A connection token. # addrVar A variable for destination address. # portVar A variable for destination port. # # Result: # An empty string or error if address and port can't be parsed. # # Side effects: # The address type and IP or name is read from the socket. proc socks5::ParseAtypAddr {token addrVar portVar} { variable $token variable const upvar 0 $token state upvar $addrVar addr upvar $portVar port Debug 2 "socks5::ParseAtypAddr" set sock $state(sock) # Start by reading atyp. if {[catch {read $sock 1} data] || [eof $sock]} { return -code error network-failure } set atyp "" binary scan $data c atyp Debug 2 "\tatyp=$atyp" # Treat the three address types in order. switch -- $atyp { 1 { if {[catch {read $sock 6} data] || [eof $sock]} { return -code error network-failure } binary scan $data ccccS i0 i1 i2 i3 port set addr "" foreach n [list $i0 $i1 $i2 $i3] { # Translate to unsigned! append addr [expr ( $n + 0x100 ) % 0x100] if {$n <= 2} { append addr . } } # Translate to unsigned! set port [expr ( $port + 0x10000 ) % 0x10000] } 3 { if {[catch {read $sock 1} data] || [eof $sock]} { return -code error network-failure } binary scan $data c len Debug 2 "\tlen=$len" set len [expr ( $len + 0x100 ) % 0x100] if {[catch {read $sock $len} data] || [eof $sock]} { return -code error network-failure } set addr $data Debug 2 "\taddr=$addr" if {[catch {read $sock 2} data] || [eof $sock]} { return -code error network-failure } binary scan $data S port # Translate to unsigned! set port [expr ( $port + 0x10000 ) % 0x10000] Debug 2 "\tport=$port" } 4 { # todo } default { return -code error err_unknown_address_type } } } proc socks5::GetIpAndPort {token} { variable $token upvar 0 $token state return [list $state(bnd_addr) $state(bnd_port)] } # socks5::Timeout -- # # This proc is called in case of timeout. # # Arguments: # token A connection token. # # Result: # An empty string. # # Side effects: # A proxy negotiation is finished with error. proc socks5::Timeout {token} { Finish $token timeout return } # socks5::Free -- # # Frees a connection token. # # Arguments: # token A connection token. # # Result: # An empty string. # # Side effects: # A connection token and its state informationa are destroyed. proc socks5::Free {token} { variable $token upvar 0 $token state catch {after cancel $state(timeoutid)} catch {unset state} } # socks5::Finish -- # # Finishes a negotiation process. # # Arguments: # token A connection token. # errormsg (optional) error message. # # Result: # An empty string. # # Side effects: # If connection is asynchronous then a callback is executed. # Otherwise state(status) is set to allow https::connect to return # with either success or error. proc socks5::Finish {token {errormsg ""}} { variable $token upvar 0 $token state Debug 2 "socks5::Finish errormsg=$errormsg" catch {after cancel $state(timeoutid)} if {$state(async)} { # In case of asynchronous connection we do the cleanup. if {[string length $errormsg]} { catch {close $state(sock)} uplevel #0 $state(-command) [list ERROR $errormsg] } else { uplevel #0 $state(-command) [list OK $state(sock)] } Free $token } else { # Otherwise we trigger state(status). if {[string length $errormsg]} { catch {close $state(sock)} set state(sock) $errormsg set state(status) ERROR } else { set state(status) OK } } return } # socks5::serverinit -- # # The SOCKS5 server. Negotiates with a SOCKS5 client. # Sets up bytestreams between client and DST. # # Arguments: # sock: socket connected to the servers socket # ip: ip address # port: it's port number # command: tclProc for callabcks {token type args} # args: # -blocksize bytes # -bytestream boolean # -opendstsocket boolean # -timeout millisecs # # Results: # token. proc socks5::serverinit {sock ip port command args} { variable msg variable const Debug 2 "socks5::serverinit" # Initialize the state variable, an array. We'll return the # name of this array as the token for the transaction. set token [namespace current]::$sock variable $token upvar 0 $token state array set state { -blocksize 8192 -bytestream 1 -opendstsocket 1 -timeout 60000 auth 0 state "" status "" } array set state [list \ command $command \ sock $sock] array set state $args fconfigure $sock -translation {binary binary} -blocking 0 fileevent $sock writable {} # Start by reading the method stuff. if {[catch {read $sock 2} data] || [eof $sock]} { serv_finish $token network-failure return } set ver "" set method $const(nomatchingmethod) binary scan $data cc ver nmethods set nmethods [expr ( $nmethods + 0x100 ) % 0x100] Debug 2 "\tver=$ver, nmethods=$nmethods" # Error checking. Must have either noauth or userpasswdauth. if {![string equal $ver 5]} { serv_finish $token "Socks server isn't version 5!" return } for {set i 0} {$i < $nmethods} {incr i} { if {[catch {read $sock 1} data] || [eof $sock]} { serv_finish $token network-failure return } binary scan $data c method set method [expr ( $method + 0x100 ) % 0x100] Debug 2 "\tmethod=$method" if {[string equal $method 0]} { set noauthmethod 1 } elseif {[string equal $method 2]} { set userpasswdmethod 1 } } set isok 1 if {[info exists userpasswdmethod]} { set ans "$const(ver)$const(auth_userpass)" set state(auth) 1 } elseif {[info exists noauthmethod]} { set ans "$const(ver)$const(auth_no)" } else { set ans "$const(ver)$const(nomatchingmethod)" set isok 0 } Debug 2 "\tsend: ver method" if {[catch { puts -nonewline $sock $ans flush $sock } err]} { serv_finish $token $err return } if {!$isok} { serv_finish $token "Unrecognized method requested by client" return } if {$state(auth)} { fileevent $sock readable \ [list [namespace current]::serv_auth $token] } else { fileevent $sock readable \ [list [namespace current]::serv_request $token] } return $token } proc socks5::serv_auth {token} { variable $token variable const upvar 0 $token state Debug 2 "socks5::serv_auth" set sock $state(sock) fileevent $sock readable {} if {[catch {read $sock 2} data] || [eof $sock]} { serv_finish $token network-failure return } set auth_ver "" set method $const(nomatchingmethod) binary scan $data cc auth_ver ulen set ulen [expr ( $ulen + 0x100 ) % 0x100] Debug 2 "\tauth_ver=$auth_ver, ulen=$ulen" if {![string equal $auth_ver 2]} { serv_finish $token "Wrong authorization method" return } if {[catch {read $sock $ulen} data] || [eof $sock]} { return -code error network-failure } set state(username) $data Debug 2 "\tusername=$data" if {[catch {read $sock 1} data] || [eof $sock]} { serv_finish $token network-failure return } binary scan $data c plen set plen [expr ( $plen + 0x100 ) % 0x100] Debug 2 "\tplen=$plen" if {[catch {read $sock $plen} data] || [eof $sock]} { serv_finish $token network-failure return } set state(password) $data Debug 2 "\tpassword=$data" set ans [uplevel #0 $state(command) [list $token authorize \ -username $state(username) -password $state(password)]] if {!$ans} { catch { puts -nonewline $state(sock) "\x00\x01" } serv_finish $token notauthorized return } # Write auth response. if {[catch { puts -nonewline $sock "\x01\x00" flush $sock } err]} { serv_finish $token $err return } fileevent $sock readable \ [list [namespace current]::serv_request $token] } proc socks5::serv_request {token} { variable $token variable const variable msg variable ipv4_num_re variable ipv6_num_re upvar 0 $token state Debug 2 "socks5::serv_request" set sock $state(sock) # Start by reading ver+cmd+rsv. if {[catch {read $sock 3} data] || [eof $sock]} { serv_finish $token network-failure return } set ver "" set cmd "" set rsv "" binary scan $data ccc ver cmd rsv Debug 2 "\tver=$ver, cmd=$cmd, rsv=$rsv" if {![string equal $ver 5]} { serv_finish $token "Socks server isn't version 5!" return } if {![string equal $cmd 1]} { serv_finish $token "Unsuported CMD, must be CONNECT" return } # Now parse the variable length atyp+addr+host. if {[catch {ParseAtypAddr $token addr port} err]} { serv_finish $token $err return } # Store in our state array. set state(dst_addr) $addr set state(dst_port) $port # Init the SOCKS connection to dst if wanted. Else??? if {$state(-opendstsocket)} { if {[catch {socket -async $addr $port} sock_dst]} { serv_finish $token network-failure return } set state(sock_dst) $sock_dst # Setup timeout timer. set state(timeoutid) \ [after $state(-timeout) [namespace current]::ServTimeout $token] fileevent $sock_dst writable \ [list [namespace current]::serv_dst_connect $token] } else { # ??? uplevel #0 $state(command) [list $token reply] } } proc socks5::serv_dst_connect {token} { variable $token upvar 0 $token state Debug 2 "socks5::serv_dst_connect" fileevent $state(sock_dst) writable {} after cancel $state(timeoutid) set sock_dst $state(sock_dst) if {[eof $sock_dst]} { serv_finish $token network-failure return } if {[catch { fconfigure $sock_dst -translation {binary binary} -blocking 0 foreach {bnd_ip bnd_addr bnd_port} [fconfigure $sock_dst -sockname] \ break } err]} { Debug 2 "\tfconfigure failed: $err" serv_finish $token network-failure return } array set state [list bnd_ip $bnd_ip bnd_addr $bnd_addr bnd_port $bnd_port] serv_reply $token } proc socks5::serv_reply {token} { variable $token variable const upvar 0 $token state Debug 2 "socks5:serv_reply" set sock $state(sock) set bnd_addr $state(bnd_addr) set bnd_port $state(bnd_port) Debug 2 "\tbnd_addr=$bnd_addr, bnd_port=$bnd_port" set aconst "$const(ver)$const(rsp_succeeded)$const(rsv)" # Domain length (binary 1 byte) set dlen [binary format c [string length $bnd_addr]] # Network byte-ordered port (2 binary-bytes, short) set bport [binary format S $bnd_port] set atyp_addr_port \ "$const(atyp_domainname)$dlen$bnd_addr$bport" # We send SOCKS server's reply to client. Debug 2 "\tsend: ver rep rsv atyp_domainname dlen bnd_addr bnd_port" if {[catch { puts -nonewline $sock "$aconst$atyp_addr_port" flush $sock } err]} { serv_finish $token $err return } # New we are ready to stream data if wanted. if {$state(-bytestream)} { establish_bytestreams $token } else { # ??? serv_finish $token } } proc socks5::establish_bytestreams {token} { variable $token upvar 0 $token state Debug 2 "socks5::establish_bytestreams" set sock $state(sock) set sock_dst $state(sock_dst) # Forward client stream to dst. fileevent $sock readable \ [list [namespace current]::read_stream $token $sock $sock_dst] # Forward dst stream to client. fileevent $sock_dst readable \ [list [namespace current]::read_stream $token $sock_dst $sock] } proc socks5::read_stream {token in out} { variable $token upvar 0 $token state set primary [string equal $state(sock) $in] Debug 3 "::socks5::read_stream primary=$primary: in=$in, out=$out" # If any of client (sock) or dst (sock_dst) closes down we shall # close down everthing. # Only client or dst can determine if a close down is premature. if {[catch {eof $in} iseof] || $iseof} { serv_finish $token } elseif {[catch {eof $out} iseof] || $iseof} { serv_finish $token } elseif {[catch {read $in} data]} { serv_finish $token network-failure } else { # We could wait here (in the event loop) for channel to be writable # to avoid any blocking... # BUT, this would keep $data in memory for a while which is a bad idee. if {0} { fileevent $out writable \ [list [namespace current]::stream_writeable $token $primary] vwait $token\(writetrigger${primary}) } if {[catch {puts -nonewline $out $data; flush $out}]} { serv_finish $token network-failure } } } proc socks5::stream_writeable {token primary} { variable $token upvar 0 $token state incr state(writetrigger${primary}) } proc socks5::serv_finish {token {errormsg ""}} { variable $token upvar 0 $token state Debug 2 "socks5::serv_finish" if {$state(-bytestream)} { catch {close $state(sock)} catch {close $state(sock_dst)} } if {[string length $errormsg]} { uplevel #0 $state(command) [list $token $errormsg] } else { uplevel #0 $state(command) [list $token ok] } unset state } # Just a trigger for vwait. proc socks5::readable {token} { variable $token upvar 0 $token state incr state(trigger) } proc socks5::ServTimeout {token} { variable $token upvar 0 $token state serv_finish $token timeout } proc socks5::Debug {num str} { variable debug if {$num <= $debug} { puts $str } } # Test code... if {0} { # Server proc serv_cmd {token status} { puts "server: token=$token, status=$status" switch -- $status { ok { } authorize { # Here we should check that the username and password is ok. return 1 } default { puts "error $status" } } } proc server_connect {sock ip port} { fileevent $sock readable \ [list socks5::serverinit $sock $ip $port serv_cmd] } socket -server server_connect 1080 } if {0} { # Client proc cb {status socket} { puts "client: status=$status, socket=$socket" if {$status eq "OK"} { fconfigure $socket -buffering none close $socket } } proc dump {} { puts "dump:" } set s [socket 192.168.0.1 1080] #socks5::connect $s jabber.ru 5222 -command cb socks5::connect $s jabber.ru 5222 -command cb -username xxx -password xxx } tkabber-0.11.1/jabberlib/streamerror.tcl0000644000175000017500000000650010701637340017511 0ustar sergeisergei# $Id: streamerror.tcl 1244 2007-10-06 07:53:04Z sergei $ # ########################################################################## package provide streamerror 1.0 ########################################################################## namespace eval streamerror { variable NS set NS(streams) "urn:ietf:params:xml:ns:xmpp-streams" foreach {cond message} \ [list \ bad-format [::msgcat::mc "Bad Format"] \ bad-namespace-prefix [::msgcat::mc "Bad Namespace Prefix"] \ conflict [::msgcat::mc "Conflict"] \ connection-timeout [::msgcat::mc "Connection Timeout"] \ host-gone [::msgcat::mc "Host Gone"] \ host-unknown [::msgcat::mc "Host Unknown"] \ improper-addressing [::msgcat::mc "Improper Addressing"] \ internal-server-error [::msgcat::mc "Internal Server Error"] \ invalid-from [::msgcat::mc "Invalid From"] \ invalid-id [::msgcat::mc "Invalid ID"] \ invalid-namespace [::msgcat::mc "Invalid Namespace"] \ invalid-xml [::msgcat::mc "Invalid XML"] \ not-authorized [::msgcat::mc "Not Authorized"] \ policy-violation [::msgcat::mc "Policy Violation"] \ remote-connection-failed [::msgcat::mc "Remote Connection Failed"] \ resource-constraint [::msgcat::mc "Resource Constraint"] \ restricted-xml [::msgcat::mc "Restricted XML"] \ see-other-host [::msgcat::mc "See Other Host"] \ system-shutdown [::msgcat::mc "System Shutdown"] \ undefined-condition [::msgcat::mc "Undefined Condition"] \ unsupported-encoding [::msgcat::mc "Unsupported Encoding"] \ unsupported-stanza-type [::msgcat::mc "Unsupported Stanza Type"] \ unsupported-version [::msgcat::mc "Unsupported Version"] \ xml-not-well-formed [::msgcat::mc "XML Not Well-Formed"]] \ { set streamerror_desc($cond) $message } } ########################################################################## proc streamerror::condition {error} { return [lindex [cond_msg $error] 0] } ########################################################################## proc streamerror::message {error} { return [lindex [cond_msg $error] 1] } ########################################################################## proc streamerror::cond_msg {error} { variable NS variable streamerror_desc jlib::wrapper:splitxml $error tag1 vars1 isempty1 chdata1 children1 if {[llength $children1] == 0} { # Legacy error if {$chdata1 != ""} { set chdata1 " ($chdata1)" } return [list legacy \ [format [::msgcat::mc "Stream Error%s%s"] $chdata1 ""]] } else { # XMPP error set condition undefined-condition set description "" set textdescription "" foreach errelem $children1 { jlib::wrapper:splitxml $errelem tag vars isempty chdata children set xmlns [jlib::wrapper:getattr $vars xmlns] set cond $tag switch -- $cond { text { if {$xmlns == $NS(streams)} { set textdescription ": $chdata" } } undefined-condition { # TODO } default { if {[info exists streamerror_desc($cond)]} { set condition $cond set description " ($streamerror_desc($cond))" } } } } return [list $condition \ [format [::msgcat::mc "Stream Error%s%s"] \ $description $textdescription]] } } ########################################################################## tkabber-0.11.1/jabberlib/stanzaerror.tcl0000644000175000017500000001716411015004476017523 0ustar sergeisergei# $Id: stanzaerror.tcl 1442 2008-05-21 11:36:30Z sergei $ # ########################################################################## package provide stanzaerror 1.0 ########################################################################## namespace eval stanzaerror { variable NS set NS(stanzas) "urn:ietf:params:xml:ns:xmpp-stanzas" array set error_type [list \ auth [::msgcat::mc "Authentication Error"] \ cancel [::msgcat::mc "Unrecoverable Error"] \ continue [::msgcat::mc "Warning"] \ modify [::msgcat::mc "Request Error"] \ wait [::msgcat::mc "Temporary Error"]] set defined_error_conditions {} # Code is zero iff the condition isn't mentioned in XEP-0086 foreach {clist lcode type cond description} [list \ {400} 400 modify bad-request [::msgcat::mc "Bad Request"] \ {409} 409 cancel conflict [::msgcat::mc "Conflict"] \ {501} 501 cancel feature-not-implemented [::msgcat::mc "Feature Not Implemented"] \ {403} 403 auth forbidden [::msgcat::mc "Forbidden"] \ {302} 302 modify gone [::msgcat::mc "Gone"] \ {500} 500 wait internal-server-error [::msgcat::mc "Internal Server Error"] \ {404} 404 cancel item-not-found [::msgcat::mc "Item Not Found"] \ {} 400 modify jid-malformed [::msgcat::mc "JID Malformed"] \ {406} 406 modify not-acceptable [::msgcat::mc "Not Acceptable"] \ {405} 405 cancel not-allowed [::msgcat::mc "Not Allowed"] \ {401} 401 auth not-authorized [::msgcat::mc "Not Authorized"] \ {402} 402 auth payment-required [::msgcat::mc "Payment Required"] \ {} 404 wait recipient-unavailable [::msgcat::mc "Recipient Unavailable"] \ {} 302 modify redirect [::msgcat::mc "Redirect"] \ {407} 407 auth registration-required [::msgcat::mc "Registration Required"] \ {} 404 cancel remote-server-not-found [::msgcat::mc "Remote Server Not Found"] \ {408 504} 504 wait remote-server-timeout [::msgcat::mc "Remote Server Timeout"] \ {} 500 wait resource-constraint [::msgcat::mc "Resource Constraint"] \ {502 503 510} 503 cancel service-unavailable [::msgcat::mc "Service Unavailable"] \ {} 407 auth subscription-required [::msgcat::mc "Subscription Required"] \ {} 500 any undefined-condition [::msgcat::mc "Undefined Condition"] \ {} 400 wait unexpected-request [::msgcat::mc "Unexpected Request"]] \ { lappend defined_error_conditions $cond set error_description($type,$cond) $description # XEP-0086 foreach code $clist { set error_type_descelem($code) [list $type $cond] } set legacy_error_codes($cond) $lcode } # Error messages from jabberd 1.4 # [::msgcat::mc "Access Error"] # [::msgcat::mc "Address Error"] # [::msgcat::mc "Application Error"] # [::msgcat::mc "Format Error"] # [::msgcat::mc "Not Found"] # [::msgcat::mc "Not Implemented"] # [::msgcat::mc "Recipient Error"] # [::msgcat::mc "Remote Server Error"] # [::msgcat::mc "Request Timeout"] # [::msgcat::mc "Server Error"] # [::msgcat::mc "Unauthorized"] # [::msgcat::mc "Username Not Available"] } ########################################################################## proc stanzaerror::register_errortype {type description} { variable error_type set error_type($type) $description } ########################################################################## proc stanzaerror::register_error {lcode type cond description} { variable defined_error_conditions variable error_description variable error_type_descelem lappend defined_error_conditions $cond set error_description($type,$cond) $description set legacy_error_codes($cond) $lcode } ########################################################################## proc stanzaerror::error_to_list {errmsg} { variable NS variable error_type variable defined_error_conditions variable error_description variable error_type_descelem if {$errmsg == [::msgcat::mc "Disconnected"]} { return [list none none [::msgcat::mc "Disconnected"]] } lassign $errmsg code desc if {[string is integer $code]} { if {[info exists error_type_descelem($code)]} { lassign $error_type_descelem($code) type descelem } else { lassign {none none} type descelem } return [list $type $descelem "$code ([::msgcat::mc $desc])"] } else { set type $code set errelem $desc set condition "undefined-condition" set description "" set textdescription "" jlib::wrapper:splitxml $errelem tag vars isempty chdata children foreach child $children { jlib::wrapper:splitxml $child tag1 vars1 isempty1 chdata1 children1 set xmlns [jlib::wrapper:getattr $vars1 xmlns] set cond $tag1 switch -- $cond { text { if {$xmlns == $NS(stanzas)} { set textdescription ": $chdata1" } } undefined-condition { # TODO set description $error_description(any,undefined-condition) } default { if {[lsearch -exact $defined_error_conditions $cond] >= 0} { set condition $cond if {[info exists error_description($type,$cond)] && \ ($description == "")} { set description $error_description($type,$cond) } } else { # TODO } } } } if {[info exists error_type($type)]} { set typedesc $error_type($type) } set res "" if {$description != ""} { set res $description } if {[info exists typedesc] && $typedesc != ""} { if {$res == ""} { set res $typedesc } else { set res "$typedesc ($res)" } } return [list $type $condition "$res$textdescription"] } } ########################################################################## proc stanzaerror::error {type condition args} { return [eval {xmpp_error $type $condition} $args] } ########################################################################## proc stanzaerror::legacy_error {type condition args} { variable NS variable legacy_error_codes variable error_description if {[info exists legacy_error_codes($condition)] && \ $legacy_error_codes($condition)} { set code $legacy_error_codes($condition) } else { set code 501 } if {[info exists error_description($type,$condition)]} { set description $error_description($type,$condition) } else { set description "" } set xml "" foreach {opt val} $args { switch -- $opt { -xml { set xml $val } -text { set description $val } } } set err [jlib::wrapper:createtag error \ -vars [list code $code] \ -chdata $description] if {$xml == ""} { return [list $err] } else { return [list $xml $err] } } ########################################################################## proc stanzaerror::xmpp_error {type condition args} { variable NS variable legacy_error_codes set subtags [list [jlib::wrapper:createtag $condition \ -vars [list xmlns $NS(stanzas)]]] set xml "" foreach {opt val} $args { switch -- $opt { -xml { set xml $val } -text { lappend subtags [jlib::wrapper:createtag text \ -vars [list xmlns $NS(stanzas)] \ -chdata $val] } -application-specific { lappend subtags $val } } } set vars [list type $type] if {[info exists legacy_error_codes($condition)] && \ $legacy_error_codes($condition)} { lappend vars code $legacy_error_codes($condition) } set err [jlib::wrapper:createtag error \ -vars $vars \ -subtags $subtags] if {$xml == ""} { return [list $err] } else { return [list $xml $err] } } ########################################################################## tkabber-0.11.1/jabberlib/pkgIndex.tcl0000644000175000017500000000223610710423253016713 0ustar sergeisergeipackage ifneeded jabberlib 0.10.1 [list source [file join $dir jabberlib.tcl]] package ifneeded namespaces 1.0 [list source [file join $dir namespaces.tcl]] package ifneeded jlibauth 1.0 [list source [file join $dir jlibauth.tcl]] package ifneeded jlibsasl 1.0 [list source [file join $dir jlibsasl.tcl]] package ifneeded jlibtls 1.0 [list source [file join $dir jlibtls.tcl]] package ifneeded jlibcompress 1.0 [list source [file join $dir jlibcompress.tcl]] package ifneeded streamerror 1.0 [list source [file join $dir streamerror.tcl]] package ifneeded stanzaerror 1.0 [list source [file join $dir stanzaerror.tcl]] package ifneeded jlibdns 1.0 [list source [file join $dir jlibdns.tcl]] package ifneeded idna 1.0 [list source [file join $dir idna.tcl]] package ifneeded ntlm 1.0 [list source [file join $dir ntlm.tcl]] package ifneeded autoconnect 0.2 [list source [file join $dir autoconnect.tcl]] package ifneeded autoconnect::socks4 1.0 [list source [file join $dir socks4.tcl]] package ifneeded autoconnect::socks5 1.0 [list source [file join $dir socks5.tcl]] package ifneeded autoconnect::https 1.0 [list source [file join $dir https.tcl]] # don't forget to define ::LOG tkabber-0.11.1/jabberlib/jabberlib.tcl0000644000175000017500000013402011066760706017067 0ustar sergeisergei###################################################################### # # $Header$ # # This is JabberLib (abbreviated jlib), the Tcl library for # use in making Jabber clients. # # # Variables used in JabberLib : # roster(users) : Users currently in roster # # roster(group,$username) : Groups $username is in. # # roster(name,$username) : Name of $username. # # roster(subsc,$username) : Subscription of $username # ("to" | "from" | "both" | "") # # roster(ask,$username) : "Ask" of $username # ("subscribe" | "unsubscribe" | "") # # lib(wrap) : Wrap ID # # lib(sck) : SocketName # # lib(sckstats) : Socket status, "on" or "off" # # lib(disconnect) : disconnect procedure # # iq(num) : Next iq id-number. Sent in # "id" attributes of packets. # # iq($id) : Callback to run when result packet # of $id is received. # # ###################################################################### # # Procedures defined in this library # if {0} { proc jlib::connect {sck server} proc jlib::disconnect {} proc jlib::got_stream {vars} proc jlib::end_of_parse {} proc jlib::outmsg {msg} proc jlib::inmsg {} proc jlib::clear_vars {} proc jlib::clear_iqs {} proc jlib::parse {xmldata} proc jlib::parse_send_auth {cmd type data} proc jlib::parse_send_create {cmd type data} proc jlib::parse_roster_get {connid ispush cmd type data} proc jlib::parse_roster_set {item cmd groups name type data} proc jlib::parse_roster_del {item cmd type data} proc jlib::send_iq {type xmldata args} proc jlib::send_auth {user pass res cmd} proc jlib::send_create {user pass name mail cmd} proc jlib::send_msg {to args} proc jlib::send_presence {args} proc jlib::roster_get {args} proc jlib::roster_set {item args} proc jlib::roster_del {item args} proc ::LOG text proc jlib::noop args } if {[catch {package present tdom}]} { package require -exact xml 2.0 } package require sha1 package require msgcat package require namespaces 1.0 package require streamerror 1.0 package require stanzaerror 1.0 package require idna 1.0 package require jlibauth 1.0 package require jlibdns 1.0 package require autoconnect 0.2 catch {package require autoconnect::https 1.0} catch {package require autoconnect::socks5 1.0} catch {package require autoconnect::socks4 1.0} ###################################################################### namespace eval jlib { # Load XML:Wrapper source [file join [file dirname [info script]] wrapper.tcl] set lib(capabilities,auth) {non_sasl} # Load connection transports source [file join [file dirname [info script]] transports.tcl] catch { package require jlibtls 1.0 } catch { package require jlibcompress 1.0 } if {![catch { package require jlibsasl 1.0 }]} { lappend lib(capabilities,auth) sasl } set lib(connections) {} set lib(connid) 0 set iq(num) 1 # Export procedures. # namespace export \ wrapper:splitxml wrapper:createtag \ wrapper:createxml wrapper:xmlcrypt \ wrapper:isattr wrapper:getattr } ###################################################################### proc jlib::capabilities {type} { variable lib set res {} switch -- $type { proxy { set res [autoconnect::proxies] } transport { set res [transport::capabilities] } auth { set res $lib(capabilities,$type) } } return $res } ###################################################################### # TODO register callbacks in jlib::new proc jlib::client {callback args} { uplevel #0 [list client:$callback] $args } ###################################################################### proc jlib::new {args} { variable lib variable connjid variable connhist foreach {attr val} $args { switch -- $attr { -user {set user $val} -server {set server $val} -resource {set resource $val} } } if {![info exists user] || ![info exists server] || \ ![info exists resource]} { return -code error "Usage: jlib::new -user username\ -server servername -resource resourcename" } set jid $user@$server/$resource if {[info exists connhist($jid)]} { set connid $connhist($jid) if {[lsearch -exact $lib(connections) $connid] >= 0} { set connid [incr lib(connid)] } } else { set connid [incr lib(connid)] set connhist($jid) $connid } set connjid($connid,user) $user set connjid($connid,server) $server set connjid($connid,resource) $resource ::LOG "(jlib::new) JID:'$jid' ConnectionID:'$connid'" return $connid } ###################################################################### proc jlib::connect {connid args} { variable lib variable connjid set user $connjid($connid,user) set server $connjid($connid,server) set resource $connjid($connid,resource) set transport tcp set host $server set port 5222 set hosts {} set xmlns jabber:client set use_sasl 0 set allow_auth_plain 0 set allow_google_token 1 set use_starttls 0 set use_compression 0 set cacertstore "" set certfile "" set keyfile "" foreach {attr val} $args { switch -- $attr { -password {set password $val} -transport {set transport $val} -host {set host $val} -hosts {set hosts $val} -port {set port $val} -xmlns {set xmlns $val} -usesasl {set use_sasl $val} -allowauthplain {set allow_auth_plain $val} -allowgoogletoken {set allow_google_token $val} -usestarttls {set use_starttls $val} -usecompression {set use_compression $val} -cacertstore {set cacertstore $val} -certfile {set certfile $val} -keyfile {set keyfile $val} } } if {$hosts == {}} { set hosts [list [list [idna::domain_toascii $host] $port]] } ::LOG "(jlib::connect) Server:'$server' ConnectionID:'$connid'" # TODO: do not change autoconnect options on every login. eval autoconnect::configure $args foreach hp $hosts { if {[catch { eval [list transport::${transport}::connect \ $connid \ [lindex $hp 0] \ [lindex $hp 1]] $args } sock]} { set error 1 } else { set lib($connid,sck) $sock set error 0 break } } if {$error} { ::LOG "error (jlib::connect) Can't connect to the server: $sock" return -code error $sock } set lib($connid,xmlns) $xmlns set lib($connid,password) $password set lib($connid,transport) $transport add_connection_route $connid $server set lib($connid,disconnect) reconnect set lib($connid,parse_end) 0 set lib($connid,use_sasl) $use_sasl set lib($connid,allow_auth_plain) $allow_auth_plain set lib($connid,allow_google_token) $allow_google_token set lib($connid,use_starttls) $use_starttls set lib($connid,use_compression) $use_compression set lib($connid,cacertstore) $cacertstore set lib($connid,certfile) $certfile set lib($connid,keyfile) $keyfile set lib($connid,disconnecting) 0 set lib($connid,bytes_counter) 0 catch { unset lib($connid,features) } set lib($connid,version) 0.0 set lib($connid,wrap) \ [wrapper:new [list [namespace current]::got_stream $connid] \ [list [namespace current]::end_of_parse $connid] \ [list [namespace current]::parse $connid]] set lib($connid,authtoken) \ [::jlibauth::new $connid -username $user \ -server $server \ -resource $resource \ -password $password \ -allow_plain $allow_auth_plain] if {[info commands ::jlibtls::new] != ""} { set lib($connid,tlstoken) \ [::jlibtls::new $connid -certfile $certfile \ -cacertstore $cacertstore \ -keyfile $keyfile] } if {[info commands ::jlibcompress::new] != ""} { set lib($connid,compresstoken) \ [::jlibcompress::new $connid] } if {[info commands ::jlibsasl::new] != ""} { set lib($connid,sasltoken) \ [::jlibsasl::new $connid -username $user \ -server $server \ -resource $resource \ -password $password \ -allow_plain $allow_auth_plain \ -allow_google_token $allow_google_token] } set params [list -xmlns $xmlns -xml:lang [get_lang]] if {$use_sasl || $use_starttls || $use_compression} { lappend params -version "1.0" } lappend lib(connections) $connid eval [list start_stream $server -connection $connid] $params return $connid } ###################################################################### proc jlib::socket_ip {connid} { variable lib if {[info exists lib($connid,sck)] && \ ![catch {fconfigure $lib($connid,sck) -sockname} sock]} { return [lindex $sock 0] } else { return "" } } ###################################################################### proc jlib::reset {connid} { variable lib wrapper:reset $lib($connid,wrap) catch { unset lib($connid,features) } catch { unset lib($connid,sessionid) } } ###################################################################### proc jlib::login {connid cmd} { ::LOG "(jlib::login) $connid" wait_for_stream $connid \ [list [namespace current]::login_aux $connid $cmd] } proc jlib::login_aux {connid cmd} { variable lib ::LOG "(jlib::login_aux) $connid" if {$lib($connid,use_starttls)} { $lib($connid,tlstoken) starttls \ -command [list [namespace current]::login_aux2 $connid $cmd] } else { login_aux1 $connid $cmd } } proc jlib::login_aux1 {connid cmd} { variable lib ::LOG "(jlib::login_aux1) $connid" if {$lib($connid,use_compression)} { $lib($connid,compresstoken) start \ -command [list [namespace current]::login_aux2 $connid $cmd] } else { login_aux3 $connid $cmd } } proc jlib::login_aux2 {connid cmd res xmldata} { ::LOG "(jlib::login_aux2) $connid" if {$res == "ERR"} { login_aux5 $connid $cmd $res $xmldata } else { login_aux3 $connid $cmd } } proc jlib::login_aux3 {connid cmd} { variable lib ::LOG "(jlib::login_aux3) $connid" if {$lib($connid,use_sasl)} { $lib($connid,sasltoken) auth \ -command [list [namespace current]::login_aux5 $connid $cmd] } else { wait_for_stream $connid \ [list [namespace current]::login_aux4 $connid $cmd] } } proc jlib::login_aux4 {connid cmd} { variable lib ::LOG "(jlib::login_aux4) $connid" $lib($connid,authtoken) auth \ -command [list [namespace current]::login_aux5 $connid $cmd] \ -sessionid $lib($connid,sessionid) } proc jlib::login_aux5 {connid cmd res xmldata} { ::LOG "(jlib::login_aux5) $connid" after idle [list uplevel #0 $cmd [list $res $xmldata]] } ######################################################################## proc jlib::disconnect {connid} { variable lib ::LOG "(jlib::disconnect) $connid" set idx [lsearch -exact $lib(connections) $connid] if {$idx < 0} continue set lib(connections) [lreplace $lib(connections) $idx $idx] if {!$lib($connid,disconnecting)} { set lib($connid,disconnecting) 1 finish_stream -connection $connid catch { transport::$lib($connid,transport)::disconnect $connid transport::$lib($connid,transport)::close $connid } } clear_vars $connid if {$lib(connections) == {}} { clear_iqs } } ###################################################################### proc jlib::emergency_disconnect {connid} { variable lib ::LOG "(jlib::emergency_disconnect) $connid" if {[lsearch -exact $lib(connections) $connid] < 0} return set lib($connid,disconnecting) 1 catch { transport::$lib($connid,transport)::close $connid } client $lib($connid,disconnect) $connid } ###################################################################### proc jlib::got_stream {connid vars} { variable lib set version [jlib::wrapper:getattr $vars version] if {($lib($connid,use_starttls) || $lib($connid,use_sasl) || \ $lib($connid,use_compression)) && \ [string is double -strict $version] && ($version >= 1.0)} { set lib($connid,version) $version } set sessionid [jlib::wrapper:getattr $vars id] ::LOG "(jlib::got_stream $connid)\ Session ID = $sessionid, Version = $lib($connid,version)" if {$version < 1.0} { # Register iq-register and iq-auth namespaces to allow # register and auth when using non-XMPP server parse_stream_features $connid \ [list [wrapper:createtag register \ -vars [list xmlns $::NS(iq-register)]] \ [wrapper:createtag auth \ -vars [list xmlns $::NS(iq-auth)]]] } set lib($connid,sessionid) $sessionid set lib($connid,bytes_counter) 0 } ###################################################################### proc jlib::wait_for_stream {connid cmd} { variable lib ::LOG "(jlib::wait_for_stream $connid)" if {[info exists lib($connid,sessionid)]} { uplevel #0 $cmd } else { # Must be careful so this is not triggered by a reset or something... trace variable [namespace current]::lib($connid,sessionid) w \ [list [namespace current]::wait_for_stream_aux $connid $cmd] } } proc jlib::wait_for_stream_aux {connid cmd name1 name2 op} { variable lib trace vdelete [namespace current]::lib($connid,sessionid) w \ [list [namespace current]::wait_for_stream_aux $connid $cmd] uplevel #0 $cmd } ###################################################################### proc jlib::end_of_parse {connid} { after idle [list [namespace current]::end_of_parse1 $connid] } proc jlib::end_of_parse1 {connid} { variable lib ::LOG "(jlib::end_of_parse $connid)" set lib($connid,parse_end) 1 if {$lib(connections) == {}} { ::LOG "error (jlib::end_of_parse) No connection" return -1 # Already disconnected } if {!$lib($connid,disconnecting)} { after idle [list [namespace current]::emergency_disconnect $connid] } } ###################################################################### proc jlib::outmsg {msg args} { variable lib foreach {attr val} $args { switch -- $attr { -connection {set connid $val} } } if {![info exists connid]} { ::LOG "error (jlib::outmsg) -connection is mandatory" return -1 } if {[lsearch -exact $lib(connections) $connid] < 0} { ::LOG "error (jlib::outmsg) Connection $connid doesn't exist" return -1 } if {$lib($connid,disconnecting)} { ::LOG "error (jlib::outmsg) Message while disconnecting..." return -1 } ::LOG "(jlib::outmsg) ($connid) '$msg'" ::LOG_OUTPUT $connid $msg return [transport::$lib($connid,transport)::outmsg $connid $msg] } ###################################################################### proc jlib::start_stream {to args} { variable lib foreach {attr val} $args { switch -- $attr { -connection {set connid $val} } } if {![info exists connid]} { ::LOG "error (jlib::start_stream) -connection is mandatory" return -1 } if {[lsearch -exact $lib(connections) $connid] < 0} { ::LOG "error (jlib::start_stream) Connection $connid doesn't exist" return -1 } if {$lib($connid,disconnecting)} { ::LOG "error (jlib::start_stream) Message while disconnecting..." return -1 } set msg [eval [list wrapper:streamheader $to] $args] ::LOG "(jlib::start_stream) ($connid) '$msg'" ::LOG_OUTPUT $connid $msg return [eval [list transport::$lib($connid,transport)::start_stream \ $connid $to] $args] } ###################################################################### proc jlib::finish_stream {args} { variable lib foreach {attr val} $args { switch -- $attr { -connection {set connid $val} } } if {![info exists connid]} { ::LOG "error (jlib::finish_stream) -connection is mandatory" return -1 } if {[lsearch -exact $lib(connections) $connid] < 0} { ::LOG "error (jlib::finish_stream) Connection $connid doesn't exist" return -1 } if {$lib($connid,disconnecting)} { ::LOG "error (jlib::finish_stream) Message while disconnecting..." return -1 } set msg [wrapper:streamtrailer] ::LOG "(jlib::finish_stream) ($connid) '$msg'" ::LOG_OUTPUT $connid $msg return [eval [list transport::$lib($connid,transport)::finish_stream \ $connid] $args] } ###################################################################### proc jlib::inmsg {connid msg eof} { variable lib if {[lsearch -exact $lib(connections) $connid] < 0} { ::LOG "error (jlib::inmsg) Connection $connid doesn't exist" return -1 } incr lib($connid,bytes_counter) [string bytelength $msg] ::LOG "(jlib::inmsg) ($connid) '$msg'" ::LOG_INPUT $connid $msg wrapper:parser $lib($connid,wrap) parse $msg if {!$lib($connid,parse_end) && $eof} { transport::$lib($connid,transport)::close $connid if {$lib($connid,disconnecting)} { ::LOG "(jlib::inmsg) Socket is closed by server. Disconnecting..." } else { ::LOG "error (jlib::inmsg) Socket is closed by server. Disconnecting..." after idle [list [namespace current]::emergency_disconnect $connid] } } } ###################################################################### proc jlib::clear_vars {connid} { # # unset all the variables # variable roster variable pres variable lib if {![info exists lib($connid,wrap)]} return wrapper:free $lib($connid,wrap) if {[info exists lib($connid,tlstoken)]} { $lib($connid,tlstoken) free } if {[info exists lib($connid,compresstoken)]} { $lib($connid,compresstoken) free } if {[info exists lib($connid,sasltoken)]} { $lib($connid,sasltoken) free } $lib($connid,authtoken) free array unset lib $connid,* set lib($connid,disconnect) reconnect } ###################################################################### proc jlib::clear_iqs {} { variable iq array unset iq presence,* foreach id [array names iq] { if {$id != "num"} { set cmd $iq($id) unset iq($id) uplevel #0 $cmd [list DISCONNECT [::msgcat::mc "Disconnected"]] } } set iq(num) 1 } ###################################################################### proc jlib::connections {} { variable lib return $lib(connections) } proc jlib::connection_jid {connid} { variable lib variable connjid if {[info exists lib($connid,sasltoken)]} { set username [$lib($connid,sasltoken) cget -username] set server [$lib($connid,sasltoken) cget -server] set resource [$lib($connid,sasltoken) cget -resource] return $username@$server/$resource } else { return \ $connjid($connid,user)@$connjid($connid,server)/$connjid($connid,resource) } } proc jlib::connection_bare_jid {connid} { variable lib variable connjid if {[info exists lib($connid,sasltoken)]} { set username [$lib($connid,sasltoken) cget -username] set server [$lib($connid,sasltoken) cget -server] return $username@$server } else { return $connjid($connid,user)@$connjid($connid,server) } } proc jlib::connection_user {connid} { variable lib variable connjid if {[info exists lib($connid,sasltoken)]} { set username [$lib($connid,sasltoken) cget -username] return $username } else { return $connjid($connid,user) } } proc jlib::connection_server {connid} { variable lib variable connjid if {[info exists lib($connid,sasltoken)]} { set server [$lib($connid,sasltoken) cget -server] return $server } else { return $connjid($connid,server) } } proc jlib::connection_resource {connid} { variable lib variable connjid if {[info exists lib($connid,sasltoken)]} { set resource [$lib($connid,sasltoken) cget -resource] return $resource } else { return $connjid($connid,resource) } } ###################################################################### proc jlib::connection_requested_user {connid} { variable connjid return $connjid($connid,user) } proc jlib::connection_requested_server {connid} { variable connjid return $connjid($connid,server) } proc jlib::connection_requested_resource {connid} { variable connjid return $connjid($connid,resource) } ###################################################################### proc jlib::register_xmlns {connid xmlns callback} { variable lib set lib($connid,registered_xmlns,$xmlns) $callback } proc jlib::unregister_xmlns {connid xmlns} { variable lib catch {unset lib($connid,registered_xmlns,$xmlns)} } proc jlib::xmlns_is_registered {connid xmlns} { variable lib if {[info exists lib($connid,registered_xmlns,$xmlns)]} { return 1 } else { return 0 } } proc jlib::xmlns_callback {connid xmlns} { variable lib if {[info exists lib($connid,registered_xmlns,$xmlns)]} { return $lib($connid,registered_xmlns,$xmlns) } else { return "" } } ###################################################################### proc jlib::register_element {connid element callback} { variable lib set lib($connid,registered_element,$element) $callback } proc jlib::unregister_element {connid element} { variable lib catch {unset lib($connid,registered_element,$element)} } proc jlib::element_is_registered {connid element} { variable lib if {[info exists lib($connid,registered_element,$element)]} { return 1 } else { return 0 } } proc jlib::element_callback {connid element} { variable lib if {[info exists lib($connid,registered_element,$element)]} { return $lib($connid,registered_element,$element) } else { return "" } } ###################################################################### proc jlib::parse {connid xmldata} { variable lib set size 0 catch {set size $lib($connid,bytes_counter) } set lib($connid,bytes_counter) 0 after idle [list [namespace current]::parse1 $connid $xmldata] after idle [list ::LOG_INPUT_SIZE $connid $xmldata $size] } proc jlib::parse1 {connid xmldata} { variable global variable roster variable pres variable lib variable iq ::LOG "(jlib::parse) xmldata: '$xmldata'" ::LOG_INPUT_XML $connid $xmldata if {$lib(connections) == {}} { ::LOG "error (jlib::parse) No connection" return -1 } wrapper:splitxml $xmldata tag vars isempty chdata children if {[wrapper:isattr $vars from]} { set usefrom 1 set from [wrapper:getattr $vars from] } else { set usefrom 0 set from "" } set xmlns [wrapper:getattr $vars xmlns] if {[xmlns_is_registered $connid $xmlns]} { uplevel \#0 [xmlns_callback $connid $xmlns] [list $xmldata] return } if {[element_is_registered $connid $tag]} { uplevel \#0 [element_callback $connid $tag] [list $xmldata] return } if {[wrapper:isattr $vars xml:lang]} { set lang [wrapper:getattr $vars xml:lang] } else { set lang en } switch -- $tag { iq { set useid 0 set id "" set type [wrapper:getattr $vars type] if {[wrapper:isattr $vars id] == 1} { set useid 1 set id [wrapper:getattr $vars id] } if {$type != "result" && $type != "error" && $type != "get" && $type != "set"} { ::LOG "(error) iq: unknown type:'$type' id ($useid):'$id'" return } if {$type == "result"} { if {$useid == 0} { ::LOG "(error) iq:result: no id reference" return } if {[info exists iq($id)] == 0} { ::LOG "(error) iq:result: id doesn't exists in memory. Probably a re-replied iq" return } set cmd $iq($id) unset iq($id) uplevel \#0 $cmd [list OK [lindex $children 0]] } elseif {$type == "error"} { if {$useid == 0} { ::LOG "(error) iq:result: no id reference" return } if {[info exists iq($id)] == 0} { ::LOG "(error) iq:result: id doesn't exists in memory. Probably a re-replied iq." return } set cmd $iq($id) unset iq($id) set child "" foreach child $children { if {[lindex $child 0] == "error"} { break } set child "" } if {$child == ""} { set errcode "" set errtype "" set errmsg "" } else { set errcode [wrapper:getattr [lindex $child 1] code] set errtype [wrapper:getattr [lindex $child 1] type] set errmsg [lindex $child 3] } if {$errtype == ""} { uplevel #0 $cmd [list ERR [list $errcode $errmsg]] } else { uplevel #0 $cmd [list ERR [list $errtype $child]] } } elseif {$type == "get" || $type == "set"} { set child [lindex $children 0] if {$child == ""} { ::LOG "(error) iq:$type: Cannot find 'query' tag" return } # # Before calling the 'client:iqreply' procedure, we should check # the 'xmlns' attribute, to understand if this is some 'iq' that # should be handled inside jlib, such as a roster-push. # if {$type == "set" && \ [wrapper:getattr [lindex $child 1] xmlns] == $::NS(roster)} { if {$from != "" && \ !([string equal -nocase $from [connection_server $connid]] || \ [string equal -nocase $from [connection_bare_jid $connid]] || \ [string equal -nocase $from [connection_jid $connid]])} { send_iq error \ [stanzaerror::error cancel not-allowed -xml $child] \ -id [wrapper:getattr $vars id] \ -to $from \ -connection $connid return } # Found a roster-push ::LOG "(info) iq packet is roster-push. Handling internally" # First, we reply to the server, saying that, we # got the data, and accepted it. # if [wrapper:isattr $vars id] { send_iq result \ [wrapper:createtag query \ -vars [list xmlns $::NS(roster)]] \ -id [wrapper:getattr $vars id] \ -connection $connid } else { send_iq result \ [wrapper:createtag query \ -vars [list xmlns $::NS(roster)]] \ -connection $connid } # And then, we call the jlib::parse_roster_get, because this # data is the same as the one we get from a roster-get. parse_roster_get \ $connid 1 [namespace current]::noop OK $child return } client iqreply $connid $from $useid $id $type $lang $child } } message { set type [wrapper:getattr $vars type] set id [wrapper:getattr $vars id] set body "" set err [list "" ""] set is_subject 0 set subject "" set priority "" set thread "" set x "" foreach child $children { wrapper:splitxml $child ctag cvars cisempty cchdata cchildren switch -- $ctag { body {set body $cchdata} error { set errmsg $cchdata set errcode [wrapper:getattr $cvars code] set errtype [wrapper:getattr $cvars type] if {$errtype == ""} { set err [list $errcode $errmsg] } else { set err [list $errtype $child] } } subject { set is_subject 1 set subject $cchdata } priority {set priority $cchdata} thread {set thread $cchdata} default { if {[wrapper:getattr $cvars xmlns] != ""} { lappend x $child } } } } client message $connid $from $id $type $is_subject \ $subject $body $err $thread $priority $x } presence { set type [wrapper:getattr $vars type] set cmd "" set status "" set priority "" set meta "" set icon "" set show "" set loc "" set x "" set param "" if {[wrapper:isattr $vars id]} { set id [wrapper:getattr $vars id] if {[info exists iq(presence,$id)]} { set cmd $iq(presence,$id) unset iq(presence,$id) } lappend param -id $id } if {[wrapper:isattr $vars name]} { lappend param -name [wrapper:getattr $vars name] } foreach child $children { wrapper:splitxml $child ctag cvars cisempty cchdata cchildren switch -- $ctag { status { if {$type != "error"} { lappend param -status $cchdata } } priority {lappend param -priority $cchdata} meta {lappend param -meta $cchdata} icon {lappend param -icon $cchdata} show {lappend param -show $cchdata} loc {lappend param -loc $cchdata} error { if {$type == "error"} { set errcode [wrapper:getattr $cvars code] set errtype [wrapper:getattr $cvars type] if {$errtype == ""} { set err [list $errcode $cchdata] } else { set err [list $errtype $child] } lappend param -status [lindex [stanzaerror::error_to_list $err] 2] lappend param -error [lrange [stanzaerror::error_to_list $err] 0 1] } } default {lappend x $child} } } set cont "" if {$cmd != ""} { set cont \ [uplevel \#0 $cmd [list $connid $from $type $x] $param] } if {$cont != "break"} { eval [list client presence $connid $from $type $x] $param } } error { if {[wrapper:getattr $vars xmlns] == $::NS(stream)} { parse_stream_error $connid $xmldata } } features { if {[wrapper:getattr $vars xmlns] == $::NS(stream)} { parse_stream_features $connid $children } } } } ###################################################################### proc jlib::parse_send_create {cmd type data} { variable lib ::LOG "(jlib::parse_send_create) type:'$type'" if {$type == "ERR"} { ::LOG "error (jlib::parse_send_create) errtype:'[lindex $data 0]'" ::LOG "error (jlib::parse_send_create) errdesc:'[lindex $data 1]'" uplevel #0 $cmd [list ERR [lindex $data 1]] return } uplevel #0 $cmd [list OK {}] } ###################################################################### proc jlib::parse_roster_get {connid ispush cmd type data} { variable lib variable roster ::LOG "(jlib::parse_roster_get) ispush:'$ispush' type:'$type'" if {$type == "ERR"} { ::LOG "error (jlib::parse_roster_get) errtype:'[lindex $data 0]'" ::LOG "error (jlib::parse_roster_get) errdesc:'[lindex $data 1]'" uplevel #0 $cmd [list $connid ERR] return } if {!$ispush} { client status [::msgcat::mc "Got roster"] uplevel #0 $cmd [list $connid BEGIN_ROSTER] } wrapper:splitxml $data tag vars isempty chdata children if {![cequal [wrapper:getattr $vars xmlns] $::NS(roster)]} { ::LOG "warning (jlib::parse_roster_get) 'xmlns' attribute of\ query tag doesn't match '$::NS(roster)':\ '[wrapper:getattr $vars xmlns]" } foreach child $children { wrapper:splitxml $child ctag cvars cisempty cchdata cchildren switch -- $ctag { default { set groups "" set jid [wrapper:getattr $cvars jid] set name [wrapper:getattr $cvars name] set subsc [wrapper:getattr $cvars subscription] set ask [wrapper:getattr $cvars ask] foreach subchild $cchildren { wrapper:splitxml $subchild subtag tmp tmp subchdata tmp switch -- $subtag { group {lappend groups $subchdata} } } # Ok, collected information about item. # Now we can set our variables... # if {[lsearch $roster(users) $jid] == -1} { lappend roster(users) $jid } set roster(group,$jid) $groups set roster(name,$jid) $name set roster(subsc,$jid) $subsc set roster(ask,$jid) $ask add_connection_route $connid $jid # ...and call client procedures if $ispush { client roster_push $connid $jid $name $groups $subsc $ask } else { client roster_item $connid $jid $name $groups $subsc $ask } } } } if {!$ispush} { uplevel #0 $cmd [list $connid END_ROSTER] } } ###################################################################### proc jlib::parse_roster_set {item cmd groups name type data} { variable lib variable roster ::LOG "(jlib::parse_roster_set) item:'$item' type:'$type'" if {$type == "ERR"} { ::LOG "error (jlib::parse_roster_set) errtype:'[lindex $data 0]'" ::LOG "error (jlib::parse_roster_set) errdesc:'[lindex $data 1]'" uplevel #0 $cmd ERR return } if { [lsearch $roster(users) $item] == -1} { lappend roster(users) $item set roster(subsc,$item) "none" set roster(ask,$item) "" } set roster(group,$item) $groups set roster(name,$item) $name uplevel #0 $cmd OK } ###################################################################### proc jlib::parse_roster_del {item cmd type data} { variable lib variable roster ::LOG "(jlib::parse_roster_del) item:'$item' type:'$type'" if {$type == "ERR"} { ::LOG "error (jlib::parse_roster_set) errtype:'[lindex $data 0]'" ::LOG "error (jlib::parse_roster_set) errdesc:'[lindex $data 1]'" uplevel #0 $cmd ERR return } if {[set num [lsearch $roster(users) $item]] != -1} { set roster(users) [lreplace $roster(users) $num $num] catch {unset roster(group,$item) } catch {unset roster(name,$item) } catch {unset roster(subsc,$item) } catch {unset roster(ask,$item) } } else { ::LOG "warning (jlib::parse_roster_del) Item '$item' doesn't\ exist in roster for deletion." } uplevel #0 $cmd OK } ###################################################################### proc jlib::parse_stream_error {connid xmldata} { variable lib switch -- [streamerror::condition $xmldata] { bad-format - bad-namespace-prefix - connection-timeout - invalid-from - invalid-id - invalid-namespace - invalid-xml - remote-connection-failed - restricted-xml - unsupported-encoding - unsupported-stanza-type - xml-not-well-formed { set lib($connid,disconnect) reconnect } default { set lib($connid,disconnect) disconnect } } client errormsg [streamerror::message $xmldata] } ###################################################################### proc jlib::parse_stream_features {connid xmldata} { variable lib set features {} foreach child $xmldata { wrapper:splitxml $child tag vars isempty cdata children set xmlns [wrapper:getattr $vars xmlns] if {[xmlns_is_registered $connid $xmlns]} { lappend features $xmlns uplevel \#0 [xmlns_callback $connid $xmlns] [list $child] continue } switch -- $tag { register { lappend features register } } } set lib($connid,features) $features } ###################################################################### proc jlib::trace_stream_features {connid cmd} { variable lib if {[info exists lib($connid,features)]} { uplevel #0 $cmd } else { # Must be careful so this is not triggered by a reset or something... trace variable [namespace current]::lib($connid,features) w \ [list [namespace current]::trace_stream_features_aux $connid $cmd] } } proc jlib::trace_stream_features_aux {connid cmd name1 name2 op} { trace vdelete [namespace current]::lib($connid,features) w \ [list [namespace current]::trace_stream_features_aux $connid $cmd] uplevel #0 $cmd } ###################################################################### proc jlib::send_iq {type xmldata args} { variable lib variable iq ::LOG "(jlib::send_iq) type:'$type'" set useto 0 set useid 0 set to {} set id {} set cmd [namespace current]::noop set vars {} set timeout 0 foreach {attr val} $args { switch -- $attr { -from { lappend vars from $val } -to { set useto 1 ; set to $val } -id { set useid 1 ; set id $val } -command { set cmd $val } -timeout { if {$val > 0} { set timeout $val } } -connection { set connid $val } } } if {![info exists connid]} { return -code error "jlib::send_iq: -connection is mandatory" } if {[lsearch [connections] $connid] < 0} { ::LOG "error (jlib::send_iq) Connection $connid doesn't exist" if {$cmd != ""} { uplevel #0 $cmd [list DISCONNECT [::msgcat::mc "Disconnected"]] } return -1 } if {$type != "set" && $type != "result" && $type != "error"} { set type "get" } ::LOG "(jlib::send_iq) type:'$type' to ($useto):'$to' cmd:'$cmd' xmldata:'$xmldata'" # Temporary hack that allows to insert more than 1 subtag in error iqs if {($type != "error") && ($xmldata != "")} { set xmldata [list $xmldata] } if {$type == "get" || $type == "set"} { if {!$useid} { set id $iq(num) incr iq(num) } lappend vars id $id set iq($id) $cmd if {$timeout > 0} { after $timeout [list [namespace current]::iq_timeout $id] } } elseif {$useid} { lappend vars id $id } if {$useto == 1} { lappend vars to $to } lappend vars type $type xml:lang [get_lang] if {$xmldata != ""} { set data [wrapper:createtag iq -vars $vars -subtags $xmldata] } else { set data [wrapper:createtag iq -vars $vars] } set xml [wrapper:createxml $data] ::LOG_OUTPUT_XML $connid $data ::LOG_OUTPUT_SIZE $connid $data [string bytelength $xml] outmsg $xml -connection $connid } ###################################################################### proc jlib::iq_timeout {id} { variable iq ::LOG "(jlib::iq_timeout) id: $id" if {[info exists iq($id)]} { set cmd $iq($id) unset iq($id) uplevel #0 $cmd [list TIMEOUT [::msgcat::mc "Timeout"]] } } ###################################################################### proc jlib::route {jid} { variable lib if {[catch { set calling_routine [info level -1] }]} { set calling_routine none } if { $lib(connections) == {} } { ::LOG "error (jlib::route) No connection" return -1 } set user $jid regexp {([^/]*)/.*} $jid temp user set serv $user regexp {[^@]*@(.*)} $user temp serv set connid [lindex $lib(connections) 0] foreach dest [list $user $serv] { foreach c $lib(connections) { if {[info exists lib($c,route,$dest)]} { ::LOG "(jlib::route) $jid: $c \[$calling_routine\]" return $c } } } ::LOG "(jlib::route) $jid: $connid \[$calling_routine\]" return $connid } ###################################################################### proc jlib::add_connection_route {connid jid} { variable lib set lib($connid,route,$jid) 1 } ###################################################################### # TODO proc jlib::send_create {connid user pass name email cmd} { variable lib ::LOG "(jlib::send_create) username:'$user' password:'$pass' name:'$name' email:'$email'" if { $lib(connections) == {} } { ::LOG "error (jlib::send_create) No connection" return -1 } set data [wrapper:createtag query \ -vars [list xmlns $::NS(register)] \ -subtags [list \ [wrapper:createtag name -chdata $name] \ [wrapper:createtag email -chdata $email] \ [wrapper:createtag username -chdata $user] \ [wrapper:createtag password -chdata $pass]]] send_iq set $data \ -connection $connid \ -command [list [namespace current]::parse_send_create $cmd] } ###################################################################### proc jlib::send_msg {to args} { variable lib ::LOG "(jlib::send_msg) to:'$to'" set vars [list to $to] set children [list] foreach {attr val} $args { switch -- $attr { -from { lappend vars from $val } -type { lappend vars type $val } -id { lappend vars id $val } -subject { lappend children [wrapper:createtag subject -chdata $val] } -thread { lappend children [wrapper:createtag thread -chdata $val] } -body { lappend children [wrapper:createtag body -chdata $val] } -xlist { foreach x $val { lappend children $x } } -connection { set connid $val } } } if {![info exists connid]} { return -code error "jlib::send_msg: -connection is mandatory" } if {[lsearch [connections] $connid] < 0} { ::LOG "error (jlib::send_msg) Connection $connid doesn't exist" return -1 } lappend vars xml:lang [get_lang] set data [wrapper:createtag message -vars $vars -subtags $children] set xml [wrapper:createxml $data] ::LOG_OUTPUT_XML $connid $data ::LOG_OUTPUT_SIZE $connid $data [string bytelength $xml] outmsg $xml -connection $connid } ###################################################################### proc jlib::send_presence {args} { variable lib variable iq ::LOG "(jlib::send_presence)" set children [list] set vars [list] foreach {attr val} $args { switch -glob -- $attr { -from { lappend vars from $val } -to { lappend vars to $val } -type { lappend vars type $val } -command { lappend vars id $iq(num) set iq(presence,$iq(num)) $val incr iq(num) } -stat* { lappend children [wrapper:createtag status -chdata $val] } -pri* { lappend children [wrapper:createtag priority -chdata $val] } -show { lappend children [wrapper:createtag show -chdata $val] } -meta { lappend children [wrapper:createtag meta -chdata $val] } -icon { lappend children [wrapper:createtag icon -chdata $val] } -loc { lappend children [wrapper:createtag loc -chdata $val] } -xlist { foreach x $val { lappend children $x } } -connection { set connid $val } } } if {![info exists connid]} { return -code error "jlib::send_presence: -connection is mandatory" } if {[lsearch [connections] $connid] < 0} { ::LOG "error (jlib::send_presence) Connection $connid doesn't exist" return -1 } lappend vars xml:lang [get_lang] set data [wrapper:createtag presence -vars $vars -subtags $children] set xml [wrapper:createxml $data] ::LOG_OUTPUT_XML $connid $data ::LOG_OUTPUT_SIZE $connid $data [string bytelength $xml] outmsg $xml -connection $connid } ###################################################################### proc jlib::roster_get {args} { variable lib variable roster ::LOG "(jlib::roster_get)" if { $lib(connections) == {} } { ::LOG "error (jlib::roster_get) No connection" return -1 } set cmd "[namespace current]::noop" set connid [lindex $lib(connections) 0] foreach {attr val} $args { switch -- $attr { -command {set cmd $val} -connection {set connid $val} } } foreach array [array names roster] { unset roster($array) } set roster(users) "" set vars [list xmlns $::NS(roster)] set data [wrapper:createtag query -empty 1 -vars $vars] send_iq get $data \ -command [list [namespace current]::parse_roster_get $connid 0 $cmd] \ -connection $connid client status [::msgcat::mc "Waiting for roster"] } ###################################################################### proc jlib::roster_set {connid item args} { variable lib variable roster ::LOG "(jlib::roster_set) item:'$item'" if {$lib(connections) == {}} { ::LOG "error (jlib::roster_set) No connection" return -1 } set usename 0 set name "" if { [lsearch $roster(users) $item] == -1 } { set groups "" } else { set groups $roster(group,$item) } if {[wrapper:isattr $args -name]} { set usename 1 set name [wrapper:getattr $args -name] } if {[wrapper:isattr $args -groups]} { set groups [wrapper:getattr $args -groups] } if {[wrapper:isattr $args -command]} { set cmd [wrapper:getattr $args -command] } else { set cmd [namespace current]::noop } set vars [list jid $item] if {$usename} { lappend vars name $name } set subdata "" foreach group $groups { lappend subdata [wrapper:createtag group -chdata $group] } set xmldata [wrapper:createtag query \ -vars [list xmlns $::NS(roster)] \ -subtags [list [wrapper:createtag item \ -vars $vars \ -subtags $subdata]]] send_iq set $xmldata \ -connection $connid \ -command [list [namespace current]::parse_roster_set $item $cmd $groups $name] } ###################################################################### proc jlib::roster_del {connid item args} { variable lib variable roster ::LOG "(jlib::roster_del) item:'$item'" if { $lib(connections) == {} } { ::LOG "error (jlib::roster_del) No connection" return -1 } # TODO if [wrapper:isattr $args -command] { set cmd [wrapper:getattr $args -command] } else { set cmd [namespace current]::noop } set xmldata [wrapper:createtag query \ -vars [list xmlns $::NS(roster)] \ -subtags [list [wrapper:createtag item \ -vars [list jid $item \ subscription remove]]]] send_iq set $xmldata \ -connection $connid \ -command [list [namespace current]::parse_roster_del $item $cmd] } ###################################################################### # proc jlib::x_delay {xml} { foreach xelem $xml { jlib::wrapper:splitxml $xelem tag vars isempty chdata children switch -- [jlib::wrapper:getattr $vars xmlns] { urn:xmpp:delay { # 2006-07-17T05:29:12Z # 2006-11-18T03:35:56.415699Z if {[regsub {(\d+)-(\d\d)-(\d\d)T(\d+:\d+:\d+)[^Z]*Z?} \ [jlib::wrapper:getattr $vars stamp] \ {\1\2\3T\4} \ stamp]} { if {![catch {clock scan $stamp -gmt 1} seconds]} { return $seconds } } } jabber:x:delay { # 20060717T05:29:12 # 20061118T03:35:56.415699 if {[regexp {\d+\d\d\d\dT\d+:\d+:\d+} \ [jlib::wrapper:getattr $vars stamp] \ stamp]} { if {![catch {clock scan $stamp -gmt 1} seconds]} { return $seconds } } } } } return [clock seconds] } ###################################################################### # proc ::LOG {text} { # # For debugging purposes. # puts "LOG: $text\n" } proc ::LOG_OUTPUT {connid t} {} proc ::LOG_OUTPUT_XML {connid x} {} proc ::LOG_OUTPUT_SIZE {connid x size} {} proc ::LOG_INPUT {connid t} {} proc ::LOG_INPUT_XML {connid x} {} proc ::LOG_INPUT_SIZE {connid x size} {} ###################################################################### proc jlib::noop {args} {} ###################################################################### proc jlib::get_lang {} { set prefs [::msgcat::mcpreferences] if {[info tclversion] > 8.4} { set lang [lindex $prefs end-1] } else { set lang [lindex $prefs end] } switch -- $lang { "" - c - posix { return en } } if {[info tclversion] > 8.4} { set lang2 [lindex $prefs end-2] } else { set lang2 [lindex $prefs end-1] } if {[regexp {^([A-Za-z]+)_([0-9A-Za-z]+)} $lang2 ignore l1 l2]} { return "[string tolower $l1]-[string toupper $l2]" } else { return $lang } } ###################################################################### # # Now that we're done... # package provide jabberlib 0.10.1 tkabber-0.11.1/jabberlib/autoconnect.tcl0000644000175000017500000001307010710423253017462 0ustar sergeisergei# autoconnect.tcl --- # # Interface to socks4/5 or https to make usage of 'socket' transparent. # Can also be used as a wrapper for the 'socket' command without any # proxy configured. # # Copyright (c) 2007 Mats Bengtsson # Modifications Copyright (c) Sergei Golovan # # This source file is distributed under the BSD license. # # $Id: autoconnect.tcl 1282 2007-10-26 17:40:59Z sergei $ package provide autoconnect 0.2 namespace eval autoconnect { variable options array set options { -proxy "" -proxyhost "" -proxyport "" -proxyusername "" -proxypassword "" -proxyuseragent "" -proxyno "" -proxyfilter autoconnect::filter } variable packs array set packs {} } # autoconnect::register -- proc autoconnect::register {proxy connectCmd} { variable packs set packs($proxy) $connectCmd } # autoconnect::proxies -- proc autoconnect::proxies {} { variable packs return [linsert [lsort [array names packs]] 0 none] } # autoconnect::configure -- # # Get or set configuration options for the proxy. # # Arguments: # args: # -proxy ""|socks4|socks5|https # -proxyhost hostname # -proxyport port number # -proxyusername user ID # -proxypassword password # -proxyno glob list of hosts to not use proxy # -proxyfilter tclProc {host} # # Results: # one or many option values depending on arguments. proc autoconnect::configure {args} { variable options variable packs if {[llength $args] == 0} { return [array get options] } elseif {[llength $args] == 1} { return $options($args) } else { set idx [lsearch $args -proxy] if {$idx >= 0} { set proxy [lindex $args [incr idx]] if {[string length $proxy] && ![info exists packs($proxy)]} { return -code error "unsupported proxy \"$proxy\"" } } array set options $args } } proc autoconnect::init {} { # @@@ Here we should get default settings from some system API. } # autoconnect::socket -- # # Subclassing the 'socket' command. Only client side. # We use -command tclProc instead of -async + fileevent writable. # # Arguments: # host: the peer address, not SOCKS server # port: the peer's port number # args: # -command tclProc {token status} # the 'status' is any of: # ok, error, timeout, network-failure, # rsp_*, err_* (see socks4/5) # Results: # A socket if -command is not specified or an empty string. proc autoconnect::socket {host port args} { variable options set argsA(-command) "" array set argsA $args set proxy $options(-proxy) set hostport [$options(-proxyfilter) $host] if {[llength $hostport]} { set ahost [lindex $hostport 0] set aport [lindex $hostport 1] } else { set ahost $host set aport $port } # Connect ahost + aport. set sock [::socket -async $ahost $aport] set token [namespace current]::$sock fconfigure $sock -blocking 0 fileevent $sock writable [namespace code [list writable $token]] variable $token upvar 0 $token state set state(host) $host set state(port) $port set state(sock) $sock set state(cmd) $argsA(-command) if {[string length $state(cmd)]} { return } else { vwait $token\(status) set status $state(status) set sock $state(sock) catch {unset state} if {[string equal $status OK]} { return $sock } else { catch {close $sock} return -code error $sock } } } proc autoconnect::get_opts {} { variable options set opts [list] if {[string length $options(-proxyusername)]} { lappend opts -username $options(-proxyusername) } if {[string length $options(-proxypassword)]} { lappend opts -password $options(-proxypassword) } if {[string length $options(-proxyuseragent)]} { lappend opts -useragent $options(-proxyuseragent) } return $opts } proc autoconnect::writable {token} { variable options variable packs variable $token upvar 0 $token state set proxy $options(-proxy) set sock $state(sock) fileevent $sock writable {} if {[catch {fconfigure $sock -peername}]} { Finish $token network-failure } else { if {[string length $proxy]} { eval {$packs($proxy) $sock $state(host) $state(port) \ -command [namespace code [list SocksCb $token]]} [get_opts] } else { Finish $token } } return } proc autoconnect::SocksCb {token status sock} { variable $token upvar 0 $token state if {[string equal $status OK]} { set state(sock) $sock Finish $token } else { Finish $token $sock } return } proc autoconnect::Finish {token {errormsg ""}} { variable $token upvar 0 $token state variable options if {[string length $state(cmd)]} { if {[string length $errormsg]} { catch {close $state(sock)} uplevel #0 $state(cmd) [list ERROR $errormsg] } else { uplevel #0 $state(cmd) [list OK $state(sock)] } catch {unset state} } else { if {[string length $errormsg]} { catch {close $state(sock)} set state(sock) $errormsg set state(status) ERROR } else { set state(status) OK } } return } proc autoconnect::filter {host} { variable options if {[llength $options(-proxy)]} { foreach domain $options(-proxyno) { if {[string match $domain $host]} { return [list] } } return [list $options(-proxyhost) $options(-proxyport)] } else { return [list] } } tkabber-0.11.1/jabberlib/jlibsasl.tcl0000644000175000017500000003543611054503013016750 0ustar sergeisergei# jlibsasl.tcl -- # # This file is part of the jabberlib. It provides support for the # SASL authentication layer via the tclsasl or tcllib SASL package. # # Copyright (c) 2005 Sergei Golovan # Based on jlibsasl by Mats Bengtson # # $Id: jlibsasl.tcl 1488 2008-08-25 10:14:35Z sergei $ # # SYNOPSIS # jlibsasl::new connid args # creates auth token # args: -sessionid sessionid # -username username # -server server # -resource resource # -password password # -allow_plain boolean # -command callback # # token configure args # configures token parameters # args: the same as in jlibsasl::new # # token cget arg # returns token parameter # arg: -sessionid # -username # -server # -resource # -password # -allow_plain # -command # # token auth args # starts authenticating procedure # args: the same as in jlibsasl::new # # token free # frees token resourses ########################################################################## package require base64 package require namespaces 1.0 package provide jlibsasl 1.0 ########################################################################## namespace eval jlibsasl { variable uid 0 variable saslpack if {![catch {package require sasl 1.0}]} { set saslpack tclsasl } elseif {![catch {package require SASL 1.0}]} { catch {package require SASL::NTLM} catch {package require SASL::XGoogleToken} set saslpack tcllib } else { return -code error "No SASL package found" } switch -- $saslpack { tclsasl { sasl::client_init -callbacks [list [list log ::LOG]] } default { # empty } } # SASL error messages stanzaerror::register_errortype sasl [::msgcat::mc "Authentication Error"] foreach {lcode type cond description} [list \ 401 sasl aborted [::msgcat::mc "Aborted"] \ 401 sasl incorrect-encoding [::msgcat::mc "Incorrect encoding"] \ 401 sasl invalid-authzid [::msgcat::mc "Invalid authzid"] \ 401 sasl invalid-mechanism [::msgcat::mc "Invalid mechanism"] \ 401 sasl mechanism-too-weak [::msgcat::mc "Mechanism too weak"] \ 401 sasl not-authorized [::msgcat::mc "Not Authorized"] \ 401 sasl temporary-auth-failure [::msgcat::mc "Temporary auth failure"]] \ { stanzaerror::register_error $lcode $type $cond $description } } ########################################################################## proc jlibsasl::new {connid args} { variable uid set token [namespace current]::[incr uid] variable $token upvar 0 $token state ::LOG "(jlibsasl::new $connid) $token" set state(-connid) $connid set state(-allow_plain) 0 set state(-allow_google_token) 1 catch {unset state(-mechanisms)} proc $token {cmd args} \ "eval {[namespace current]::\$cmd} {$token} \$args" eval [list configure $token] $args jlib::register_xmlns $state(-connid) $::NS(sasl) \ [namespace code [list parse $token]] return $token } ########################################################################## proc jlibsasl::free {token} { variable saslpack variable $token upvar 0 $token state ::LOG "(jlibsasl::free $token)" jlib::unregister_xmlns $state(-connid) $::NS(sasl) if {[info exists state(-token)]} { switch -- $saslpack { tclsasl { rename $state(-token) "" } tcllib { SASL::cleanup $state(-token) } } } catch {unset state} catch {rename $token ""} } ########################################################################## proc jlibsasl::configure {token args} { variable $token upvar 0 $token state foreach {key val} $args { switch -- $key { -sessionid - -username - -server - -resource - -password - -allow_plain - -allow_google_token - -command { set state($key) $val } default { return -code error "Illegal option \"$key\"" } } } } ########################################################################## proc jlibsasl::cget {token arg} { variable $token upvar 0 $token state switch -- $arg { -sessionid - -username - -server - -resource - -password - -allow_plain - -command { if {[info exists state($arg)]} { return $state($arg) } else { return "" } } default { return -code error "Illegal option \"$arg\"" } } } ########################################################################## proc jlibsasl::parse {token xmldata} { variable $token upvar 0 $token state jlib::wrapper:splitxml $xmldata tag vars isempty cdata children switch -- $tag { mechanisms { set mechanisms {} foreach child $children { jlib::wrapper:splitxml $child tag1 vars1 isempty1 cdata1 children1 if {$tag1 == "mechanism"} { lappend mechanisms $cdata1 } } set state(-mechanisms) $mechanisms } challenge { step $token $cdata } success { success $token } failure { failure $token $children } } } ########################################################################## proc jlibsasl::auth {token args} { variable saslpack variable $token upvar 0 $token state ::LOG "(jlibsasl::auth $token) start" eval [list configure $token] $args switch -- $saslpack { tclsasl { foreach id {authname pass getrealm cnonce} { lappend callbacks \ [list $id [namespace code [list tclsasl_callback $token]]] } set state(-token) \ [sasl::client_new -service xmpp \ -serverFQDN $state(-server) \ -callbacks $callbacks \ -flags success_data] if {$state(-allow_plain)} { set flags {} } else { set flags {noplaintext} } $state(-token) -operation setprop \ -property sec_props \ -value [list min_ssf 0 \ max_ssf 0 \ flags $flags] } tcllib { set state(-token) \ [SASL::new -service xmpp \ -type client \ -server $state(-server) \ -callback [namespace code [list tcllib_callback \ $token]]] # Workaround a bug 1545306 in tcllib SASL module set ::SASL::digest_md5_noncecount 0 } } jlib::trace_stream_features $state(-connid) \ [namespace code [list auth_continue $token]] } ########################################################################## proc jlibsasl::auth_continue {token} { variable saslpack variable $token upvar 0 $token state ::LOG "(jlibsasl::auth $token)" if {![info exists state(-mechanisms)]} { finish $token ERR \ [concat modify \ [stanzaerror::error modify not-acceptable -text \ [::msgcat::mc \ "Server haven't provided SASL authentication\ feature"]]] return } ::LOG "(jlibsasl::auth $token) mechs: $state(-mechanisms)" switch -- $saslpack { tclsasl { set code [catch { $state(-token) \ -operation start \ -mechanisms $state(-mechanisms) \ -interact [namespace code [list interact $token]] } result] } tcllib { set code [catch {choose_mech $token} result] if {!$code} { set mech $result SASL::configure $state(-token) -mech $mech switch -- $mech { PLAIN - X-GOOGLE-TOKEN { # Initial responce set code [catch {SASL::step $state(-token) ""} result] if {!$code} { set output [SASL::response $state(-token)] } } default { set output "" } } if {!$code} { set result [list mechanism $mech output $output] } } } } ::LOG "(jlibsasl::auth $token) SASL code $code: $result" switch -- $code { 0 - 4 { array set resarray $result set data [jlib::wrapper:createtag auth \ -vars [list xmlns $::NS(sasl) \ mechanism $resarray(mechanism)] \ -chdata [base64::encode -maxlen 0 $resarray(output)]] jlib::outmsg [jlib::wrapper:createxml $data] \ -connection $state(-connid) } default { set str [format [::msgcat::mc "SASL auth error:\n%s"] $result] finish $token ERR \ [concat sasl [stanzaerror::error sasl undefined-condition \ -text $str]] } } } ########################################################################## proc jlibsasl::choose_mech {token} { variable $token upvar 0 $token state if {$state(-allow_plain)} { set forbidden_mechs {} } else { set forbidden_mechs {PLAIN LOGIN} } if {!$state(-allow_google_token)} { lappend forbidden_mechs X-GOOGLE-TOKEN } foreach m [SASL::mechanisms] { if {[lsearch -exact $state(-mechanisms) $m] >= 0 && \ [lsearch -exact $forbidden_mechs $m] < 0} { return $m } } if {[llength $state(-mechanisms)] == 0} { return -code error [::msgcat::mc "Server provided no SASL mechanisms"] } elseif {[llength $state(-mechanisms)] == 1} { return -code error [::msgcat::mc "Server provided mechanism\ %s. It is forbidden" \ [lindex $state(-mechanisms) 0]] } else { return -code error [::msgcat::mc "Server provided mechanisms\ %s. They are forbidden" \ [join $state(-mechanisms) ", "]] } } ########################################################################## proc jlibsasl::step {token serverin64} { variable saslpack variable $token upvar 0 $token state set serverin [base64::decode $serverin64] switch -- $saslpack { tclsasl { set code [catch { $state(-token) \ -operation step \ -input $serverin \ -interact [namespace code [list interact $token]] } result] } tcllib { set code [catch {SASL::step $state(-token) $serverin} result] if {!$code} { set result [SASL::response $state(-token)] } } } ::LOG "(jlibsasl::step $token) SASL code $code: $result" switch -- $code { 0 - 4 { set data [jlib::wrapper:createtag response \ -vars [list xmlns $::NS(sasl)] \ -chdata [base64::encode -maxlen 0 $result]] jlib::outmsg [jlib::wrapper:createxml $data] \ -connection $state(-connid) } default { finish $token ERR \ [concat sasl \ [stanzaerror::error sasl undefined-condition \ -text [format "SASL step error: %s" $result]]] } } } ########################################################################## proc jlibsasl::tclsasl_callback {token data} { variable $token upvar 0 $token state ::LOG "(jlibsasl::tclsasl_callback $token) $data" array set params $data switch -- $params(id) { user { # authzid return [encoding convertto utf-8 $state(-username)@$state(-server)] } authname { #username return [encoding convertto utf-8 $state(-username)] } pass { return [encoding convertto utf-8 $state(-password)] } getrealm { return [encoding convertto utf-8 $state(-server)] } default { return -code error \ "SASL callback error: client needs to write $params(id)" } } } ########################################################################## proc jlibsasl::tcllib_callback {token stoken command args} { variable $token upvar 0 $token state ::LOG "(jlibsasl::tcllib_callback $token) $stoken $command" switch -- $command { login { # authzid return [encoding convertto utf-8 $state(-username)@$state(-server)] } username { return [encoding convertto utf-8 $state(-username)] } password { return [encoding convertto utf-8 $state(-password)] } realm { return [encoding convertto utf-8 $state(-server)] } hostname { return [info host] } default { return -code error \ "SASL callback error: client needs to write $command" } } } ########################################################################## proc jlibsasl::interact {token data} { # empty ::LOG "(jlibsasl::interact $token) $data" } ########################################################################## proc jlibsasl::failure {token children} { variable $token upvar 0 $token state ::LOG "(jlibsasl::failure $token)" set error [lindex $children 0] if {$error == ""} { set err not-authorized } else { jlib::wrapper:splitxml $error tag vars empty cdata children set err $tag } finish $token ERR [concat sasl [stanzaerror::error sasl $err]] } ########################################################################## proc jlibsasl::success {token} { variable $token upvar 0 $token state ::LOG "(jlibsasl::success $token)" # xmpp-core sect 6.2: # Upon receiving the element, # the initiating entity MUST initiate a new stream by sending an # opening XML stream header to the receiving entity (it is not # necessary to send a closing tag first... jlib::reset $state(-connid) jlib::start_stream [jlib::connection_server $state(-connid)] \ -xml:lang [jlib::get_lang] -version "1.0" \ -connection $state(-connid) jlib::trace_stream_features $state(-connid) \ [namespace code [list resource_bind $token]] } ########################################################################## proc jlibsasl::resource_bind {token} { variable $token upvar 0 $token state set data [jlib::wrapper:createtag bind \ -vars [list xmlns $::NS(bind)] \ -subtags [list [jlib::wrapper:createtag resource \ -chdata $state(-resource)]]] jlib::send_iq set $data \ -command [namespace code [list send_session $token]] \ -connection $state(-connid) } ########################################################################## proc jlibsasl::send_session {token res xmldata} { variable $token upvar 0 $token state switch -- $res { OK { # Decompose returned JID jlib::wrapper:splitxml $xmldata tag vars isempty cdata children foreach child $children { jlib::wrapper:splitxml $child tag1 vars1 isempty1 cdata1 children1 switch -- $tag1 { jid { if {[regexp {([^@]*)@([^/]*)/(.*)} $cdata1 -> \ username server resource]} { set state(-username) $username set state(-server) $server set state(-resource) $resource } } } } # Establish the session. set data [jlib::wrapper:createtag session \ -vars [list xmlns $::NS(session)]] jlib::send_iq set $data \ -command [namespace code [list finish $token]] \ -connection $state(-connid) } default { ::LOG "error (jlibsasl::send_session) $xmldata" finish $token $res $xmldata } } } ########################################################################## proc jlibsasl::finish {token res child} { variable $token upvar 0 $token state ::LOG "(jlibsasl::finish $token) $res" if {$res != "OK"} { jlib::client status [::msgcat::mc "Authentication failed"] } else { jlib::client status [::msgcat::mc "Authentication successful"] } if {[info exists state(-command)]} { uplevel #0 $state(-command) [list $res $child] } } ########################################################################## tkabber-0.11.1/jabberlib/jlibtls.tcl0000644000175000017500000001330611054503013016600 0ustar sergeisergei# jlibtls.tcl -- # # This file is part of the jabberlib. It provides support for the # tls network socket security layer. # # Copyright (c) 2005 Sergei Golovan # Based on jlibtls by Mats Bengtsson # # $Id: jlibtls.tcl 1488 2008-08-25 10:14:35Z sergei $ # # SYNOPSIS # jlibtls::new connid args # creates auth token # args: -certfile certfile # -cacertstore cacertstore # -keyfile keyfile # -command callback # # token configure args # configures token parameters # args: the same as in jlibtls::new # # token starttls args # starts STARTTLS procedure # args: the same as in jlibtls::new # # token free # frees token resourses ########################################################################## package require tls 1.4 package require namespaces 1.0 package provide jlibtls 1.0 ########################################################################## namespace eval jlibtls { variable uid 0 } ########################################################################## proc jlibtls::new {connid args} { variable uid set token [namespace current]::[incr uid] variable $token upvar 0 $token state ::LOG "(jlibtls::new $connid) $token" set state(-connid) $connid catch { unset state(-starttls) } catch { unset state(-required) } proc $token {cmd args} \ "eval {[namespace current]::\$cmd} {$token} \$args" eval [list configure $token] $args jlib::register_xmlns $state(-connid) $::NS(tls) \ [namespace code [list parse $token]] return $token } ########################################################################## proc jlibtls::free {token} { variable $token upvar 0 $token state ::LOG "(jlibtls::free $token)" jlib::unregister_xmlns $state(-connid) $::NS(tls) catch { unset state } catch { rename $token "" } } ########################################################################## proc jlibtls::configure {token args} { variable $token upvar 0 $token state ::LOG "(jlibtls::configure $token)" foreach {key val} $args { switch -- $key { -cacertstore { if {$val != ""} { if {[file isdirectory $val]} { set state(-cadir) $val } else { set state(-cafile) $val } } } -certfile - -keyfile - -command { set state($key) $val } default { return -code error "Illegal option \"$key\"" } } } } ########################################################################## proc jlibtls::parse {token xmldata} { variable $token upvar 0 $token state jlib::wrapper:splitxml $xmldata tag vars isempty cdata children switch -- $tag { starttls { set state(-starttls) 1 foreach ch $children { jlib::wrapper:splitxml $ch tag1 vars1 isempty1 cdata1 children1 if {$tag1 == "required"} { set state(-required) 1 } } } proceed { proceed $token } failure { failure $token $children } } } ########################################################################## proc jlibtls::starttls {token args} { variable $token upvar 0 $token state ::LOG "(jlibtls::start $token)" eval [list configure $token] $args jlib::trace_stream_features $state(-connid) \ [namespace code [list tls_continue $token]] } ########################################################################## proc jlibtls::tls_continue {token} { variable $token upvar 0 $token state ::LOG "(jlibtls::tls_continue $token)" if {![info exists state(-starttls)]} { set err [stanzaerror::error modify not-acceptable -text \ [::msgcat::mc \ "Server haven't provided STARTTLS feature"]] finish $token ERR [concat modify $err] return } set data [jlib::wrapper:createtag starttls -vars [list xmlns $::NS(tls)]] jlib::outmsg [jlib::wrapper:createxml $data] -connection $state(-connid) } ########################################################################## proc jlibtls::failure {token children} { variable $token upvar 0 $token state ::LOG "(jlibtls::failure $token)" set error [lindex $children 0] if {$error == ""} { set err [stanzaerror::error modify undefined-condition \ -text [::msgcat::mc "STARTTLS failed"]] } else { jlib::wrapper:splitxml $error tag vars empty cdata children set err [stanzaerror::error modify $tag] } finish $token ERR [concat modify $err] } ########################################################################## proc jlibtls::proceed {token} { variable $token upvar 0 $token state ::LOG "(jlibtls::proceed $token)" set args {} foreach key {-cadir -cafile -certfile -keyfile} { if {[info exists state($key)] && $state($key) != ""} { lappend args $key $state($key) } } if {[catch { eval [list jlib::transport::tcp::to_tls $state(-connid)] $args } msg]} { set err [stanzaerror::error modify undefined-condition -text $msg] finish $token ERR [concat modify $err] return } jlib::reset $state(-connid) jlib::start_stream [jlib::connection_server $state(-connid)] \ -xml:lang [jlib::get_lang] -version "1.0" \ -connection $state(-connid) finish $token OK {} } ########################################################################## proc jlibtls::finish {token res xmldata} { variable $token upvar 0 $token state ::LOG "(jlibtls::finish $token) res" if {$res != "OK"} { jlib::client status [::msgcat::mc "STARTTLS failed"] } else { jlib::client status [::msgcat::mc "STARTTLS successful"] } if {[info exists state(-command)]} { uplevel #0 $state(-command) [list $res $xmldata] } } ########################################################################## tkabber-0.11.1/jabberlib/idna.tcl0000644000175000017500000000660210701637340016062 0ustar sergeisergei# idna.tcl -- # # This file is part of the jabberlib. It provides support for # Internationalizing Domain Names in Applications (IDNA, RFC 3490). # # Copyright (c) 2005 Alexey Shchepin # # $Id: idna.tcl 1244 2007-10-06 07:53:04Z sergei $ # # SYNOPSIS # idna::domain_toascii domain # ########################################################################## package provide idna 1.0 ########################################################################## namespace eval idna {} ########################################################################## proc idna::domain_toascii {domain} { set domain [string tolower $domain] set parts [split $domain "\u002E\u3002\uFF0E\uFF61"] set res {} foreach p $parts { set r [toascii $p] lappend res $r } return [join $res .] } ########################################################################## proc idna::toascii {name} { # TODO: Steps 2, 3 and 5 from RFC3490 if {![string is ascii $name]} { set name [punycode_encode $name] set name "xn--$name" } return $name } ########################################################################## proc idna::punycode_encode {input} { set base 36 set tmin 1 set tmax 26 set skew 38 set damp 700 set initial_bias 72 set initial_n 0x80 set n $initial_n set delta 0 set out 0 set bias $initial_bias set output "" set input_length [string length $input] set nonbasic {} for {set j 0} {$j < $input_length} {incr j} { set c [string index $input $j] if {[string is ascii $c]} { append output $c } else { lappend nonbasic $c } } set nonbasic [lsort -unique $nonbasic] set h [set b [string length $output]]; if {$b > 0} { append output - } while {$h < $input_length} { set m [scan [string index $nonbasic 0] %c] set nonbasic [lrange $nonbasic 1 end] incr delta [expr {($m - $n) * ($h + 1)}] set n $m for {set j 0} {$j < $input_length} {incr j} { set c [scan [string index $input $j] %c] if {$c < $n} { incr delta } elseif {$c == $n} { for {set q $delta; set k $base} {1} {incr k $base} { set t [expr {$k <= $bias ? $tmin : $k >= $bias + $tmax ? $tmax : $k - $bias}] if {$q < $t} break; append output \ [punycode_encode_digit \ [expr {$t + ($q - $t) % ($base - $t)}]] set q [expr {($q - $t) / ($base - $t)}] } append output [punycode_encode_digit $q] set bias [punycode_adapt \ $delta [expr {$h + 1}] [expr {$h == $b}]] set delta 0 incr h } } incr delta incr n } return $output; } ########################################################################## proc idna::punycode_adapt {delta numpoints firsttime} { set base 36 set tmin 1 set tmax 26 set skew 38 set damp 700 set delta [expr {$firsttime ? $delta / $damp : $delta >> 1}] incr delta [expr {$delta / $numpoints}] for {set k 0} {$delta > (($base - $tmin) * $tmax) / 2} {incr k $base} { set delta [expr {$delta / ($base - $tmin)}]; } return [expr {$k + ($base - $tmin + 1) * $delta / ($delta + $skew)}] } ########################################################################## proc idna::punycode_encode_digit {d} { return [format %c [expr {$d + 22 + 75 * ($d < 26)}]] } ########################################################################## tkabber-0.11.1/jabberlib/ntlm.tcl0000644000175000017500000003205310701637340016120 0ustar sergeisergei# ntlm.tcl -- # # This file implements NTLM Authentication messages in Tcl. # This module is based on Mozilla NTLM authenticattion module and # documentation from http://davenport.sourceforge.net/ntlm.html # # Copyright (c) 2004-2007 Sergei Golovan # # This file is distributed under BSD license. # # $Id: ntlm.tcl 1244 2007-10-06 07:53:04Z sergei $ package require des package require md4 package require md5 package require base64 package provide ntlm 1.0 namespace eval NTLM { namespace export new free type1Message parseType2Message type3Messasge # NTLM flags. array set NTLM { NegotiateUnicode 0x00000001 NegotiateOEM 0x00000002 RequestTarget 0x00000004 Unknown1 0x00000008 NegotiateSign 0x00000010 NegotiateSeal 0x00000020 NegotiateDatagramStyle 0x00000040 NegotiateLanManagerKey 0x00000080 NegotiateNetware 0x00000100 NegotiateNTLMKey 0x00000200 Unknown2 0x00000400 Unknown3 0x00000800 NegotiateDomainSupplied 0x00001000 NegotiateWorkstationSupplied 0x00002000 NegotiateLocalCall 0x00004000 NegotiateAlwaysSign 0x00008000 TargetTypeDomain 0x00010000 TargetTypeServer 0x00020000 TargetTypeShare 0x00040000 NegotiateNTLM2Key 0x00080000 RequestInitResponse 0x00100000 RequestAcceptResponse 0x00200000 RequestNonNTSessionKey 0x00400000 NegotiateTargetInfo 0x00800000 Unknown4 0x01000000 Unknown5 0x02000000 Unknown6 0x04000000 Unknown7 0x08000000 Unknown8 0x10000000 Negotiate128 0x20000000 NegotiateKeyExchange 0x40000000 Negotiate56 0x80000000 } # Send these flags with our Type1 message. set NTLM(TYPE1_FLAGS_INT) [expr {($NTLM(NegotiateUnicode) | \ $NTLM(NegotiateOEM) | \ $NTLM(RequestTarget) | \ $NTLM(NegotiateNTLMKey) | \ $NTLM(NegotiateNTLM2Key))}] set NTLM(TYPE1_FLAGS) [binary format i $NTLM(TYPE1_FLAGS_INT)] # Markers and signatures. array set NTLM [list \ SIGNATURE [binary format a8 "NTLMSSP"] \ TYPE1_MARKER [binary format i 1] \ TYPE2_MARKER [binary format i 2] \ TYPE3_MARKER [binary format i 3] \ LM_MAGIC [binary format a* "KGS!@#$%"]] # Token counter. variable uid 0 } # NTLM::new -- # # Allocates new NTLM token. # # Arguments: # -domain Domain (optional) # -host Host (optional) # -username Username (optional) # -password Password (optional) # All credentials are empty strings by default. # # Result: # A NTLM token. # # Side effects: # A new state variable in NTLM namespace is created. Also, # a new procedure with token name is created. proc NTLM::new {args} { variable uid set token [namespace current]::[incr uid] variable $token upvar 0 $token state set state(-domain) "" set state(-host) "" set state(-username) "" set state(-password) "" foreach {opt val} $args { switch -- $opt { -domain - -host - -username - -password { set state($opt) $val } default { return -code error "Illegal option \"$key\"" } } } proc $token {cmd args} \ "eval {[namespace current]::\$cmd} {$token} \$args" return $token } # NTLM::free -- # # Frees previously allocated NTLM token. # # Arguments: # token A previously allocated NTLM token. # # Result: # An empty string. # # Side effects: # A state variable is destroyed. proc NTLM::free {token} { variable $token upvar 0 $token state catch {unset state} catch {rename $token ""} return } # NTLM::type1Message -- # # Generates NTLM Type1 message (start of the authentication process). # # Arguments: # token A NTLM token. # # Result: # A BASE64 encoded NTLM Type1 message. # # Side effects: # None. proc NTLM::type1Message {token} { variable NTLM variable $token upvar 0 $token state # two empty strings correspond to security buffers for empty domain and # workstation data blocks set msg1 [binary format a*a*a*a8a8 \ $NTLM(SIGNATURE) \ $NTLM(TYPE1_MARKER) \ $NTLM(TYPE1_FLAGS) \ "" ""] return [string map {\n {}} [base64::encode $msg1]] } # NTLM::parseType2Message -- # # Parses NTLM Type2 message (server response). # # Arguments: # token A NTLM token. # -message Message (required) A server Type2 message. # # Result: # Empty string in case of success or error if something goes wrong. # # Side effects: # A target, challenge and negotiated flags are stored in state variable. proc NTLM::parseType2Message {token args} { variable NTLM variable $token upvar 0 $token state foreach {opt val} $args { switch -- $opt { -message { set msg $val } default { return -code error "Illegal option \"$key\"" } } } if {![info exists msg]} { return -code error "Message to parse isn't provided" } set msg2 [base64::decode $msg] # checking NTLM signature if {![string equal [string range $msg2 0 7] $NTLM(SIGNATURE)]} { return -code error "Invalid NTLM protocol signature" } # checking type2 message marker if {![string equal [string range $msg2 8 11] $NTLM(TYPE2_MARKER)]} { return -code error "Invalid NTLM message type (must be equal to 2)" } # storing target name (NTLM realm) binary scan [string range $msg2 12 13] s target_len binary scan [string range $msg2 16 19] i target_offset set state(target) [string range $msg2 $target_offset \ [expr {$target_offset + $target_len - 1}]] # storing negotiated flags binary scan [string range $msg2 20 23] i state(flags) # storing and returning challenge set state(challenge) [string range $msg2 24 31] return } # NTLM::type3Message -- # # Generates NTLM Type3 message (the end of the authentication process). # # Arguments: # token A NTLM token after parsing Type2 message. # # Result: # A BASE64 encoded NTLM Type3 message. # # Side effects: # None. proc NTLM::type3Message {token} { variable NTLM variable $token upvar 0 $token state set unicode [expr {$state(flags) & $NTLM(NegotiateUnicode)}] set target_type_domain [expr {$state(flags) & $NTLM(TargetTypeDomain)}] if {$unicode} { set domain [ToUnicodeLe [string toupper $state(-domain)]] set host [ToUnicodeLe [string toupper $state(-host)]] set username [ToUnicodeLe $state(-username)] } else { set domain [encoding convertto [string toupper $state(-domain)]] set host [encoding convertto [string toupper $state(-host)]] set username [encoding convertto $state(-username)] } if {$target_type_domain && ($state(-domain) == "")} { set domain $state(target) } set challenge $state(challenge) if {[expr {$state(flags) & $NTLM(NegotiateNTLM2Key)}]} { set rnd1 [expr {int((1<<16)*rand())}] set rnd2 [expr {int((1<<16)*rand())}] set rnd3 [expr {int((1<<16)*rand())}] set rnd4 [expr {int((1<<16)*rand())}] set random [binary format ssss $rnd1 $rnd2 $rnd3 $rnd4] set lm_response [binary format a24 $random] set session_hash [md5 [binary format a8a8 $challenge $random]] set ntlm_hash [NtlmHash $state(-password)] set ntlm_response [LmResponse $ntlm_hash $session_hash] } else { set lm_hash [LmHash $state(-password)] set lm_response [LmResponse $lm_hash $challenge] set ntlm_hash [NtlmHash $state(-password)] set ntlm_response [LmResponse $ntlm_hash $challenge] } # Offset of the end of header. set offset 64 set offset [CreateData $domain $offset data(domain)] set offset [CreateData $username $offset data(username)] set offset [CreateData $host $offset data(host)] set offset [CreateData $lm_response $offset data(lm)] set offset [CreateData $ntlm_response $offset data(ntlm)] set flags [expr {$state(flags) & $NTLM(TYPE1_FLAGS_INT)}] set msg3 [binary format a*a*a*a*a*a*a*a8ia*a*a*a*a* \ $NTLM(SIGNATURE) $NTLM(TYPE3_MARKER) \ $data(lm) $data(ntlm) $data(domain) $data(username) $data(host) \ "" $flags \ $domain $username $host $lm_response $ntlm_response] return [string map {\n {}} [base64::encode $msg3]] } # NTLM::md5 -- # # Returns binary MD5 hash of specified string. This procedure is needed # if md5 package has version less than 2.0. # # Arguments: # str # # Result: # The binary MD5 hash. # # Side effects: # None. proc NTLM::md5 {str} { if {[catch {::md5::md5 -hex $str} hash]} { # Old md5 package. set hash [::md5::md5 $str] } return [binary format H32 $hash] } # NTLM::CreateData -- # # Returns next offset (in error code) and security buffer data # # Arguments: # str # offset # dataVar # # Result: # The next offset. # # Side effects: # Variable dataVar is set to a binary value for packing into a NTLM # message. proc NTLM::CreateData {str offset dataVar} { upvar $dataVar data set len [string length $str] set data [binary format ssi $len $len $offset] return [expr {$offset + $len}] } # NTLM::LmHash -- # # Computes the LM hash of the given password. # # Arguments: # password A password to hash. # # Result: # A LM hash of the given password. # # Side effects: # None. proc NTLM::LmHash {password} { variable NTLM set password [encoding convertto [string toupper $password]] # pad password with zeros or truncate if it is longer than 14 set pwd [binary format a14 $password] # setup two DES keys set key1 [MakeKey [string range $pwd 0 6]] set key2 [MakeKey [string range $pwd 7 13]] # do hash set res1 [DES::des -mode encode -key $key1 $NTLM(LM_MAGIC)] set res2 [DES::des -mode encode -key $key2 $NTLM(LM_MAGIC)] return [binary format a8a8 $res1 $res2] } # NTLM::NtlmHash -- # # Computes the NTLM hash of the given password. # # Arguments: # password A password to hash. # # Result: # A NTLM hash of the given password. # # Side effects: # None. proc NTLM::NtlmHash {password} { # we have to have UNICODE password set pw [ToUnicodeLe $password] # do MD4 hash return [md4::md4 -- $pw] } # NTLM::LmResponse -- # # Generates the LM response given a 16-byte password hash and the # challenge from the Type-2 message. # # Arguments: # hash A password hash # challenge A challenge. # # Result: # A LM hash (3 concatenated DES-encrypted strings). # # Side effects: # None. proc NTLM::LmResponse {hash challenge} { # zero pad hash to 21 bytes set hash [binary format a21 $hash] # truncate challenge to 8 bytes set challenge [binary format a8 $challenge] set key1 [MakeKey [string range $hash 0 6]] set key2 [MakeKey [string range $hash 7 13]] set key3 [MakeKey [string range $hash 14 20]] set res1 [DES::des -mode encode -key $key1 $challenge] set res2 [DES::des -mode encode -key $key2 $challenge] set res3 [DES::des -mode encode -key $key3 $challenge] return [binary format a8a8a8 $res1 $res2 $res3] } # NTLM::MakeKey -- # # Builds 64-bit DES key from 56-bit raw key. # # Arguments: # key A 56-bit key. # # Result: # A 64-bit DES key. # # Side effects: # None. proc NTLM::MakeKey {key} { binary scan $key ccccccc k(0) k(1) k(2) k(3) k(4) k(5) k(6) # make numbers unsigned foreach i [array names k] { set k($i) [expr {($k($i) + 0x100) % 0x100}] } set n(0) [SetKeyParity $k(0)] set n(1) [SetKeyParity [expr {(($k(0) << 7) & 0xFF) | ($k(1) >> 1)}]] set n(2) [SetKeyParity [expr {(($k(1) << 6) & 0xFF) | ($k(2) >> 2)}]] set n(3) [SetKeyParity [expr {(($k(2) << 5) & 0xFF) | ($k(3) >> 3)}]] set n(4) [SetKeyParity [expr {(($k(3) << 4) & 0xFF) | ($k(4) >> 4)}]] set n(5) [SetKeyParity [expr {(($k(4) << 3) & 0xFF) | ($k(5) >> 5)}]] set n(6) [SetKeyParity [expr {(($k(5) << 2) & 0xFF) | ($k(6) >> 6)}]] set n(7) [SetKeyParity [expr {($k(6) << 1) & 0xFF}]] return [binary format cccccccc \ $n(0) $n(1) $n(2) $n(3) $n(4) $n(5) $n(6) $n(7)] } # NTLM::SetKeyParity -- # # Sets odd parity bit (in least significant bit position) # DES::des seems not to require setting parity, but... # # Arguments: # x A byte integer. # # Result: # An integer with parity bit set, so the total number of bits set is # odd. # # Side effects: # None. proc NTLM::SetKeyParity {x} { set xor [expr {(($x >> 7) ^ ($x >> 6) ^ ($x >> 5) ^ ($x >> 4) ^ ($x >> 3) ^ ($x >> 2) ^ ($x >> 1)) & 0x01}] if {$xor == 0} { return [expr {($x & 0xFF) | 0x01}] } else { return [expr {$x & 0xFE}] } } # NTLM::ToUnicodeLe -- # # Converts a string to unicode in little endian byte order # (taken from tcllib/sasl). # # Arguments: # str A string to convert. # # Result: # A converted to little endian byte order string. # # Side effects: # None. proc NTLM::ToUnicodeLe {str} { set result [encoding convertto unicode $str] if {[string equal $::tcl_platform(byteOrder) "bigEndian"]} { set r {} ; set n 0 while {[binary scan $result @${n}cc a b] == 2} { append r [binary format cc $b $a] incr n 2 } set result $r } return $result } tkabber-0.11.1/jabberlib/transports.tcl0000644000175000017500000004433510710423253017367 0ustar sergeisergei# $Id: transports.tcl 1282 2007-10-26 17:40:59Z sergei $ namespace eval transport { variable capabilities [list tcp http_poll] variable disconnect quick } proc transport::capabilities {} { variable capabilities return $capabilities } ###################################################################### # # TCP Socket Support # ###################################################################### namespace eval transport::tcp {} proc transport::tcp::connect {connid server port args} { variable $connid upvar 0 $connid lib set sock [eval [list autoconnect::socket $server $port] $args] fconfigure $sock -blocking 0 -buffering none \ -translation auto -encoding utf-8 set lib(socket) $sock fileevent $sock readable \ [list [namespace current]::inmsg $connid $sock] return $sock } proc transport::tcp::outmsg {connid msg} { variable $connid upvar 0 $connid lib if {![info exists lib(socket)]} { ::LOG "error ([namespace current]::outmsg)\ Cannot write to socket: socket for\ connection $connid doesn't exist" return -2 } if {[catch { puts -nonewline $lib(socket) $msg }]} { ::LOG "error ([namespace current]::outmsg)\ Cannot write to socket: $lib(socket)" return -2 } } proc transport::tcp::start_stream {connid server args} { return [outmsg $connid \ [eval [list jlib::wrapper:streamheader $server] $args]] } proc transport::tcp::finish_stream {connid args} { return [outmsg $connid [jlib::wrapper:streamtrailer]] } proc transport::tcp::disconnect {connid} { variable $connid upvar 0 $connid lib catch { if {[set [namespace parent]::disconnect] == "quick"} { flush $lib(socket) } else { fconfigure $lib(socket) -blocking 1 flush $lib(socket) vwait [namespace current]::${connid}(socket) } } } proc transport::tcp::close {connid} { variable $connid upvar 0 $connid lib catch {fileevent $lib(socket) readable {}} catch {::close $lib(socket)} catch {unset lib} } ###################################################################### proc transport::tcp::inmsg {connid sock} { set msg "" catch { set msg [read $sock] } jlib::inmsg $connid $msg [eof $sock] } ###################################################################### # TODO Cleanup proc transport::tcp::to_compress {connid method} { variable $connid upvar 0 $connid lib set [namespace parent]::${method}::${connid}(socket) $lib(socket) eval [list [namespace parent]::${method}::import $connid] set ::jlib::lib($connid,transport) $method catch {unset lib} } proc transport::tcp::to_tls {connid args} { variable $connid upvar 0 $connid lib set [namespace parent]::tls::${connid}(socket) $lib(socket) eval [list [namespace parent]::tls::tls_import $connid] $args set ::jlib::lib($connid,transport) tls catch {unset lib} } ###################################################################### # # Zlib Compressed Socket Support # ###################################################################### if {![catch { package require zlib 1.0 }]} { lappend transport::capabilities compress } namespace eval transport::zlib {} proc transport::zlib::connect {connid server port args} { variable $connid upvar 0 $connid lib set sock [eval [list autoconnect::socket $server $port] $args] set lib(socket) $sock import $connid return $sock } proc transport::zlib::outmsg {connid msg} { variable $connid upvar 0 $connid lib if {![info exists lib(socket)]} { ::LOG "error ([namespace current]::outmsg)\ Cannot write to socket: socket for connection\ $connid doesn't exist" return -2 } if {[catch { puts -nonewline $lib(socket) $msg }]} { ::LOG "error ([namespace current]::outmsg)\ Cannot write to socket: $lib(socket)" return -2 } flush $lib(socket) fconfigure $lib(socket) -flush output } proc transport::zlib::start_stream {connid server args} { return [outmsg $connid \ [eval [list jlib::wrapper:streamheader $server] $args]] } proc transport::zlib::finish_stream {connid args} { return [outmsg $connid [jlib::wrapper:streamtrailer]] } proc transport::zlib::disconnect {connid} { variable $connid upvar 0 $connid lib catch { if {[set [namespace parent]::disconnect] == "quick"} { flush $lib(socket) fconfigure $lib(socket) -finish output } else { fconfigure $lib(socket) -blocking 1 flush $lib(socket) fconfigure $lib(socket) -finish output vwait [namespace current]::${connid}(socket) } } } proc transport::zlib::close {connid} { variable $connid upvar 0 $connid lib catch {fileevent $lib(socket) readable {}} catch {::close $lib(socket)} catch {unset lib} } ###################################################################### proc transport::zlib::inmsg {connid sock} { set msg "" catch { fconfigure $sock -flush input set msg [read $sock] } jlib::inmsg $connid $msg [eof $sock] } ###################################################################### proc transport::zlib::import {connid args} { variable $connid upvar 0 $connid lib set sock $lib(socket) fconfigure $sock -blocking 0 -buffering none \ -translation auto -encoding utf-8 zlib stream $sock RDWR -output compress -input decompress fileevent $sock readable \ [list [namespace current]::inmsg $connid $sock] } ###################################################################### # # TLS Socket Support # ###################################################################### if {![catch { package require tls 1.4 }]} { lappend transport::capabilities tls } namespace eval transport::tls {} proc transport::tls::connect {connid server port args} { variable $connid upvar 0 $connid lib set tlsargs {} foreach {opt val} $args { switch -- $opt { -cacertstore { if {$val != ""} { if {[file isdirectory $val]} { lappend tlsargs -cadir $val } else { lappend tlsargs -cafile $val } } } -certfile - -keyfile { if {$val != ""} { lappend tlsargs $opt $val } } } } set sock [eval [list autoconnect::socket $server $port] $args] fconfigure $sock -encoding binary -translation binary set lib(socket) $sock eval [list tls_import $connid] $tlsargs return $sock } proc transport::tls::outmsg {connid msg} { variable $connid upvar 0 $connid lib if {![info exists lib(socket)]} { ::LOG "error ([namespace current]::outmsg)\ Cannot write to socket: socket for connection\ $connid doesn't exist" return -2 } if {[catch { puts -nonewline $lib(socket) $msg }]} { ::LOG "error ([namespace current]::outmsg)\ Cannot write to socket: $lib(socket)" return -2 } } proc transport::tls::start_stream {connid server args} { return [outmsg $connid \ [eval [list jlib::wrapper:streamheader $server] $args]] } proc transport::tls::finish_stream {connid args} { return [outmsg $connid [jlib::wrapper:streamtrailer]] } proc transport::tls::disconnect {connid} { variable $connid upvar 0 $connid lib catch { if {[set [namespace parent]::disconnect] == "quick"} { flush $lib(socket) } else { fconfigure $lib(socket) -blocking 1 flush $lib(socket) vwait [namespace current]::${connid}(socket) } } } proc transport::tls::close {connid} { variable $connid upvar 0 $connid lib catch {fileevent $lib(socket) readable {}} catch {::close $lib(socket)} catch {unset lib} } ###################################################################### proc transport::tls::inmsg {connid sock} { set msg "" catch { set msg [read $sock] } jlib::inmsg $connid $msg [eof $sock] } ###################################################################### proc ::client:tls_callback {args} { return 1 } ###################################################################### proc transport::tls::tls_import {connid args} { variable $connid upvar 0 $connid lib set sock $lib(socket) fileevent $sock readable {} fileevent $sock writable {} fconfigure $sock -blocking 1 eval [list tls::import $sock \ -command [list client:tls_callback $connid] \ -ssl2 false \ -ssl3 true \ -tls1 true \ -request true \ -require false \ -server false] $args if {[catch {tls::handshake $sock} tls_result]} { catch {::close $sock} error $tls_result } fconfigure $sock -blocking 0 -buffering none \ -translation auto -encoding utf-8 fileevent $sock readable \ [list [namespace current]::inmsg $connid $sock] } ###################################################################### # TODO Cleanup proc transport::tls::to_compress {connid method} { variable $connid upvar 0 $connid lib set [namespace parent]::${method}::${connid}(socket) $lib(socket) eval [list [namespace parent]::${method}::import $connid] set ::jlib::lib($connid,transport) $method catch {unset lib} } ###################################################################### # # HTTP Polling # ###################################################################### package require sha1 namespace eval transport::http_poll { variable http_version [package require http] } if {![catch { package require tls 1.4 }]} { ::http::register https 443 ::tls::socket } proc transport::http_poll::connect {connid server port args} { variable $connid upvar 0 $connid lib set lib(polltimeout) 0 set lib(pollint) 6000 set lib(pollmin) 6000 set lib(pollmax) 60000 set lib(proxyhost) "" set lib(proxyport) "" set lib(proxyusername) "" set lib(proxypassword) "" set lib(proxyuseragent) "" set lib(httpurl) "" set lib(httpusekeys) 1 set lib(httpnumkeys) 100 foreach {opt val} $args { switch -- $opt { -polltimeout { set lib(polltimeout) $val } -pollint { set lib(pollint) $val } -pollmin { set lib(pollmin) $val } -pollmax { set lib(pollmax) $val } -httpurl { set lib(httpurl) $val } -httpusekeys { set lib(httpusekeys) $val } -httpnumkeys { set lib(httpnumkeys) $val } -proxyhost { set lib(proxyhost) $val } -proxyport { set lib(proxyport) $val } -proxyusername { set lib(proxyusername) $val } -proxypassword { set lib(proxypassword) $val } -proxyuseragent { set lib(proxyuseragent) $val } } } set lib(httpwait) disconnected set lib(httpoutdata) "" set lib(httpseskey) 0 set lib(httpid) "" set lib(httpkeys) {} if {$lib(proxyuseragent) != ""} { ::http::config -useragent $lib(proxyuseragent) } if {($lib(proxyhost) != "") && ($lib(proxyport) != "")} { ::http::config -proxyhost $lib(proxyhost) -proxyport $lib(proxyport) if {$lib(proxyusername) != ""} { set auth \ [base64::encode \ [encoding convertto \ "$lib(proxyusername):$lib(proxypassword)"]] set lib(proxyauth) [list "Proxy-Authorization" "Basic $auth"] } else { set lib(proxyauth) {} } } else { set lib(proxyauth) {} } if {$lib(httpusekeys)} { # generate keys ::HTTP_LOG "connect ($connid): generating keys" set seed [rand 1000000000] set oldkey $seed set key_count $lib(httpnumkeys) while {$key_count > 0} { set nextkey [base64::encode [hex_decode [sha1::sha1 $oldkey]]] # skip the initial seed lappend lib(httpkeys) $nextkey set oldkey $nextkey incr key_count -1 } } set_httpwait $connid connected } proc transport::http_poll::outmsg {connid msg} { variable $connid upvar 0 $connid lib if {![info exists lib(httpwait)]} { return } switch -- $lib(httpwait) { disconnected - waiting - disconnecting { } default { poll $connid $msg } } } proc transport::http_poll::start_stream {connid server args} { return [outmsg $connid \ [eval [list jlib::wrapper:streamheader $server] $args]] } proc transport::http_poll::finish_stream {connid args} { return [outmsg $connid [jlib::wrapper:streamtrailer]] } proc transport::http_poll::disconnect {connid} { variable $connid upvar 0 $connid lib if {![info exists lib(httpwait)]} { return } switch -- $lib(httpwait) { disconnected - waiting { } polling { set_httpwait $connid waiting } default { set_httpwait $connid disconnecting } } if {[set [namespace parent]::disconnect] == "quick"} return while {[info exists lib(httpwait)] && $lib(httpwait) != "disconnected"} { vwait [namespace current]::${connid}(httpwait) } } proc transport::http_poll::close {connid} { variable $connid upvar 0 $connid lib set_httpwait $connid disconnected catch {unset lib} } ###################################################################### proc transport::http_poll::inmsg {connid body} { if {[string length $body] > 2} { jlib::inmsg $connid $body 0 } } ###################################################################### proc ::HTTP_LOG {args} {} ###################################################################### proc transport::http_poll::set_httpwait {connid opt} { variable $connid upvar 0 $connid lib set lib(httpwait) $opt if {$opt == "disconnected" && \ [info exists lib(httpid)] && $lib(httpid) != ""} { after cancel $lib(httpid) } } proc transport::http_poll::process_httpreply {connid try query token} { variable $connid upvar 0 $connid lib upvar #0 $token state if {[::http::ncode $token] != 200} { ::HTTP_LOG "error (process_httpreply) ($connid)\ Http returned [::http::ncode $token] $state(status)" if {$try < 3} { get_url $connid [expr {$try + 1}] $query } else { set_httpwait $connid disconnected jlib::emergency_disconnect $connid } ::http::cleanup $token return } foreach {name value} $state(meta) { if {[string equal -nocase "Set-Cookie" $name]} { ::HTTP_LOG "process_httpreply ($connid): Set-Cookie: $value" set start 0 set end [string first ";" $value] if {$end < 1} { set end [string length $value] } if {[string equal -nocase -length 3 "ID=" $value]} { set start 3 } set lib(httpseskey) [string range $value $start [expr {$end - 1}]] } } set inmsg [encoding convertfrom utf-8 $state(body)] ::HTTP_LOG "process_httpreply ($connid): '$inmsg'" ::http::cleanup $token if {[regexp {:0$} $lib(httpseskey)] || [regexp {%3A0$} $lib(httpseskey)]} { ::HTTP_LOG "error (process_httpreply) Cookie Error" set_httpwait $connid disconnected jlib::emergency_disconnect $connid return } if {[string length $inmsg] > 5 } { set lib(pollint) [expr $lib(pollint) / 2] if {$lib(pollint) < $lib(pollmin)} { set lib(pollint) $lib(pollmin) } } else { set lib(pollint) [expr $lib(pollint) * 11 / 10] if {$lib(pollint) > $lib(pollmax)} { set lib(pollint) $lib(pollmax) } } inmsg $connid $inmsg switch -- $lib(httpwait) { waiting { set_httpwait $connid disconnecting } polling { set_httpwait $connid connected } } } proc transport::http_poll::poll {connid what} { variable $connid upvar 0 $connid lib ::HTTP_LOG "poll ($connid): '$what'" if {![info exists lib(httpwait)]} { set_httpwait $connid disconnected return } append lib(httpoutdata) [encoding convertto utf-8 $what] switch -- $lib(httpwait) { disconnected { ::HTTP_LOG "poll ($connid): DISCONNECTED" return } disconnecting { ::HTTP_LOG "poll ($connid): DISCONNECTING" if {$lib(httpoutdata) == ""} { set_httpwait $connid disconnected return } } waiting - polling { ::HTTP_LOG "poll ($connid): RESCHEDULING" if {[info exists lib(httpid)]} { after cancel $lib(httpid) } ::HTTP_LOG "poll ($connid): $lib(pollint)" set lib(httpid) \ [after $lib(pollint) \ [list [namespace current]::poll $connid ""]] return } } if {$lib(httpusekeys)} { # regenerate set firstkey [lindex $lib(httpkeys) end] set secondkey "" if {[llength $lib(httpkeys)] == 1} { ::HTTP_LOG "poll ($connid): regenerating keys" set lib(httpkeys) {} set seed [rand 1000000000] set oldkey $seed set key_count $lib(httpnumkeys) while {$key_count > 0} { set nextkey [base64::encode [hex_decode [sha1::sha1 $oldkey]]] # skip the initial seed lappend lib(httpkeys) $nextkey set oldkey $nextkey incr key_count -1 } set secondkey [lindex $lib(httpkeys) end] } set l [llength $lib(httpkeys)] set lib(httpkeys) [lrange $lib(httpkeys) 0 [expr {$l - 2}]] if {[string length $firstkey]} { set firstkey ";$firstkey" } if {[string length $secondkey]} { set secondkey ";$secondkey" } set query "$lib(httpseskey)$firstkey$secondkey,$lib(httpoutdata)" } else { set query "$lib(httpseskey),$lib(httpoutdata)" } switch -- $lib(httpwait) { disconnecting { set_httpwait $connid waiting } default { set_httpwait $connid polling } } ::HTTP_LOG "poll ($connid): query: '[encoding convertfrom utf-8 $query]'" get_url $connid 0 $query set lib(httpoutdata) "" if {[info exists lib(httpid)]} { after cancel $lib(httpid) } ::HTTP_LOG "poll ($connid): $lib(pollint)" set lib(httpid) \ [after $lib(pollint) [list [namespace current]::poll $connid ""]] } proc transport::http_poll::get_url {connid try query} { variable http_version variable $connid upvar 0 $connid lib set get_url_args [list -headers $lib(proxyauth)] if {[package vcompare 2.3.3 $http_version] <= 0} { lappend get_url_args -binary 1 } eval [list ::http::geturl $lib(httpurl) -query $query \ -command [list [namespace current]::process_httpreply $connid $try $query] \ -timeout $lib(polltimeout)] $get_url_args } proc transport::http_poll::hex_decode {hexstring} { set result "" while { [string length $hexstring] } { scan [string range $hexstring 0 1] "%x" X regsub "^.." $hexstring "" hexstring set result [binary format "a*c" $result $X] } return $result } tkabber-0.11.1/jabberlib/jlibauth.tcl0000644000175000017500000001532011054503013016735 0ustar sergeisergei# jlibauth.tcl -- # # This file is part of the jabberlib. It provides support for the # Non-auth authentication layer (XEP-0078). # # Copyright (c) 2005 Sergei Golovan # # $Id: jlibauth.tcl 1488 2008-08-25 10:14:35Z sergei $ # # SYNOPSIS # jlibauth::new connid args # creates auth token # args: -sessionid sessionid # -username username # -server server # -resource resource # -password password # -allow_plain boolean # -command callback # # token configure args # configures token parameters # args: the same as in jlibauth::new # # token auth args # starts authenticating procedure # args: the same as in jlibauth::new # # token free # frees token resourses ########################################################################## package require sha1 package require namespaces 1.0 package provide jlibauth 1.0 ########################################################################## namespace eval jlibauth { variable uid 0 } ########################################################################## proc jlibauth::new {connid args} { variable uid set token [namespace current]::[incr uid] variable $token upvar 0 $token state ::LOG "(jlibauth::new $connid) $token" set state(-connid) $connid set state(-allow_plain) 0 proc $token {cmd args} \ "eval {[namespace current]::\$cmd} {$token} \$args" eval [list configure $token] $args jlib::register_xmlns $state(-connid) $::NS(iq-auth) \ [namespace code [list parse $token]] return $token } ########################################################################## proc jlibauth::free {token} { variable $token upvar 0 $token state ::LOG "(jlibauth::free $token)" jlib::unregister_xmlns $state(-connid) $::NS(iq-auth) catch { unset state } catch { rename $token "" } } ########################################################################## proc jlibauth::configure {token args} { variable $token upvar 0 $token state foreach {key val} $args { switch -- $key { -sessionid - -username - -server - -resource - -password - -allow_plain - -command { set state($key) $val } default { return -code error "Illegal option \"$key\"" } } } } ########################################################################## proc jlibauth::parse {token xmldata} { variable $token upvar 0 $token state jlib::wrapper:splitxml $xmldata tag vars isempty cdata children switch -- $tag { auth { set state(nonsasl) 1 } } } ########################################################################## proc jlibauth::auth {token args} { variable $token upvar 0 $token state ::LOG "(jlibauth::auth $token) start" eval [list configure $token] $args foreach key [list -sessionid \ -username \ -resource \ -password] { if {![info exists state($key)]} { return -code error "Auth error: missing option \"$key\"" } } jlib::trace_stream_features \ $state(-connid) \ [namespace code [list auth_continue $token]] } ########################################################################## proc jlibauth::auth_continue {token} { variable $token upvar 0 $token state ::LOG "(jlibauth::auth_continue $token)" if {![info exists state(nonsasl)]} { finish $token ERR \ [concat modify \ [stanzaerror::error modify not-acceptable -text \ [::msgcat::mc \ "Server haven't provided non-SASL\ authentication feature"]]] return } set data [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(auth)] \ -subtags [list [jlib::wrapper:createtag username \ -chdata $state(-username)]]] jlib::send_iq get $data \ -command [namespace code [list auth_continue2 $token]] \ -connection $state(-connid) } ########################################################################## proc jlibauth::auth_continue2 {token res xmldata} { variable $token upvar 0 $token state ::LOG "(jlibauth::auth_continue2 $token) $res" if {$res != "OK"} { finish $token $res $xmldata return } jlib::wrapper:splitxml $xmldata tag vars isempty chdata children set authtype "" foreach child $children { jlib::wrapper:splitxml $child tag1 vars1 isempty1 chdata1 children1 switch -- $tag1 { password { if {$authtype == ""} { if {$state(-allow_plain)} { set authtype plain } else { set authtype forbidden } } } digest { set authtype digest } } } switch -- $authtype { plain { set data [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(auth)] \ -subtags [list [jlib::wrapper:createtag username \ -chdata $state(-username)] \ [jlib::wrapper:createtag password \ -chdata $state(-password)] \ [jlib::wrapper:createtag resource \ -chdata $state(-resource)]]] } digest { set secret [encoding convertto utf-8 $state(-sessionid)] append secret [encoding convertto utf-8 $state(-password)] set digest [sha1::sha1 $secret] set data [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(auth)] \ -subtags [list [jlib::wrapper:createtag username \ -chdata $state(-username)] \ [jlib::wrapper:createtag digest \ -chdata $digest] \ [jlib::wrapper:createtag resource \ -chdata $state(-resource)]]] } forbidden { finish $token ERR \ [concat modify \ [stanzaerror::error modify not-acceptable -text \ [::msgcat::mc \ "Server doesn't support hashed password\ authentication"]]] return } default { finish $token ERR \ [concat modify \ [stanzaerror::error modify not-acceptable -text \ [::msgcat::mc \ "Server doesn't support plain or digest\ authentication"]]] return } } jlib::client status [::msgcat::mc "Waiting for authentication results"] jlib::send_iq set $data \ -command [namespace code [list finish $token]] \ -connection $state(-connid) } ########################################################################## proc jlibauth::finish {token res xmldata} { variable $token upvar 0 $token state ::LOG "(jlibauth::finish $token) $res" if {$res != "OK"} { jlib::client status [::msgcat::mc "Authentication failed"] } else { jlib::client status [::msgcat::mc "Authentication successful"] } if {$res != "DISCONNECT" && [info exists state(-command)]} { # Should we report about disconnect too? uplevel #0 $state(-command) [list $res $xmldata] } } ########################################################################## tkabber-0.11.1/jabberlib/jlibcompress.tcl0000644000175000017500000001434511054503013017635 0ustar sergeisergei# jlibcompress.tcl -- # # This file is part of the jabberlib. It provides support for the # compressed jabber stream. # # Copyright (c) 2005 Sergei Golovan # # $Id: jlibcompress.tcl 1488 2008-08-25 10:14:35Z sergei $ # # SYNOPSIS # jlibcompress::new connid args # creates auth token # args: -command callback # # token configure args # configures token parameters # args: the same as in jlibcompress::new # # token start args # starts COMPRESS procedure # args: the same as in jlibcompress::new # # token free # frees token resourses ########################################################################## package require zlib 1.0 package require namespaces 1.0 package provide jlibcompress 1.0 ########################################################################## namespace eval jlibcompress { variable uid 0 variable supported_methods {zlib} foreach {lcode type cond description} [list \ 409 modify setup-failed [::msgcat::mc "Compression setup failed"] \ 409 modify unsupported-method [::msgcat::mc "Unsupported compression method"]] \ { stanzaerror::register_error $lcode $type $cond $description } } ########################################################################## proc jlibcompress::new {connid args} { variable uid set token [namespace current]::[incr uid] variable $token upvar 0 $token state ::LOG "(jlibcompress::new $connid) $token" set state(-connid) $connid proc $token {cmd args} \ "eval {[namespace current]::\$cmd} {$token} \$args" eval [list configure $token] $args jlib::register_xmlns $state(-connid) $::NS(fcompress) \ [namespace code [list parse $token]] jlib::register_xmlns $state(-connid) $::NS(compress) \ [namespace code [list parse $token]] return $token } ########################################################################## proc jlibcompress::free {token} { variable $token upvar 0 $token state ::LOG "(jlibcompress::free $token)" jlib::unregister_xmlns $state(-connid) $::NS(fcompress) jlib::unregister_xmlns $state(-connid) $::NS(compress) catch { unset state } catch { rename $token "" } } ########################################################################## proc jlibcompress::configure {token args} { variable $token upvar 0 $token state ::LOG "(jlibcompress::configure $token)" foreach {key val} $args { switch -- $key { -command { set state($key) $val } default { return -code error "Illegal option \"$key\"" } } } } ########################################################################## proc jlibcompress::parse {token xmldata} { variable $token upvar 0 $token state jlib::wrapper:splitxml $xmldata tag vars isempty cdata children switch -- $tag { compression { set methods {} foreach child $children { jlib::wrapper:splitxml $child tag1 vars1 isempty1 cdata1 children1 if {$tag1 == "method"} { lappend methods $cdata1 } } set state(-methods) $methods } compressed { compressed $token } failure { failure $token $children } } } ########################################################################## proc jlibcompress::start {token args} { variable $token upvar 0 $token state ::LOG "(jlibcompress::start $token)" eval [list configure $token] $args jlib::trace_stream_features $state(-connid) \ [namespace code [list continue $token]] } ########################################################################## proc jlibcompress::continue {token} { variable supported_methods variable $token upvar 0 $token state ::LOG "(jlibcompress::continue $token)" if {![info exists state(-methods)]} { set err [stanzaerror::error modify not-acceptable -text \ [::msgcat::mc \ "Server haven't provided compress feature"]] finish $token ERR [concat modify $err] return } else { catch { unset state(-method) } foreach m $supported_methods { if {[lcontain $state(-methods) $m]} { set state(-method) $m break } if {![info exists state(-method)]} { set err [stanzaerror::error modify not-acceptable \ -text [::msgcat::mc \ "Server haven't provided supported\ compress method"]] finish $token ERR [concat modify $err] return } } } set data [jlib::wrapper:createtag compress \ -vars [list xmlns $::NS(compress)] \ -subtags [list [jlib::wrapper:createtag method \ -chdata $state(-method)]]] jlib::outmsg [jlib::wrapper:createxml $data] -connection $state(-connid) } ########################################################################## proc jlibcompress::failure {token children} { variable $token upvar 0 $token state ::LOG "(jlibcompress::failure $token)" set error [lindex $children 0] if {$error == ""} { set err [stanzaerror::error modify undefined-condition \ -text [::msgcat::mc "Compression negotiation failed"]] } else { jlib::wrapper:splitxml $error tag vars empty cdata children set err [stanzaerror::error modify $tag] } finish $token ERR [concat modify $err] } ########################################################################## proc jlibcompress::compressed {token} { variable $token upvar 0 $token state ::LOG "(jlibcompress::proceed $token)" set transport $::jlib::lib($state(-connid),transport) jlib::transport::${transport}::to_compress $state(-connid) $state(-method) jlib::reset $state(-connid) jlib::start_stream [jlib::connection_server $state(-connid)] \ -xml:lang [jlib::get_lang] -version "1.0" \ -connection $state(-connid) finish $token OK {} } ########################################################################## proc jlibcompress::finish {token res xmldata} { variable $token upvar 0 $token state ::LOG "(jlibcompress::finish $token) res" if {$res != "OK"} { jlib::client status [::msgcat::mc "Compression negotiation failed"] } else { jlib::client status [::msgcat::mc "Compression negotiation successful"] } if {[info exists state(-command)]} { uplevel #0 $state(-command) [list $res $xmldata] } } ########################################################################## tkabber-0.11.1/userinfo.tcl0000644000175000017500000007701211014017247015064 0ustar sergeisergei# $Id: userinfo.tcl 1428 2008-05-18 12:18:47Z sergei $ namespace eval userinfo { custom::defvar show_info_list {} [::msgcat::mc "List of users for userinfo."] \ -group Hidden } proc userinfo::show_info_dialog {} { variable show_info_jid variable show_info_list variable show_info_connid if {[lempty [jlib::connections]]} return set gw .userinfo catch { destroy $gw } set connid [lindex [jlib::connections] 0] set show_info_connid [jlib::connection_jid $connid] Dialog $gw -title [::msgcat::mc "Show user or service info"] -separator 1 -anchor e \ -default 0 -cancel 1 set gf [$gw getframe] grid columnconfigure $gf 1 -weight 1 set show_info_jid "" label $gf.ljid -text [::msgcat::mc "JID:"] ecursor_entry [ComboBox $gf.jid -textvariable [namespace current]::show_info_jid \ -values [linsert $show_info_list 0 ""] -width 35].e grid $gf.ljid -row 0 -column 0 -sticky e grid $gf.jid -row 0 -column 1 -sticky ew if {[llength [jlib::connections]] > 1} { set connections {} foreach c [jlib::connections] { lappend connections [jlib::connection_jid $c] } label $gf.lconnection -text [::msgcat::mc "Connection:"] ComboBox $gf.connection -textvariable [namespace current]::show_info_connid \ -values $connections grid $gf.lconnection -row 1 -column 0 -sticky e grid $gf.connection -row 1 -column 1 -sticky ew } $gw add -text [::msgcat::mc "Show"] -command "[namespace current]::show_info $gw" $gw add -text [::msgcat::mc "Cancel"] -command "destroy $gw" $gw draw $gf.jid } proc userinfo::show_info {gw} { variable show_info_jid variable show_info_list variable show_info_connid destroy $gw foreach c [jlib::connections] { if {[jlib::connection_jid $c] == $show_info_connid} { set connid $c } } if {![info exists connid]} { set connid [jlib::route $show_info_jid] } set show_info_list [update_combo_list $show_info_list $show_info_jid 10] userinfo::open $show_info_jid -connection $connid } proc userinfo::w_from_jid {jid} { return [win_id userinfo $jid] } proc userinfo::pack_frame {w text} { set tf [TitleFrame $w -borderwidth 2 -relief groove -text $text] pack $tf -fill both -expand yes return [$tf getframe] } proc userinfo::pack_entry {jid g row name text} { set w [w_from_jid $jid] label $g.l$name -text $text upvar editable editable entry $g.$name -textvariable userinfo::userinfo($name,$jid) if {$editable} { ecursor_entry $g.$name } else { set fgcolor [lindex [$g.$name configure -foreground] 4] # set bgcolor [lindex [$g.$name configure -background] 4] set bgcolor [option get $g background Notebook] if {[info tclversion] >= 8.4} { $g.$name configure -state readonly -relief flat -highlightcolor $bgcolor -takefocus 0 } else { $g.$name configure -state disabled -relief flat -background $bgcolor } } grid $g.l$name -row $row -column 0 -sticky e grid $g.$name -row $row -column 1 -sticky we grid columnconfig $g 1 -weight 1 -minsize 0 #grid rowconfig $g $row -weight 1 -minsize 0 } proc userinfo::pack_text_entry {jid g row name text} { variable userinfo set w [w_from_jid $jid] label $g.l$name -text $text text $g.$name -height 1 -state disabled -relief flat \ -background [option get $g background Notebook] ::richtext::config $g.$name -using url fill_user_description $g.$name userinfo($name,$jid) 0 grid $g.l$name -row $row -column 0 -sticky e grid $g.$name -row $row -column 1 -sticky we grid columnconfig $g 1 -weight 1 -minsize 0 trace variable [namespace current]::userinfo($name,$jid) w \ [list userinfo::fill_user_description $g.$name userinfo($name,$jid) 0] bind $g.$name \ +[list trace vdelete [namespace current]::userinfo($name,$jid) w \ [list userinfo::fill_user_description $g.$name \ userinfo($name,$jid) 0]] } proc userinfo::pack_spinbox {jid g row col name low high text} { label $g.l$name -text $text set width [expr {[string length $high] + 1}] if {[info tclversion] >= 8.4} { spinbox $g.$name -from $low -to $high -increment 1 \ -buttoncursor left_ptr -width $width \ -textvariable userinfo::userinfo($name,$jid) } else { SpinBox $g.$name -range [list $low $high 1] -width $width \ -textvariable userinfo::userinfo($name,$jid) } grid $g.l$name -row $row -column $col -sticky e grid $g.$name -row $row -column [expr {$col + 1}] -sticky we } proc userinfo::manage_focus {jid tab w editable} { variable userinfo if {$editable} { upvar $tab t set userinfo(focus_$tab,$jid) $w bind $t "+focus \$[list [namespace current]::userinfo(focus_$tab,$jid)]" bind $t "+set [list [namespace current]::userinfo(focus_$tab,$jid)] \[focus\]" } } proc userinfo::open_client {jid args} { eval [list open $jid] $args -page client } proc userinfo::open {jid args} { global tcl_platform variable userinfo set w [w_from_jid $jid] if {[winfo exists $w]} { #focus -force $w #return destroy $w } set editable 0 set top_page personal foreach {opt val} $args { switch -- $opt { -editable {set editable $val} -connection {set connid $val} -page {set top_page $val} } } if {![info exists connid]} { set connid [jlib::route $jid] } toplevel $w -relief $::tk_relief -borderwidth $::tk_borderwidth wm group $w . wm withdraw $w set title [format [::msgcat::mc "%s info"] $jid] wm title $w $title wm iconname $w $title if {$editable} { set bbox [ButtonBox $w.bbox -spacing 10 -padx 10 -default 0] $bbox add -text [::msgcat::mc "Update"] -command " userinfo::send_vcard [list $connid] [list $jid] destroy [list $w] " bind $w "ButtonBox::invoke $bbox default" bind $w "ButtonBox::invoke $bbox 1" $bbox add -text [::msgcat::mc "Cancel"] -command [list destroy $w] set sep [Separator::create $w.sep -orient horizontal] pack $sep -pady 1m -fill x -side bottom pack $bbox -padx 1m -pady 1m -anchor e -side bottom } frame $w.frame pack $w.frame -padx 1m -pady 1m -expand yes -fill both set bg [$w.frame cget -background] set tab [NoteBook $w.frame.tab] pack $tab -expand yes -fill both set personal [$tab insert end personal -text [::msgcat::mc "Personal"]] set n [pack_frame $personal.n [::msgcat::mc "Name"]] pack_entry $jid $n 0 fn [::msgcat::mc "Full Name:"] pack_entry $jid $n 1 family [::msgcat::mc "Family Name:"] pack_entry $jid $n 2 name [::msgcat::mc "Name:"] pack_entry $jid $n 3 middle [::msgcat::mc "Middle Name:"] pack_entry $jid $n 4 prefix [::msgcat::mc "Prefix:"] pack_entry $jid $n 5 suffix [::msgcat::mc "Suffix:"] pack_entry $jid $n 6 nickname [::msgcat::mc "Nickname:"] set c [pack_frame $personal.info [::msgcat::mc "Information"]] pack_entry $jid $c 0 email [::msgcat::mc "E-mail:"] if {$editable} { pack_entry $jid $c 1 url [::msgcat::mc "Web Site:"] } else { pack_text_entry $jid $c 1 url [::msgcat::mc "Web Site:"] } pack_entry $jid $c 2 jabberid [::msgcat::mc "JID:"] pack_entry $jid $c 3 uid [::msgcat::mc "UID:"] manage_focus $jid personal $n.fn $editable set phones [$tab insert end phones -text [::msgcat::mc "Phones"]] set t [pack_frame $phones.tel [::msgcat::mc "Telephone numbers"]] pack_entry $jid $t 0 tel_home [::msgcat::mc "Home:"] pack_entry $jid $t 1 tel_work [::msgcat::mc "Work:"] pack_entry $jid $t 2 tel_voice [::msgcat::mc "Voice:"] pack_entry $jid $t 3 tel_fax [::msgcat::mc "Fax:"] pack_entry $jid $t 4 tel_pager [::msgcat::mc "Pager:"] pack_entry $jid $t 5 tel_msg [::msgcat::mc "Message Recorder:"] pack_entry $jid $t 6 tel_cell [::msgcat::mc "Cell:"] pack_entry $jid $t 7 tel_video [::msgcat::mc "Video:"] pack_entry $jid $t 8 tel_bbs [::msgcat::mc "BBS:"] pack_entry $jid $t 9 tel_modem [::msgcat::mc "Modem:"] pack_entry $jid $t 10 tel_isdn [::msgcat::mc "ISDN:"] pack_entry $jid $t 11 tel_pcs [::msgcat::mc "PCS:"] pack_entry $jid $t 12 tel_pref [::msgcat::mc "Preferred:"] manage_focus $jid phones $t.tel_home $editable set location [$tab insert end location -text [::msgcat::mc "Location"]] set l [pack_frame $location.address [::msgcat::mc "Address"]] pack_entry $jid $l 0 address [::msgcat::mc "Address:"] pack_entry $jid $l 1 address2 [::msgcat::mc "Address 2:"] pack_entry $jid $l 2 city [::msgcat::mc "City:"] pack_entry $jid $l 3 state [::msgcat::mc "State:"] pack_entry $jid $l 4 pcode [::msgcat::mc "Postal Code:"] pack_entry $jid $l 5 country [::msgcat::mc "Country:"] set g [pack_frame $location.geo [::msgcat::mc "Geographical position"]] pack_entry $jid $g 0 geo_lat [::msgcat::mc "Latitude:"] pack_entry $jid $g 1 geo_lon [::msgcat::mc "Longitude:"] manage_focus $jid location $l.address $editable set organization [$tab insert end organization -text [::msgcat::mc "Organization"]] set d [pack_frame $organization.details [::msgcat::mc "Details"]] pack_entry $jid $d 0 orgname [string trim [::msgcat::mc "Name: "]] pack_entry $jid $d 1 orgunit [::msgcat::mc "Unit:"] set p [pack_frame $organization.personal [string trim [::msgcat::mc "Personal "]]] pack_entry $jid $p 0 title [::msgcat::mc "Title:"] pack_entry $jid $p 1 role [::msgcat::mc "Role:"] manage_focus $jid organization $d.orgname $editable # This strange trim is to distinguish different "about"s set about [$tab insert end about -text [string trim [::msgcat::mc "About "]]] set b [pack_frame $about.bday [::msgcat::mc "Birthday"]] if {!$editable} { pack_entry $jid $b 0 bday [::msgcat::mc "Birthday:"] } else { pack_spinbox $jid $b 0 0 bdayyear 1900 1000000 [::msgcat::mc "Year:"] grid [label $b.space0 -text " "] -row 0 -column 2 pack_spinbox $jid $b 0 3 bdaymonth 0 12 [::msgcat::mc "Month:"] grid [label $b.space1 -text " "] -row 0 -column 5 pack_spinbox $jid $b 0 6 bdayday 0 31 [::msgcat::mc "Day:"] } set a [pack_frame $about.about [string trim [::msgcat::mc "About "]]] set sw [ScrolledWindow $a.sw -scrollbar vertical] if {!$editable} { text $a.text -height 12 -wrap word ::richtext::config $a.text -using {url emoticon} } else { textUndoable $a.text -height 12 -wrap word } $sw setwidget $a.text if {$editable} { bind $a.text [bind Text ] bind $a.text +break bind $a.text " ButtonBox::invoke $bbox default break " } fill_user_description $a.text userinfo(desc,$jid) $editable pack $sw -fill both -expand yes pack $a -fill both -expand yes trace variable [namespace current]::userinfo(desc,$jid) w \ [list userinfo::fill_user_description $a.text \ userinfo(desc,$jid) $editable] bind $a.text \ +[list trace vdelete [namespace current]::userinfo(desc,$jid) w \ [list userinfo::fill_user_description $a.text \ userinfo(desc,$jid) $editable]] set userinfo(descfield,$jid) $a.text manage_focus $jid about $b.bday[expr {$editable ? "year" : ""}] $editable if {!$editable} { set photo [$tab insert end photo -text [::msgcat::mc "Photo"] \ -raisecmd [list after idle \ [list [namespace current]::reconfigure_photo $jid]]] } else { set photo [$tab insert end photo -text [::msgcat::mc "Photo"]] } set p [pack_frame $photo.photo [::msgcat::mc "Photo"]] set photo_img photo_$jid if {![lcontain [image names] $photo_img]} { image create photo $photo_img } if {!$editable} { pack_text_entry $jid $p 0 photo_extval [::msgcat::mc "URL:"] set sw [ScrolledWindow $p.sw] grid $sw -row 1 -column 0 -sticky wens -columnspan 2 -pady 0.5m grid rowconfig $p 1 -weight 1 set sf [ScrollableFrame $p.sf] $sw setwidget $sf set l [label [$sf getframe].photo -image $photo_img -bd 0] grid $l -row 0 -column 0 bindscroll $l $sf bindscroll $sf $sf } else { if {![info exists userinfo(photo_use,$jid)]} { set userinfo(photo_use,$jid) none } radiobutton $p.use_url -text [::msgcat::mc "URL"] \ -value url -variable userinfo::userinfo(photo_use,$jid) \ -command [list [namespace current]::enable_active_photo $p $jid] radiobutton $p.use_image -text [::msgcat::mc "Image"] \ -value image -variable userinfo::userinfo(photo_use,$jid) \ -command [list [namespace current]::enable_active_photo $p $jid] radiobutton $p.use_none -text [::msgcat::mc "None"] \ -value none -variable userinfo::userinfo(photo_use,$jid) \ -command [list [namespace current]::enable_active_photo $p $jid] entry $p.photo_url -textvariable userinfo::userinfo(photo_extval,$jid) label $p.photo -image $photo_img grid $p.use_url -row 1 -column 0 -sticky w grid $p.photo_url -row 1 -column 1 -sticky we grid $p.use_image -row 2 -column 0 -sticky w grid $p.photo -row 3 -column 1 -sticky we grid $p.use_none -row 0 -column 0 -sticky w button $p.loadimage -text [::msgcat::mc "Load Image"] \ -command [list userinfo::load_photo $jid $p.photo] grid $p.loadimage -row 2 -column 1 -sticky w grid columnconfig $p 1 -weight 1 -minsize 0 #grid rowconfig $p 0 -weight 1 grid rowconfig $p 1 #grid rowconfig $p 1 -weight 1 enable_active_photo $p $jid manage_focus $jid photo $p.use_none $editable trace variable [namespace current]::userinfo(photo_use,$jid) w \ [list userinfo::enable_active_photo $p $jid] bind $p \ +[list trace vdelete [namespace current]::userinfo(photo_use,$jid) w \ [list userinfo::enable_active_photo $p $jid]] } if {!$editable} { $a.text configure -state disabled } hook::run userinfo_hook $tab $connid $jid $editable set vjid [node_and_server_from_jid $jid] if {[chat::is_groupchat [chat::chatid $connid $vjid]]} { set vjid $jid } jlib::send_iq get \ [jlib::wrapper:createtag vCard \ -vars [list xmlns vcard-temp]] \ -to $vjid \ -connection $connid \ -command [list userinfo::parse_vcard $jid] $tab compute_size bind $w [list ifacetk::tab_move $tab -1] bind $w [list ifacetk::tab_move $tab 1] $tab raise $top_page wm deiconify $w } proc userinfo::reconfigure_photo {jid} { set w [w_from_jid $jid] set tab $w.frame.tab if {![winfo exists $tab]} return set photo [$tab getframe photo].photo set p [$photo getframe] set sw $p.sw set sf $p.sf set l [$sf getframe].photo update if {![winfo exists $l]} return $sf configure -areawidth [max [winfo width $l] [winfo width $sw]] \ -areaheight [max [winfo height $l] [winfo height $sw]] } proc userinfo::client_page {tab connid jid editable} { if {$editable} return set client [$tab insert end client -text [::msgcat::mc "Client"]] set c [pack_frame $client.client [::msgcat::mc "Client"]] pack_entry $jid $c 0 clientname [::msgcat::mc "Client:"] pack_entry $jid $c 1 clientversion [::msgcat::mc "Version:"] pack_entry $jid $c 2 os [::msgcat::mc "OS:"] set l [pack_frame $client.last [::msgcat::mc "Last Activity or Uptime"]] pack_entry $jid $l 0 lastseconds [::msgcat::mc "Interval:"] pack_entry $jid $l 1 lastdesc [::msgcat::mc "Description:"] set o [pack_frame $client.computer [::msgcat::mc "Time"]] pack_entry $jid $o 0 time [::msgcat::mc "Time:"] pack_entry $jid $o 1 tz [::msgcat::mc "Time Zone:"] pack_entry $jid $o 2 utc [::msgcat::mc "UTC:"] # FIX -to ... request_iq version $connid $jid request_iq time $connid $jid request_iq last $connid $jid } hook::add userinfo_hook [namespace current]::userinfo::client_page proc userinfo::enable_active_photo {p jid args} { switch -- $userinfo::userinfo(photo_use,$jid) { url { $p.photo_url configure -state normal $p.loadimage configure -state disabled focus $p.use_url } image { $p.photo_url configure -state disabled $p.loadimage configure -state normal focus $p.use_image } none { $p.photo_url configure -state disabled $p.loadimage configure -state disabled focus $p.use_none } } } proc userinfo::fill_user_description {txt descvar editable args} { variable userinfo if {[info exists $descvar] && [winfo exists $txt]} { set state [$txt cget -state] $txt configure -state normal $txt delete 0.0 end if {$editable} { $txt insert 0.0 [set $descvar] } else { ::richtext::render_message $txt [set $descvar] "" $txt delete {end - 1 char} } $txt configure -state $state } } proc userinfo::load_photo {jid l} { variable userinfo set photo_img photo_$jid if {[catch { package require Img }]} { set types [list [list [::msgcat::mc "GIF images"] {.gif}] \ [list [::msgcat::mc "All files"] {*}]] } else { set types [list [list [::msgcat::mc "JPEG images"] {.jpg .jpeg}] \ [list [::msgcat::mc "GIF images"] {.gif}] \ [list [::msgcat::mc "PNG images"] {.png}] \ [list [::msgcat::mc "All files"] {*}]] } set filename [tk_getOpenFile -filetypes $types] if {$filename != ""} { if {[catch {image create photo $photo_img -file $filename} res]} { if {[winfo exists .load_photo_error]} { destroy .load_photo_error } NonmodalMessageDlg .load_photo_error -aspect 50000 -icon error \ -message [format [::msgcat::mc "Loading photo failed: %s."] \ $res] } else { set f [::open $filename] fconfigure $f -translation binary set userinfo(photo_binval,$jid) [read $f] binary scan $userinfo(photo_binval,$jid) H4 binsig switch -- $binsig { ffd8 { set userinfo(photo_type,$jid) "image/jpeg" } 4749 { set userinfo(photo_type,$jid) "image/gif" } 8950 { set userinfo(photo_type,$jid) "image/png" } default { set userinfo(photo_type,$jid) "image" } } close $f set userinfo(photo_use_binval,$jid) 1 } } } proc userinfo::parse_vcard {jid res child} { debugmsg userinfo "$res $child" if {![cequal $res OK]} { return } jlib::wrapper:splitxml $child tag vars isempty chdata children foreach item $children { parse_vcard_item $jid $item } } proc userinfo::parse_vcard_item {jid child} { variable userinfo set w [w_from_jid $jid] jlib::wrapper:splitxml $child tag vars isempty chdata children # TODO: # VERSION, --- # ADR?, # LABEL?, # TEL?, +? # EMAIL?, # MAILER?, # TZ?, # LOGO?, # AGENT?, # CATEGORIES?, # NOTE?, # PRODID?, # REV?, # SORT-STRING?, # SOUND?, # UID?, # URL?, # CLASS?, # KEY?, switch -- $tag { FN {set userinfo(fn,$jid) $chdata} NICKNAME {set userinfo(nickname,$jid) $chdata} N {parse_vcard_n_item $jid $children} PHOTO {parse_vcard_photo_item $jid $children} ADR {parse_vcard_adr_item $jid $children} TEL {parse_vcard_tel_item $jid $children} TEL {set userinfo(telephone,$jid) $chdata} EMAIL { set userinfo(email,$jid) $chdata parse_vcard_email_item $jid $children } JABBERID {set userinfo(jabberid,$jid) $chdata} GEO {parse_vcard_geo_item $jid $children} ORG {parse_vcard_org_item $jid $children} TITLE {set userinfo(title,$jid) $chdata} ROLE {set userinfo(role,$jid) $chdata} BDAY { set userinfo(bday,$jid) $chdata if {![catch {set bday [clock scan $chdata]}]} { set userinfo(bdayyear,$jid) [clock format $bday -format %Y] set userinfo(bdaymonth,$jid) [clock format $bday -format %m] set userinfo(bdayday,$jid) [clock format $bday -format %d] } } UID {set userinfo(uid,$jid) $chdata} URL {set userinfo(url,$jid) $chdata} DESC {set userinfo(desc,$jid) $chdata} default {debugmsg userinfo "Unknown vCard tag $tag"} } } proc userinfo::parse_vcard_email_item {jid items} { variable userinfo foreach item $items { jlib::wrapper:splitxml $item tag vars isempty chdata children switch -- $tag { USERID {set userinfo(email,$jid) $chdata} } } } proc userinfo::parse_vcard_n_item {jid items} { variable userinfo set w [w_from_jid $jid] foreach item $items { jlib::wrapper:splitxml $item tag vars isempty chdata children switch -- $tag { FAMILY {set userinfo(family,$jid) $chdata} GIVEN {set userinfo(name,$jid) $chdata} MIDDLE {set userinfo(middle,$jid) $chdata} PREFIX {set userinfo(prefix,$jid) $chdata} SUFFIX {set userinfo(suffix,$jid) $chdata} default {debugmsg userinfo "Unknown vCard subtag $tag"} } } } proc userinfo::parse_vcard_photo_item {jid items} { variable userinfo set w [w_from_jid $jid] foreach item $items { jlib::wrapper:splitxml $item tag vars isempty chdata children switch -- $tag { BINVAL { catch { set userinfo(photo_binval,$jid) [base64::decode $chdata] set userinfo(photo_use,$jid) image photo_$jid blank photo_$jid put $chdata catch { reconfigure_photo $jid } } } EXTVAL { set userinfo(photo_extval,$jid) $chdata set userinfo(photo_use,$jid) url } TYPE { set userinfo(photo_type,$jid) $chdata } default {debugmsg userinfo "Unknown vCard subtag $tag"} } } } proc userinfo::parse_vcard_adr_item {jid items} { variable userinfo set w [w_from_jid $jid] foreach item $items { jlib::wrapper:splitxml $item tag vars isempty chdata children # TODO: # HOME?, # WORK?, # POSTAL?, # PARCEL?, # (DOM | INTL)?, # PREF?, # POBOX?, # LOCALITY?, switch -- $tag { STREET {set userinfo(address,$jid) $chdata} EXTADD {set userinfo(address2,$jid) $chdata} LOCALITY {set userinfo(city,$jid) $chdata} REGION {set userinfo(state,$jid) $chdata} PCODE {set userinfo(pcode,$jid) $chdata} COUNTRY {set userinfo(country,$jid) $chdata} CTRY {set userinfo(country,$jid) $chdata} default {debugmsg userinfo "Unknown vCard subtag $tag"} } } } proc userinfo::parse_vcard_tel_item {jid items} { variable userinfo set w [w_from_jid $jid] set types {} foreach item $items { jlib::wrapper:splitxml $item tag vars isempty chdata children # TODO: # HOME?, # WORK?, # VOICE?, # FAX?, # PAGER?, # MSG?, # CELL?, # VIDEO?, # BBS?, # MODEM?, # ISDN?, # PCS?, # PREF?, # NUMBER switch -- $tag { HOME {lappend types home} WORK {lappend types work} VOICE {lappend types voice} FAX {lappend types fax} PAGER {lappend types pager} MSG {lappend types msg} CELL {lappend types cell} VIDEO {lappend types video} BBS {lappend types bbs} MODEM {lappend types modem} ISDN {lappend types isdn} PCS {lappend types pcs} PREF {lappend types pref} NUMBER { foreach t $types { set userinfo(tel_$t,$jid) $chdata } } default {debugmsg userinfo "Unknown vCard subtag $tag"} } } } proc userinfo::parse_vcard_geo_item {jid items} { variable userinfo set w [w_from_jid $jid] foreach item $items { jlib::wrapper:splitxml $item tag vars isempty chdata children switch -- $tag { LAT {set userinfo(geo_lat,$jid) $chdata} LON {set userinfo(geo_lon,$jid) $chdata} default {debugmsg userinfo "Unknown vCard subtag $tag"} } } } proc userinfo::parse_vcard_org_item {jid items} { variable userinfo set w [w_from_jid $jid] # TODO: foreach item $items { jlib::wrapper:splitxml $item tag vars isempty chdata children switch -- $tag { ORGNAME {set userinfo(orgname,$jid) $chdata} ORGUNIT {set userinfo(orgunit,$jid) $chdata} default {debugmsg userinfo "Unknown vCard subtag $tag"} } } } proc userinfo::request_iq {kind connid jid} { jlib::send_iq get \ [jlib::wrapper:createtag query \ -vars [list xmlns jabber:iq:$kind]] \ -to [get_jid_of_user $connid $jid] \ -connection $connid \ -command [list userinfo::parse_iq$kind $jid] } proc userinfo::parse_iqversion {jid res child} { debugmsg userinfo "$res $child" if {![cequal $res OK]} { return } jlib::wrapper:splitxml $child tag vars isempty chdata children if {[cequal [jlib::wrapper:getattr $vars xmlns] jabber:iq:version]} { userinfo::parse_iqversion_item $jid $children } } proc userinfo::parse_iqversion_item {jid items} { variable userinfo set w [w_from_jid $jid] foreach item $items { jlib::wrapper:splitxml $item tag vars isempty chdata children switch -- $tag { name {set userinfo(clientname,$jid) $chdata} version {set userinfo(clientversion,$jid) $chdata} os {set userinfo(os,$jid) $chdata} default {debugmsg userinfo "Unknown iq:version tag '$tag'"} } } } proc userinfo::parse_iqtime {jid res child} { debugmsg userinfo "$res $child" if {![cequal $res OK]} { return } jlib::wrapper:splitxml $child tag vars isempty chdata children if {[cequal [jlib::wrapper:getattr $vars xmlns] jabber:iq:time]} { userinfo::parse_iqtime_item $jid $children } } proc userinfo::parse_iqtime_item {jid items} { variable userinfo set w [w_from_jid $jid] foreach item $items { jlib::wrapper:splitxml $item tag vars isempty chdata children switch -- $tag { utc {set userinfo(utc,$jid) $chdata} display {set userinfo(time,$jid) $chdata} tz {set userinfo(tz,$jid) $chdata} default {debugmsg userinfo "Unknown iq:time tag '$tag'"} } } } proc userinfo::parse_iqlast {jid res child} { variable userinfo debugmsg userinfo "$res $child" if {![cequal $res OK]} { return } set w [w_from_jid $jid] jlib::wrapper:splitxml $child tag vars isempty chdata children if {[cequal [jlib::wrapper:getattr $vars xmlns] jabber:iq:last]} { set seconds [jlib::wrapper:getattr $vars seconds] if {[string is integer -strict $seconds]} { set userinfo(lastseconds,$jid) [format_time $seconds] } else { set userinfo(lastseconds,$jid) "" } set userinfo(lastdesc,$jid) $chdata } } proc userinfo::append_tag {varname tag chdata {subtags {}}} { upvar $varname tags if {$chdata != "" || $subtags != {}} { lappend tags [jlib::wrapper:createtag $tag -chdata $chdata \ -subtags $subtags] } } proc userinfo::send_vcard {connid jid} { variable userinfo set w [w_from_jid $jid] set tags {} append_tag tags FN $userinfo(fn,$jid) append_tag tags NICKNAME $userinfo(nickname,$jid) append_tag tags N "" [make_n_item $jid] append_tag tags PHOTO "" [make_photo_item $jid] append_tag tags ADR "" [make_adr_item $jid] eval lappend tags [make_tel_item $jid] eval lappend tags [make_email_item $jid] append_tag tags EMAIL $userinfo(email,$jid) append_tag tags JABBERID $userinfo(jabberid,$jid) append_tag tags GEO "" [make_geo_item $jid] append_tag tags ORG "" [make_org_item $jid] append_tag tags TITLE $userinfo(title,$jid) append_tag tags ROLE $userinfo(role,$jid) if {($userinfo(bdaymonth,$jid) > 0) && ($userinfo(bdayday,$jid) > 0)} { set userinfo(bday,$jid) [format "%d-%02d-%02d" \ [string trimleft $userinfo(bdayyear,$jid) "0"] \ [string trimleft $userinfo(bdaymonth,$jid) "0"] \ [string trimleft $userinfo(bdayday,$jid) "0"]] } else { set userinfo(bday,$jid) "" } append_tag tags BDAY $userinfo(bday,$jid) append_tag tags UID $userinfo(uid,$jid) append_tag tags URL $userinfo(url,$jid) append_tag tags DESC [$userinfo(descfield,$jid) get 0.0 "end -1 chars"] debugmsg userinfo $tags jlib::send_iq set \ [jlib::wrapper:createtag vCard \ -vars [list xmlns vcard-temp] \ -subtags $tags] \ -connection $connid } proc userinfo::make_n_item {jid} { variable userinfo set tags {} append_tag tags FAMILY $userinfo(family,$jid) append_tag tags GIVEN $userinfo(name,$jid) append_tag tags MIDDLE $userinfo(middle,$jid) append_tag tags PREFIX $userinfo(prefix,$jid) append_tag tags SUFFIX $userinfo(suffix,$jid) return $tags } proc userinfo::make_email_item {jid} { variable userinfo set tags {} if {$userinfo(email,$jid) != ""} { append_tag tags EMAIL "" \ [list [jlib::wrapper:createtag INTERNET] \ [jlib::wrapper:createtag USERID \ -chdata $userinfo(email,$jid)]] } return $tags } proc userinfo::make_photo_item {jid} { variable userinfo set tags {} switch -- $userinfo(photo_use,$jid) { url { append_tag tags EXTVAL $userinfo(photo_extval,$jid) } image { if {[info exists userinfo(photo_binval,$jid)]} { append_tag tags TYPE $userinfo(photo_type,$jid) append_tag tags \ BINVAL [base64::encode $userinfo(photo_binval,$jid)] } } } return $tags } proc userinfo::make_adr_item {jid} { variable userinfo set tags {} append_tag tags STREET $userinfo(address,$jid) append_tag tags EXTADD $userinfo(address2,$jid) append_tag tags LOCALITY $userinfo(city,$jid) append_tag tags REGION $userinfo(state,$jid) append_tag tags PCODE $userinfo(pcode,$jid) append_tag tags CTRY $userinfo(country,$jid) return $tags } proc userinfo::make_tel_item {jid} { variable userinfo set tags {} foreach t {home work voice fax pager msg cell \ video bbs modem isdn pcs pref} { if {$userinfo(tel_$t,$jid) != ""} { append_tag tags TEL "" \ [list \ [jlib::wrapper:createtag [string toupper $t]] \ [jlib::wrapper:createtag NUMBER \ -chdata $userinfo(tel_$t,$jid)]] } } return $tags } proc userinfo::make_geo_item {jid} { variable userinfo set tags {} append_tag tags LAT $userinfo(geo_lat,$jid) append_tag tags LON $userinfo(geo_lon,$jid) return $tags } proc userinfo::make_org_item {jid} { variable userinfo set tags {} append_tag tags ORGNAME $userinfo(orgname,$jid) append_tag tags ORGUNIT $userinfo(orgunit,$jid) return $tags } proc userinfo::add_menu_item {m connid jid} { $m add command -label [::msgcat::mc "Show info"] \ -command [list userinfo::open $jid -connection $connid] } hook::add chat_create_user_menu_hook userinfo::add_menu_item 60 hook::add chat_create_conference_menu_hook userinfo::add_menu_item 60 hook::add roster_create_groupchat_user_menu_hook userinfo::add_menu_item 60 hook::add roster_conference_popup_menu_hook userinfo::add_menu_item 60 hook::add roster_service_popup_menu_hook userinfo::add_menu_item 60 hook::add roster_jid_popup_menu_hook userinfo::add_menu_item 60 hook::add message_dialog_menu_hook userinfo::add_menu_item 60 hook::add search_popup_menu_hook userinfo::add_menu_item 60 hook::add postload_hook \ [list disco::browser::register_feature_handler vcard-temp userinfo::open \ -desc [list user [::msgcat::mc "User info"] \ client [::msgcat::mc "User info"] \ * [::msgcat::mc "Service info"]]] hook::add postload_hook \ [list disco::browser::register_feature_handler jabber:iq:last userinfo::open_client \ -desc [list user [::msgcat::mc "Last activity"] \ client [::msgcat::mc "Last activity"] \ * [::msgcat::mc "Uptime"]]] hook::add postload_hook \ [list disco::browser::register_feature_handler jabber:iq:time userinfo::open_client \ -desc [list * [::msgcat::mc "Time"]]] hook::add postload_hook \ [list disco::browser::register_feature_handler jabber:iq:version userinfo::open_client \ -desc [list * [::msgcat::mc "Version"]]] # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/gpgme.tcl0000644000175000017500000011450711062704714014337 0ustar sergeisergei# $Id: gpgme.tcl 1502 2008-09-13 09:37:16Z sergei $ namespace eval ::ssj {} ############################################################################# # Draw icons aside encrypted messages even if no GPG support proc ::ssj::draw_encrypted {chatid from type body x} { # we already deciphered it in rewrite_message_hook set chatw [chat::chat_win $chatid] foreach xe $x { jlib::wrapper:splitxml $xe tag vars isempty cdata children if {![cequal [jlib::wrapper:getattr $vars xmlns] $::NS(encrypted)]} { continue } if {[cequal $cdata ""] || \ [cequal [info commands ::ssj::encrypted:input] ""]} { $chatw image create end -image gpg/badencrypted } else { $chatw image create end -image gpg/encrypted } break } } hook::add draw_message_hook ::ssj::draw_encrypted 6 ############################################################################# proc ::ssj::process_x_encrypted {rowvar bodyvar f x connid from id type replyP} { upvar 2 $rowvar row upvar 2 $bodyvar body if {!$replyP || [cequal $type error]} { return } foreach xa $x { jlib::wrapper:splitxml $xa tag vars isempty cdata children set xmlns [jlib::wrapper:getattr $vars xmlns] if {$xmlns != $::NS(encrypted)} continue # we already deciphered it in rewrite_message_hook set lb [join [lrange [split $f .] 0 end-1] .].title.encrypted if {[winfo exists $lb]} { destroy $lb } if {[cequal $cdata ""] || \ [cequal [info commands ::ssj::encrypted:input] ""]} { Label $lb -image gpg/badencrypted } else { Label $lb -image gpg/encrypted } grid $lb -row 1 -column 3 -sticky e } return } hook::add message_process_x_hook ::ssj::process_x_encrypted 21 ############################################################################# if {![catch {package require gpg}]} { set gpgPkg gpg } elseif {![catch {package require gpgme}]} { set gpgPkg gpgme } else { debugmsg ssj "unable to load the GPG package, so no crypto!" return } namespace eval ::ssj { variable options custom::defgroup GPG [::msgcat::mc "GPG options (signing and encryption)."] \ -group Tkabber custom::defvar options(one-passphrase) 1 \ [::msgcat::mc "Use the same passphrase for signing and decrypting messages."] \ -group GPG -type boolean custom::defvar options(sign-traffic) 0 \ [::msgcat::mc "GPG-sign outgoing messages and presence updates."] \ -group GPG -type boolean custom::defvar options(encrypt-traffic) 0 \ [::msgcat::mc "GPG-encrypt outgoing messages where possible."] \ -group GPG -type boolean custom::defvar options(key) "" \ [::msgcat::mc "Use specified key ID for signing and decrypting messages."] \ -group GPG -type string custom::defvar options(display_sig_warnings) 1 \ [::msgcat::mc "Display warning dialogs when signature verification fails."] \ -group GPG -type boolean } package require base64 namespace eval ::ssj { variable ctx variable e4me variable j2k variable options variable passphrase variable s2e variable signers variable warnings variable gpg_error_id 0 array set ctx {} array set j2k {} array set options {} array set passphrase {} array set s2e \ [list none [::msgcat::mc "No information available"] \ bad [::msgcat::mc "Invalid signature"] \ nokey [::msgcat::mc "Signature not processed due to missing key"] \ nosig [::msgcat::mc "Malformed signature block"] \ error [::msgcat::mc "Error in signature processing"] \ diff [::msgcat::mc "Multiple signatures having different authenticity"] \ expired [::msgcat::mc "The signature is good but has expired"] \ expiredkey [::msgcat::mc "The signature is good but the key has expired"]] catch {unset warnings} array set warnings {} variable signedid 0 } proc ::ssj::once_only {connid {armorP 0}} { global env gpgPkg variable options variable ctx debugmsg ssj "ONCE_ONLY $connid" if {[info exists ctx($connid)] && ![cequal $ctx($connid) ""]} { $ctx($connid) -operation set \ -property armor \ -value $armorP return } set ctx($connid) [${gpgPkg}::context] $ctx($connid) -operation set \ -property armor \ -value $armorP if {![info exists env(GPG_AGENT_INFO)]} { $ctx($connid) -operation set \ -property passphrase-callback \ -value [list ::ssj::passphrase $connid] } set pattern [jlib::connection_bare_jid $connid] set firstP 1 if {$options(key) != ""} { set patterns [list $options(key)] } else { set patterns {} } lappend patterns $pattern "" foreach p $patterns { set command [list $ctx($connid) -operation start-key -secretonly true] if {![cequal $p ""]} { lappend command -patterns [list $p] } eval $command for {set keys {}} \ {![cequal [set key [$ctx($connid) -operation next-key]] ""]} \ {lappend keys $key} {} $ctx($connid) -operation done-key if {[llength $keys] > 0} { break } if {[cequal $p ""]} { return } set firstP 0 } switch -- [llength $keys] { 0 { return } 1 { if {$firstP} { e4meP $connid $keys return } } default { } } set dw .selectkey$connid catch {destroy $dw} set titles {} set balloons {} foreach key $keys { set key_info [$ctx($connid) -operation info-key -key $key] foreach {k v} $key_info { if {[string equal $k email]} { lappend titles $key $v lappend balloons $key [key_balloon_text $key_info] break } } foreach {k v} [$ctx($connid) -operation info-key -key $key] { if {![string equal $k subkeys]} { continue } foreach subkey $v { foreach {k1 v1} $subkey { if {[string equal $k1 email]} { lappend titles $key $v1 lappend balloons $key [key_balloon_text $subkey] break } } } } } CbDialog $dw [::msgcat::mc "Select Key for Signing %s Traffic" $pattern] \ [list [::msgcat::mc "Select"] "::ssj::once_only_aux $dw $connid" \ [::msgcat::mc "Cancel"] "destroy $dw"] \ ::ssj::selectkey$connid $titles $balloons \ -modal local } proc ::ssj::key_balloon_text {key} { array set params $key if {[catch {format "%d%s/%s %s" $params(length) \ [string range $params(algorithm) 0 0] \ [string range $params(keyid) end-7 end] \ [clock format $params(created) \ -format "%Y-%m-%d"]} text]} { return "" } foreach {k v} $key { switch -- $k { userid { append text [format "\n\t%s" $v] } } } return $text } proc ::ssj::once_only_aux {dw connid} { variable selectkey$connid set keys {} foreach key [array names selectkey$connid] { if {[set selectkey${connid}($key)]} { lappend keys $key } } destroy $dw if {[llength $keys] > 0} { e4meP $connid $keys } } proc ::ssj::passphrase {connid data} { variable passphrase variable options array set params $data set lines [split [string trimright $params(description)] "\n"] set text [lindex $lines 0] if {[set x [string first " " [set keyid [lindex $lines 1]]]] > 0} { set userid [string range $keyid [expr $x+1] end] if {!$options(one-passphrase)} { set keyid [string range $keyid 0 [expr $x-1]] } else { regexp { +([^ ]+)} [lindex $lines 2] ignore keyid } } else { set userid unknown! } if {([cequal $text ENTER]) \ && ([info exists passphrase($keyid)]) \ && (![cequal $passphrase($keyid) ""])} { return $passphrase($keyid) } set pw .passphrase$connid if {[winfo exists $pw]} { destroy $pw } set title [::msgcat::mc "Please enter passphrase"] switch -- $text { ENTER { } TRY_AGAIN { set title [::msgcat::mc "Please try again"] } default { append title ": " $text } } Dialog $pw -title $title -separator 1 -anchor e -default 0 -cancel 1 set pf [$pw getframe] grid columnconfigure $pf 1 -weight 1 foreach {k v} [list keyid [::msgcat::mc "Key ID"] \ userid [::msgcat::mc "User ID"]] { label $pf.l$k -text ${v}: entry $pf.$k $pf.$k insert 0 [set $k] if {[string length [set $k]] <= 72} { $pf.$k configure -width 0 } if {[info tclversion] >= 8.4} { set bgcolor [lindex [$pf.$k configure -background] 4] $pf.$k configure -state readonly -readonlybackground $bgcolor } else { $pf.$k configure -state disabled } } label $pf.lpassword -text [::msgcat::mc "Passphrase:"] entry $pf.password \ -textvariable ::ssj::passphrase($connid,$keyid) \ -show * set passphrase($connid,$keyid) "" grid $pf.lkeyid -row 0 -column 0 -sticky e grid $pf.keyid -row 0 -column 1 -sticky ew grid $pf.luserid -row 1 -column 0 -sticky e grid $pf.userid -row 1 -column 1 -sticky ew grid $pf.lpassword -row 2 -column 0 -sticky e grid $pf.password -row 2 -column 1 -sticky ew $pw add -text [::msgcat::mc "OK"] -command "$pw enddialog 0" $pw add -text [::msgcat::mc "Cancel"] -command "$pw enddialog 1" if {[set abort [$pw draw $pf.password]]} { $params(token) -operation cancel # TODO: unset options(sign-traffic) etc. ? } destroy $pw if {!$abort} { set passphrase($keyid) $passphrase($connid,$keyid) unset passphrase($connid,$keyid) return $passphrase($keyid) } } proc ::ssj::armor:encode {text} { if {[set x [string first "\n\n" $text]] >= 0} { set text [string range $text [expr $x+2] end] } if {[set x [string first "\n-----" $text]] > 0} { set text [string range $text 0 [expr $x-1]] } return $text } proc ::ssj::armor:decode {text} { return "-----BEGIN PGP MESSAGE-----\n\n$text\n-----END PGP MESSAGE-----" } proc ::ssj::signed:input {connid from signature data what} { variable ctx variable j2k variable s2e variable warnings variable gpg_error_id variable options once_only $connid if {[catch {$ctx($connid) -operation verify \ -input [binary format a* [encoding convertto utf-8 $data]] \ -signature [armor:decode $signature]} result]} { debugmsg ssj "verify processing error ($connid): $result ($from)" if {![info exists warnings(verify-traffic,$connid)]} { set warnings(verify-traffic,$connid) 1 after idle [list NonmodalMessageDlg .verify_error$connid -aspect 50000 -icon error \ -message [::msgcat::mc "Error in signature verification software: %s." \ $result]] } set params(reason) $result return [array get params] } debugmsg ssj "VERIFY: $connid $from ($data); $result" array set params $result set result $params(status) set signatures {} foreach signature $params(signatures) { catch {unset sparams} array set sparams $signature if {[info exists sparams(key)]} { set sparams(key) [$ctx($connid) -operation info-key -key $sparams(key)] foreach {k v} $sparams(key) { switch -- $k { keyid { set j2k($from) $v break } subkeys { foreach subkey $v { catch {unset kparams} array set kparams $subkey if {[info exists kparams(keyid)]} { set j2k($from) $kparams(keyid) break } } } } } } lappend signatures [array get sparams] } catch {unset params} array set params [list signatures $signatures] if {![cequal $result good]} { if {[info exists s2e($result)]} { set result $s2e($result) } set params(reason) $result if {![info exists warnings(verify,$from)] && $options(display_sig_warnings)} { set warnings(verify,$from) 1 incr gpg_error_id after idle [list NonmodalMessageDlg .verify_error$gpg_error_id -aspect 50000 -icon error \ -message [::msgcat::mc "%s purportedly signed by %s can't be verified.\n\n%s." \ $what $from $result]] } } return [array get params] } proc ::ssj::signed:output {connid data args} { variable ctx variable options variable warnings variable gpg_error_id if {(!$options(sign-traffic)) || ([cequal $data ""])} { return } once_only $connid 1 if {[catch {$ctx($connid) -operation sign \ -input [binary format a* [encoding convertto utf-8 $data]] \ -mode detach} result]} { set options(sign-traffic) 0 debugmsg ssj "signature processing error ($connid): $result ($data)" if {[llength $args] == 0} { set buttons ok set cancel 0 set message [::msgcat::mc "Unable to sign presence information:\ %s.\n\nPresence will be sent, but\ signing traffic is now disabled." $result] } else { set buttons {ok cancel} set cancel 1 set message [::msgcat::mc "Unable to sign message body:\ %s.\n\nSigning traffic is now\ disabled.\n\nSend it WITHOUT a signature?"\ $result] } incr gpg_error_id if {[MessageDlg .sign_error$gpg_error_id -aspect 50000 -icon error -type user \ -buttons $buttons -default 0 -cancel $cancel \ -message $message]} { error "" } return } set result [armor:encode $result] debugmsg ssj "SIGN: $data; $result" whichkeys $connid sign return $result } proc ::ssj::signed:info {pinfo} { set text "" array set params $pinfo foreach {k v} $pinfo { if {![cequal $k signatures]} { if {![cequal $v ""]} { append text [format "%s: %s\n" $k $v] } } } foreach signature $params(signatures) { set info "" set addrs "" set s "" foreach {k v} $signature { switch -- $k { key { foreach {k v} $v { if {![cequal $k subkeys]} { continue } foreach subkey $v { catch {unset sparams} array set sparams $subkey if {[info exists sparams(email)]} { append addrs $s $sparams(email) set s "\n " } } } } created { append info "created: [clock format $v]\n" } expires { append info "expires: [clock format $v]\n" } fingerprint { append info [format "keyid: 0x%s\n" [string range $v end-7 end]] append info [format "%s: %s\n" $k $v] } default { if {![cequal $v ""]} { append info [format "%s: %s\n" $k $v] } } } } if {![cequal $addrs ""]} { set info "email: $addrs\n$info" } if {![cequal $info ""]} { append text "\n" [string trimright $info] } } return [string trimleft $text] } proc ::ssj::signed:Label {lb connid jid pinfo} { if {[set rjid [muc::get_real_jid $connid $jid]] == ""} { set rjid [node_and_server_from_jid $jid] } else { set rjid [node_and_server_from_jid $rjid] } array set params $pinfo set checks {} set trust 0 foreach signature $params(signatures) { set emails {} set valid 0 foreach {k v} $signature { switch -- $k { key { foreach {k v} $v { if {![cequal $k subkeys]} { continue } foreach subkey $v { catch {unset sparams} array set sparams $subkey if {[info exists sparams(email)]} { lappend emails $sparams(email) } } } } validity { switch -- $v { ultimate - full - marginal { set valid 1 } never - undefined - unknown - default { set valid 0 } } } } } if {$valid && ([lsearch -exact $emails $rjid] >= 0)} { set trust 1 break } } if {[info exists params(reason)]} { set args [list -image gpg/badsigned] } elseif {$trust} { set args [list -image gpg/signed] } else { set args [list -image gpg/vsigned] } if {![cequal [set info [signed:info $pinfo]] ""]} { lappend args -helptext $info -helptype balloon } eval [list Label $lb] $args -cursor arrow \ -padx 0 -pady 0 -borderwidth 0 -highlightthickness 0 if {[info exists params(reason)] && [cequal $params(reason) nokey]} { bind $lb <3> [list ::ssj::signed:popup $pinfo] } return $lb } ############################################################################### proc ::ssj::signed:popup {pinfo} { set m .signed_label_popupmenu if {[winfo exists $m]} { destroy $m } menu $m -tearoff 0 $m add command -label [::msgcat::mc "Fetch GPG key"] \ -command [list ::ssj::fetchkeys $pinfo] tk_popup $m [winfo pointerx .] [winfo pointery .] } proc ::ssj::signed:user_menu {m connid jid} { variable signed global curuser if {[cequal $jid "\$curuser"]} { set jid $curuser } if {[info exists signed($connid,$jid)]} { array set params $signed($connid,$jid) if {[info exists params(status)] && [cequal $params(status) nokey]} { $m add command -label [::msgcat::mc "Fetch GPG key"] \ -command [list ::ssj::fetchkeys \ $signed($connid,$jid)] } } } hook::add chat_create_user_menu_hook ::ssj::signed:user_menu 78 ############################################################################### proc ::ssj::fetchkeys {pinfo} { variable gpg_error_id array set params $pinfo set keyids {} foreach signature $params(signatures) { catch {unset sparams} array set sparams $signature if {[info exists sparams(fingerprint)]} { lappend keyids [string range $sparams(fingerprint) end-7 end] } } set res [catch {set output [eval [list exec gpg --recv-keys] $keyids]} errMsg] incr gpg_error_id if {$res} { NonmodalMessageDlg .keyfetch_ok$gpg_error_id -aspect 50000 -icon error \ -message "Key fetch error\n\n$errMsg" } else { NonmodalMessageDlg .keyfetch_error$gpg_error_id -aspect 50000 -icon info \ -message "Key fetch result\n\n$output" } } ############################################################################### proc ::ssj::rewrite_message_body \ {vconnid vfrom vid vtype vis_subject vsubject vbody verr vthread vpriority vx} { upvar 2 $vconnid connid upvar 2 $vfrom from upvar 2 $vbody body upvar 2 $vx x set badenc 0 set xs {} foreach xe $x { jlib::wrapper:splitxml $xe tag vars isempty cdata children if {![cequal [jlib::wrapper:getattr $vars xmlns] $::NS(encrypted)]} { lappend xs $xe } elseif {[cequal $cdata ""]} { # in case the sender didn't check the exit code from gpg we ignore # jabber:x:encrypted } elseif {[catch {ssj::encrypted:input $connid $from $cdata} msg]} { set body [::msgcat::mc ">>> Unable to decipher data: %s <<<" $msg] # Add empty x tag to show problems with gpg lappend xs [jlib::wrapper:createtag x \ -vars [list xmlns $::NS(encrypted)]] set badenc 1 } else { set body $msg lappend xs $xe } } set x $xs if {!$badenc} return # if decryption failed, then remove signature. It can't be correct. set xs {} foreach xe $x { jlib::wrapper:splitxml $xe tag vars isempty cdata children if {![cequal [jlib::wrapper:getattr $vars xmlns] $::NS(signed)]} { lappend xs $xe } } set x $xs } hook::add rewrite_message_hook ::ssj::rewrite_message_body 10 ############################################################################### proc ::ssj::encrypted:input {connid from data} { variable ctx variable warnings variable gpg_error_id once_only $connid if {[catch {$ctx($connid) -operation decrypt \ -input [armor:decode $data]} result]} { debugmsg ssj "decryption processing error ($connid): $result ($from)" if {![info exists warnings(decrypt,$from)]} { set warnings(decrypt,$from) 1 incr gpg_error_id after idle [list NonmodalMessageDlg .decrypt_error$gpg_error_id -aspect 50000 -icon error \ -message [::msgcat::mc "Data purported sent by %s can't be deciphered.\n\n%s." \ $from $result]] } error $result } debugmsg ssj "DECRYPT: $connid; $from; $result" array set params $result binary scan $params(plaintext) a* temp_utf8 return [encoding convertfrom utf-8 $temp_utf8] } proc ::ssj::encrypted:output {connid data to} { global gpgPkg variable ctx variable e4me variable j2k variable options variable gpg_error_id if {[cequal $data ""]} { return } if {![encryptP $connid $to]} { return } set bto [node_and_server_from_jid $to] if {[info exists j2k($to)]} { set name $j2k($to) } elseif {[llength [set k [array names j2k $to/*]]] > 0} { set name $j2k([lindex $k 0]) } else { set name $bto } set recipient [${gpgPkg}::recipient] $recipient -operation add \ -name $name \ -validity full foreach signer $e4me($connid) { $recipient -operation add \ -name $signer \ -validity full } once_only $connid 1 set code \ [catch { $ctx($connid) \ -operation encrypt \ -input [binary format a* [encoding convertto utf-8 $data]] \ -recipients $recipient } result] rename $recipient {} if {$code} { debugmsg ssj "encryption processing error ($connid): $result ($data)" set options(encrypt,$connid,$to) 0 incr gpg_error_id if {[MessageDlg .encrypt_error$gpg_error_id \ -aspect 50000 \ -icon error \ -type user \ -buttons {ok cancel} \ -default 0 \ -cancel 1 \ -message [::msgcat::mc \ "Unable to encipher data for %s:\ %s.\n\nEncrypting traffic to this user is\ now disabled.\n\nSend it as PLAINTEXT?" \ $to $result]]} { error "" } return } set result [armor:encode $result] debugmsg ssj "ENCRYPT: $connid; $data; $result" return $result } proc ::ssj::whichkeys {connid what} { variable ctx variable warnings set s [$ctx($connid) -operation get -property last-op-info] if {[cequal $s ""]} { return } set keys {} while {([set x [string first $s]] > 0) \ && ([set y [string first $s]] > $x) \ && ($x+45 == $y)} { lappend keys [string range $s [expr $x+20] [expr $y-1]] set s [string range $s $y end] } if {![info exists warnings($what)]} { set warnings($what) "" } elseif {[cequal $warnings($what) $keys]} { return } set warnings($what) $keys debugmsg ssj "${what}ing with $keys" } ############################################################################# proc ::ssj::prefs {connid jid} { variable ctx variable options variable optionsX set w [win_id security_preferences [list $connid $jid]] if {[winfo exists $w]} { focus -force $w return } Dialog $w \ -title [::msgcat::mc "Change security preferences for %s" $jid] \ -separator 1 -anchor e -default 0 -cancel 1 $w add -text [::msgcat::mc "OK"] \ -command [list ::ssj::prefs_ok $w $connid $jid] $w add -text [::msgcat::mc "Cancel"] -command [list destroy $w] set f [$w getframe] if {![info exists options(encrypt,$connid,$jid)]} { set options(encrypt,$connid,$jid) [encryptP $connid $jid] } set optionsX(encrypt,$connid,$jid) $options(encrypt,$connid,$jid) checkbutton $f.encrypt \ -text [::msgcat::mc "Encrypt traffic"] \ -variable ::ssj::optionsX(encrypt,$connid,$jid) pack $f.encrypt -side left pack [frame $f.f -width 9c -height 2c] $w draw $f.name } proc ::ssj::prefs_ok {w connid jid} { variable options variable optionsX set options(encrypt,$connid,$jid) $optionsX(encrypt,$connid,$jid) destroy $w } proc ::ssj::prefs_user_menu {m connid jid} { $m add command -label [::msgcat::mc "Edit security..."] \ -command [list ::ssj::prefs $connid $jid] } hook::add chat_create_user_menu_hook ::ssj::prefs_user_menu 78 hook::add roster_conference_popup_menu_hook ::ssj::prefs_user_menu 78 hook::add roster_service_popup_menu_hook ::ssj::prefs_user_menu 78 hook::add roster_jid_popup_menu_hook ::ssj::prefs_user_menu 78 ############################################################################# proc ::ssj::signP {} { variable options return $options(sign-traffic) } proc ::ssj::encryptP {connid jid} { global gpgPkg variable ctx variable j2k variable options if {[cequal $jid ""]} { return $options(encrypt-traffic) } lassign [roster::get_category_and_subtype $connid $jid] \ category subtype switch -- $category { conference - server - gateway - service { set resP 0 } default { set resP 1 } } set bjid [node_and_server_from_jid $jid] if {[info exists options(encrypt,$connid,$jid)]} { return $options(encrypt,$connid,$jid) } elseif {[info exists options(encrypt,$connid,$bjid)]} { return $options(encrypt,$connid,$bjid) } elseif {[info exists options(encrypt,$jid)]} { return $options(encrypt,$jid) } elseif {[info exists options(encrypt,$bjid)]} { return $options(encrypt,$jid) } if {!$options(encrypt-traffic)} { return 0 } if {[info exists options(encrypt-tried,$connid,$jid)]} { return $options(encrypt-tried,$connid,$jid) } once_only $connid if {[info exists j2k($jid)]} { set name $j2k($jid) } elseif {($resP) && ([llength [set k [array names j2k $jid/*]]] > 0)} { set name $j2k([lindex $k 0]) } else { set name $bjid } [set recipient [${gpgPkg}::recipient]] \ -operation add \ -name $name \ -validity full if {[catch {$ctx($connid) -operation encrypt \ -input "Hello world." \ -recipients $recipient}]} { set options(encrypt-tried,$connid,$jid) 0 } else { set options(encrypt-tried,$connid,$jid) 1 } rename $recipient {} return $options(encrypt-tried,$connid,$jid) } ############################################################################# proc ::ssj::e4meP {connid keys} { global gpgPkg variable ctx variable e4me variable signers $ctx($connid) -operation set \ -property signers \ -value [set signers($connid) $keys] set e4me($connid) {} foreach signer $signers($connid) { [set recipient [${gpgPkg}::recipient]] \ -operation add \ -name $signer \ -validity full if {![catch {$ctx($connid) -operation encrypt \ -input "Hello world." \ -recipients $recipient} result]} { lappend e4me($connid) $signer } rename $recipient {} } } ############################################################################# proc ::ssj::sign:toggleP {} { variable options set options(sign-traffic) [expr {!$options(sign-traffic)}] } proc ::ssj::encrypt:toggleP {{connid ""} {jid ""}} { variable options if {[cequal $jid ""]} { set options(encrypt-traffic) [expr {!$options(encrypt-traffic)}] return } if {![cequal $connid ""]} { if {![info exists options(encrypt,$connid,$jid)]} { set options(encrypt,$connid,$jid) [encryptP $connid $jid] } set options(encrypt,$connid,$jid) \ [expr {!$options(encrypt,$connid,$jid)}] } else { return -code error \ "::ssj::encrypt:toggleP: connid is empty and jid is not" } } ############################################################################# proc ::ssj::signed:trace {script} { variable options variable trace if {![info exists trace(sign-traffic)]} { set trace(sign-traffic) {} ::trace variable ::ssj::options(sign-traffic) w ::ssj::trace } lappend trace(sign-traffic) $script } proc ::ssj::encrypted:trace {script {connid ""} {jid ""}} { variable options variable trace if {[cequal $jid ""]} { set k encrypt-traffic } else { if {![cequal $connid ""]} { set k encrypt,$connid,$jid } else { return -code error \ "::ssj::encrypted:trace: connid is empty and jid is not" } } if {![info exists trace($k)]} { set trace($k) {} ::trace variable ::ssj::options($k) w ::ssj::trace } lappend trace($k) $script } proc ::ssj::trace {name1 name2 op} { variable trace set new {} foreach script $trace($name2) { if {[catch {eval $script} result]} { debugmsg ssj "$result -- $script" } else { lappend new $script } } set trace($name2) $new } ############################################################################# proc ::ssj::clear_signatures {connid} { variable signed if {$connid == {}} { catch {array unset signed} } else { catch {array unset signed $connid,*} } } hook::add disconnected_hook ::ssj::clear_signatures ############################################################################# proc ::ssj::check_signature {connid from type x args} { variable signed switch -- $type { unavailable - available { catch {unset signed($connid,$from)} set signature "" foreach xs $x { jlib::wrapper:splitxml $xs tag vars isempty cdata children if {[jlib::wrapper:getattr $vars xmlns] == $::NS(signed)} { set signature $cdata break } } # in case the sender didn't check the exit code from gpg... if {[cequal $signature ""]} return set status "" foreach {key val} $args { switch -- $key { -status { set status $val } } } set signed($connid,$from) \ [signed:input $connid $from $signature $status \ [::msgcat::mc "Presence information"]] } } } hook::add client_presence_hook ::ssj::check_signature ############################################################################# proc ::ssj::make_signature {varname connid status} { upvar 2 $varname var if {![cequal $status ""] && \ ![catch {signed:output $connid $status} cdata] && \ ![cequal $cdata ""]} { lappend var [jlib::wrapper:createtag x \ -vars [list xmlns $::NS(signed)] \ -chdata $cdata] } return } hook::add presence_xlist_hook ::ssj::make_signature ############################################################################# proc ::ssj::userinfo {tab connid jid editable} { variable signed if {$editable} return set bare_jid [node_and_server_from_jid $jid] set chatid [chat::chatid $connid $bare_jid] if {[chat::is_groupchat $chatid]} { if {[info exists signed($connid,$jid)]} { set jids [list $connid,$jid] } else { set jids [list] } } else { set jids [array names signed $connid,$bare_jid/*] } if {[llength $jids] > 0} { set presenceinfo [$tab insert end presenceinfo \ -text [::msgcat::mc "Presence"]] set i 0 foreach j $jids { regexp {[^,]*,(.*)} $j -> fjid set x [userinfo::pack_frame $presenceinfo.presence_$i $fjid] catch {array unset params} array set params $signed($j) set kv {} set addrs "" set s "" foreach signature $params(signatures) { foreach {k v} $signature { switch -- $k { key { foreach {k v} $v { if {![cequal $k subkeys]} continue foreach subkey $v { catch {unset sparams} array set sparams $subkey if {[info exists sparams(email)]} { append addrs $s $sparams(email) set s ", " } } } continue } status { continue } created - expires { set v [clock format $v] } fingerprint { lappend kv keyid \ [format "0x%s" [string range $v end-7 end]] } default { if {[cequal $v ""]} { continue } } } lappend kv $k $v } } userinfo::pack_entry $jid $x $i presence_$i [::msgcat::mc "Reason:"] if {![info exists params(reason)]} { set params(reason) [::msgcat::mc "Presence is signed"] if {![cequal $addrs ""]} { append params(reason) [::msgcat::mc " by "] $addrs } } set userinfo::userinfo(presence_$i,$jid) $params(reason) incr i foreach {k v} $kv { userinfo::pack_entry $jid $x $i presence_$i \ [::msgcat::mc [string totitle ${k}:]] set userinfo::userinfo(presence_$i,$jid) $v incr i } } } } hook::add userinfo_hook ::ssj::userinfo 90 ############################################################################# proc ::ssj::message_buttons {mw connid jid} { set bbox1 [ButtonBox $mw.bottom.buttons1 -spacing 0] set b [$bbox1 add \ -image [signed:icon] \ -helptype balloon \ -helptext [::msgcat::mc "Toggle signing"] \ -height 24 \ -width 24 \ -relief link \ -bd $::tk_borderwidth \ -command ::ssj::sign:toggleP] signed:trace "$b configure -image \[::ssj::signed:icon\]" # TODO reflect changes of connid set b [$bbox1 add \ -image [encrypted:icon $connid $jid] \ -helptype balloon \ -helptext [::msgcat::mc "Toggle encryption"] \ -height 24 \ -width 24 \ -relief link \ -bd $::tk_borderwidth \ -command [list ::ssj::encrypt:toggleP $connid $jid]] encrypted:trace \ "$b configure -image \[::ssj::encrypted:icon [list $connid] [list $jid]\]" \ $connid $jid pack $bbox1 -side left -fill x -padx 2m -pady 2m } hook::add open_message_post_hook ::ssj::message_buttons ############################################################################# proc ::ssj::process_x_signed {rowvar bodyvar f x connid from id type replyP} { upvar 2 $rowvar row upvar 2 $bodyvar body if {!$replyP || [cequal $type error]} { return } foreach xa $x { jlib::wrapper:splitxml $xa tag vars isempty chdata children set xmlns [jlib::wrapper:getattr $vars xmlns] if {$xmlns != $::NS(signed)} continue # in case the sender didn't check the exit code from gpg... if {[cequal $chdata ""]} { return } set lb [join [lrange [split $f .] 0 end-1] .].title.signed if {[winfo exists $lb]} { destroy $lb } signed:Label $lb $connid $from \ [signed:input $connid $from $chdata $body \ [::msgcat::mc "Message body"]] grid $lb -row 1 -column 2 -sticky e } return } hook::add message_process_x_hook ::ssj::process_x_signed 20 ############################################################################# proc ::ssj::signed:icon {} { return [lindex [list toolbar/gpg-unsigned toolbar/gpg-signed] \ [signP]] } proc ::ssj::encrypted:icon {{connid ""} {jid ""}} { return [lindex [list toolbar/gpg-unencrypted toolbar/gpg-encrypted] \ [encryptP $connid $jid]] } ############################################################################# proc ::ssj::draw_signed {chatid from type body x} { variable signedid set chatw [chat::chat_win $chatid] foreach xe $x { jlib::wrapper:splitxml $xe tag vars isempty chdata children # in case the sender didn't check the exit code from gpg... if {[cequal $chdata ""] || \ ![cequal [jlib::wrapper:getattr $vars xmlns] $::NS(signed)]} { continue } incr signedid set connid [chat::get_connid $chatid] catch { $chatw window create end \ -window [signed:Label $chatw.signed$signedid $connid $from \ [signed:input $connid $from $chdata $body \ [::msgcat::mc "Message body"]]] } } } hook::add draw_message_hook ::ssj::draw_signed 7 ############################################################################### proc ::ssj::chat_window_button {chatid type} { set connid [chat::get_connid $chatid] set jid [chat::get_jid $chatid] set cw [chat::winid $chatid] Button $cw.status.encrypted \ -relief flat \ -image [encrypted:icon $connid $jid] \ -helptype balloon \ -helptext [::msgcat::mc "Toggle encryption"] \ -command [list ::ssj::encrypt:toggleP $connid $jid] encrypted:trace "$cw.status.encrypted configure \ -image \[::ssj::encrypted:icon $connid $jid\]" \ $connid $jid pack $cw.status.encrypted -side left -before $cw.status.mb } hook::add open_chat_post_hook ::ssj::chat_window_button ############################################################################### proc ::ssj::toolbar {} { set idx [ifacetk::add_toolbar_button \ [signed:icon] \ ::ssj::sign:toggleP \ [::msgcat::mc "Toggle signing"]] signed:trace \ [list ifacetk::set_toolbar_icon $idx ::ssj::signed:icon] set idx [ifacetk::add_toolbar_button \ [encrypted:icon] \ ::ssj::encrypt:toggleP \ [::msgcat::mc "Toggle encryption (when possible)"]] encrypted:trace \ [list ifacetk::set_toolbar_icon $idx ::ssj::encrypted:icon] } hook::add finload_hook ::ssj::toolbar ############################################################################### proc ::ssj::setup_menu {} { variable options catch { set m [.mainframe getmenu tkabber] set ind [$m index [::msgcat::mc "View"]] incr ind -1 set mm .ssj_menu menu $mm -tearoff $::ifacetk::options(show_tearoffs) $mm add checkbutton -label [::msgcat::mc "Sign traffic"] \ -variable ::ssj::options(sign-traffic) $mm add checkbutton -label [::msgcat::mc "Encrypt traffic (when possible)"] \ -variable ::ssj::options(encrypt-traffic) $m insert $ind cascade -label [::msgcat::mc "Encryption"] \ -menu $mm } } hook::add finload_hook ::ssj::setup_menu ############################################################################### proc ::ssj::add_user_popup_info {infovar connid jid} { variable signed upvar 0 $infovar info if {[info exists signed($connid,$jid)]} { set signed_info [signed:info $signed($connid,$jid)] append info [::msgcat::mc "\n\tPresence is signed:"] regsub -all {(\n)} "\n$signed_info" "\\1\t " extra append info $extra } } hook::add roster_user_popup_info_hook ::ssj::add_user_popup_info 99 ############################################################################### tkabber-0.11.1/disco.tcl0000644000175000017500000011270711062001355014330 0ustar sergeisergei# $Id: disco.tcl 1498 2008-09-10 17:25:01Z sergei $ ############################################################################## set ::NS(disco_items) "http://jabber.org/protocol/disco#items" set ::NS(disco_info) "http://jabber.org/protocol/disco#info" option add *JDisco.fill Black widgetDefault option add *JDisco.featurecolor MidnightBlue widgetDefault option add *JDisco.identitycolor DarkGreen widgetDefault option add *JDisco.optioncolor DarkViolet widgetDefault namespace eval disco { variable supported_nodes variable supported_features {} variable root_nodes {} variable additional_items } ############################################################################## proc disco::request_items {jid node args} { variable disco set handler {} set cache no foreach {attr val} $args { switch -- $attr { -handler {set handler $val} -cache {set cache $val} -connection {set connid $val} } } if {![info exists connid]} { return -code error "disco::request_items: -connection is mandatory" } switch -- $cache { first - only - yes { if {[info exists disco(items,$connid,$jid,$node)]} { set items $disco(items,$connid,$jid,$node) if {$handler != ""} { eval $handler [list OK $items] } if {$cache != "first"} { return [list OK $items] } } elseif {$cache == "only"} { return NO } } } set vars [list xmlns $::NS(disco_items)] if {$node != ""} { lappend vars node $node } jlib::send_iq get \ [jlib::wrapper:createtag query \ -vars $vars] \ -to $jid \ -connection $connid \ -command [list [namespace current]::parse_items \ $connid $jid $node $handler] } proc disco::parse_items {connid jid node handler res child} { variable disco if {![string equal $res OK]} { if {$handler != ""} { eval $handler [list ERR $child] } hook::run disco_items_hook $connid $jid $node ERR $child return } set items {} jlib::wrapper:splitxml $child tag vars isempty chdata childrens foreach ch $childrens { jlib::wrapper:splitxml $ch tag1 vars1 isempty1 chdata1 childrens1 switch -- $tag1 { item { set ijid [jlib::wrapper:getattr $vars1 jid] set inode [jlib::wrapper:getattr $vars1 node] set name [jlib::wrapper:getattr $vars1 name] lappend items [list jid $ijid node $inode name $name] set disco(jidname,$connid,$ijid,$inode) $name } } } set disco(items,$connid,$jid,$node) $items debugmsg disco "ITEMS: [list $items]" if {$handler != ""} { eval $handler [list OK $items] } hook::run disco_items_hook $connid $jid $node OK $items } ############################################################################## proc disco::request_info {jid node args} { variable disco set handler {} set cache no foreach {attr val} $args { switch -- $attr { -handler {set handler $val} -cache {set cache $val} -connection {set connid $val} } } if {![info exists connid]} { return -code error "disco::request_items: -connection is mandatory" } # disco(info,featured_nodes,$connid,$jid,$node) isn't cached because it # isn't really reported. It's for internal use only. set disco(info,featured_nodes,$connid,$jid,$node) {} switch -- $cache { first - only - yes { if {[info exists disco(info,identities,$connid,$jid,$node)] && \ [info exists disco(info,identities,$connid,$jid,$node)]} { set identities $disco(info,identities,$connid,$jid,$node) set features $disco(info,features,$connid,$jid,$node) set extras $disco(info,extras,$connid,$jid,$node) if {$handler != ""} { eval $handler [list OK $identities $features $extras] } if {$cache != "first"} { return [list OK $identities $features $extras] } } elseif {$cache == "only"} { return NO } } } set vars [list xmlns $::NS(disco_info)] if {$node != ""} { lappend vars node $node } jlib::send_iq get \ [jlib::wrapper:createtag query \ -vars $vars] \ -to $jid \ -connection $connid \ -command [list [namespace current]::parse_info \ $connid $jid $node $handler] } proc disco::parse_info {connid jid node handler res child} { variable disco variable additional_nodes if {![string equal $res OK]} { if {$handler != ""} { eval $handler [list ERR $child {} {}] } hook::run disco_info_hook $connid $jid $node ERR $child {} {} {} return } set identities {} set features {} set extras {} set featured_nodes {} jlib::wrapper:splitxml $child tag vars isempty chdata children foreach ch $children { jlib::wrapper:splitxml $ch tag1 vars1 isempty1 chdata1 children1 switch -- $tag1 { identity { lappend identities \ [list \ category [jlib::wrapper:getattr $vars1 category] \ name [jlib::wrapper:getattr $vars1 name] \ type [jlib::wrapper:getattr $vars1 type]] } feature { set var [jlib::wrapper:getattr $vars1 var] if {$var == ""} { set var [jlib::wrapper:getattr $vars1 type] } lappend features [list var $var] if {($node == "") && [info exists additional_nodes($var)]} { lappend featured_nodes \ [concat [list jid $jid] $additional_nodes($var)] set inode [jlib::wrapper:getattr $additional_nodes($var) node] set iname [jlib::wrapper:getattr $additional_nodes($var) name] if {![info exists disco(jidname,$connid,$jid,$inode)]} { set disco(jidname,$connid,$jid,$inode) $iname } } } default { if {[jlib::wrapper:getattr $vars1 xmlns] == $::NS(data) && \ [jlib::wrapper:getattr $vars1 type] == "result"} { lappend extras [data::parse_xdata_results $children1 -hidden 1] } } } } set disco(info,identities,$connid,$jid,$node) $identities set disco(info,features,$connid,$jid,$node) $features set disco(info,extras,$connid,$jid,$node) $extras set disco(info,featured_nodes,$connid,$jid,$node) [lrmdups $featured_nodes] debugmsg disco \ "INFO: IDENTITIES [list $identities] FEATURES [list $features]\ EXTRAS [list $extras] FEATURED NODES [list [lrmdups $featured_nodes]]" if {$handler != ""} { eval $handler [list OK $identities $features $extras] } hook::run disco_info_hook $connid $jid $node OK $identities $features \ $extras [lrmdups $featured_nodes] } ############################################################################### proc disco::get_jid_name {connid jid node} { variable disco if {[info exists disco(jidname,$connid,$jid,$node)]} { return $disco(jidname,$connid,$jid,$node) } else { return "" } } proc disco::get_jid_identities {connid jid node} { variable disco if {[info exists disco(info,identities,$connid,$jid,$node)]} { return $disco(info,identities,$connid,$jid,$node) } else { return {} } } proc disco::get_jid_features {connid jid node} { variable disco if {[info exists disco(info,features,$connid,$jid,$node)]} { return $disco(info,features,$connid,$jid,$node) } else { return {} } } proc disco::get_jid_items {connid jid node} { variable disco if {[info exists disco(items,$connid,$jid,$node)]} { return $disco(items,$connid,$jid,$node) } else { return {} } } ############################################################################### proc disco::register_featured_node {feature node name} { variable additional_nodes set additional_nodes($feature) [list node $node name $name] } ############################################################################### proc disco::info_query_get_handler {connid from lang child} { variable supported_nodes variable node_handlers variable supported_features variable feature_handlers variable extra_handlers jlib::wrapper:splitxml $child tag vars isempty chdata children set node [jlib::wrapper:getattr $vars node] if {![string equal $node ""]} { if {![info exists supported_nodes($node)]} { # Probably temporary node set res {error cancel not-allowed} hook::run disco_node_reply_hook \ res info $node $connid $from $lang $child return $res } else { # Permanent node set restags [eval $node_handlers($node) \ [list info $connid $from $lang $child]] if {[string equal [lindex $restags 0] error]} { return $restags } else { set res [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(disco_info) node $node] \ -subtags $restags] } } } else { set restags {} lappend restags [jlib::wrapper:createtag identity \ -vars [list category client \ type pc \ name Tkabber]] foreach h $extra_handlers { lappend restags [eval $h [list $connid $from $lang]] } foreach ns [lsort [concat $::iq::supported_ns $supported_features]] { lappend restags [jlib::wrapper:createtag feature \ -vars [list var $ns]] } set res [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(disco_info)] \ -subtags $restags] } return [list result $res] } iq::register_handler get query $::NS(disco_info) \ [namespace current]::disco::info_query_get_handler ############################################################################### proc disco::items_query_get_handler {connid from lang child} { variable supported_nodes variable node_handlers variable root_nodes jlib::wrapper:splitxml $child tag vars isempty chdata children set node [jlib::wrapper:getattr $vars node] if {![string equal $node ""]} { if {![info exists supported_nodes($node)]} { # Probably temporary node set res {error cancel not-allowed} hook::run disco_node_reply_hook \ res items $node $connid $from $lang $child return $res } else { # Permanent node set restags [eval $node_handlers($node) \ [list items $connid $from $lang $child]] if {[string equal [lindex $restags 0] error]} { return $restags } else { set res [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(disco_items) node $node] \ -subtags $restags] } } } else { set restags {} set myjid [my_jid $connid $from] foreach node $root_nodes { set vars [list jid $myjid] if {![string equal $supported_nodes($node) ""]} { lappend vars name [::trans::trans $lang $supported_nodes($node)] } if {![string equal $node ""]} { lappend vars node $node } lappend restags [jlib::wrapper:createtag item \ -vars $vars] } set res [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(disco_items)] \ -subtags $restags] } return [list result $res] } iq::register_handler get query $::NS(disco_items) \ [namespace current]::disco::items_query_get_handler ############################################################################### proc disco::register_feature {feature {handler ""}} { variable supported_features variable feature_handlers if {[lsearch $supported_features $feature] < 0} { lappend supported_features $feature } set feature_handlers($feature) $handler } ############################################################################### proc disco::unregister_feature {feature} { variable supported_features variable feature_handlers if {[set idx [lsearch $supported_features $feature]] >= 0} { set supported_features [lreplace $supported_features $idx $idx] unset feature_handlers($feature) } } ############################################################################### proc disco::register_node {node handler {name ""}} { variable root_nodes lappend root_nodes $node register_subnode $node $handler $name } ############################################################################### proc disco::register_subnode {node handler {name ""}} { variable supported_nodes variable node_handlers set supported_nodes($node) $name set node_handlers($node) $handler } ############################################################################### proc disco::register_extra {handler} { variable extra_handlers lappend extra_handlers $handler } ############################################################################### proc disco::publish_items {jid node action items args} { set command "" foreach {key val} $args { switch -- { -connection { set connid $val } -command { set command $val } } } if {![info exists connid]} { return "disco::publish_items: option -connection required" } jlib::send_iq set \ [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(disco#publish) node $node] \ -subtags $items] \ -to $jid \ -connection $connid \ -command [list [namespace current]::publish_items_result $command] } proc disco::publish_items_result {command res child} { if {$command != ""} { eval $command [list $res $child] } } ############################################################################### # Disco Browser namespace eval disco::browser { set winid 0 image create photo "" variable options # Do not show items number in node title if this number # is not greater than 20 # (It is questionnable whether to add this option to Customize). set options(upper_items_bound) 20 custom::defvar disco_list {} [::msgcat::mc "List of discovered JIDs."] \ -group Hidden custom::defvar node_list {} [::msgcat::mc "List of discovered JID nodes."] \ -group Hidden } ############################################################################### proc disco::browser::open_win {jid args} { variable winid variable disco variable config variable curjid variable disco_list variable node_list variable browser if {[llength [jlib::connections]] == 0} return foreach {opt val} $args { switch -- $opt { -connection { set connid $val } } } if {![info exists connid]} { set connid [lindex [jlib::connections] 0] } if {$jid == ""} { set curjid($winid) [jlib::connection_server $connid] } else { set curjid($winid) $jid } set w .disco_$winid set wid $winid incr winid set browser(connid,$w) $connid add_win $w -title [::msgcat::mc "Service Discovery"] \ -tabtitle [::msgcat::mc "Discovery"] \ -raisecmd [list focus $w.tree] \ -class JDisco \ -raise 1 set config(fill) [option get $w fill JDisco] set config(featurecolor) [option get $w featurecolor JDisco] set config(identitycolor) [option get $w identitycolor JDisco] set config(optioncolor) [option get $w optioncolor JDisco] bind $w [list [namespace current]::destroy_state $w] frame $w.navigate button $w.navigate.back -text <- \ -command [list [namespace current]::history_move $w 1] button $w.navigate.forward -text -> \ -command [list [namespace current]::history_move $w -1] label $w.navigate.lentry -text [::msgcat::mc "JID:"] ComboBox $w.navigate.entry -textvariable [namespace current]::curjid($wid) \ -dropenabled 1 -droptypes {JID {}} \ -dropcmd [list [namespace current]::entrydropcmd $w] \ -command [list [namespace current]::go $w] \ -values $disco_list label $w.navigate.lnode -text [::msgcat::mc "Node:"] ComboBox $w.navigate.node -textvariable [namespace current]::curnode($wid) \ -values $node_list -width 20 button $w.navigate.browse -text [::msgcat::mc "Browse"] \ -command [list [namespace current]::go $w] #bind $w.navigate.entry [list disco::go $w] pack $w.navigate.back $w.navigate.forward $w.navigate.lentry -side left pack $w.navigate.browse -side right pack $w.navigate.entry -side left -expand yes -fill x pack $w.navigate.lnode -side left pack $w.navigate.node -side left -expand no -fill x pack $w.navigate -fill x set sw [ScrolledWindow $w.sw] set tw [Tree $w.tree -deltax 16 -deltay 18 -dragenabled 1 \ -draginitcmd [list [namespace current]::draginitcmd $w]] $sw setwidget $tw pack $sw -side top -expand yes -fill both set disco(tree,$w) $tw $tw bindText \ [list [namespace current]::textaction $w] $tw bindText \ [list [namespace current]::textpopup $w] balloon::setup $tw -command [list [namespace current]::textballoon $w] bindscroll $tw.c # HACK bind $tw.c \ "[namespace current]::textaction $w \[$tw selection get\]" bind $tw.c \ "[namespace current]::clear $w \[$tw selection get\]" lappend browser(opened) $w set browser(opened) [lrmdups $browser(opened)] set browser(required,$w) {} set browser(tree,$w) $tw set browser(hist,$w) {} set browser(histpos,$w) 0 hook::run open_disco_post_hook $w $sw $tw go $w } proc disco::browser::go {bw} { variable browser variable disco_list variable node_list if {[winfo exists $bw]} { set jid [$bw.navigate.entry.e get] set node [$bw.navigate.node.e get] history_add $bw [list $jid $node] set disco_list [update_combo_list $disco_list $jid 20] set node_list [update_combo_list $node_list $node 20] $bw.navigate.entry configure -values $disco_list $bw.navigate.node configure -values $node_list lappend browser(required,$bw) $jid set browser(required,$bw) [lrmdups $browser(required,$bw)] disco::request_info $jid $node -connection $browser(connid,$bw) disco::request_items $jid $node -connection $browser(connid,$bw) } } proc disco::browser::info_receive \ {connid jid node res identities features extras featured_nodes} { variable browser if {![info exists browser(opened)]} return foreach w $browser(opened) { if {[winfo exists $w] && [lcontain $browser(required,$w) $jid]} { draw_info $w $connid $jid $node $res $identities \ $features $extras $featured_nodes } } } hook::add disco_info_hook \ [namespace current]::disco::browser::info_receive proc disco::browser::draw_info \ {w connid jid node res identities features extras featured_nodes} { variable browser variable config set tw $browser(tree,$w) set name [disco::get_jid_name $connid $jid $node] set tnode [jid_to_tag [list $jid $node]] set parent_tag [jid_to_tag [list $jid $node]] set data [list item $connid $jid $node] if {![$tw exists $tnode] || [llength [$tw nodes $tnode]] == 0} { set nitems 0 } else { set nitems [llength [disco::get_jid_items $connid $jid $node]] } set desc [item_desc $jid $node $name $nitems] set icon "" add_line $tw $parent_tag $tnode $icon $desc $data \ -fill $config(fill) if {$res != "OK"} { set tnode [jid_to_tag "error info $jid $node"] set data [list error_info $connid $jid] #set name [jlib::wrapper:getattr $identity name] set desc [format [::msgcat::mc "Error getting info: %s"] \ [error_to_string $identities]] set icon "" add_line $tw $parent_tag $tnode $icon $desc $data \ -fill $config(identitycolor) remove_old $tw $parent_tag identity [list $tnode] remove_old $tw $parent_tag feature [list $tnode] reorder_node $tw $parent_tag return } set identitynodes {} set category "" set type "" foreach identity $identities { set tnode [jid_to_tag "identity $identity $jid $node"] lappend identitynodes $tnode set name [jlib::wrapper:getattr $identity name] set category [jlib::wrapper:getattr $identity category] set type [jlib::wrapper:getattr $identity type] set data [list identity $connid $jid $node $category $type] set desc "$name ($category/$type)" set icon [item_icon $category $type] add_line $tw $parent_tag $tnode $icon $desc $data \ -fill $config(identitycolor) } set extranodes {} foreach eform $extras { foreach extra $eform { lassign $extra var type label values if {$type == "hidden"} continue set tnode [jid_to_tag "extra $var $jid $node"] lappend extranodes $tnode set data [list extra $var $connid $jid $node] set value [join $values ", "] if {$label != ""} { set desc "$label ($var): $value" } else { set desc "$var: $value" } set icon "" add_line $tw $parent_tag $tnode $icon $desc $data \ -fill $config(identitycolor) } } set featurenodes {} foreach feature $features { set var [jlib::wrapper:getattr $feature var] set tnode [jid_to_tag "feature $feature $jid $node"] lappend featurenodes $tnode set data [list feature $connid $jid $node $feature $category $type] set desc $var if {[info exists browser(feature_handler_desc,$var)]} { catch { array unset tmp } array set tmp $browser(feature_handler_desc,$var) if {[info exists tmp($category)]} { set desc "$tmp($category) ($var)" } elseif {[info exists tmp(*)]} { set desc "$tmp(*) ($var)" } } set icon "" add_line $tw $parent_tag $tnode $icon $desc $data \ -fill $config(featurecolor) } # Draw all implicit item nodes, which are not received explicitly # (don't overwrite node because it can have different name) foreach item $featured_nodes { set ijid [jlib::wrapper:getattr $item jid] set node [jlib::wrapper:getattr $item node] set name [jlib::wrapper:getattr $item name] set tnode [jid_to_tag [list $ijid $node]] set data [list item $connid $ijid $node] if {![$tw exists $tnode] || [llength [$tw nodes $tnode]] == 0} { set nitems 0 } else { set nitems [llength [disco::get_jid_items $connid $ijid $node]] } set desc [item_desc $ijid $node $name $nitems] set icon "" if {![$tw exists $tnode]} { add_line $tw $parent_tag $tnode $icon $desc $data \ -fill $config(fill) } } remove_old $tw $parent_tag identity $identitynodes remove_old $tw $parent_tag extra $extranodes remove_old $tw $parent_tag feature $featurenodes remove_old $tw $parent_tag error_info {} reorder_node $tw $parent_tag } proc disco::browser::items_receive {connid jid node res items} { variable browser if {![info exists browser(opened)]} return foreach w $browser(opened) { if {[winfo exists $w] && [lcontain $browser(required,$w) $jid]} { draw_items $w $connid $jid $node $res $items } } } hook::add disco_items_hook \ [namespace current]::disco::browser::items_receive proc disco::browser::draw_items {w connid jid node res items} { variable browser variable config set tw $browser(tree,$w) set parent_tag [jid_to_tag [list $jid $node]] set name [disco::get_jid_name $connid $jid $node] set tnode [jid_to_tag [list $jid $node]] set data [list item $connid $jid $node] if {![$tw exists $tnode] || [llength [$tw nodes $tnode]] == 0} { set nitems 0 } else { set nitems [llength [disco::get_jid_items $connid $jid $node]] } set desc [item_desc $jid $node $name $nitems] set icon "" add_line $tw $parent_tag $tnode $icon $desc $data \ -fill $config(fill) if {$res != "OK"} { # HACK if {[info exists ::disco::disco(info,featured_nodes,$connid,$jid,$node)] && \ ![lempty $::disco::disco(info,featured_nodes,$connid,$jid,$node)]} { set items {} } else { set tnode [jid_to_tag "error items $jid $node"] set data [list error_items $connid $jid] #set name [jlib::wrapper:getattr $identity name] set desc [::msgcat::mc "Error getting items: %s" \ [error_to_string $items]] set icon "" add_line $tw $parent_tag $tnode $icon $desc $data \ -fill $config(fill) remove_old $tw $parent_tag item [list $tnode] reorder_node $tw $parent_tag return } } # HACK # Don't remove nodes, which are drawn after disco#info query # (if the service's features change then this node list may be # incorrect) set itemnodes {} if {[info exists ::disco::disco(info,featured_nodes,$connid,$jid,$node)]} { foreach item $::disco::disco(info,featured_nodes,$connid,$jid,$node) { set ijid [jlib::wrapper:getattr $item jid] set inode [jlib::wrapper:getattr $item node] lappend itemnodes [jid_to_tag [list $ijid $inode]] } } foreach item $items { set ijid [jlib::wrapper:getattr $item jid] set node [jlib::wrapper:getattr $item node] set name [jlib::wrapper:getattr $item name] set tnode [jid_to_tag [list $ijid $node]] set data [list item $connid $ijid $node] if {![$tw exists $tnode] || [llength [$tw nodes $tnode]] == 0} { set nitems 0 } else { set nitems [llength [disco::get_jid_items $connid $ijid $node]] } set desc [item_desc $ijid $node $name $nitems] set icon "" lappend itemnodes $tnode add_line $tw $parent_tag $tnode $icon $desc $data \ -fill $config(fill) } remove_old $tw $parent_tag item $itemnodes remove_old $tw $parent_tag error_items {} if {![info exists browser(sort,$w,$parent_tag)]} { set browser(sort,$w,$parent_tag) sort } browser_action $browser(sort,$w,$parent_tag) $w $parent_tag } proc disco::browser::negotiate_feature {tw connid jid parent type} { variable config lassign [negotiate::send_request $connid $jid $type] res opts if {![winfo exists $tw]} return if {$res != "OK"} { set node [jid_to_tag "error negotiate $parent"] set data [list error_negotiate $parent $connid $jid] #set name [jlib::wrapper:getattr $identity name] set desc [format [::msgcat::mc "Error negotiate: %s"] \ [error_to_string $opts]] set icon "" add_line $tw $parent $node $icon $desc $data \ -fill $config(optioncolor) remove_old $tw $parent option [list $node] return } set optnodes {} foreach opt $opts { set node [jid_to_tag "option $opt $parent"] lappend optnodes $node set data [list option $opt $node] set desc $opt set icon "" add_line $tw $parent $node $icon $desc $data \ -fill $config(optioncolor) } remove_old $tw $parent option $optnodes remove_old $tw $parent error_negotiate {} } proc disco::browser::add_line {tw parent node icon desc data args} { if {[$tw exists $node]} { if {[$tw parent $node] != $parent && [$tw exists $parent] && \ $parent != $node} { if {[catch { $tw move $parent $node end }]} { debugmsg disco "MOVE FAILED: $parent $node" } else { debugmsg disco "MOVE: $parent $node" } } if {[$tw itemcget $node -data] != $data || \ [$tw itemcget $node -text] != $desc} { debugmsg disco RECONF $tw itemconfigure $node -text $desc -data $data } } elseif {[$tw exists $parent]} { eval {$tw insert end $parent $node -text $desc -open 1 -image $icon \ -data $data} $args } else { eval {$tw insert end root $node -text $desc -open 1 -image $icon \ -data $data} $args } } proc disco::browser::reorder_node {tw node {order {}}} { set subnodes [$tw nodes $node] set identities {} set features {} set extras {} set items {} foreach sn $subnodes { lassign [$tw itemcget $sn -data] kind switch -- $kind { error_items - item {lappend items $sn} error_info - identity {lappend identities $sn} feature {lappend features $sn} extra {lappend extras $sn} } } if {$order == {}} { $tw reorder $node [concat $identities $extras $features $items] } else { $tw reorder $node [concat $identities $extras $features $order] } } proc disco::browser::remove_old {tw node kind newnodes} { set subnodes [$tw nodes $node] set items {} foreach sn $subnodes { lassign [$tw itemcget $sn -data] kind1 if {$kind == $kind1 && ![lcontain $newnodes $sn]} { $tw delete $sn } } } proc disco::browser::item_desc {jid node name nitems} { variable options if {$node != ""} { set snode " \[$node\]" } else { set snode "" } if {$nitems > $options(upper_items_bound)} { set sitems " - $nitems" } else { set sitems "" } if {![string equal $name ""]} { return "$name$snode ($jid)$sitems" } else { return "$jid$snode$sitems" } } proc disco::browser::item_icon {category type} { switch -- $category { service - gateway - application { if {[lsearch -exact [image names] browser/$type] >= 0} { return browser/$type } else { return "" } } default { if {[lsearch -exact [image names] browser/$category] >= 0} { return browser/$category } else { return "" } } } } proc disco::browser::textaction {bw tnode} { variable disco variable browser set tw $browser(tree,$bw) set data [$tw itemcget $tnode -data] set data2 [lassign $data type] switch -- $type { item { lassign $data2 connid jid node goto $bw $jid $node } feature { lassign $data2 connid jid node feature category subtype set var [jlib::wrapper:getattr $feature var] debugmsg disco $jid if {$var != ""} { if {[info exists browser(feature_handler,$var)]} { if {$browser(feature_handler_node,$var)} { eval $browser(feature_handler,$var) [list $jid $node \ -category $category -type $subtype \ -connection $connid] } else { eval $browser(feature_handler,$var) [list $jid \ -category $category -type $subtype \ -connection $connid] } } else { negotiate_feature $tw $connid $jid $tnode $var } } } } } proc disco::browser::textpopup {bw tnode} { variable browser set m .discopopupmenu if {[winfo exists $m]} { destroy $m } menu $m -tearoff 0 set tw $browser(tree,$bw) set data [$tw itemcget $tnode -data] set data2 [lassign $data type] # Parent node category shouldn't impact node action in theory, # but sometimes (e.g. when joining MUC group) it's useful. set tparentnode [$tw parent $tnode] set parentdata {} catch {set parentdata [$tw itemcget $tparentnode -data]} hook::run disco_node_menu_hook $m $bw $tnode $data $parentdata tk_popup $m [winfo pointerx .] [winfo pointery .] } proc disco::browser::textpopup_menu_setup {m bw tnode data parentdata} { variable browser set tw $browser(tree,$bw) if {[$m index end] != "none"} { $m add separator } set tparentnode [$tw parent $tnode] set data2 [lassign $data type] switch -- $type { feature { $m add command -label [::msgcat::mc "Browse"] \ -command [list [namespace current]::browser_action browse $bw $tnode] $m add separator } item { $m add command -label [::msgcat::mc "Browse"] \ -command [list [namespace current]::browser_action browse $bw $tnode] $m add command -label [::msgcat::mc "Sort items by name"] \ -command [list [namespace current]::browser_action sort $bw $tnode] $m add command -label [::msgcat::mc "Sort items by JID/node"] \ -command [list [namespace current]::browser_action sortjid $bw $tnode] $m add separator if {$tparentnode == "root"} { set label [::msgcat::mc "Delete current node and subnodes"] } else { set label [::msgcat::mc "Delete subnodes"] } $m add command -label $label \ -command [list [namespace current]::clear $bw $tnode] } default { } } $m add command -label [::msgcat::mc "Clear window"] \ -command [list [namespace current]::clearall $bw] } hook::add disco_node_menu_hook \ [namespace current]::disco::browser::textpopup_menu_setup 100 proc disco::browser::clearall {bw} { variable browser set tw $browser(tree,$bw) set subnodes [$tw nodes root] foreach sn $subnodes { $tw delete $sn } } proc disco::browser::clear {bw tnode} { variable browser set tw $browser(tree,$bw) set tparentnode [$tw parent $tnode] set type [lindex [$tw itemcget $tnode -data] 0] if {$tparentnode != "root"} { if {$type != "item"} { set tnode $tparentnode } foreach sn [$tw nodes $tnode] { $tw delete $sn } lassign [$tw itemcget $tnode -data] type connid jid node if {$type == "item"} { set name [disco::get_jid_name $connid $jid $node] set desc [item_desc $jid $node $name 0] $tw itemconfigure $tnode -text $desc } } else { $tw delete $tnode } } proc disco::browser::browser_action {action bw tnode} { variable browser set tw $browser(tree,$bw) set data [$tw itemcget $tnode -data] set data2 [lassign $data type] switch -glob -- $type/$action { item/browse - feature/browse { textaction $bw $tnode } item/sort { set browser(sort,$bw,$tnode) sort set items {} foreach child [$tw nodes $tnode] { set data [lassign [$tw itemcget $child -data] type] switch -- $type { item { lassign $data connid jid node lappend items \ [list $child \ [disco::get_jid_name $connid $jid $node]] } } } set neworder {} foreach item [lsort -dictionary -index 1 $items] { lappend neworder [lindex $item 0] } reorder_node $tw $tnode $neworder foreach child [$tw nodes $tnode] { browser_action $action $bw $child } } item/sortjid { set browser(sort,$bw,$tnode) sortjid set items {} set items_with_nodes {} foreach child [$tw nodes $tnode] { set data [lassign [$tw itemcget $child -data] type] switch -- $type { item { lassign $data connid jid node if {$node != {}} { lappend items_with_nodes \ [list $child "$jid\u0000$node"] } else { lappend items [list $child $jid] } } } } set neworder {} foreach item [concat [lsort -dictionary -index 1 $items] \ [lsort -dictionary -index 1 $items_with_nodes]] { lappend neworder [lindex $item 0] } reorder_node $tw $tnode $neworder foreach child [$tw nodes $tnode] { browser_action $action $bw $child } } default { } } } # TODO proc disco::browser::textballoon {bw node} { variable disco variable browser set tw $browser(tree,$bw) if {[catch {set data [$tw itemcget $node -data]}]} { return [list $bw:$node ""] } lassign $data type connid jid category subtype name version if {$type == "jid"} { return [list $bw:$node \ [item_balloon_text $jid $category $subtype $name $version]] } else { return [list $bw:$node ""] } } proc disco::browser::goto {bw jid node} { $bw.navigate.entry.e delete 0 end $bw.navigate.entry.e insert 0 $jid $bw.navigate.node.e delete 0 end $bw.navigate.node.e insert 0 $node go $bw } proc disco::browser::get_category_type {t tnode} { foreach child [$t nodes $tnode] { set data [$t itemcget $child -data] set data2 [lassign $data type connid jid node] if {$type == "identity"} { return $data2 } } return {} } proc disco::browser::draginitcmd {bw t tnode top} { set data [$t itemcget $tnode -data] set data2 [lassign $data type connid jid node] if {$type == "item"} { if {[set img [$t itemcget $tnode -image]] != ""} { pack [label $top.l -image $img -padx 0 -pady 0] } lassign [get_category_type $t $tnode] category type if {![info exists category]} { # Using parent tag to get conference category. # ??? Which else category could be got from parent? lassign [get_category_type $t [$t parent $tnode]] category type if {![info exists category] || ($category != "conference")} { # For other JIDs use heuristics from roster code. lassign [roster::get_category_and_subtype $connid $jid] category type } } return [list JID {copy} [list $connid $jid $category $type "" ""]] } else { return {} } } proc disco::browser::entrydropcmd {bw target source pos op type data} { set jid [lindex $data 1] goto $bw $jid "" } proc disco::browser::history_move {bw shift} { variable browser set newpos [expr {$browser(histpos,$bw) + $shift}] if {$newpos < 0} { return } if {$newpos >= [llength $browser(hist,$bw)]} { return } set newjidnode [lindex $browser(hist,$bw) $newpos] set browser(histpos,$bw) $newpos lassign $newjidnode newjid newnode $bw.navigate.entry.e delete 0 end $bw.navigate.entry.e insert 0 $newjid $bw.navigate.node.e delete 0 end $bw.navigate.node.e insert 0 $newnode disco::request_info $newjid $newnode -connection $browser(connid,$bw) disco::request_items $newjid $newnode -connection $browser(connid,$bw) } proc disco::browser::history_add {bw jid} { variable browser set browser(hist,$bw) [lreplace $browser(hist,$bw) 0 \ [expr {$browser(histpos,$bw) - 1}]] lvarpush browser(hist,$bw) $jid set browser(histpos,$bw) 0 debugmsg disco $browser(hist,$bw) } #proc disco::browser::item_balloon_text {jid category type name version} { # variable disco # set text [format [::msgcat::mc "%s: %s/%s, Description: %s, Version: %s\nNumber of children: %s"] \ # $jid $category $type $name $version $disco(nchilds,$jid)] # return $text #} proc disco::browser::register_feature_handler {feature handler args} { eval [list hook::run browser_register_feature_handler_hook \ $feature $handler] $args } proc disco::browser::register_feature_handler1 {feature handler args} { variable browser set node 0 set desc "" foreach {attr val} $args { switch -- $attr { -node {set node $val} -desc {set desc $val} } } set browser(feature_handler,$feature) $handler set browser(feature_handler_node,$feature) $node if {$desc != ""} { set browser(feature_handler_desc,$feature) $desc } } hook::add browser_register_feature_handler_hook \ disco::browser::register_feature_handler1 # Destroy all (global) state assotiated with the given browser window. # Intended to be bound to a event handler for browser windows. proc disco::browser::destroy_state {bw} { variable browser array unset browser *,$bw array unset browser *,$bw,* set idx [lsearch -exact $browser(opened) $bw] if {$idx >= 0} { set browser(opened) [lreplace $browser(opened) $idx $idx] } } tkabber-0.11.1/plugins.tcl0000644000175000017500000000141610661540637014721 0ustar sergeisergei# $Id: plugins.tcl 1198 2007-08-18 09:53:35Z sergei $ namespace eval plugins {} proc plugins::load {dir args} { set dir [fullpath $dir] set uplev 0 foreach {attr val} $args { switch -- $attr { -uplevel {set uplev $val} } } foreach file [lsort [glob -nocomplain $dir/*.tcl]] { debugmsg plugins "Loading plugin from $file" if {$uplev} { uplevel [list source $file] } else { source $file } } } proc plugins::load_dir {plugins_dir} { foreach dir [lsort [glob -nocomplain -type {d l} [file join $plugins_dir *]]] { set file [file join $dir [file tail $dir].tcl] if {[file exists $file]} { debugmsg plugins "Loading plugin from $file" source $file } else { debugmsg plugins "Can't load plugin from $file" } } } tkabber-0.11.1/pixmaps/0000755000175000017500000000000011076120366014205 5ustar sergeisergeitkabber-0.11.1/pixmaps/default/0000755000175000017500000000000011076120366015631 5ustar sergeisergeitkabber-0.11.1/pixmaps/default/services/0000755000175000017500000000000011076120366017454 5ustar sergeisergeitkabber-0.11.1/pixmaps/default/services/mrim_away.gif0000644000175000017500000000023210563366067022137 0ustar sergeisergeiGIF89a³ 6Ü"›ÿÿÿ|||ttt@@@OOObbb!ù ,GPÉ j˜†½AÖVx0*z‚j§’¦‹ôk¿1~ |ÏëÁ`HBÂ!Qg!qhÄU’tn5Ÿ¯º|Îç;tkabber-0.11.1/pixmaps/default/services/msn_away.gif0000644000175000017500000000053110563366067021772 0ustar sergeisergeiGIF89aÕ-ÿÿÿg”¯LvYwœSo’HaWu™s¶`¦Mg‰e…®NiŠmŒ³`©AWuaªv“¸w”¸D\{@@@E^}Oj‹Ib‚Zyžg‡¯Wuš^}£d…®OOOb‚ªbƒ«bbbt’·z–¹tttgˆ±x”¸|||\z oŽ´YwXu™Le…!ù-,vÀ–P((†H¤ÀÁHŽÉáR‚ˆШ€0= †lRˆŽ  *!ŽA-%7"ØA”¸â0@+61áâ 2/âAöÿí@p€¡@;tkabber-0.11.1/pixmaps/default/services/yahoo_online.gif0000644000175000017500000000051710563366067022643 0ustar sergeisergeiGIF89aÕ"ÿ»›=˜ïÚößÿçÿéûäÿéôÝÿï_åÐòÜíÙLF ìØÿì(KEûåÿó|ÿí:ýçÿï`êÕæÑÿîCÿðcÿèçÑóÝêÔÿñjûâ!ù",l@‘pH,D€r @ ËÁ@Äd—WÀ›mà€ršT6 ŠALN"І Ãc‘vYx|O ‰C •–£ D §Ea®NCA;tkabber-0.11.1/pixmaps/default/services/icq_offline.gif0000644000175000017500000000020010563152474022416 0ustar sergeisergeiGIF89aÂWWWuuu………¾¾¾ÿÿÿÿÿÿÿÿÿÿÿÿ!ù,EHºÀž{Ë5ZÅÓÅyA¥LÝ8J_ˆbØ]Ú9CþÂÓ—¨ˆ†-G"m#|µ2‰$ÌXZLj+&…Y½5B;tkabber-0.11.1/pixmaps/default/services/gg_xa.gif0000644000175000017500000000054310563366067021244 0ustar sergeisergeiGIF89aÕ*gggJJJŸŸŸnnnttthhh]]]}}}bbbSSSOOOXXXÌÌÌLLL›››†††•••ÒÒÒ×××ÍÍÍÅÅÅŽŽŽÚÚÚÕÕÕÔÔÔêêêÓÓÓÊÊÊÖÖÖIIIÆÆÆººº´´´ÀÀÀØØØÐÐÐËËË»»»æææÜÜܳ³³!ù*,€@•p¨H#r¨6‹É" 0>‰€ÎCj\™›‰à"(U¾EÉè¤ÁpDÏ* ÑÈ\P’ $þ!€~‰)*Š€’ ‰™‘ ¢¤œž© •­¦¯ ±³•œ¸²D¾CÄDA;tkabber-0.11.1/pixmaps/default/services/jud.gif0000644000175000017500000000036010606341131020715 0ustar sergeisergeiGIF89a„wš]*šh2±{A!Ãÿ$Äÿ(Åÿ)Åÿ-Æÿ/Çÿ2Çÿ5Èÿ:Êÿ@ËÿBÌÿNÏÿTÑÿVÑÿYÒÿcÕÿnØÿrÙÿvÚÿ„Þÿ‰ßÿ•âÿœäÿªèÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù,mà'$)ž(‰]Öô˜è˜iÙEE ¦mLEâHèR—YíÖ@OËeÕz0ÏÑ„R¡L E!Ë{D$‘‡ca y Gƒ¡h¿y€âPp;#%:;†ˆ‰'‹‡Ž‘“†“”!;tkabber-0.11.1/pixmaps/default/services/weather_away.gif0000644000175000017500000000035010563366067022633 0ustar sergeisergeiGIF89aÄJJJ~~~ŸŸŸºººtttnnnhhhbbb}}}˜˜˜SSS]]]XXX›››†††OOO•••¢¢¢LLL“““œœœIIIŽŽŽ©©©‹‹‹¸¸¸!ù,e 'Ždižf ’ê:DˆA6YÊÌÁ1±©7E%¢™ÁH€MIÎ.€tP‰‚À‰N’¤ö€` ¥`Ì#k 3 dz=.Ã!A—Þ¶/ðz]c…y…$…‚‹(‘’#!;tkabber-0.11.1/pixmaps/default/services/yahoo_dnd.gif0000644000175000017500000000052010563366067022116 0ustar sergeisergeiGIF89aÕ%sss™ÿÿÿDDDÖÒðÐô€€ñ€€ð€€Øÿ‹‹ø€€Þÿ©©ÿSSä÷€€ì€€ÿ++ÿ¹¹âÿIIêÚìÔÿWWÿššÜÿ!!ÿ__뀀èÿ77!ù%,mÀ’pH,D€r @ ËÁ Äd—WÀ›mà€ršT"ALNHPÅ †Äâ™$$vY† O# ‡‹C "•–  D¨Ea¯NCA;tkabber-0.11.1/pixmaps/default/services/msn_chat.gif0000644000175000017500000000054610563366067021756 0ustar sergeisergeiGIF89aÕ)€?¤?ä·ÿÐ øÇÿÖ/ÿÕ)ðÁÖ¬ôÄÿÑÿÏ Ø®ÆŸ¶’ÿÏ â¶Ð§ÿÒÿÍüËÿÎÿÓ!Ê¢ÿÖ-ÿÓگȡÿÔ#ÿÐÿ×3æ¹ÿÎöÆÿÒì¾ÿ×1ÿÕ+¾™è»!ù),ƒÀ”p(†Hdರ(ŽIâep€ Ðh`q(1œl2`0D‰“X©ƒÇZÙÄç€l ŸÍ§sByGEŒ‰G~&‘b#!s k $( › ¯|Ç~BA;tkabber-0.11.1/pixmaps/default/services/weather_chat.gif0000644000175000017500000000051210563366067022611 0ustar sergeisergeiGIF89aÕ!ÊŠë¡ÿÿÿõBÿçÿëÿÙÿùžÿÓÿÖÿû¼ÿÝÿâÿÔÿåÿû·ÿð#ÿð)ÿ÷uÿÞÿø„ÿÒÿ×ÿãÿô=ÿìÿðÿú¦ÿÛÿîÿ÷QÿúŸÿá!ù!,gÀpH,C€$à8\ç p:«Ej5À h—Äd 38<¼`a2¸0Å&€S‰Cã¡H¼XH[ €vK  tkMx  hY[]_V‚ia‚X¥FJ©L­A;tkabber-0.11.1/pixmaps/default/services/msn_xa.gif0000644000175000017500000000052710563366067021446 0ustar sergeisergeiGIF89aÕ!ÿÿÿttt±±±™™™¢¢¢›››¦¦¦•••ŠŠŠ®®®¨¨¨„„„œœœ«««‡‡‡¤¤¤£££@@@²²²OOOžžžŸŸŸ‹‹‹ˆˆˆ¯¯¯‘‘‘|||¬¬¬bbb!ù!,tÀP(†Hdà0ŽÉá’°Ðh± Šl2`ˆXy($šÆZP@äÑñ`ŸÏþ€cE†‡J… ‰D …‡†”! ŽœDmš›”nR{¸¹HA;tkabber-0.11.1/pixmaps/default/services/yahoo_away.gif0000644000175000017500000000033710563366067022320 0ustar sergeisergeiGIF89aÄÿWWWÈÈÈÊÊʘÇÇÇÉÉÉØØØÆÆÆÓÓÓÕÕÕÔÔÔ<<<ÒÒÒ@@@×××ÐÐÐÙÙÙÜÜÜÍÍÍ!ù,\`%Ždiž$ ®*+AT,;®70ãy À€j–RÇ@HL‰b°<‘Ç„Ñ8Åë € _’,p8P½hp) 8£ëù¼^èç] z(A†.&!;tkabber-0.11.1/pixmaps/default/services/gg_online.gif0000644000175000017500000000050010563366067022111 0ustar sergeisergeiGIF89aÕ"ÿùÓíÉß½îÊýÖóÎäÁåÂöÐ÷ÑϯëÇÍ®êÆõÐÿçcÿãGÒ²Ù¸úÔñÌѱ޼øÒˬÿØÐ°ìÈήʫطֵ!ù",]@‘p(H#r¨6‹É"@0>‰€Œ`aé\™AÀh ¾ÅCEY<Ï*`0P6‡$Ç&hŠhE! ŽVUPGqXKLžKŽ KA;tkabber-0.11.1/pixmaps/default/services/aim_online.gif0000644000175000017500000000052410564135314022256 0ustar sergeisergeiGIF89aÕ>ÿÊXˤ`É¡^Ñ­kÿÇSÿ­)¿‘IÆVº‹DΨe¼Lÿ±4ÿ°/¿‘Jÿ»AÓ¯pÈŸYÌ¥aÿ³3Ò®k¼ŽD¾•Rÿ³1ÇžXÿÄQÿ·8ÿ¿LÒ®lЫiÿ¶=É¢]ÿ«)ÿÊYÿ²4ÿÀJÇWÿ²5ÿºD̦cÿ±0–PÿÌ[ÿ±2ÿ³=Ï©gÿÅOÿ¯5ÿª/ÿÂMÈ ]¾H¿’MÿÄS¾GÀ“NÿÁJÉ¡\ΧeϪhÉ \Ê¢]!ù>,q@Ÿpè‰È! sÒ’D—qIžÐb+Rí°Y€@A‡f(æ ÓBÀâU  xÑ2¢D$zE&eGj%,z3"2 i=+9F<(`b 7XF6© 4fF)²‡QfA;tkabber-0.11.1/pixmaps/default/services/weather_offline.gif0000644000175000017500000000106010563366067023313 0ustar sergeisergeiGIF89aæEÿÿÿ®ºÃÄîäÿ\\ÓÝú¤ÿMMÿiiÀÜÿeeòÇéÿBBÿ]]ÿ£õá²ÿ[[ÿÿÿïÿýÿµÍÉíÿOOÿ99þÿ88¸ÿAAÿNNöÿ++¨Ì¯ÿ??ÿ''Þÿÿÿaaÿ Ñÿ..ϼƭÛÿGG¹Õ!ùE,€E‚ƒ„…†‡ˆE‹‹‰< †70-…*.9(4„"8+B )5®‚ !:# ¼Š= AÀ/ 'Ê%D 6ÊŠC,?&2;ãE>@3$ç †  1HĨQ¢ƒ;tkabber-0.11.1/pixmaps/default/services/gg_offline.gif0000644000175000017500000000033110563366067022251 0ustar sergeisergeiGIF89aĬ¬¬±±±———¥¥¥œœœ«««¦¦¦•••®®®£££ªªªŸŸŸ   ›››¯¯¯¨¨¨­­­²²²“““ŽŽŽ¤¤¤ÐÐÐÇÇÇ‘‘‘ššš’’’!ù,V 'Ž@ž¨‰ŽªØ–i €ù’€¤q³…@p¸4~%D“ , ¯€@& Ç` Å9DcÐA '±± K Š¡‚yÛ†ìÅ­X+o+!;tkabber-0.11.1/pixmaps/default/services/weather_online.gif0000644000175000017500000000055010563366067023160 0ustar sergeisergeiGIF89aÕ,ÊŠ¨§§kkkÿÿÿë¡ÿÿåååêêêáááÜÜÜÅÅÅÖÖÖïïïµµµýýýúúúÿõBÑÑѨ¨¨óóóöööÿçÿÞÿâÿîÿÝÿú¦ÿ÷Qÿð#ÿ÷uÿìÿø„ÿô=ÿû·ÿãÿùžÿð)ÿû¼ŸŸŸÿåÿëÿúŸÿÛÿð!ù,,…@–pH,Y€$à8\ çPp:«Ej•À%h—Ä$Á…¼`a’E¡@©’†€SËiµùt¼XHƒ$„`Ž* ,„— ƒŽ–¡  ƒ¦¨ ¢­ š±ª³ µ&·š ¼¶ÂD¿,ÈEA;tkabber-0.11.1/pixmaps/default/services/sms.gif0000644000175000017500000000022710606341131020737 0ustar sergeisergeiGIF89a³QQQeeeggg„„„vvv|||bÇhÔˆˆˆnnnuí}}}qåséÿÿÿ!ù,DðÉ9½Øâ ºÞŒß(ZrAÛ®p4 ‚ÀÕ¼87øÈ‡]p½|€R‰ 1 OFóG¨V§…A«À ¾ßéÏ‹;tkabber-0.11.1/pixmaps/default/services/aim_away.gif0000644000175000017500000000052710564135314021736 0ustar sergeisergeiGIF89aÕ4ÿÿÿÿÊXÿÇSˤ`¿‘I|||ÿÀJÏ©gOOOÿ¶=ÿÊYÿÂMÿ±2ÿºDϪhЫiÉ¢]¾•Rÿª/ÿ¿LΨeÿÌ[È ]¼LbbbÓ¯pΧeº‹DÿÄȘcÌ¥aÿ³=À“Nÿ²5Ê¢]É¡^ttt¿’MÿÄQÿÅOÿ«)ÿ²4Ò®lÿÁJÿ±4É¡\¾H@@@ÿ¯5Ñ­k!ù4,t@špH‰È! òá’D«…JžÐb¢Á¸@°Y@Á2‡f(€²Ø ÓB@Fæxq‚øÿ~H‡ˆQ%#!†1Šq0+†ˆ‡•$/ &E.*"O›œŠF'X€€qG‚fA;tkabber-0.11.1/pixmaps/default/services/yahoo_xa.gif0000644000175000017500000000033710563366067021767 0ustar sergeisergeiGIF89aÄtttWWWÈÈÈÊÊÊEEEÇÇÇÉÉÉØØØÆÆÆÓÓÓÕÕÕÔÔÔÐÐÐ×××@@@ÜÜÜÙÙÙÒÒÒ<<<ÍÍÍ!ù,\`%Ždiž$ ®*+AT,;®70ãy À€j–RÉ@HLˆˆb°<„19Åë € _’,p8P½hp) 8£ëù¼^èç] z(A†.&!;tkabber-0.11.1/pixmaps/default/services/aim_chat.gif0000644000175000017500000000053210564135314021710 0ustar sergeisergeiGIF89aÕ>ŽŽŽÎ·YηWк[ÿÓ)ÿåSÿèXÖÂfÿãSèAèBÿÖ5ÿÕ2ÿßLÿÖ4ÿÛDÿÏ/ÿÓ5ÿ×0ͶTĨDÿÑ)ÿÕ4ÿÝAĨGÿé[˵QÿÛ8ÿØ=¿¢>Á¥GÿØ1Å©HÿØ3ëMÿÖ/Ô¿cÔ¾b̵SÌ´RÿâMÿèY×Ãg×ÃfѼ^ÿáJÿäOÿÕ=Ä©CÓ¼`ÿãQϸXÇ­JͶX×ÃkθXÿßJÁ¦>Ñ»\Ó¾`ÕÀd!ù>,w@Ÿp8‰Èb¯%Ѐ°rÍ^;grjJ©4%íÖ ðbaTJ6¦·€Hçæ~O?’ÄÁ`8h£S#9,(vShGp 0'ˆ8 6 $o41 F:be!ZF" ¯iF5¸DA;tkabber-0.11.1/pixmaps/default/services/weather_xa.gif0000644000175000017500000000033210563366067022302 0ustar sergeisergeiGIF89aÄÞÿJJJlÿŸŸŸnnnttt}}}›››hhhSSS†††•••]]]ŽŽŽbbbOOOLLLXXXIII!ù,W Ed)žh@¬+R)K Œ³Faªs}ç‰GC¢ Ñl¸Bp¨€D£ŸRHtN #à`Û|nQÛ@§³š|FQk8ÙýfÛÑôw‰€Že2J]™*ËárØd¾EÌÉÄ™ˆ>Ï*@"Ñ\<˜Ð %þ$€~‰% ,Š €’ ‰™‘  ¢¤œž© •­¦¯ ± ³•œ¾¸²¾D¾»,ÄGA;tkabber-0.11.1/pixmaps/default/services/aim_dnd.gif0000644000175000017500000000052710564135314021542 0ustar sergeisergeiGIF89aÕ4ÿÿÿÿSWÿX[Ë`g¿IS@@@É\c¼LWÒlqÏgmÿ=NÌciÉ^fÓpvÿ5EÿOTÿDPÈ]eÿ/Eÿ2BÎelÏhnÿ5Hÿ[\|||ÎekÐioOOOÑkpÉ]cÌahÿSZÿJQÊ]dÿMT¿MXÿQWbbb¾RZtttÿY\ÿJRÿLV¾HRºDPÿ=Kÿ)<ÿ4EÀNYÿ4D!ù4,t@špH‰È!€Ó°’D€BdŠ€žÐ₤Ê\°Y@aã‡f(€òz ÓB@" xµ øÿ~H,‡ˆQ †'Šq-3†ˆ‡•#)E102O›œŠF.%X€€qG‚fA;tkabber-0.11.1/pixmaps/default/services/icq_xa.gif0000644000175000017500000000024710563152474021417 0ustar sergeisergeiGIF89a³ AAA«««½½½ÿÿÿüáøü@@@bbb|||tttOOO!ù ,T°ÉÙ ˜‚!®½“UqÅÛGšB'måºjg ƒ•Z~⻃á†Ûœ¤2ùℨ4ûA ˆ„‚@…Å Òhw0`] qs$‡©´çR‰ùhp;tkabber-0.11.1/pixmaps/default/services/icq_dnd.gif0000644000175000017500000000024710563152474021554 0ustar sergeisergeiGIF89a³ uÍÿ66ÿÿÿüáøütttOOO@@@bbb|||!ù ,T°ÉÙ ˜‚!®½“UqÅÛGšB'måºjg ƒ•Z~⻆Bá†Ûœ ¤2ùℨ4ûAŠƒ@…Å Òhw0`]qs$‡©´çR‰ùhp;tkabber-0.11.1/pixmaps/default/services/mrim_offline.gif0000644000175000017500000000014510563366067022623 0ustar sergeisergeiGIF89a‘¥¥¥MMM!ù,6”™Çÿ@s*ÙÀŠoêE¦I¥…ŽêX²_ _±ùʶ¹‘öQ—cœ*A!äXD““¦¡;tkabber-0.11.1/pixmaps/default/services/icq_chat.gif0000644000175000017500000000036010563152474021722 0ustar sergeisergeiGIF89aÄZ¥Î"ÿàqÿÝqÿÕpÿíqÿóqÿèqÿñqÿÓpÿåqÿïqÿÚqÿüÄÿö…ÿòqÿØqÿØpÿäqš6ÿéqÿãqš‘6!ù,m`&Ž( Âiž£Y²­ÉÂëKÛB+®­€P¸S  ø~¦£€0l&„áA»] ‹âH8ŸQÉ™p PÞ.³Á0D“]4 d1QCoO%€5@‰262(/*[!;tkabber-0.11.1/pixmaps/default/services/yahoo_offline.gif0000644000175000017500000000013110563366067022771 0ustar sergeisergeiGIF89a‘„„„\\\!ù,*”©‹à˜ /áy\ÞEÎ…y DVÊØ‘§y¸!ç,ÖMÊÒÎ÷þ¿+;tkabber-0.11.1/pixmaps/default/services/aim_offline.gif0000644000175000017500000000035010564135314022411 0ustar sergeisergeiGIF89aÄyyyttt}}}uuuhhhˆˆˆ{{{www†††xxxvvv‚‚‚~~~zzzƒƒƒlll€€€rrr„„„kkkqqq|||dddeeejjj………pppiii‰‰‰ggg!ù,eà'Ž`’èXJ¤$Ð0Ú„¼py‰ÑcB]™™‰Š’Ym¾ÅÇÓ„RÏ*@"¹PJ‘Žæ$þ€~‰$ , .Š €’ ‰™‘ ¢¤œž© •­¦¯±#³•œ¾¸²¾D¾».ÄGA;tkabber-0.11.1/pixmaps/default/services/gg_chat.gif0000644000175000017500000000052710563366067021555 0ustar sergeisergeiGIF89aÕ(ÿY¤kÅ™æÿíÉß½óÎùÓÝ÷ÿåÂöнïÿîÊýÖ[×ÿ÷ÑäÁҲϯ­ëÿKÓÿÿçcʫήìÈÿãGÿØ3ÍÿõÐñÌÙ¸øÒˬֵêÆëÇÞ¼úÔkÛÿ!ù(,t@”pˆH#r¨6‹É"`0 ®IâÉÁÐA Rä*&&22<«€BaáØ‚w  ‚ c%‘‹c"!•cRU'–Nn(‚‚KP¤§ ‚·µ¯GA;tkabber-0.11.1/pixmaps/default/services/mrim_online.gif0000644000175000017500000000014510563366067022465 0ustar sergeisergeiGIF89a‘6Ü"›!ù,6”™Çÿ@s*ÙÀŠoêE¦I¥…ŽêX²_ _±ùʶ¹‘öQ—cœ*A!äXD““¦¡;tkabber-0.11.1/pixmaps/default/services/msn_dnd.gif0000644000175000017500000000052710563366067021603 0ustar sergeisergeiGIF89aÕ(ÿÿÿ¤!!Í==àccÄ;;Ñ>>ÜNNß^^ÞXXÚEE»99¢55º99ÛHHÛJJÚFF¨66°88Ù@@Ò>>|||@@@OOOÖ??Ô??¶99½::±88àeeß``«77ßZZtttÝQQÝSSàffbbb!ù(,t@”P((†H¤@XŽÉá²xШ‘øD ”lR°xD,މXy ¡ÆZÉ LäÑñ`ŸÏþ€cE†‡J …'‰D%"&…‡†”($Ž#œDmš›”nR{¸¹HA;tkabber-0.11.1/pixmaps/default/tkabber/0000755000175000017500000000000011076120366017243 5ustar sergeisergeitkabber-0.11.1/pixmaps/default/tkabber/toolbar-show-offline.gif0000644000175000017500000000203110563064247023773 0ustar sergeisergeiGIF89a÷X:::ÿñÿÍèèèÿÝÿÑÿíl[:]]]ÿÚÏÏÏåååÖÖÖÂÂÂÿáÿÂÿäÍÍÍxo^ãããÿçÿ¿ÿÓÿÛÿ¹ÙÙÙÿÏ´´´êêê±±±áááÛÛÛ666ªªªMMMÿåÊÊÊ…Dÿ´ëëëÚÚÚ§S¿¿¿äÞÔl5àààl/ÔÅ¥×××ÞÞÞl2ÿôÌÌÌÿÈÐÐÐÿÞÿ¯ÿ×ÿîÃÃÃáѱÑÑÑÿÐÿèíííÿêÿëÿÊl3ÿÉÿ¼ÿÖaaaû¬çª555îîîÿÔÿÃäääÿãÿÅ999l`Fÿïlll¥¥¥ç¢!ùX,ö±H° Áƒ*\ÈЊÇ ZQAC‰¬Dh…ƒ1>ôØ‘q£N x‚âÅ•—0vÀÈW¢(0¤Ž+ ­D˜ÀÂ+5Œ€p¡À @Zɰ`ÀŠ+ ÐAႨAI|ðàኃ3¹á£BT© 2À¸’CH*?h0òö •4¸Å€ ôõÛ!DˆW,@ à ‰“ÅE€b‰ˆ+G$Æl° ¨«\)bAÃÒ«Èž}%‰’+&`À–DXÈp‘b#A ’O‘`|àìÙÍöö½ºõë;tkabber-0.11.1/pixmaps/default/tkabber/xaddress-blue.gif0000644000175000017500000000021310572331547022475 0ustar sergeisergeiGIF89a³ )±c‡ýs“ý2aüT{ý‚Ÿý:güFpüªþœ³þ!ù ,8PÉI«½x+¶ZÀ`DYœTº¶BÀ’̺H‚ë4›Ï£ÚÕn¨b—}L(Ú¤Z¯;tkabber-0.11.1/pixmaps/default/tkabber/gpg-vsigned.gif0000644000175000017500000000034510607415615022151 0ustar sergeisergeiGIF89aÄìììè»}ÔÔÔÝÝÝãããûûûÊÊÊê½ÅÅÅÂ~"¯DÅsçç爈ˆÿÿÿÿÿÿÿ!ù,b $ŽdižhªŠMë¾0Ù"ÁÜ7! ­l´@` Z?ˆcÙ Š…4ÑJeƒñ(¤`@áÁÀŠÛ‡z( ¨Éf$ý>,oøyÎÍûõ# 8„„qs0Š.+Ž+!;tkabber-0.11.1/pixmaps/default/tkabber/xaddress-green.gif0000644000175000017500000000021310572331547022646 0ustar sergeisergeiGIF89a³ Z·¼¨±¬¥ Ç!Ë"!ù ,8PÉI«½x+¶Z€1DyœTº¶ÂÀ’̺H‚ë4›Ï£ÚÕn¨b—}L(Ú¤Z¯;tkabber-0.11.1/pixmaps/default/tkabber/toolbar-add-user.gif0000644000175000017500000000120410563064247023100 0ustar sergeisergeiGIF89aæj×ÜÎÅÉÓåàîÀòé÷ûð“Hñ’Jì…9óœUåo(ìƒ:Ü`öŒLÁâg óŒIÍA)®wIè|0÷¦cøªhï†L lCé}2íŠ=¨g2ªn<¯yMèx+çj.ø’Pô›TÛ]÷£_àaÄñ•J÷ \ ô¡[ ÏS2¼ó™Pë„9¯{N¬sCö¢^ºët<øšZÝ]ìˆ:Òï‘Eçy-îŒ?ôœT ìr5ñ•KÈó‡Eìz:îBäl"©sFôŸYø§eås(ÊÚZú©kÙ[ðŒFñ˜Oäm*Ç$ä¯yK½Œÿÿÿ!ùj,á€j‚ƒ„…†‡ˆ‰Š… K‹‡.’„><›‚ Q1¦j+SCg&\D–±4Z)(7=0±V;E[AT/ ±$5Pc:MOJ‰ii…X-'2ŠÚ…B,N]Y‹å…#8_6ˆÚöö„ aIdõ÷ø‚Œ‘2㊘2@üBS ’*~€æ;Ah,˜PED0`èbF 48€ d(BƒR%K—0,˜™reK/c.¨8ÍM ¼è$* Ó§NcIJ(;tkabber-0.11.1/pixmaps/default/tkabber/toolbar-join-conference.gif0000644000175000017500000000206410563064247024445 0ustar sergeisergeiGIF89a÷nnnwww„„„þ6ˆˆˆVVV1*%ëa;ñùLîú9òHï}`F1-)Aðñ”K```–=ñKîý‹5‚`œ-ôìˆ8ø‚d÷•QßdXìë„5*õýŒ6ù›X@ñ?1&ø¢`í‰;ú†/ð”I‚O+dè###í?Õz4öv$ZI:"÷[_²ß`"pÅn.év2¸èw&òjÓ*÷ï’Fõ¢\Ê&ô–Q2ôTíú)öýŠ4ú&öç]&ÿŽ7ðŽH6óCðôœT`êîAd`¯ñˆ6ü‰2ø€*ùƒ-]ê¯Vø§cò™Q‹9û¨gô™Të€8 ûì\Â0 SízBÚ)hèyKšâl!\ëê€/àj#X-ò‡C‹‹‹GGGM8'ÜY4ó´\ þŽ7NîdQbñ–MæD ßZ ôžW0ôû‡1/èbbbïk.Ú7ëccc$$$ÿÿÿÿ!ù,ÿ H° Áƒ*<ø§¡Ã„Š‘áŸ± Øa (.°˜åŒ?$üƒ†8HŽ0a¥“9ÖˆB䂈´Ø¹’ÂÉŸ„8¤LAgà$x´Ð°A—/ÚØr„™…>nè(X§Í2 ýx ‹A¼Ì@èg‚Š7UÀè!˜GΑ=iÆô)èÇPãG`120px’àÎà~ F¬¸q >+¨±@ÂÍ —ùY£ùpbÏ}š|ˆ³¤A†ERÞ½{`Ÿ2_TbDƒÔ ?/ˆ $Ä!\#äÃÇqŸëØ“ó¨zrƒÛ¹wÿNºøîÞÉ ¤N]½û;tkabber-0.11.1/pixmaps/default/tkabber/toolbar-show-online.gif0000644000175000017500000000171110563064247023641 0ustar sergeisergeiGIF89a÷0mmmÿë;;;ÿÑÿÒÿßÿÁÿÞÿËÿÔÿãÿÄÿðÿåÿÎÿÀÿíÿòm3ÿæÿÇÿâÿÛÿºm\;m`Gÿïè¨ÿÜm1m/ÿóèŸÿÍHÿÆÿ³ÿÕè—ÿìÿèm3ÿ´ÿØÿõÿáÿÙè¢!ù0,¦aH° Áƒ*\Ȱ¡Ã#:ø‚€ x1ñ…ƒ p 0Bdž/ @`aÂN2|1!‹'*”X sá >0P!χ.0Ѐâ=zl @ .D•J €‚F·J}ÀŠZ' ¬ˆªÚµ 6¼0!vaŠ»<ˆx @ 2à  °a¾0(€¸±ãÇa;tkabber-0.11.1/pixmaps/default/tkabber/gpg-badencrypted.gif0000644000175000017500000000052710563064247023162 0ustar sergeisergeiGIF89aÕ9ÂÂ쬭………¬­­³²²ÉÉÉ»»»¡¡¡ÝÜÝÀÀÀÑÑÑÒÒÒ‚‚‚¸¸¸xwx€€€ÓÔÔ‡††ÕÕÕÃÂí¬­ààá½¼¼¶¶¶–——ÛÛÛÇÇÇÍÌÍ|{|«ªªÈÈÉÁÁÁººº±±±ØØØ×××­­­ÏÏÏÄÄÄÆÅÆÎÏϪªª|||¾¿¾ÊÊÊÃÃ‡‡‡³³³ËËË‚¨¨¨º¹¹———WWWÿÿÿÿÿÿ!ù9,tÀœpH,¹›R‰Þ„€ðDÞJá`èV7ŒM¸´Ù¾ÅÛ9½>Þè$ܽüÖãÉJFbúq!x7$ -.*„# 2'16„(,43„) /0+„ 5"– „uN·MºA;tkabber-0.11.1/pixmaps/default/tkabber/xaddress-red.gif0000644000175000017500000000021310572331547022320 0ustar sergeisergeiGIF89a³ |ýmmþ€€ý[[ýJJü22ü<<þ’’þ££ÿ±±!ù ,8PÉI«½x+¶Z@aCyœTº¶ÂÀ’̺H‚ë4›Ï£ÚÕn¨b—}L(Ú¤Z¯;tkabber-0.11.1/pixmaps/default/tkabber/gpg-signed.gif0000644000175000017500000000025110607415615021757 0ustar sergeisergeiGIF89a³ˆˆˆÿÿÿçççÅsìììãããÔÔÔÝÝÝè»}ÊÊÊê½ûûûÅÅÅÂ~"¯Dÿÿÿ!ù,VðÉI«½8k ºÿ 0F!œga0—t qt/WØ€3ü @¬à ÂoIXÅ àÌ~ˆê3*™jŠâ 5~ÏÕ²Ô€j· ÜhþÙØïøL;tkabber-0.11.1/pixmaps/default/tkabber/gpg-badsigned.gif0000644000175000017500000000025310607415615022430 0ustar sergeisergeiGIF89a³ìììãããÝÝÝÔÔÔè»}ÊÊÊê½ÅÅÅûûûÂ~"¯DÅsçççÿÿÿˆˆˆÿÿÿ!ù,XðÉI«½8kéºÿÞCÀœg08bѹŽ ,ÀÁí(‹`"–{8F:EGƒ‘lXiABÔJu(­ ÃÂ`Ýv¿àt#Ú Þ'ö D†6ø¼Þ;tkabber-0.11.1/pixmaps/default/tkabber/tkabber-logo.gif0000644000175000017500000001730410570607470022313 0ustar sergeisergeiGIF89ac–çÿ ")+)/1.796>@=9.â24äFHEKõ"?êMñD=ãQSPWø`ÿQ@ádÿ5MìeòjôqÑiÿY[XcßpìjîMLæCdÿ`Eàcö |¡rÿa ‚–-dÜnÿ5xÿrçKVêbda€±A[î‘V˜4bPãzÉŽ{¹.w¹%tãž':ið9oÓœ."sÿjkiFeñ$™=ßsUá#¢"Mq¸‡Ë~ÿ`q‘"‹°&Žl\æoqn"—we`è¦>/yþ0}æ"¥6]gë'’˜LvË*§'/§(’¤#ª2&¬ #žuJsõ+¡Stvs{_â1Ÿa)¨H(«;-„ÿ:þ6¤Cxzwd{­2Ý(²6vjè/²(Jù|~{4´ ]xò7Šÿ>œ6±:2²AD†þ;¶;˜¼~nçz‚Œ€‚?”Ðqƒ£@ŽñB°:{‚–EŽêY‚÷@ÿ9¹9Tˆû„†ƒ?³R|xëLÿ;¸GG–Ý>¸@>¼,A½C¨‹>³a7ÅA®{‰‹ˆH—ÿu…òE¾FT”ÿeøJÄ(JµyGÁAI¿NGÄ;Oª´NÃ2QÆYœóZ›ÿ\žïIÐQÄLKÎ(u“÷VÀ]W±­ošühžþXÍ.a­Äa«Ða£ÿXËCYÌ;ZËK_º™yœù^ÊRi§òkªâl©îmªèn¦ÿgÒ8eÌ^aàcÓBa×7~¤úm¼®eÑYhÒRjÓLdÞ#{ªÿoÓDt®ÿoÌoqÓ[~°ý³ÿ~ºâƒ³úuÛLvÝDzÌ•ƒ¶÷wÙa€Ð‰}ÜV|Ü]…ÅÆ·ÿ‹ÂÛ{ì-†àS„Üo¾ð…Þg–ºþ‘¿ÿ“¿ú€ñ"ŠàbŒÚ€“ÈÔŽâ]’álšÒÀ•æp”êd›Ùµ‘óE˜ék–í_©Êíœèy«Éû—òV äŽ¡äŸ©ë¥ñl§îx¤òu©ìŒ®æ§°î™°ó†¶òŒ»ò”µú~ÊÜöÚåðâåäñôòÿÿÿ!ù ÿ,c–þÿ H° ÁƒFˆ0aaC† &œH±¢Å‹!b˜€! 'BžèHrㄇSª\Y0â!wì1³¦Ì"Cz4)‘¥ÏŸeØ81A¤Ì&)š(mBdiÓ&YdÊ Ùñ$†€jň °jÀnezJ$L˜4`â¤Uk6 ˜§)¤î‚ãɬ[óÄÕW·jÝÎã§ ¡Ãˆ ù9ܦ Û·L‘Ö¤Zƒ †zõ~úäõkµsŸÏ‘ó#鑤N¨;™–$i!ÇŽÁ˜m’§Ñs©ò\˜ùç¦Mº>é¶Lð¹tíÚ¹S¥ÊTóç¦P³n½8Žu0`ü´Ê5ªJš!FþîžÐ[%£M¡8Ÿ[¶ÌZºxíâÅ“V+ذúµvÕ2=úôÅŽ©)¹°²J%CL%ÞI•w#¡„¢‹.ì¹'_<úèSO2Æt8Ì0Áà·Ks¦”ÒÉt¯YWX%ÂÃJ+n8A×G òæ B‰$B‰&¶Ø¢Œ5á ƒŽ<úÈs=ØLsÌ4zLˆÎE‡ši‹½æX£¬Â +˜,r=,¸D7´ÆšhòË/ÐDsÍ;¼ŒcŽ=øäCÍ4x*Éd‡öáG"j¥°VueܲЖšXâÆP ÖH^™] "˜¬ò‹›ÒÐŒ1ÇÓO=In“'žòy_-µhb ’(àþ†Š &‚Ð`x<õtãhüa ,Ås )õu(*6܈º6¢âÉé1|>‰js©­vXaqÌË/•Îú‡"N„PÙ]˜98…z€J/Â^S8KN³,³ô*›ç’ÐÓ'ªÎIw"€…å±È*­TjɬpT±Á¸5–wÃoDrI1·\óÍ7ô¸£Î4Ú0;o½£*™¯¾Òîej~œI+¾´² &ÿ ‹AGcêºÕ V¼qÉ%·sÍ5ë¸c48ËλMÒIË{/´ Þ"sü(èk®øò Á³ZbÉôêE6T`R¹ZéðÄ‚Œ2 1B_ìŽ=õ°ãñÝI3òþÈOJ»_ÕªµvXÖ,·ÒŠ×^ƒmf˜¡Å `…×O0ˆÁ„ m MŒÜGÓë¹Òz7o¾}†h2ହ¦ˆ/-~x⊟kÅZX 9å00áæpoþÑîŒSo½K./7L–jLÔüþøbÒ°‹á–¼þÇ!˜ñ†Vtß‚K“«”»‚,ò6Üœ ïqñŸ¿:ýô³Ï6Êè7Õ°*‰¤#}+ @ØÑ3+pïX¨ÀCl”ø@ ^0ß"ˆÁŒôiC^ë˜û>¦ ~Ä/~ûØ“©P•ª~Y5spF/z X€–ˆ„%°§=îu 9¨Qø,2\€þw˜Ã<á‰`ÄBÔ Æ™æ>z±cûð ?>Èmä D}k^'¤ÄT«-T—º‰ëÕð O°BÈÅ@ž )aˆƒ±Eû#Oy«7ØÁø1~S!§š´¯iU-P'êß YÆFâ‡xC÷º÷l"X¹ÈKvÀ9žF¨êÐ’†Ç>vøñ”ì?6¦¼å…Jü\)ÁŒ/‚…ê’!$µ8¼á ÀüžCÚ˜Žœ€“q$ÄiLQ‹apŠcxÓà6¸ÑGT‚ð‚­ÔˆHèUT‹ÄpF°ZFP’‡0ÃÖi…'Àl|ÔD8ÂÉ´f‹õþÙÔ1¸Á¤ñ•û@žž®ˆEü”?ž@/ž!NŠñ-¼„9#Qˆ7øÒ h| d0L)=¨g”‰ÏMuŠŸÃûÜÕ!P= ÒT÷{N*ž1´¡5ô……DAq HB ë|ž Hm¡gY ãÔ€Ò™ñ"e4õ6*|,j!âf-Hñ¡e£7íDo!ÑKPô…(„/ƒªQ¨à¨ ‰H9Òe†2^yË#ñœ–Œ¶Ò>YV-x±qdãÎȆ3nšSþŒ¢ýP)T¸®IÅ2Á@ÒN€Ò¤xj"3جª¾Ô•Y$¡4ÖQÓlÖ׸þÅp Q‰žU­z*Q ƒÞ’ ÃDHQRPOzUPÅ)?¶4§=MIMrå©ôS T\#ëp­W¬ÆþìgiUë:¿0T&è0(ÁBb„`Yˆc&ñþ ¯Œ¦Òœ‹¯èÚo›$œÅ7 { q\7·Xìlq ‹H86¼pÈídŸÐ[ôzà’(i‰f‰eJÂ9Í|&ÇšHÊ‘jd$“Z~TaŒzÃÀ¬Õ.l¿H[r~ÂãªFa´`½;üÇz…&„¡ ÷dæ“ö¹´¼æu‰O{)OEÂÁ’£°®=¬MÚÓKè…¸„Z{I^¡2ÇèþVtv’¤ Ã§9®>ñúd¦9ׯMb^`kAu¼øÊ‡}­3Ü]Xt™¬bNk/™T& —Ç/røèiäºnQKÎS~‰·ßª^µtÈE…9¾AŽRgùÔ ¦˜X í` …¹z„n™@k1ð/n†Rd"¹¾Ì¼oh¥*ͪŠPº¨ 6Ü1R;›¨Nuw½ûÝDÃAä%¯£a€^,0|8&,Ogî¥N†ò½’Á dgUßh6:Èo@Û®MìbŹBï¼£ðôÀ1 ÀÖ>€š×Œ¹óÈ„ £’7¥¤t‹ö^ΪÇ=ðad #¨xÇ;þ˜-¤yÏÛøvm4¤] F’“§7.„¬AkZ£½%ø6^N"î8Lb‹±h7Íß䙣Hú¸<È1y ÃéB¢w½Q®ò•¯¼å㌨ ažV ÓœàG¯¼9|G¾§~>tRÑöãM:º>æ‘!y4êBòÆÔQ¾G£ç÷-»ÌõKèAæ@%¸å pt½bÈÓb×G•Äžsî “!{ ýîñ@G<Êáôr £|G¹7¬ _´|…UWµ!œxm3^áeÏÊB@ß6|²™ÎœF_ì>§aƒØ@Æ8Þ‘! Åcχ~9¦O}o„ãúÞhSß}þ±rÖùb…/#(Îzx23ÚÖç±<`IC¤oŽÃ'—,ô»‘Voà°ÇÆñQ÷æÏë0zå €ÓåhÚ×z­çz¾@N[§.¯†V½”x5‡>ðh>  ·{'Ð{§‘l"fMFUÜ`r‚2î`©@ ´°Zh å0,´`´à ­ Zó ÞÇ:êRNã‡VŠÖhO~ ×c ·@'ãöaÀW#…Ó€ ù€ž—!÷ðà` ùQ5ÒPéÓÇ žP%Mu ÐÀ&­Çƒ†c88~TQ˜QÛf=æ" sgGMeyš–RÃWàPöïÐqþ÷a &ãM¥ ä†Þ û£ŠqÑ  ʰ&kÒ ¿À2 @¹ gus(TOÐ"/ÀcG „ÑkM¨dL¦_MZЕ r?ýb"À éà ÒP%mð†À ΀‰k" [³5.s8d A(„‘µNwÁ%àdyñ^M0_à‡#˜REç$YE5R‚´À ¨ðœ0¼À Ä Ë  ¹  ʸ ʸ5‡B=ШK¤8fãõ/ÀÁ2 GÕs5n}8 £2Z2æˆ*‹¬ò‹á©à ÖÀõ¨ ì! º ¹ %‡B0«€81„N‘¤[hÄþ3`e÷mQ#Ð#Õ » tÆ\Í•'Í0”CÙWü‚:(rwð ÊÐ ¹ ºÐ#&É ²%³b0ÏøH‘19ö33¹‡I¡YMÀYud‹ùµ_Ôdõ@né–+È Ø8ÿ°a™À ¾@’¶0!ºÀ ¶°%¬  «  ]ó5_ƒNÜ#Ií$“4)9zHO)Ê„i£4U¢¢õP…VxD"ò èðw (®ár²̰ }© §` §p —`˜0s˜f1oÀNBõ•w™ÃÄ{”‡iÊ5tÛœ¹q÷Мv'¢7}ä “˜"Žáf1n‹þ0§0!¡0›spePiâ-I‘„Qh„F%`.P“·ç{á¸$ “4ÔP…Ëé™ iw£wzá ¼ ±ÖÑØÙv ~•ßI ‹À'p‚€ˆ 3‹0Ð?`X [ÀÄßC#Á d¼&W&GdGà?P–iaŠ!(æ,ÉÖáÀ³+Áq“„«“~`_U5©ssp "¼%¿0˜ƒ™&ú¼k€ÅØ,ËMW0S€o z07\Î¥qBÿ‘"–¼Îm<¾øfÊK&„"~€-eà  °Ï€Ì TÐÊ9rþÅšÐÙ,ËW`Ð}Ð ­£`ìa¬‘©‘”mPÑw‘ÌI* tÒ±?Õq²q£ÐÏÒüÊÝÒWðÒQMT€ÐS°Ð£ ¨ Ñ:ŽE]D0ìŒ7d“é{¥ñ¦áVh±ÃMáYâψÐÊkðYŒýÒT]ÕU½ÐzÐ|0R¤AG&KÎs"®QÑ>|I–ÌË‘\ÆâÀAº? þ¼Òw6ØÓR=UÐzÐQpL5NQÂE‹)ÀÆòÔÂ:™Ê*ÒÀOq±wð+}¡x}&TÍ×TmÕ£]ÚP–‡gÑñ$t‘Ñþñ„a}AF竉-«éÀKÑÛM[`ãÙk€SÚTëÐV GP–ž´LÝTeÍãM'B–ÁÙ=éÛà *M{á±Z6h@ Î×MÕìA07 bðÉÄ¥À&C]É–Uô¬ß;ðÓ+!9Þˆ´GË¥ëJ4°àhÐà~-Ú.áAÀ3OP§GgÍ‘lÀ§g©‚ÝcâéYðµÛÛ4¾º60ýà=á6~7 O C©ô­}")65þ 'pým@6W·Š««b`ТmÕS`å7z þ:`áNPWò5Ë]ûR"½Ø köÇT¨s‘pN#1;£]åy~®å}.]°ãrö$æÖJXÔÐD€ÝiîØƒ "&9Aqnà•nã¶®X^„b°Q€d¥æsö,"Ã'ûÑ „' ¾Z!9qþê ±&±ñ•ó@]ÀºîΔùä„p3èžîw ïþð¹^-/ñöî}þ@Z€Ú“°»w/#fZPòñ²í ¹è7 Ÿ&ÏÅ«hï½Uñb€dÀYõå“ÃV|Î"àa0â!_GµÜxòkV5à@<¦0 ]PN`O‡;‹™]\h ŸÏó옜%zò*P- 4 @\€Î»ü”7¤²ö¥ÞO )qŸøÜ˜õ#/WEqLJÁ‡žuGy”4}Å…ª@Ý`ìU#X¿ø¹g“=ÿïåfnAŸÆZbJrÞ4 çÎ^â¨r¯øh“8ÓèJaö»;bwã,¬"qµûúq¯‡Çoáùf!áþÈ¢N-ÁP5~¨>Û±¯îî·Xîf¸|OˆÛiÒä’ÐßùÄÏýä"ú oL¸ï#µôV{AO%­ò?¼þÛõîŸðqbÇÀ&`â’ÔÉT°iÓ¶iÛÖpš±aµLu’çDŽþ}RäH’%Erœ!¥ÊŽ(;®œÃÌ#v¤h¦ ÂNª†“ØðÅZµTu"D$&K“M:m•åJ–U1LÀpBàŽœý$¬ ¨Ã‰CƒSe*ãÆ•Oݾ Y5%U˜-cÊ̺cD"` zdªÖO‰@«xtºp?uiWjÝ«3{Øl’3N?:…þ=66ô°Š%µÙ±”ãcÖ%«NuIu*ÖZ щP’à`Ʀ…zØ"Fs=¶F7²Ô—sc†Èk÷ß΂‡3œbâRIOPMþŸd¹åUÎÌÚc`–œ¹ ‹û°`FÕÆÉr•©xäÆ#ËFI¦ NA¯› òJ’R:Ùe°Ãè;k8?ÀØ!„—øCî¥×þS « j³-³®’DASv9+ÅúÒB*Œô[ ÃÖ&3/¥Ê²ªé@ÜÂ8ˆIJ)å•QlД‹N#¢B˜dœÑ? ›«L«­¸Ê"‹0ÒˆI&å/¿,å¢îÂHa \ØIÇèZ®Ãg¡¶ËvÀþa‡*Ã`£H EH^éPQ&$Ž&*Ä %5c®¼”Bxƒ&Å᪄‚<õܳO>÷œ¤>²À!„"€ ÍEÝÊÕF;BÖ]0µ‡ €" (Τ×=ÙsO6a£   ˆUáªU¦u5Õi¯ÅöXVpÁ[oÍ”W_{– :ÎXb…’u€4päÙ·’ÈaYe•¶}íÕ· þ¥@ÝV@b ƒw=ƒŽAèP˜á3 @"†$pÀX@Šxå}*‰ "X Ey H™‚u;€y…b@ .¸8ã .Æùf.$þ–@‚.fÀ…=6温$¶‚€úi¨§†ºbŠ%  h@˜™f |ö™Ž›ˆak¡+f!A:é’xH‚)œfàb¢ë:o«`k¿ük°Ç&ŠÛ]‚ØnÛí‘x€›!@ž:o@àr¾à[ë¿cœ ›k=â°NÙÅë`Üq“xØò$Š0A_¨óÆ}èŠù6Üï™k6x‰‚ –æ!èamGXoÜu | È0!•©vwå–'†9p!øƒ îa‰n#pA)ð`¼uçI‚~é-¶¨c!L¨`Y~þ—[‚½…BÀö=¨€ þr@†=0¯}Í{ß?d—„¥a cCŠP!äÀ&€B&eªI'¬ÒÐB †` ÙÆ:Fðqœ1¨öpEø!ð@!’ÁˆBÄÃð Ã6‘m6 âǃ ^p‡j¨ƒì°E;b‹DáDΰ}L|"C?ùYQ‡=Ôb¸F:ÒÑctâò(C5†DŠ8ÌáyÈE1z‘ެ#јGÆÕ¡Ïcc/X‡1ôÐZ´ƒ YÈ;² wyÉL6ó“tTƒ' <àö¬¦c7„VQŸƒä§!_Q5Ìo¤!)©Iy€Ò{Bn ÌçÕ©E,²ó’L n*’œž”§)…žôÚHÉ VRY̤¥Çƒ,u$ kN3ÀÓR–Óœ§Äf.7d «^%IXM:V”¢´¬Q5çÒ€j¼P<¬pm X V§¶5¥P-kJéêWÖ-ÛT“žô¤E ëXM ÖÀ±p@ÙÀ@­;YÔš¶³ÀgA Œ–´ @gK[ZÓà´ €b+[·ÐV´ÀmP;ØÊž´­P€âζ¶È%ÀiKZÐÈõUºÃ­îlE;€ÒÀ¤)5©t©ÞÖ„V´¸5€` Üõ²79ƵíðÚW<´pÕ;tkabber-0.11.1/pixmaps/default/tkabber/chat-bookmark-red.gif0000644000175000017500000000052710572331547023235 0ustar sergeisergeiGIF89aÕ:|îÿllô11ùIIö<<ûUUúNNó''õ55ÿjjøGGõ33÷@@÷BBö::ô..ó,,ö88ü[[ò""ñïðïùLLùJJñ!!ýccðîïøEEðûVVý__ü^^þhhúQQïüYYü\\ô00ñò%%ó**ûXXõ77÷>>úPPþeeò$$ý``úSSó))þggøCCýbb!ù:,t@@,…Èa`•@ H8(Ž":B‹éÆíŒFÆ•SHÍ›ˆdJÉÞSÀ…5€iD4xI'+-/81‚T!3*KŒC6V”:_ œžgi¥Rr«x¥ŒD]¸‚A;tkabber-0.11.1/pixmaps/default/tkabber/gpg-encrypted.gif0000644000175000017500000000053010563064247022505 0ustar sergeisergeiGIF89aÕ=ÂÂ쬭………¬­­¨¨¨ÈÈÉÁÁÁ–——ÎÏϳ²³ÊÊÊ”“”ººº€€€xwxÝÜÝž½¼¼­¬­ààá³²²ÃÂÃ×××¶¶¶¥¥¦ÛÛÛÁÂÂÓÔÔ‡††±±±|||‚‚‚»»»º¹¹ÀÀÀ®®¯ÇÇÇ‚ÏÏÏÕÕÕ‡‡‡ªªªØØØ­­­ÒÒÒ|{|«ªªÄÄÄÃÃÃËËË¡¡¡ÆÅÆÉÉÉÑÑѸ¸¸ÍÌͳ³³¾¿¾———WWWÿÿÿ!ù=,uÀžpH,=žR‰,ò,€(€×òX“Á À¥6y‡Ýr'®òÊV4’'ð&Ûߥ|¹¦hP§Â¦Qy¹6 1! *3D<+-209; ŠC<84: &–V%#7$)¢I5"; .­s¹UUA;tkabber-0.11.1/pixmaps/default/tkabber/toolbar-disco.gif0000644000175000017500000000224610563064247022504 0ustar sergeisergeiGIF89aççBÿ*\ÿU¬W-^ÿGÿKuÿzÇiwÆfFqÿ@mÿa·WÀô™w—ÿq’ÿ¹ÉÿsÄcyMQÿe‰ÿCžPgº_›³ÿ‚Ïj#VÿLÿ[ÿhŒÿNÿY²TPÿ‰®ä®ÁÿJÿ{šÿ½Ìÿk¾^‹Ôs©½ÿW~ÿW‚ö CÿQ«P+ŒET|ÿsäV­XcˆÿkŽÿŠÎ‚µ×ÐHÿ.GsÄann¹Êÿf®&r »ËþOˆË1‡tG‚ÊYçÁÐÿ¦»ÿ°ÔÎX¶U”íQZµP¶ÏéAœO²ìm´Š“¬ÿ˜Ö††Ðn£Ý•=¡>9‹y4dÿŸ¼ìPµ³ìqª´Qzÿ˜Ñ M©N“ĺ nŸžÛ™Ô–6fÿ˜Ì³“Ò‹.ŠT}‡"‚[ ¶üJ¤W˜Üz¤äƒ“²ñ¶ÉùæææÆÎ(aè|Êi)^óÅì½Åñ®7˜D˜·êãçö"m¢j¼f=–n¹ï–Ÿà‡£ÿ{Ìai»a«¾ÿ£Ç×fö TÿŠÒs—¯ÿŠ¥ÿ‚Îl±Ãÿ©øsÈZ™Ý}u•ÿyÆi±ÕÏ”Ûvf¹_ixQ«SV}ÿV’±¼Ìÿe¹\'ŠBªÿŒ¸ÄG•‡®é¾òšTÿ³Åÿ¾Íþ²ë0{¨£Úž0•>&p£u­¿ Fÿ[»EŸÁÞ”¬ú¹Óå €U4jéB¾YÙb¸YÍ×úÅÒÿF|ÜNówÀ{(q¤2bÿ@œMšÝ}Y€ÿBoÿ?{Ê„·»‰Òq.eéSÿªÅí¬È焦ð‹§ÿ8gÿR±G¿Îÿ¨åˆªÇák¹iz­ÅF¥G•®ÿH¥L‰Òr§å†’ØwŽÓ~³îŒzªÍe§Oxÿ>H=šJQçjÿXÿgŠÿF¤J˜±ÿ×r à€e¿QY¡ Cÿ‚ŸÿY¨u]´DpÿnÂ[ŒÔs›Ý~´í—Ø„._ÿލÿCÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ùÿ,þÿ H° Áƒ*üg®¡Ã† 6ÒiE3YZ‚d‚¨Ðœ a[4«€ªOrL™Kh.X7HÊ…b AZl½˜|YiУHÀðäxc&P'¾ ¶©O‚æB”áà*0uB°ðBCA•6£ž 4g‚˜¯Tý¨¶ËøZ)zö(‘XsÓ*ˆðaã®'g–À"a€‚€W*jÜÖÇ’ƒ2DØ,wlwZL˜á®H%>ˆZc”+\Œ2<¡Kg¨¶UÈH?²Rr‘€"­ Ý-@ˆÌJs¢h¢B †fÙf5áân º”ašô‹ŽkRì„Äáá w,ze̵pÈHX8rŠ“•0 Ë0A=Ë$Îi<07¥ pÁèõS˜p+žÂ$¶\Ðð7V¼xƒ€ pB1jì± ²tËä5Îì´Ø‘9DÐW¬â‰6EôÐC%©ä’;tkabber-0.11.1/pixmaps/default/tkabber/gpg-unsigned.gif0000644000175000017500000000024010607415615022320 0ustar sergeisergeiGIF89a³ ûûûÔÔÔãããÅÅÅÊÊÊìììÝÝÝçç爈ˆÿÿÿÿÿÿ!ù ,MPÉI«½8kŠºÿ ‡ pœ§ GtF$@at/'Øðq#1‚s ñ`²Äa8AÆCº$B¯X*SâÌz«Íj<l ôgÃn»3;tkabber-0.11.1/pixmaps/default/tkabber/gpg-unencrypted.gif0000644000175000017500000000053310563064247023053 0ustar sergeisergeiGIF89aÕ=ÂÂ쬭………¬­­¨¨¨ÈÈÉÁÁÁ–——ÎÏϳ²³ÊÊÊ”“”ººº€€€xwxÝÜÝž½¼¼­¬­ààá³²²ÃÂÃ×××¶¶¶¥¥¦ÛÛÛÁÂÂÓÔÔ‡††±±±|||‚‚‚»»»º¹¹ÀÀÀ®®¯ÇÇÇ‚ÏÏÏÕÕÕ‡‡‡ªªªØØØ­­­ÒÒÒ|{|«ªªÄÄÄÃÃÃËËË¡¡¡ÆÅÆÉÉÉÑÑѸ¸¸ÍÌͳ³³¾¿¾———WWWÿÿÿ!ù=,xÀžpH,…¼dòhäYP9ä±&ƒA`;¥ò;å.LíñÈH4“'èšÛe%RI—y êTØ4*/nE<6 1! *3‚D<+-209; ŽU84: &šH%#7$)¥f5"; .°u¼eeA;tkabber-0.11.1/pixmaps/default/tkabber/chat-bookmark-blue.gif0000644000175000017500000000052710572331547023412 0ustar sergeisergeiGIF89aÕ;)±2aüœ³þT{ýf‰ý\ýdˆýt”ýlŽý‚Ÿý^ƒýr“ýNwýjŒýz™ýb†ýV}ýZ€ý’«þ©þ‡£þEpü™±þPxýŠ¥þ–®þnýƒ þ—¯þh‹ýš²þ~œýX~ý|šý9gü5cü>jüAlü¨þªþp‘ýLuüx—ýGqüRzýIsü8fü`„ý6düŒ§þ…¡þ•­þv–ý‰¤þKtü?kü€ýDoü;hü!ù;,tÀ@,…È!á0q@ P ‰':B \,Ãí…†Jv²HÍ«ÁõÁÌÞS@)éÐ6xI:,/!5‚T076 K ŒC"9V”;#$-_ œž.gi¥Rr«x¥ŒD]¸‚A;tkabber-0.11.1/pixmaps/default/tkabber/chat-bookmark-green.gif0000644000175000017500000000052210572331547023556 0ustar sergeisergeiGIF89aÕ+Z¥¸Î"»´Ä!¿ Æ!¶Á  È!±Í"°Ì"¨Ê!¹²µ³¾ ¦¯¬À Ç!§É!½ Å!à ª®­·©º«Ë"¼!ù+,oÀ•@,…Èáä``@@ H‰#:Z—“Û<*„ H+-“(‚Ï‚“jO¨LáÄôØ“ %* T"zK‰C‚ V +&#_—™fh Rp¦v ‰D]˜³A;tkabber-0.11.1/pixmaps/default/docking/0000755000175000017500000000000011076120366017247 5ustar sergeisergeitkabber-0.11.1/pixmaps/default/docking/available-xa.gif0000644000175000017500000000054010563064247022270 0ustar sergeisergeiGIF89a¥":::MMMNNNOOOPPP^^^```uuu¢¢¢¤¤¤¦¦¦¬¬¬±±±²²²³³³´´´¶¶¶···¸¸¸¼¼¼ÄÄÄÇÇÇÈÈÈÉÉÉËËËÐÐÐÑÑÑÓÓÓÖÖÖ×××ÚÚÚÜÜÜÝÝÝÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù?,}ÀŸpH,Ȥr¹$8 Ì"!D ¢Bh»½F Åóñ~9D¥cnj††ÓV(…eSO4 „…„~ "Ž~†"‘H ŽšG  —„£J¡¢¤HW††K·XF}½ÀÁÂGA;tkabber-0.11.1/pixmaps/default/docking/tkabber.ico0000644000175000017500000004771610606503151021367 0ustar sergeisergei°h¶hh† hîhVh¾h&"hŽ'hö, ¨^2 ¨; ¨®C(VL(~M(¦N( ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ( DNGQJTNXQ\Jddre‰ |Œ´Í·Ð¶ËºÔ¼Ô¿ÙÀÛÃÞÉäÌèÏé ÐéÕòÜûÞûàÿ"àûâÿ#äÿ3æÿ;çÿ            ûÿùÿùÿðÿàà?à?à?àððøøüþÿ( DNGQJTNXQ\Jddre‰ |Œ´Í·Ð¶Ë¼Ô¿ÙÀÛÌèÏé ÐéÕòÜûÞûàÿ"àûâÿ#äÿ3æÿ;çÿÿÿÿ              ûÿùÿùðàààààððøøüþÿ( DNGQJTNXQ\Jddre‰ |Œ´Í·Ð¶Ë¼Ô¿ÙÀÛÉäÌèÏé ÐéÕòÝÛÜûÞûàÿééìì"àûâÿîîðð#äÿóó3æÿ;çÿ÷÷ÿÿÿÿRÿÿ[ÿÿ—ÿÿ¶ÿÿÿÿÿ   $$$  &)&  $(*($  #%'%      !!!!!""""ûÿùÇùƒðƒàààààððøøüþÿ( MPT iX[\ qŽ /‹-¢0ª1¬1°2³4¸5½7Ã8È9Ì:Î=Ø=ÚGÓAçDñFùNèGý!YèTúUþ#_ú$aþ4lþÿoCÿqF@:ÿsH«ŠFÉ„JÿxNaœBÿxOJ CJ¢D|˜H”IóRÿ|TP¤JV¤Lÿ€YN¨LU¦NV§Nÿ‚\†žVý…_ÿ†aL±Uÿˆdq«Xÿ‹gV²ZЍ^s­^ÿŽl¬¢dÿlV¶^®c`¶d\¸d[ºe`¹g`ºg†³jÿ–wÿ—wØ¢toºlXÀjÿšzÁªuaÂpmÂttÂwÿ¢†9Ônò¦…Ȳ‚iÈ|ÿ¥ŠhÉ{þ¦ŠkÉ|¨¼ƒlÊ~ê­‰~Ç€ø©ÿ©Žkσ̹¼ŒoІŠÊˆç·–ÿ±™¸Ã’rÖ¡Ë’tÖŽÿµžx֮ɘwØ’xØ“ö»¢ÿ¹¤ÿº¤ðÀ¥|Ü™þ½©üÀ¬Yë”àžÿÁ®ÿ®ÓΪƒâ¢±Ùª´ÙªÿÆ´…䦅æ§ÿÈ·ÿȸï͵ˆæªÂÙ±øË¾ÿ̼›å°òÏÄÀß·ÅÞ¸‘ë³ÿÓÆ•ï¸þÖÉÁ误¯¯¯¯¯¯¯¯¯¯¯¯¯¯'# ¯¯¯¯¯¯ "./EKB*¯¯¯¯$9AFg`VD(  ¯¯¯-)Js©£‚p†…m^I1Sƒ—¡®˜¦„‰vaM6!UŽ¥ “¨šŒxbL5¯J«¥–ˆ|~‹r_H2¯¯,nœŸ­¤udjl\C+¯¯¯OŠ’§{[J]R;¯¯¯¯3hqyiYN@@@çBàDÌ<'FFFGGGâOãOâP(AbJJJÛYÛbÛcWWWÕk6PtXXX,O|ÕtÔv]]]Ãm#Άφggghhh`iulllNf…É—ªcurrrao‚NltttuuuNn“vx|~~~ `édÞg솆†'rÛlîX€¯3wÏŠŠŠ$rà‹‹‹rñ’…¬'{ç'|ç"xô’†°5äb¾3„ê5„ê*€ø.„ú<Ší0‡û?ŒíNŽå3‰ü4Šý5Œý6þG’ï7ŽþN˜ñW˜îP˜ñTœóXžóZ ôa¤ög¦ñf¨÷k¬ùx¯ðm­ùq°úu²ûw´ümmmmmmmmmmmmmmmmmmmmmmmmmm m)mmmm(! %.8<@m+'  %.7;@Em2,# "-0/5:Gmm*IM3mm4$AF1mmmmW^_mmmmm?=>mmmPKJmmmmmmmBHLmmb`\VTmmmmmmRSUXmgfdcammmmmYZ[]mlkjiemmmmmQN&DmhO69CmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmÿÿÿÀƒÃããáÁÁÁãƒÿÇÿÿ( @ÿ=ÿ?ÿBéHÿHçLÿB¬ZÿRõT´[ ÿM6u ¶ddn…dLsþH'õQÿXôY¯jÓ]ÿR&/„qƒo"?jzÿ\#Èf+þX3±r¤p(ÿ_*A‰!‡x*m„"™y(ÿc2D&Èt,Ðm7;‘'èi7Þl:)–+ÿm0F5^Ž.t‹,ÿi=K”0E”5;˜4R”7ßtCCš2H—8&¥)ÿt=ÿpGFœAI :y–?ÿzFÿvOD¢?Q¢C…•J;¨A‚™GH¦DÁŒL°ŽO¬NÿOÿ}WO¦LÚ‰Ub¥K9®Kî‡[SªPÿƒ^G­OMªSÄ•ST¬Rªš[R±Pÿ‰cÓ–Z£\˜¢[ä’`S±Ze¯XHµZøf° aU´]Q·Y8¾WE»YX¸Xþp]¶\ÿ‘j!ÇRh±d^µeY¸aUºfQ¿dÿ•wÿ™q^½fõ™vÀ§u_½oþšzZÀlŒµqؤx»¨{¸­s¢°wPÅmnÀmÿ}É©{dÄm^Äpz½uó¤|XÅt@ÏkþŸ†ÿ¤‚Ú­~mÆugÆxİ„-ÚidËwø§‰þ¦‹²¹„ͲŠð¬nÍÿªh΂É„ÿ­ÝµŒþª–uÍ…qωÿ°“mÔˆtԆƽšÿ²›úµšuÔŽ’ÐŒq׋Rà…žÍ”ñ¸Ÿrד컞6ê…yØ’±Ë™ÿ» ÿ¸¦ÞÁ¡ÔĤ}Ü–“ÕxÞšþ¾¨ÙœŠÜ˜ó¾²†Þ¹Ó¡ÿÁ¬‚á›êƪñǦöïþó`후â¤<ø–ÿƶÿË·×Ô´âиæ®ÿɾçÌÁ²à®ÓسÄݳŒë­ýÏ¿‡í°ÐÛ¹ŽëµòÏÈ–í´ÿÓÃÚÝÀüÔÈ“ò»ô£ùȵöÌòèçðóñøûùââââââââââââââââââââââââââââââââââââââââââââââââââââââââ ââââââââââââââ -25+$âââââââââââ"',DN??:& âââââââââ"3333K`VSVND âââââââ 33==BB^qek`SN) ââââââ35#âââL‚²ÌÈØÇ¾Ã¸¤›ŠŠs”¡—zq`N95# ââââ3j‹±ÌÇÃÚáàÖ‹sl[_{zeeV>+âââââ!J}£À²¸¾ÚßßÍ‚sjTMdˆqZH++ââââââ 5n𹳤 ¤¤»“sj[TAYrfUC6âââââââ>pžª‹‹“‹yyj[TA=YhbF7 âââââââââ.Q€|°vsl[[TMQgÑjØmZZZ*P‚ÔvOšÑbbb°Ms·Έɉiiijjjˑƕ©elpppÈ™Zk„Èš+aªqqqMlÆŸ&b³0f¬Pn‘_Åvvv¥bwwwVäWåYå{{{[æSu€€€ aé m bꃃƒfë3tÈh쇇‡jík‰qãŠŠŠ‹‹‹sänïtäoŒuä4zÕqñ wå!wåtòuò)yè'{ç(|ç"wô#xô+~è,è%zõ4ã-€è%{öe½'}ö0‚ém‰Ç(~÷3„ê)€÷5…ë+ø+‚ø-ƒù9ˆì-„ù:‰ì.…ú‘Æ/…ú0†û>‹í1‡û?Œí1ˆû2ˆü@î2‰ü3‰üBŽî3ŠüDî4‹ý5Œý6þ7þF’ï7Žþ7ŽÿH“ï8Žÿ8ÿI”ðt–ÝašÞK•ðmÕM–ñO—ñQ™òSšòS›óT›óUœóVóWžóYžô[ ô\¡õ^¢õ_£õ`¤öa¤öb¥öc¦÷d¦÷e¨÷f¨÷h©øhªøiªøj«øk¬ùl¬ùm­ùn®ùo®úp¯úq¯úq°úr°úr±ûs±ût²ûu²ûu³ûv³üw´üxµüyµüz¶ü{·ý|¸ý}¸ý¹þºþÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ+$ ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ741*" Ü .5:@IRÜÜÜÜ<9741*"  .5:@DPVY]ÜÜA=9741*"  .5:@DPVY]adÜEA=9740)#  .5:@DPVY]adfÜÜGA=9740)# !.5:@DPVY]adfgÜÜKGA=3,&%)# ÜÜ5:?DPVY]adfglÜÜÜK>QŽŽ[;ÜÜÜ:?DP(-//IlÜÜÜÜÜBCÁÁÁÁÁ§#ÜÜÜÜÜÜP8‡‡‡‡LDÜÜÜÜÜÜÜÜ‚¯¯¯¯¯ÜÜÜÜÜÜÜÜÜOrrrrFÜÜÜÜÜÜÜÜhep}“–ÜÜÜÜÜÜÜÜÜÜÜÜÜ`\TSUÜÜÜÜÜÜÜ„zuqjmÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜWZ^ckÜÜÜÜÜ£›“Œ†yvÜÜÜÜÜÜÜÜÜÜÜÜÜbiosx~ƒÜÜÜܲ®¬© ™‘ŠÜÜÜÜÜÜÜÜÜÜÜÜÜw{€…ˆ‹ÜÜÜÜ»¸¶´±­«¦ ÜÜÜÜÜÜÜÜÜÜÜt‡‰”—šÜÜÜÆÄ¿½º·µ³°ÜÜÜÜÜÜÜÜÜÜÜH’•˜šœžÜÜÏÍÊÈÆÃÀ¾¼¹ÜÜÜÜÜÜÜÜÜ6œžžž¡¡ÜÜÕÔÓÑÎÌÉÇŨÜÜÜÜÜÜÜÜÜžžŸ¡¢¢¤¥ÜÜÙØ×ÖÕÓÒÐÎËÜÜÜÜÜÜÜÜÜ|¢¢n MMÜÜÛÚªN'''2XJÜÜÜÜÜÜÜÜÜ_M ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÿÿÿÿÿÿÿÿÿÿÿÿÿÀÿÿ€€€€ÀàððàüÀÿþ€ü€ü€?ø?øðððððø€üÀÿÿà?ÿÿüÿÿÿÿÿÿÿÿÿÿÿÿÿ( @=Z@dAdBdCdBnCxIƒOxJƒQxRxTxXxNSƒZ—U¢ S¶c—d—m [¶g¢c¬n¢hÕiÕfêkà {ÁЬqêË}Õkÿ†Õ Ávÿwÿxÿ|ÿ}ÿ~ÿ€ÿÿ‚ÿ‘àˆôƒÿ‰ô„ÿŠô…ÿê†ÿ‡ÿ‰ÿŠÿ‹ÿŒÿŽÿÿÿ‘ÿ’ÿ“ÿ”ÿ•ÿ–ÿ—ÿ™ÿšÿœÿ±ÕÿžÿŸÿ¥ô ÿ¡ÿ¢ÿ£ÿ¤ÿ¥ÿ´à¦ÿ§ÿ­ô¨ÿ©ÿªÿ«ÿ¬ÿ­ÿ®ÿ¯ÿ°ÿ±ÿ²ÿ³ÿ´ÿµÿÀê¶ÿ·ÿ½ô¸ÿ¹ÿºÿ»ÿ¼ÿÇê½ÿ¾ÿ¿ÿÀÿÁÿÂÿÃÿÅÿËôÆÿÌôÇÿÈÿÉÿÊÿËÿÌÿÍÿÎÿÏÿÑÿÒÿÓÿÔÿÕÿ×ÿØÿÙÿÚÿÜÿ,BR&;K^nw(#-DVd7?QamuSA CRanx|raC)0I[hu}viwG8DRaoxzobQ@+ 2K[iu}uhuZH9DSboxznaTbRA,4K\iv}uh\i\I: EKRlzznaVqcSC."9*'5[tf[uk]K<3F=71.Bi`VrdVDM6GC?>>B_Zwl^PYQ$!LKKIKO]PreZ`[T/VY[\]^[Qmafa]W Nbflnol\Ysflic_Z Xqx€wiWnlokea[ jƒ‰Œ‹†xcitqmh\f% {Žˆn\nuro\mzUpŠ…}n]vuu\kx„yJ‡‚xo_vvuet~„†g„}vl]vu]htz€}vnc[u]ensvtmc]\^acb_[ýÿÿÿýÿÿÿýÿÿÿüÿÿÿüÿÿÿüÿÿþÿÿüÿÿüÿÿøÿø?ÿôÿüÿüÿüÿüÿüÿüÿþÿþÿÿÿ€?ÿ€ÿÀÿàÿðÿøÿüÿþÿÿ€ÿÿà?ÿÿÿÿ( qqquuu{{{………ˆˆˆŠŠŠ¶¶¶ººº¼¼¼¾¾¾ÂÂÂÅÅÅÉÉÉÍÍÍÿeT3"!ÿÿjª˜ˆwpÿÿjUUUwpÿÿkUUUWpÿÿkUUˆ‡pÿÿkUUUˆpÿÿl»ºªˆ€ÿÿlUUUY€ÿÿmUU»ªÿÿmUUUº ÿÿmUUU[ ÿÿnUUÜ˰ÿÿnîÝṴ̈ÿÿnîíÕUÀÿÿnîîÝÝÀÿÿeT3"!ÿÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ( qqquuu{{{†††ŠŠŠµµµàààåååêêêíííñññõõõøøøüüüÿUD3"!ÿÿY™ˆˆwpÿÿYfffwpÿÿZfffgpÿÿZffˆ‡pÿÿ[fffˆpÿÿ[»ª™ˆ€ÿÿ\fffh€ÿÿ\ffª™€ÿÿ]fff©ÿÿ]fffjÿÿ^ff˺ ÿÿ^îÝÌË ÿÿ^îíÖf°ÿÿ^îîÝÌÀÿÿUD3"!ÿÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ( jvo|u‚y‡}Œ²Èïÿ&ïÿ.ïþ9ñþEñþUñþbòþkòþÿUD3"ÿÿZ™ˆ‡wpÿÿZfffwpÿÿ[fffgpÿÿ[ff™ˆpÿÿ[fff˜€ÿÿ\Ë»ª™ÿÿ\fffjÿÿ\ff»ª ÿÿ]fffº ÿÿ]fffk°ÿÿ^ffÌ»°ÿÿ^íÝḬ̀ÿÿ^îÝÖfÀÿÿ^îîÝÜÀÿÿUD3"ÿÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀtkabber-0.11.1/pixmaps/default/docking/available-dnd.gif0000644000175000017500000000054010563064247022425 0ustar sergeisergeiGIF89a¥%MPTi X[\q Ž‹/ ¢-ª0¬1°1³2¸4½5Ã7È8Ì9Î:Ø=Ú=ÓGçAñDùFèNýGèY!úTþUú_#þa$þl4þr<ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù?,}ÀŸpH,Ȥr¹L8Ìb‚D%¢ÂÄh»½F¢'$ò~?dnn*ˆÊ¦ÓV&,‡ƒESO&2„…„~%Ž~†%‘H  ŽšG  Œ™„£J ¡¢¤HW††K·XF}½ÀÁÂGA;tkabber-0.11.1/pixmaps/default/docking/message-personal.gif0000644000175000017500000000030510570615546023210 0ustar sergeisergeiGIF89aãvj|o‚u‡yŒ}Ȳÿïÿï&þï.þñ9þñEþñUþòbþòkÿÿÿ!ù,rðÉI«½8ë]K!Ä0B`Zá¬kã2 š©­kÜqZ70¼ÈÕ ÇX—BcÈ<¦–LÃB¡@Z Œæ”jíd£E¢KÁÔ„š<),À ‚-q3Õòýaô) ~{bqy€3!#%'’“”•;tkabber-0.11.1/pixmaps/default/docking/message-server.gif0000644000175000017500000000030310563064247022667 0ustar sergeisergeiGIF89a³ˆˆˆÂÂÂÉÉÉÍÍÍ{{{ÅÅÅqqqŠŠŠ¶¶¶ºººuuu¾¾¾¼¼¼………!ù,pðÉI«½8ë]㤢Ú1¬«à š©¬ûqZ»EÈÕ +~)ÁðX/å²éL‹ãi9–F‚Û1b³‰4™r€Óˆõ¤=L'ñ”Œ—K |})YZvxy3!#%'‘’“;tkabber-0.11.1/pixmaps/default/docking/available-away.gif0000644000175000017500000000054010563064247022621 0ustar sergeisergeiGIF89a¥$NDQGTJXN\QdJrd‰eŒ| ¢Ž«–­˜±›´ž¹¢¾§Ä¬É°Í´Ð·Ô¼Ù¿ÛÀèÌéÏéÐ òÕûÜûÞÿàûà"ÿâÿä#ÿæ3ÿç;ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù?,}ÀŸpH,Ȥr¹D8Ì"bD¢B„h»½F¡æò~;•Ddnr( ÇÓV",…‚eSO"0„…„~ $Ž~†$‘H ŽšG  Œ™„£J ¡¢¤HW††K·XF}½ÀÁÂGA;tkabber-0.11.1/pixmaps/default/docking/available-chat.gif0000644000175000017500000000055710563064247022607 0ustar sergeisergeiGIF89a¥2NDQGTJXN\QdJrd‰eŒ| ¢Ž«–­˜±›´ž¹¢¾§Ä¬É°Í´Ð·Ô¼Ù¿ÛÀäÉèÌéÏéÐ òÕÛÝûÜûÞÿàééììûà"ÿâîîððÿä#óóÿæ3ÿç;÷÷ÿÿÿÿÿÿRÿÿ[ÿÿ—ÿÿ¶ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù?,ŒÀŸpH,Ȥr¹D8Ì"BEU¢BDj»½F§Ñftò~?•„†dnz(ŠÔV",…‚…è3%&%M +-/-(ŠI,020,–H ".1."£G  ,¢L W!°I^}ÈQÆCÉÊXÏÐÑÑA;tkabber-0.11.1/pixmaps/default/docking/invisible.gif0000644000175000017500000000052110563437022021720 0ustar sergeisergeiGIF89a¥*:::OOOVVVWWWXXXYYYZZZ[[[lllˆˆˆ¶¶¶···½½½ÃÃÃÆÆÆÇÇÇÈÈÈÊÊÊËËËÌÌÌÍÍÍÏÏÏÐÐÐÓÓÓÙÙÙàààâââäääæææèèèéééëëëíííîîîòòòóóóôôô÷÷÷ùùùûûûüüüþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù?,nÀŸpH,Ȥr¹ 8Ìb•R©QaÀt¢^³ÒhSBaÁ!Ibs:3žâ12¹›ÃCº+ "~I  ‡ˆH –GžH¥Iª«­¦Y±²³³A;tkabber-0.11.1/pixmaps/default/docking/available.gif0000644000175000017500000000052010563064247021660 0ustar sergeisergeiGIF89a¥'NDQGTJXN\QdJrd‰eŒ| ¢Ž«–­˜±›´ž¹¢¾§Ä¬É°Ì³Í´Ð·ÔºÔ¼Ù¿ÛÀÞÃäÉèÌéÏéÐ òÕûÜûÞÿàûà"ÿâÿä#ÿæ3ÿç;ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù?,mÀŸpH,Ȥr¹<8ÌâÁD5¢ÂCi»½F$QGDò~Agdn~(Ê'ÔV.ÂÅSO6}H †‡ŽG •F G ¤H©ª¬¥X°±²²A;tkabber-0.11.1/pixmaps/default/docking/blank.gif0000644000175000017500000000012010110221066021001 0ustar sergeisergeiGIF89aÂ333QQQfff)%¿ÿÿÿÿÿÿÿ!ù,xºÜþ0ÊI«½8ëÍ»ÿ`(Ždin ;tkabber-0.11.1/pixmaps/default/docking/unavailable.gif0000644000175000017500000000052010563064247022223 0ustar sergeisergeiGIF89a¥$:::OOObbbfffhhhjjjoooqqqtttvvvxxxyyy€€€„„„………‡‡‡‰‰‰‹‹‹ŒŒŒ‘‘‘“““———™™™ššš²²²¾¾¾ÁÁÁÅÅÅÆÆÆÈÈÈÊÊÊÌÌÌÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù?,mÀŸpH,Ȥr¹ 8Ìb`CÝ¢Â@f»½F–‹æbñ~'›ÎEbn:0 ŒƒÑV"£QdQO" }H! †‡ ŽG •FGXE£Iª¨©®°±²IA;tkabber-0.11.1/pixmaps/default/docking/message.gif0000644000175000017500000000030410563064247021364 0ustar sergeisergeiGIF89a³µµµåååàààêêêííí{{{ŠŠŠqqqõõõñññüüüuuuøøø†††!ù,qðÉI«½8ë]iã䲚¡¬+à 0𩬠܉ŒÑŠ # ‚݀AaŠalC‹Ù<¡)„óˆv´U@ ›J˜ ܱ—bH„Ç‚õÄ@hŽ‚xªÎË%}~)†wx„3!#%'‘’“”;tkabber-0.11.1/pixmaps/default/roster/0000755000175000017500000000000011076120366017147 5ustar sergeisergeitkabber-0.11.1/pixmaps/default/roster/available-xa.gif0000644000175000017500000000052310563064247022171 0ustar sergeisergeiGIF89aÕ#ÿÿÿOOO:::ÜÜÜÝÝÝNNNÐÐÐPPP×××¼¼¼ÓÓÓ¬¬¬±±±···ÚÚÚÉÉɸ¸¸¶¶¶^^^¦¦¦³³³```¤¤¤MMM´´´ÑÑÑÖÖÖËËËÄÄÄ¢¢¢ÈÈÈÇÇÇuuu²²²!ù#,pÀ‘p(Äd±À, ”Ca:}B(ñ°^¢PgãM Œ ã°( B¡qGÀï󣆇Q…~‰E…‡†’#  |šD˜™›BO~~I®PPvDA;tkabber-0.11.1/pixmaps/default/roster/available-dnd.gif0000644000175000017500000000052310563064247022326 0ustar sergeisergeiGIF89aÕ&ÿÿÿŽi þl4þr<¬1\Ø=þa$½5Î:PMÃ7ùFú_#q ª0³2èN¢-èY!çAÈ8¸4Ì9ñD°1‹/ ÓGX[þUTÚ=úTýG!ù&,p@“p(Äd±À, ”Ca:}B ˆ’°^Iž%äM ‹ÈâQ*ˆÃ±qG/šOÀïó£#"†‡Q …~‰E …‡†’& „‘|šD ˜™›BO~~I®PPvDA;tkabber-0.11.1/pixmaps/default/roster/conference-available.gif0000644000175000017500000000111410563064247023665 0ustar sergeisergeiGIF89aæRu=v?:S™ÿÿ££óê“ÿ¼¼ÿ^^ðåvöÿ±±ÿSSdö^Ÿÿôì›òèˆïãlu­ÿÿæÓ£Èÿòè…z°ÿÿuuóê’_ëñçƒ\à×Åÿ  â\\7ˆÿëøÚÚ±Ñÿqÿïâj ÆÿX¢æÿ¯¯àéØ9ÐDDó½½òè‡ mÿDÿÔêþ{ÿmÿÿÿxxÿ11¼×ÿ*ÿîádÿDD1…ÿÿ>>€³ÿÿzzåÒÿÿ€€ÿ**ìÝOxÿÈ·ÿŽŽÿÜÊçÕ$¼Úõÿ77>ŒÿÿŽ»ÿc§¯Ðÿÿ¢¢Ê¹ÿ !ùR,©€R‚‚†††/H…‚‰Š&M…=P”‹„!+›ˆ•%N5*Ÿ;"šš$³ƒ9 L<'½´J ? È,´04DÒ7ŸR1 :EOAá B.K 3)î-6Ip8ânƒÈÀ`ˆ‘pâˆ)E HàÆRt} ;tkabber-0.11.1/pixmaps/default/roster/available-away.gif0000644000175000017500000000052310563064247022522 0ustar sergeisergeiGIF89aÕ%ÿÿÿ‰edJÿæ3ÿç;\Qûà"ûÜĬзNDÙ¿¾§ÿä#QG­˜òÕɰ«–XNèÌÿâ±›¢Ž¹¢´žÍ´éÏÛÀÔ¼TJûÞéÐ rdÿàŒ| !ù%,pÀ’p(Äd±À, ”Ca:}BŽCèà°^AÇâM  ‘1* ƒqG+JÀïó£ †‡Q  …~‰E …‡†’% „‘|šD˜™›BO~~I®PPvDA;tkabber-0.11.1/pixmaps/default/roster/group-opened.gif0000644000175000017500000000011410110221066022221 0ustar sergeisergeiGIF89a¡îîîÿÿÿÿÿÿ!ù ,”©Ë혴‚Þá®Ìy ØA™ø Ñʶ.S;tkabber-0.11.1/pixmaps/default/roster/available-chat.gif0000644000175000017500000000054310563064247022502 0ustar sergeisergeiGIF89aÕ3‰edJÿæ3ÿÿÿç;\Qîîÿÿ—ÛÝÿÿRQG­˜ûà"¾§ììٿĬзÿä#ûÜÿÿNDéÐ ÿâŒ| rdèÌXNÔ¼¹¢ððóóéÏ´žÍ´ÿÿ[¢ŽÿÿÿÿàTJ÷÷±›äÉééÿÿ¶ûÞɰòÕÛÀ«–!ù3,€À™p( Äd±À,”ÃÀ`:}B“Æ¥1±^]LãM(„r*ƒ͈ؕãYf1*()$ ƒQ &E"%/ - ›3  •šJ2O , §CVv¿P½CÀÁPCA;tkabber-0.11.1/pixmaps/default/roster/invisible.gif0000644000175000017500000000050610563437022021623 0ustar sergeisergeiGIF89aÕ+:::OOOÿÿÿüüüäääWWWóóóëëëþþþôôôûûûùùùlllÇÇÇYYYòòòXXXÈÈÈÆÆÆæææ½½½ZZZ¶¶¶îîîÐÐÐVVVÓÓÓËËË[[[èèèéé鈈ˆ÷÷÷àààÙÙÙÊÊÊÃÃ÷··ÌÌÌíííÍÍÍÏÏÏâââ!ù+,cÀ•p( Ädq€Êa`¡`>£«@Â@  ØÀeó!(ÀÊ€‡Ähèd@Sáˆqb`‚rPyR!%)'‚R&‰E *Y—B #C¢£¥žXBA;tkabber-0.11.1/pixmaps/default/roster/available.gif0000644000175000017500000000050310563064247021561 0ustar sergeisergeiGIF89aÕ'dJ‰eÿæ3ÿç;\Q­˜èÌûÜNDÿä#ûà"Ĭ¾§Ù¿QGзûÞéÐ rd̳¢ŽÔº´žÛÀÞÃòÕÿàɰäÉÍ´«–ÿâéϹ¢Œ| TJ±›Ô¼XN!ù',`À“p( ÄdqÀ”À`:}B ED‘°^!%èãMÉã ) ¡‘qG Sˆc°/$# ~E  …'Œ ŒBšCŸ ¢›PCA;tkabber-0.11.1/pixmaps/default/roster/stalker.gif0000644000175000017500000000032510563064247021310 0ustar sergeisergeiGIF89aÄ]]]nnn"""ªªª### $$$666MMM999!!!:::777III444FFF“““………¦¦¦›››!ù,R`%Žb`dZ ¬¨cв/,Æc,µm@’V ¡ÐKƒAƒI ƒÄ²I2& jõ= ¸]E–p&EÛ]Dh ¯ç«ü!;tkabber-0.11.1/pixmaps/default/roster/group-closed.gif0000644000175000017500000000011410110221066022220 0ustar sergeisergeiGIF89a¡îîîÿÿÿÿÿÿ!ù ,”©ËÝà€Ñ€@ãÅusç}Œ—ø O Vîk;tkabber-0.11.1/pixmaps/default/roster/unavailable.gif0000644000175000017500000000050410563064247022125 0ustar sergeisergeiGIF89aÕ$:::OOO™™™tttyyy“““ÆÆÆ———oooÌÌ̇‡‡‘‘‘ÊÊÊ………šššfffÁÁÁqqqxxxjjj€€€‰‰‰‹‹‹¾¾¾ÅÅŲ²²ÈÈÈvvvŒŒŒhhhbbb„„„!ù$,a@’p( ÄdQÀ”ÃÀ`:}B ƒÄа^5‚!ãMˆb) …‚QpG #ÇãC°+  ~E…$!Œ"ŒB„PJšD¡Ÿ ¥$A;tkabber-0.11.1/pixmaps/default/roster/conference-unavailable.gif0000644000175000017500000000054610563064247024240 0ustar sergeisergeiGIF89aÕ-VVVAAAØØØ©©©¼¼¼{{{®®®ÑÑÑŸŸŸéééÝÝ݇‡‡»»»ÃÃÔ””ÆÆÆ˜˜˜„„„›››ppp¡¡¡```××׳³³ÏÏÏÈÈÈ¿¿¿žžžºººuuuŽŽŽƒƒƒÂÂÂwww€€€‘‘‘ŠŠŠ†††¬¬¬oooÐÐÐzzzÇÇÇ!ù-,ƒÀ–£…fR @XŠÄ€uº$›$· d.Šª Ài¸€Áæàô¢÷0b€”Ïixpqsp|tqc …,*!” $%”•—#'”  ¢)+cd^ª¬HJÁ³µÁƼOJA;tkabber-0.11.1/pixmaps/default/icondef.xml0000644000175000017500000004044210607415615017771 0ustar sergeisergei Default 2.1t Tkabber's Default Style Artem Bannikov tkabber/logo tkabber/tkabber-logo.gif toolbar/add-user tkabber/toolbar-add-user.gif toolbar/disco tkabber/toolbar-disco.gif toolbar/join-conference tkabber/toolbar-join-conference.gif toolbar/show-offline tkabber/toolbar-show-offline.gif toolbar/show-online tkabber/toolbar-show-online.gif toolbar/gpg-signed tkabber/gpg-signed.gif toolbar/gpg-unsigned tkabber/gpg-unsigned.gif toolbar/gpg-encrypted tkabber/gpg-encrypted.gif toolbar/gpg-unencrypted tkabber/gpg-unencrypted.gif gpg/vsigned tkabber/gpg-vsigned.gif gpg/signed tkabber/gpg-signed.gif gpg/badsigned tkabber/gpg-badsigned.gif gpg/encrypted tkabber/gpg-encrypted.gif gpg/badencrypted tkabber/gpg-badencrypted.gif browser/server services/server.gif browser/client roster/available.gif browser/user roster/available.gif browser/conference roster/conference-available.gif browser/headline services/rss_online.gif browser/directory services/jud.gif browser/jud services/jud.gif browser/sms services/sms.gif browser/aim services/aim_online.gif browser/icq services/icq_online.gif browser/mrim services/mrim_online.gif browser/msn services/msn_online.gif browser/yahoo services/yahoo_online.gif browser/gadu-gadu services/gg_online.gif browser/weather services/weather_online.gif browser/x-weather services/weather_online.gif docking/blank docking/blank.gif docking/chat docking/available-chat.gif docking/available docking/available.gif docking/away docking/available-away.gif docking/xa docking/available-xa.gif docking/dnd docking/available-dnd.gif docking/invisible docking/invisible.gif docking/unavailable docking/unavailable.gif docking/message docking/message.gif docking/message-personal docking/message-personal.gif docking/message-server docking/message-server.gif docking/tkabber docking/tkabber.ico roster/user/chat roster/available-chat.gif roster/user/available roster/available.gif roster/user/away roster/available-away.gif roster/user/xa roster/available-xa.gif roster/user/dnd roster/available-dnd.gif roster/user/invisible roster/invisible.gif roster/user/unavailable roster/unavailable.gif roster/user/unsubscribed roster/stalker.gif roster/user/error roster/unavailable.gif roster/conference/available roster/conference-available.gif roster/conference/unavailable roster/conference-unavailable.gif roster/group/closed roster/group-closed.gif roster/group/opened roster/group-opened.gif services/aim/away services/aim_away.gif services/aim/chat services/aim_chat.gif services/aim/dnd services/aim_dnd.gif services/aim/unavailable services/aim_offline.gif services/aim/available services/aim_online.gif services/aim/xa services/aim_xa.gif services/gadu-gadu/away services/gg_away.gif services/gadu-gadu/chat services/gg_chat.gif services/gadu-gadu/dnd services/gg_dnd.gif services/gadu-gadu/unavailable services/gg_offline.gif services/gadu-gadu/available services/gg_online.gif services/gadu-gadu/xa services/gg_xa.gif services/icq/away services/icq_away.gif services/icq/chat services/icq_chat.gif services/icq/dnd services/icq_dnd.gif services/icq/unavailable services/icq_offline.gif services/icq/available services/icq_online.gif services/icq/xa services/icq_xa.gif services/jud services/jud.gif services/msn/away services/msn_away.gif services/msn/chat services/msn_chat.gif services/msn/dnd services/msn_dnd.gif services/msn/unavailable services/msn_offline.gif services/msn/available services/msn_online.gif services/msn/xa services/msn_xa.gif services/rss/away services/rss_online.gif services/rss/chat services/rss_online.gif services/rss/dnd services/rss_online.gif services/rss/unavailable services/rss_offline.gif services/rss/available services/rss_online.gif services/rss/xa services/rss_online.gif services/sms services/sms.gif services/weather/away services/weather_away.gif services/weather/chat services/weather_chat.gif services/weather/dnd services/weather_dnd.gif services/weather/unavailable services/weather_offline.gif services/weather/available services/weather_online.gif services/weather/xa services/weather_xa.gif services/x-weather/away services/weather_away.gif services/x-weather/chat services/weather_chat.gif services/x-weather/dnd services/weather_dnd.gif services/x-weather/unavailable services/weather_offline.gif services/x-weather/available services/weather_online.gif services/x-weather/xa services/weather_xa.gif services/yahoo/away services/yahoo_away.gif services/yahoo/chat services/yahoo_chat.gif services/yahoo/dnd services/yahoo_dnd.gif services/yahoo/unavailable services/yahoo_offline.gif services/yahoo/available services/yahoo_online.gif services/yahoo/xa services/yahoo_xa.gif services/mrim/away services/mrim_away.gif services/mrim/chat services/mrim_online.gif services/mrim/dnd services/mrim_away.gif services/mrim/unavailable services/mrim_offline.gif services/mrim/available services/mrim_online.gif services/mrim/xa services/mrim_away.gif chat/bookmark/red tkabber/chat-bookmark-red.gif chat/bookmark/green tkabber/chat-bookmark-green.gif chat/bookmark/blue tkabber/chat-bookmark-blue.gif xaddress/info/red tkabber/xaddress-red.gif xaddress/info/green tkabber/xaddress-green.gif xaddress/info/blue tkabber/xaddress-blue.gif tkabber-0.11.1/pixmaps/feather16/0000755000175000017500000000000011076120366015772 5ustar sergeisergeitkabber-0.11.1/pixmaps/feather16/services/0000755000175000017500000000000011076120366017615 5ustar sergeisergeitkabber-0.11.1/pixmaps/feather16/services/rss_chat.gif0000644000175000017500000000016710563064247022123 0ustar sergeisergeiGIF89aò|O¼q£s"ï¸dÿôÖÿÿÿ!ù,¿¤ß¹Óºy÷ݱÿùëÿÿÿ!ù,BxºÜ+0JÈ„¹8‹z§5ÛsdÙqY*Öà¾.ÈtMË"ñ.Ú»@!˜Ó3Ûp·:´ŒÄ_-¸D²R;Œå™(;tkabber-0.11.1/pixmaps/feather16/tkabber/0000755000175000017500000000000011076120366017404 5ustar sergeisergeitkabber-0.11.1/pixmaps/feather16/tkabber/toolbar-show-offline.gif0000644000175000017500000000062610563064247024144 0ustar sergeisergeiGIF89a¥ÿ×iÿÑaê¹Fä´AÿßtÿÛnùÈWÞ®;×§5ÿÿÑÿä{ÿÔeð¿MÑ¡/Ê›*ÿáwëºGÓ£1Å–&Úª8õÄS½Ž!www^^^XXXÈ™)ì»H·‰}}}oooRRRNNNÆ—'ÿÏ_µµµˆˆˆxxxdddGGGBBBƒƒƒ___III???°‚OOOiii;;;777ÌÌÌ```uuuQQQÀÀÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù ?,³ÀŸpH,ȤRh–I@ç‚É<¡E©¬ãù€®ØŸvD*™N(0péŒRÕŠåT#O)îzvF(**} „Y ,5$Œ ’D(,& Ÿ 01 ª®Lu·ºb2324 !" ÂÄb6tM Ãa72W-РÞuâ…ÆÈæYÒÔa…ÜêGMîôõö÷øDA;tkabber-0.11.1/pixmaps/feather16/tkabber/gpg-vsigned.gif0000644000175000017500000000023510563064247022312 0ustar sergeisergeiGIF89aã ===W”‘Y€®é@¸0w T,ßIdhŠ^º‚A´ôež€æ‘z¬«‹{*i äI-ü*Yj™–ŒSÚÓ×13ý©_Zm ^~fƒŠ‹ŒŽ‹ ;tkabber-0.11.1/pixmaps/feather16/tkabber/toolbar-show-online.gif0000644000175000017500000000052610563064247024005 0ustar sergeisergeiGIF89a¥ÿ×iÿÑaê¹Fä´AÿßtÿÛnùÈWÞ®;×§5ÿÿÑÿä{ÿÔeð¿MÑ¡/Ê›*ÿáwëºGÓ£1Å–&HHH666Úª8õÄS½Ž!£££’’’ŽŽŽRRRÈ™)ì»H·‰§§§ŠŠŠ~~~Æ—'ÿÏ_ÍÍÍ®®®–––‚‚‚«««yyy}}}°‚€€€™™™zzzwwwÌÌÌ```‡‡‡¡¡¡ŸŸŸQQQ???ÀÀÀªªªÜÜÜÿÿÿ!ù ?,sÀŸpH,ȤrÉl:ŸÐ¨@H…€€`@°F³Ã‘ð:ÁŠ£áx˜™AD$“÷080ìzS„I5 $% ‹{ ŒW?.–pUTW343¥9:¤¥<3¡M¯œ¶·¸¶A;tkabber-0.11.1/pixmaps/feather16/tkabber/gpg-badencrypted.gif0000644000175000017500000000040410563064247023315 0ustar sergeisergeiGIF89a„nH}VHHHTTTfffxxx‡^›q´‰1ÈDÕ©Qáµ`÷Ê|†††˜˜˜¦¦¦···ÿç¨ÈÈÈÚÚÚæææÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù,à'Ž"0(©–Á ‡¹–R[B<@#Ÿ‰Ÿ °òF`Їb$™À@4ˆ¢F@›~@Pj'€ˆìÊ$ex‡Á@0S"uw{|f€)(o}q€‰&(†“•—˜Co–|¡+(¬L­!;tkabber-0.11.1/pixmaps/feather16/tkabber/gpg-signed.gif0000644000175000017500000000044010563064247022122 0ustar sergeisergeiGIF89aó ===W”Y•בY<¾‚dÎ’t”””ŽÃñÖž„ó¾«ÀÀÀÿÿÿ!ù ,Í1ÆcŒ1Æ€€1ÆcŒ1Æd €DcŒ1Æ cŒ1H" 0cŒ1Æ$h`Œ1ÆcŒA@I*Æc 2Æ©ec1ÆcŒD’‚0ÆcŒ1ÆcŒ1Æ cŒÀcŒ1cŒ1Æ`Œ1ÈcŒ1Æc @Àc c 2ÆŒ1ÆÀZðÆcŒÆƒŒ1°cŒ1ÆdŒ1ÆX'Æ cŒ1Æ  Ç€1ÆcŒ1ÈX;tkabber-0.11.1/pixmaps/feather16/tkabber/gpg-badsigned.gif0000644000175000017500000000035510563064247022576 0ustar sergeisergeiGIF89aòW”Y•×”””ÀÀÀÿÿÿ!ù,²XUU…UUUXUU…UUUXUU…UUUXUU…UUUXUU…UUUXUU…UUUXUU…UUUXUU…UUUXUU…UUUXUU…UUUXUU…UUUXUU…UUUXUU…UUUXUU…UUUXUU…UUUXUU…UUXUU…UU…UUUXUU…@@XUU…UUU(@4‚PUXUU…(PU…"""(…PUX%"‚RUUX;tkabber-0.11.1/pixmaps/feather16/tkabber/gpg-encrypted.gif0000644000175000017500000000056010563064247022651 0ustar sergeisergeiGIF89aônH}VHHHTTTfffxxx‡^›q´‰1ÈDÕ©Qáµ`÷Ê|†††˜˜˜¦¦¦···ÿç¨ÈÈÈÚÚÚæææÿÿÿ!ù,í eY–eY––eY–eY–eY€Ô€K‚€eY–eY–eR €eY–Z–e `Y–$€eY–eY–,€eY(€eY–eY–$À–eY–eY @EM€€eY–epQ=@€`Y–eÕDc<`€eY–PB@Ža€eY–P†AhY–Dd@FA–eYA DE1–eY=@TÃX–e–EQA `Y–eY–€e…;tkabber-0.11.1/pixmaps/feather16/tkabber/toolbar-disco.gif0000644000175000017500000000162210563064247022642 0ustar sergeisergeiGIF89a õ%N9U>ZAeIiL!nP#xV%€](ˆb*•k.–m0q.šp2¡r.§y3±}1­€<·…:ÃŒ;È‘=×™;ê¤>ÃDÊ”DÕšCÜ¢JàŸ@å¦Gç¬Rï°Iî´Zñ«Bý³Gú¹Yÿ¿`ÿÁc!ù%, þÀR©T*•J¥R©T*•J¥R©T*•J¥R©T*•J¥R©T*•J¥R©T*•J¥R©T*•J¥R©T*•€¥R©T*•J¥R©T*•J¥R©T*•J¥Ð¦T*•J¥R©T*•J¥R©Te2O©T"u$Âñ¸C¥R©T*•J¥R©”Q$I©D’$“ÃA“Q–R©T*•J¥R)’•K©“ˆˆJ¢Ã!T‚ ‚I©T*•J¥R 3ДD F©s”J%Ì Q*•ƒJ©T*•J¥RéP •8J)2•J¥Ç@,•<ƒC¨T*•J¥Ri40xJJFt8”J¥‚`)•Nþ©T*•J¥R‰40TJ’LJC8”J¥Ï˜(qO©T*•J¥R©T¢ˆJ™£T!H¥RfpH ‰¨T*•J¥R©T*•J ãZhJ¥ð1 ”BCáQ*•J¥R©T*•J%ÆàR*•J¥Ré0°”J¥¡P*•J¥R©T*•J%àS*•J%`i48”J¥’dp(•J¥R©T*•J¥ÊàP*•J¥Ré2¨”J¥’c)•J¥R©T*•J%ÉÀQ*•JÀRI„”J¥’ˆ•J¥R©T*•J¥Rb )•J¥Qç)•J%N‚*•J¥R©T*•J¥áQ*•€%A(‰Ä¢R±*•J¥R©T*•J¥Qâ*•J¥Œd"¹H.™P©T*•J¥R©TÒd4¦T*K¥R©T*•J¥R©T*•J¥R©TE§T*•J¥R©T*•J¥R©T*•J¥R©Tê@$šR©T–J¥R©T*•J¥R©T*•J¥R©T*•J¥R©T*•J¥R©T*•J¥R©T*•J¥R©T*•J¥R©,•J¥R©T*•J¥R©T*•J¥R©T ;tkabber-0.11.1/pixmaps/feather16/tkabber/gpg-unsigned.gif0000644000175000017500000000035510563064247022472 0ustar sergeisergeiGIF89aò===W”Y•×”””ŽÃñÀÀÀÿÿÿ!ù,²xww‡wwwxww‡wwwxww‡wwwxww‡wwwxww‡wwwxww‡wwwxww‡wwwxww‡wwwxww‡wwwxww‡wwwxww‡wwwxww‡wwwxww‡wwwxww‡wwwxww‡wwwxww‡wwwxww‡www‡wwwxww€fwxww‡wwwx`p‡wwwxww‡Fxww‡wwwxP3ƒwwxww‡w—;tkabber-0.11.1/pixmaps/feather16/tkabber/gpg-unencrypted.gif0000644000175000017500000000056010563064247023214 0ustar sergeisergeiGIF89aônH}VFFFTTTfffxxx‡^›q´‰1ÈDÕ©Qáµ`÷Ê|†††˜˜˜¦¦¦···ÿç¨ÈÈÈÚÚÚæææÿÿÿ!ù,í e€eY–eY–eY 5K‚€e–eY–eY€Ô`Y–eY–e Z–e `Y–eY–e `Y–(€eYhY–e `Y–0– €eY @EMÑ €€eQ=0€`–eÕDc<Î`€eY–PB@Ža€eY–PFAhY–Dd@FA–eYA DE1–eY=@TÃX–e–EQA `Y–eY–€e…;tkabber-0.11.1/pixmaps/feather16/docking/0000755000175000017500000000000011076120366017410 5ustar sergeisergeitkabber-0.11.1/pixmaps/feather16/docking/available-xa.gif0000644000175000017500000000052710563064247022436 0ustar sergeisergeiGIF89aò333UUU«««ÿÿÿÿÿÿ!ù,þhff†fff83f†fffhff†f6fhfF„Dffhff†fffHDD‚fffhffƒcFDHDb†fffh6f†DDD(ff†ff6hfD„DDbhff†f6fHDE„$ffhff†fFDXD$†fffhff†FTD(ff†ffF„EDbhFf†QUhFE„$f3hfQ…UUAX$$†fffUR…R%hff†6fQ(%R‚bfh63†fQRXURfffhff†%U(`†fffhff%URff†fffhf…"fhff†fffh%‚ffhff†fff €fffhff†ffHb†fffhff†fff†fffhf–;tkabber-0.11.1/pixmaps/feather16/docking/tkabber.ico0000644000175000017500000002302610563064247021526 0ustar sergeisergei°(¶(Þ((.(V(~°¦hV h¾ ¨& èÎ è¶(ž"(Æ#(î$( ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ( ÿ333¿%)ÿÿÿÿÿ" DBDB$DD $DD $DD%DB3Q" 0S01113ÇÿÇÿƒÿƒÿƒÿÿÿ€ÆþÿÿÿÀÿàÿø( ÿ333¿%)ÿÿÿ" DBDB$DD $DD $DD$DB3A" 0C01113ÇÿÇÿƒÿƒÿƒÿÿÿ€ÆþÿÿÿÀÿàÿø( ÿ¿%)ÿÿ33333033030333333333333033 2 !1!!"àÿ€?€?€€àÿÿÿÀÿàÿø( |333ÿÿÿÿÿÿ" DBDB$DD $DD $DD%DBS0" 503S05333300ÇÿÇÿƒÿƒÿƒÿÿÿ€ÆþÿÿÿÀÿàÿø( 333\\\«««ÿÿÿ10DADADDDDDD# DA3C2423C2343 33 332323ÇÿÇÿƒÿƒÿƒÿÿÿ€ÆþÿÿÿÀÿàÿø( 333\\\«««ÿÿÿ1031313333#33# 313C2423C2343 33 332323ÇÿÇÿƒÿƒÿƒÿÿÿ€ÆþÿÿÿÀÿàÿø( ___Çÿ×ÿ«ÿ»ÿ»ÿ}ÿ|ÿ|ºoƧþÛÿmÿ½ÿÞÿæÿøÇÿ×ÿ«ÿ»ÿ»ÿ}ÿ|ÿ|ºoƧþÛÿmÿ½ÿÞÿæÿø( *U*€U*>*ªUUU?*?UªU?U?UªU?U_UUÔU?ªª_UU_UUª_U_ªªUUU_Ôª………UªUÔªŸUŸª¤  UÿªŸªÿŸªU¿ªª¿ªÿŸÔªŸÿª¿Ôðʦÿ¿Ôª¿ÿÀÜÀªßÔUßÿÿßÔªßÿÿÿªÿÔÿßÿUÿÿªÿÿõüÿ! -! #!+  #7!#  -!))7! ( .76 ,,,( #6).&((((367!(("!%5  1! 752%77!%2/#6$'-0&&67)+# -!-! 4*!7+!#77-+ -þÀ€€€€€€€€€Àâöÿ( Uÿÿ*U>*ÿ*ÿUU?UUÔU?Uÿÿ?UU_Uªÿÿ?Uÿÿ_UUU?ÿU_ªÿ__ÿ………ÿU_ÿª_ÿÿÿªªÿŸÿÿŸªªŸÔUŸÿÿŸÔªŸÿU¿ÿª¿ÿÿßÔªßÿðûÿ      ! !!$$ $$"%%'$%%'#!( & ( üø?À€€€€€€„ÂÇçÏ( @9N>UAZIe!Li#Pn%Vx(]€*bˆ.k•0m–2pš.q.r¡3y§1}±<€­:…·;ŒÃDÃ=‘ÈD”Ê;™×CšÕ@ŸàJ¢Ü>¤êG¦åR¬çB«ñI°ïZ´îG³ýY¹ú`¿ÿcÁÿ$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" $$$$$$$$$$$$$$$$$$$$$$$$$$$ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$"$$$$ $$$$$$$$$$$$$$$$$$$$ $$$$$$$$$$$$$$$$$$$"$$$$ $$$$$$$$$$$$$ $$$$$$!$$$$!!$$$$$$$$$$$$$$$$$$$$$$$ $$$$$$$$$$$$$$$$$$$"$$$$$$$$$$$$$$$$$ $$$$$$$$$$$$$$$$$$$$$$$$ $$$$ $$$$$$$$$$!$ $#$$$$$$$$$$$#$$$$$$$$$$$$$$$"$!$$$$$$ $$$$$$$$$$#$$$$$$$ $$$$$$$$$$! $$$$ $$$$$$$$$$$$$$ $!$! $$$$$$$$$$$$ $$# $$$$$$$$$$$$$!$$$#  $$$$$$$$$$$$$$$$$$$$$$$$$$ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ‡ÿÿÿÿÿÿÀÿÿÿü<ÿþ<ÿÿÿÇÿÇÿãÿˆâüˆ`ø@âø@ñüDq‡üDqÇþ"‡ÿÿÁÀÿÿüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ( @h‚'¢É<´ÙA¹ÝRÆçhÔñDDDP""!BVfe"%fUfRE`VRB`f#$$""" DDT$"@  " "&e "%f 1Ua $ffV`&Pf@C`f`1Pa $`f`&Uf@ffV`#46@44B"#CÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàÿÿÀÿÿ€ÿÿ€ÿÿ€ÿÿ€ÿÿ€ÿÿ€ÿÿÀÿÿÿþü?ø?ø?ø?ø?ø?ü?þ€ÿÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ( @ÿ$$$333¿%) aƒfff{{{™™™ÿÿÿÿÿÿÿ`3f03f3c6c336c336c33333303UU303™Y•™39™Y•™“™™Y•™™09™™Y•™™“™™•™™Y™™0™™••YY™™09™™•Y•Y™™“f`9™™•™™Y™™“9™™Y™™•™™“9™™Y™™•™™“f9™™•UUY™™“`™™™™™™™™1™™™™™™™š;±9™™™™™™“»™™™™™™0±9™™™™“D»9™™“0»330`A±AfD`DwDDÿÿÿþÿÿüÿÿüÿÿüÿÿüÿÿøÿÿøÿÿðÿÿðÿÿàÿÀ?ÿ€ÿ€ÿÇûÿó}€?€Àà@ðÀøàþpÿÿøÿÿ¼ÿÿÎÿÿÿÿÿßÀÿÿãð( ŸŸŸÿÿÀÀÀÀÀÀÀÀÀÀÀÀÀÀÿÿ( åååÿÿÀÀÀÀÀÀÀÀÀÀÀÀÀÀÿÿ( ñÿÿÿÀÀÀÀÀÀÀÀÀÀÀÀÀÀÿÿtkabber-0.11.1/pixmaps/feather16/docking/available-dnd.gif0000644000175000017500000000063110563064247022567 0ustar sergeisergeiGIF89aó333fffƒa ÿÿÿÿÿÿÿÿÿ!ù,þ!„B!„Æ€!„B!„D!4B!! !„B!BHˆR @!ˆB¡1¥ÀR @!„B„(¥”B!„B!$J¥”B!„D!QÊ)¥„ B!„BH”O) „B!ˆBH”S @A„B!„€*žR @ „P0Ð*§”‚c „‚1Æ<€B¡` !ÆcÂ!B¡`ˆ!Äh@!4Æ@Á`ˆ1ÆB"„B¡`ˆ1˜B!„‚¡`ˆ1Ä„D!„B¡` G!& „B!B¡`1!ˆB!„BAÂ!„B"„B€!„B!„‚¡@@!„D!„Š;tkabber-0.11.1/pixmaps/feather16/docking/message-personal.gif0000644000175000017500000000020610563064247023347 0ustar sergeisergeiGIF89aÂ|O£s"¼qï¸dÿ»¡ÿÿÿÿÿÿÿÿÿ!ù ,KxºÜþ0ÊI«8k,ù`tßæctl[’aœBž`ß6J|Ïë*¤|¾â£6ÌÍ–Gäïé`6•Õ¨Û8Å@Ô®ic)›Ï‘;tkabber-0.11.1/pixmaps/feather16/docking/message-server.gif0000644000175000017500000000020610563064247023032 0ustar sergeisergeiGIF89a¿¤ß¹Óºy÷ݱÿùëÿÿÿÿÿÿÿÿÿ!ù ,KxºÜþ0ÊI«8k,ù`tßæct l[’aœB^`ß6J|Ïë*¤|¾â£6ÌÍ–Gäïé`6•Õ¨Û8Å@Ô®ic)›Ï‘;tkabber-0.11.1/pixmaps/feather16/docking/available-away.gif0000644000175000017500000000052710563064247022767 0ustar sergeisergeiGIF89aò333QQQfff)%¿ÿÿÿÿÿÿÿ!ù,þxww‡www83w‡wwwxww‡w7wxwG„Dwwxww‡wwwHTU€wwwxwwƒsGUXUp‡wwwx7w‡TUUww‡ww7xwT…UUpxww‡w7wHUV…wwxww‡wGUhU‡wwwxww‡WeUww‡wwW…VUpx7w‡afxWV…w3xwa†ff1h‡wwwfb†b&xww‡7wa(&b‚pwx73‡wabhfbwwwxww‡&f(q‡wwwxww&fbww‡wwwxw†"wxww‡wwwx&‚wwxww‡www €wwwxww‡wwhr‡wwwxww‡www‡wwwxw—;tkabber-0.11.1/pixmaps/feather16/docking/available-chat.gif0000644000175000017500000000052710563064247022745 0ustar sergeisergeiGIF89aòfff)%¿ÿÿÿÿÿÿ!ù,þXUU…UUUU…UUUXUU…UUXU%‚"UUXUU…UUU(23€UUUXUUQ%383P…UUUXU…233UU…UUXU2ƒ33PXUU…UU(34ƒUUXUU…U%3H3…UUUX…%C3UU…U@HDƒ43PXU…@DDHD0ƒUXU@„DH…UUUX@D„DDDPU…U@HD@„@DX…U@DH@„DUXUU…@DHD„UUXU„DDHD€UUUXU@„@DHU…UUUX@D€@DUU…UUUDD„DUXUU…UUDD€PUUXUU…UUU…UUUXU•;tkabber-0.11.1/pixmaps/feather16/docking/invisible.gif0000644000175000017500000000050110563064247022064 0ustar sergeisergeiGIF89añˆˆˆÿÿÿ!ù,þ”(Q¢D‰F”(Q¢D‰%JT(Q¢Ä„ %J”(Q¢D‰JT(Q¢D‰FT(Q¢B‰%J”QbD‰#J”(Q¢B‰ %J”Q¢D‰JŒ(Q¢B‰%J”(Q¡D…#J”(Q¢D‰ %FT(Q¢D… #JŒ¨PbD‰%F”¨PbĈ %&”¨P¢D‰ %&Œ(Q¢Äˆ %FT¨P¢D‰ %FŒ˜P¡Âˆ%&Œ(1bD‰ J”(Q¢D‰ JŒ˜P¢D‰%JT¨PbĈ%J”(Q¢Äˆ J”(Q¢D‰%FL¨P¢D‰%J”(1a„%J”(Q¢D‰ %&”(Q¢D‰%JT˜0¢D‰%J”(;tkabber-0.11.1/pixmaps/feather16/docking/available.gif0000644000175000017500000000063110563064247022024 0ustar sergeisergeiGIF89aó333fff)%¿ÿƒa ÿÿÿÿÿÿÿÿ!ù,þ!„B!„„€!„B!„D!$B¡1à!„B!Bh B@!ˆB!!„@B@!„B „Ð „B!„B!4„B!„D¡AÈ!„„ B!„Bh! „B!ˆBhC@A„B!„€"B@ „P0Ð"‡‚B „‚1Æ<€B¡` )ÆcÂ!B¡`Š)Åh@!$„@Á`Š1ÆB"„B¡`Š1°B!„‚¡`Š1Å„D!„B¡``G)& „B!B¡`J1!ˆB!„BAD!„B"„B€!„B!„‚¡@@!„D!„Š;tkabber-0.11.1/pixmaps/feather16/docking/blank.gif0000644000175000017500000000012010563064247021164 0ustar sergeisergeiGIF89aÂ333QQQfff)%¿ÿÿÿÿÿÿÿ!ù,xºÜþ0ÊI«½8ëÍ»ÿ`(Ždin ;tkabber-0.11.1/pixmaps/feather16/docking/unavailable.gif0000644000175000017500000000052710563064247022373 0ustar sergeisergeiGIF89aò333UUU¬¬¬ÿÿÿÿÿÿ!ù,þhff†fff83f†fffhff†f6fhfF„Dffhff†fffHDD‚fffhffƒcFDHDb†fffh6f†DDD(ff†ff6hfD„DDbhff†f6VHDE„$ffhff†f6DXD$†fffhff†FTD(ff†ffF„EDbhFf†ADhFE„$f3hfA„DDAX$$†fffDB„B%hff†6fA($B‚bfh63†fABHDBfffhff†$D(`†fffhff$DBff†fffhf„"fhff†fffh$‚ffhff†fff €fffhff†ffHb†fffhff†fff†fffhf–;tkabber-0.11.1/pixmaps/feather16/docking/message.gif0000644000175000017500000000020610563064247021526 0ustar sergeisergeiGIF89aÂ|OÿôÖ£s"¼qï¸dÿÿÿÿÿÿÿÿÿ!ù ,KxºÜþ0ÊI«8k,Aø`tßæct l[’aœBÞ`ß6J|Ï몤|¾â£6ÌÍ–Gäïé`6•Õ¨Û8Å@Ô®ic)›Ï‘;tkabber-0.11.1/pixmaps/feather16/roster/0000755000175000017500000000000011076120366017310 5ustar sergeisergeitkabber-0.11.1/pixmaps/feather16/roster/available-xa.gif0000644000175000017500000000032110563064247022326 0ustar sergeisergeiGIF89aò333\\\ªªªÿÿÿÿÿÿ!ù,–XUU…UUUX3S…UUUXU3ƒ#UUXUU…33#XUU…U538#U…UUU834ƒRUUXU3ƒ4#UX…5C#XUUD3H3R…UADH$ƒRUUDD„!UUXU„DDQXUU…UDHQT…UUUXADUUUXUU€UXUU…UU0UU…UUUX…UUUXU•;tkabber-0.11.1/pixmaps/feather16/roster/available-dnd.gif0000644000175000017500000000032110563064247022463 0ustar sergeisergeiGIF89aò333ÿÿÿÿÿÿÿÿÿ!ù,–hff†fffh"b†fffhf"ƒffhff†23hff†f&38f†fff(35ƒ`ffhf2ƒ5fh†&ShffD"X3`†fADHƒ`ffDD„ffhf„DDahff†fDHae†fffhADfffhff€fhff†ffff†fffh†fffhf–;tkabber-0.11.1/pixmaps/feather16/roster/conference-available.gif0000644000175000017500000000071110563064247024030 0ustar sergeisergeiGIF89aõ**?UUU?U?UU_UUUÿ*ÿ*ÿUÿU?ÿ?ÿU_ÿ_ÿÿª_Uÿ?ÔUÿUÿUÿ_ÿÿ_Uªÿÿªÿÿÿ_ªÿªÿŸÿŸUÿ¿U€€€ªŸÿÔŸªÿŸªÿ¿ªÔŸÿÿߪÔßÿÿûð!ù*,æ@•J¨T*• P©T*• €2T* e¨T*•  Tà@¨T* 2¨)@P©€* t"}€ÐáT* T:! Sêp*`D¦Ì€ÁT*• 2"ä¨'•Jø|Ìã¡h*•Jø\$€ÇcL•Jð\,GC¨P!CH¸X,R(C(¤\,C‘P(ƒJ¥R€B*•J¥R©T*@"‘¨T*•J¥R©T*¨T*•J¥ ;tkabber-0.11.1/pixmaps/feather16/roster/available-away.gif0000644000175000017500000000032110563064247022657 0ustar sergeisergeiGIF89aò333)%¿ÿÿÿÿÿÿÿ!ù,–XUU…UUUX"R…UUUXU"ƒ#UUXUU…23XUU…U%38U…UUU(34ƒPUUXU2ƒ$UX…%CXUUD"H3P…UADHƒPUUDD„UUXU„DDQXUU…UDHQT…UUUXADUUUXUU€UXUU…UUUU…UUUX…UUUXU•;tkabber-0.11.1/pixmaps/feather16/roster/available-chat.gif0000644000175000017500000000032110563064247022635 0ustar sergeisergeiGIF89aò)%¿ÿÿÿÿÿÿ!ù,–HDD„DDDHA„DDDHD‚DDHDD„!"HDD„D"8D„DDD"#‚@D ‚DH3ƒ3HDD€3338 @„D033ƒ@DD3ƒ03@HDƒ3338D„D0830ƒ@DD3€03@HDD€3338@D„D083€DDDHD€DDHD”;tkabber-0.11.1/pixmaps/feather16/roster/invisible.gif0000644000175000017500000000030010563064247021761 0ustar sergeisergeiGIF89añ‡‡‡ÿÿÿ!ù,‘”(Q¢D‰&”(Q¢D‰ #*”(Q¢D‰%*”(Q¢D…%F”(Q¢Äˆ %F”(Q¢B‰J”˜0¢B… #JT(Q¡Âˆ %JŒ(Qb„%JŒ(QbB‰%JŒ(QbD‰%JT(Q¡B‰%JT(Q¡D‰%JT¨P¡D‰%J”1¢D‰%J”˜0¢D‰%J;tkabber-0.11.1/pixmaps/feather16/roster/available.gif0000644000175000017500000000032110563064247021720 0ustar sergeisergeiGIF89aò333)%¿ÿÿÿÿÿÿÿÿÿ!ù,–hff†fffh"b†fffhf"ƒ#ffhff†23hff†f&38f†fff(35ƒ`ffhf2ƒ%fh†&ShffD"X3`†fADHƒ`ffDD„ffhf„DDahff†fDHae†fffhADfffhff€fhff†ffff†fffh†fffhf–;tkabber-0.11.1/pixmaps/feather16/roster/stalker.gif0000644000175000017500000000051310563064247021450 0ustar sergeisergeiGIF89aôK%R+\3c:h>!lA#rG'~R0ppp²†Y5Ža<‘d?—iCª{Tÿ·ˆaÿÿÿ!ù,È $I’$I€$I’$I’$I’$ ’$’$I’$Nà I’$I’8Q´J’$IMôÇ€$IÀ²Œ³ÃHÀa ȱÅ CÄq A’$0 !H’$%€’$II’$I B ¤€$I’”@’’$I(%I’$€$I’$II’’$I $I’”$ ’$IR;tkabber-0.11.1/pixmaps/feather16/roster/unavailable.gif0000644000175000017500000000032110563064247022263 0ustar sergeisergeiGIF89aò333\\\«««ÿÿÿÿÿÿ!ù,–XUU…UUUX3S…UUUXU3ƒ#UUXUU…33#XUU…U538#U…UUU834ƒRUUXU3ƒ4#UX…5C#XUU33H3R…U238$ƒRUU33ƒ!UUXUƒ33QXUU…U38QT…UUUX13UUUXUU€UXUU…UU0UU…UUUX…UUUXU•;tkabber-0.11.1/pixmaps/feather16/roster/conference-unavailable.gif0000644000175000017500000000040010563064247024366 0ustar sergeisergeiGIF89aó***JJJZZZjjjˆˆˆŸŸŸ¬¬¬¾¾¾ÏÏÏÔÔÔééé÷÷÷!ù,­ð½À{ï=Þƒï½ï=àï½÷À à`à½÷€à à½÷c+Ì*÷`lÁŠ­Þ ¦ÖR ¤tÀ{ð”€Zk%p €ï=P+¥ ï½’1 ¥c (€¼÷€1$8b0ƈÐÇbÌÆ@2À@Þ{À9ðÞ{ð½÷0Æ€÷Þƒï½÷Þ{€÷|ï½;tkabber-0.11.1/pixmaps/feather16/icondef.xml0000644000175000017500000001517410563064247020140 0ustar sergeisergei Feather 16 1.0 Tkabber's Old Default Iconset 2006-01-20 toolbar/add-user tkabber/toolbar-add-user.gif toolbar/disco tkabber/toolbar-disco.gif toolbar/join-conference tkabber/toolbar-join-conference.gif toolbar/show-offline tkabber/toolbar-show-offline.gif toolbar/show-online tkabber/toolbar-show-online.gif toolbar/gpg-signed tkabber/gpg-signed.gif toolbar/gpg-unsigned tkabber/gpg-unsigned.gif toolbar/gpg-encrypted tkabber/gpg-encrypted.gif toolbar/gpg-unencrypted tkabber/gpg-unencrypted.gif gpg/vsigned tkabber/gpg-vsigned.gif gpg/signed tkabber/gpg-signed.gif gpg/badsigned tkabber/gpg-badsigned.gif gpg/encrypted tkabber/gpg-encrypted.gif gpg/badencrypted tkabber/gpg-badencrypted.gif browser/client roster/available.gif browser/user roster/available.gif browser/conference roster/conference-available.gif browser/headline services/rss_online.gif docking/blank docking/blank.gif docking/chat docking/available-chat.gif docking/available docking/available.gif docking/away docking/available-away.gif docking/xa docking/available-xa.gif docking/dnd docking/available-dnd.gif docking/invisible docking/invisible.gif docking/unavailable docking/unavailable.gif docking/message docking/message.gif docking/message-personal docking/message-personal.gif docking/message-server docking/message-server.gif docking/tkabber docking/tkabber.ico roster/user/chat roster/available-chat.gif roster/user/available roster/available.gif roster/user/away roster/available-away.gif roster/user/xa roster/available-xa.gif roster/user/dnd roster/available-dnd.gif roster/user/invisible roster/invisible.gif roster/user/unavailable roster/unavailable.gif roster/user/unsubscribed roster/stalker.gif roster/user/error roster/unavailable.gif roster/conference/available roster/conference-available.gif roster/conference/unavailable roster/conference-unavailable.gif services/rss/away services/rss_away.gif services/rss/chat services/rss_chat.gif services/rss/dnd services/rss_dnd.gif services/rss/unavailable services/rss_offline.gif services/rss/available services/rss_online.gif services/rss/xa services/rss_xa.gif tkabber-0.11.1/pixmaps/stars/0000755000175000017500000000000011076120366015341 5ustar sergeisergeitkabber-0.11.1/pixmaps/stars/services/0000755000175000017500000000000011076120366017164 5ustar sergeisergeitkabber-0.11.1/pixmaps/stars/services/rss_chat.gif0000644000175000017500000000026110563064247021465 0ustar sergeisergeiGIF89aãK+ÿ˜ÿ²ÔÀŠÿËÿÌÿåÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!þCreated with The GIMP!ù,EðÉIë 8ëPù ÈQ^ެÀÙ™.©®&*•°`?˃.4( ^>@ñ`”KspäÍXKCõ6°`g“K";tkabber-0.11.1/pixmaps/stars/services/rss_xa.gif0000644000175000017500000000026110563064247021156 0ustar sergeisergeiGIF89aã 2™K+e²˜Ì™ÌËåÔÀŠÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!þCreated with The GIMP!ù,EðÉIë8ëQú ÈQ^ެÀÙ™.©®&*•ða?Ë"†.d ^>@Q`”ËÓP¸ÍXKB5+n¹]á&S@E;tkabber-0.11.1/pixmaps/stars/services/rss_online.gif0000644000175000017500000000026110563064247022032 0ustar sergeisergeiGIF89aã K+ÿÿ˜ÿ±ÿ²ÔÀŠÿËÿåÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!þCreated with The GIMP!ù,EðÉIë 8ëPƒù ÈQ^Ž—¬ÀÙ™.©®&*•0b?ˇ.t(^>@q`”KópäÍXKBõ6°`g“K";tkabber-0.11.1/pixmaps/stars/services/rss_offline.gif0000644000175000017500000000022510563064247022170 0ustar sergeisergeiGIF89aÂ???DDDRRRiii†††¦¦¦ËËÊ!þCreated with The GIMP!ù,AxºÜ0ÊЂ¹SfsÞŒÀWy&'ލt¨àIà g1œ6@¯àSaCqð£­HÃbÕkN©ºI$·H;tkabber-0.11.1/pixmaps/stars/services/rss_away.gif0000644000175000017500000000026110563064247021507 0ustar sergeisergeiGIF89aã3™K+e²f²™ÌÌåÿÿÔÀŠÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!þCreated with The GIMP!ù,EðÉIë8kQú ÈQ^ެÀÙ™.©®&*•p`?Ë"ƒ.4( ^>@Ñ`”Ës@¸ÍXËB5+n¹]á&C@E;tkabber-0.11.1/pixmaps/stars/services/rss_dnd.gif0000644000175000017500000000026110563064247021313 0ustar sergeisergeiGIF89aã c‚K+¡ÀÁßÔÀŠddddddd!þCreated with The GIMP!ù,EðÉIë8ëQú ÈQ^ެÀÙ™.©®&*•ða?Ë"†.d ^>@Q`”ËÓP¸ÍXKB5+n¹]á&S@E;tkabber-0.11.1/pixmaps/stars/tkabber/0000755000175000017500000000000011076120366016753 5ustar sergeisergeitkabber-0.11.1/pixmaps/stars/tkabber/toolbar-show-offline.gif0000644000175000017500000000037010563064247023507 0ustar sergeisergeiGIF89aãgggxxw‰‰ˆ™™˜ÿžªª©ÿ®ºººÿ¾ÿÎËËÊÿÞÿîÿÿçççççç!þCreated with The GIMP!ù ,ŒðÉI«½8ëÍ©RÚ·)Gi•¸E[Hnqtì`ß¶Ü=Å üÀÁKC À|d@PÜ Ð€Œb‹¸CG›(›Ëáá‘X¸ß „°Ã^0îŒE\8ã´ y .}!ƒ(*uxƒ"uonq;dgfac``bNVVXM©¨;­®¯®;tkabber-0.11.1/pixmaps/stars/tkabber/xaddress.gif0000644000175000017500000000035410563064247021266 0ustar sergeisergeiGIF89a„s¨ržÝ&&ooo¸Îÿ€ýžþŸÿ ÿÿÿ¯ÿÑÿáÿåÿÿoooooooooooooooooooooooooooooooooooooooooooooooo!ù ,ià‘@drhŠ0,‹¤0Ä84ƒ äûü8 ‚P(({4àTP «ã…*Eœ GÒñ–KnLLƲærzœ nT£™£ü›ÔXøé(0  my{u~ €poq|tvg(!;tkabber-0.11.1/pixmaps/stars/tkabber/toolbar-disco_old.gif0000644000175000017500000000047210563064247023051 0ustar sergeisergeiGIF89a„Š*•*?Ÿ?TªTUªUi´ij´j¿”É””Ê”©Ô©ªÔª¾Þ¾¿ß¿ÓéÓÔéÔéôéÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!þCreated with The GIMP!ù ,žà'ŽdižhªžÀê°›BÈ"¬ 1ºØ¬V …ñ68 ‡hÒ TÑŒPDq($«Í¬b¡à~ÌÓUÌh0ʇ3¸´>  ÇÃñ6£K4  q$uwy‹ri’P•Us&4EOœE®AFrA9M»¼¾¿¼ÂÄÅ(!;tkabber-0.11.1/pixmaps/stars/tkabber/toolbar-show-online.gif0000644000175000017500000000022110563064247023344 0ustar sergeisergeiGIF89aÂÿžÿ®ÿ¾ÿÎÿÞÿîÿÿççç!ù ,VxºÜþ0ÊI«½8ë}Þ¤C߬ ´BP­Cm×±% Dï.¯@,€˜¡Á`d”Ì#fG(6ƒª¯‡œín¶eÕzµd¢“‰”Š„ÜmŽ|~I;tkabber-0.11.1/pixmaps/stars/tkabber/toolbar-disco.gif0000644000175000017500000000025410563064247022211 0ustar sergeisergeiGIF89a€ZÿÌÿÿ~ÿÀÿæÿÿÌÿ!ù ,qxºÜþ0‚ ¢=@èz_Ö×1(ޏ¡T¹Ž@0©!ÜîiÅ7þvN6 ž°x9 …I×DB ¡¬ú,` Q*׋…&u'\@ŒÏ¯™ð"åH:êˆwïïyupyt„nˆ(ƒƒŒ( ;tkabber-0.11.1/pixmaps/stars/docking/0000755000175000017500000000000011076120366016757 5ustar sergeisergeitkabber-0.11.1/pixmaps/stars/docking/available-xa.gif0000644000175000017500000000055110563064247022002 0ustar sergeisergeiGIF89a¥+rž{¤|¥}¦ˆ­Š®²‘³’´–·—·˜¸›ºœ»»ž¼¥Á¦Â§ÂªÄ«Å±É²Ê³Ê¶Ì¸Î¹Ï»Ð¼Ñ¾Ò¿ÓÄÖÄ×ÇØÇÙÌÜÑßÓáÔáÖâÚåÜçàêËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊ!þCreated with The GIMP!ù?,mÀŸpH,È$™T6JFBшX:H†@88(™@„$Aa!Á|Jã!DA Ömœ,œ4c|? ‡qBc‘c&*C˜‡"$)E‘ !#&¢I%%'(›J±²DA;tkabber-0.11.1/pixmaps/stars/docking/available-dnd.gif0000644000175000017500000000055110563064247022137 0ustar sergeisergeiGIF89a¥-s|}‡ˆ‰”•–™š›¢£¥¦§¬­®¯°²³µ¶¸¹½¾¿ÀÄÈÊËÌÍÐÑÒÓÖËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊ!þCreated with The GIMP!ù?,mÀŸpH,È$òñT6ʆBÑxP:ÈÆ¡P84$™@|$!ñ¸|Jã¡ã¬œ,Œ0  c|?  ‡qBc‘c%,C˜‡ #+E‘ "$*J$$&(›J±²DA;tkabber-0.11.1/pixmaps/stars/docking/message-personal.gif0000644000175000017500000000023710563064247022722 0ustar sergeisergeiGIF89aã ÿ•ÿšÿ«ÿµÿ¶ÿÁÿÑÿ×ÿìÿíÿÿÿÿÿÿ!ù ,LðÉI«½8ëÙÖ0ÆNƒ¡š§h å)¥o¢Ž` ¯D¿Ñ%Ÿ0ãÉ@PöÂcáðdœ‡U€”n™g,“›ç´zÍžD;tkabber-0.11.1/pixmaps/stars/docking/message-server.gif0000644000175000017500000000026710563064247022410 0ustar sergeisergeiGIF89aã ‚Š¡°±À×ßþÿÿÿÿÿÿÿ!þCreated with The GIMP!ù ,KðÉI«½8ëÂØÖ0ÆNƒ¡š§h å)¥o²²Y ßâF—= `v“  ì!(‚ÆÂÁ¹4‰©àÕ.'MîW"3Íè´z=‰;tkabber-0.11.1/pixmaps/stars/docking/available-away.gif0000644000175000017500000000055210563064247022334 0ustar sergeisergeiGIF89a¥.²“µ•¶š¹œ»Ÿ½¤À¨Ã©Ã©Ä«Å°É±É³Ë´Ë·Í·ÎºÐ½Ñ¾ÒÄÖÅׯ×ÇÙÈÙÉÙÉÚÊÚÑßÒàÓáÖã×ãØäÙäÝçÞèßéåíæíçîèïòöô÷õøÿÿËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊ!þCreated with The GIMP!ù?,nÀŸpH,È$ò‚¡HJÎÔÉHHÎÈt"u*C«E¼|Lª*¤‰(ã!tZ±R¢NR:$()%c}?-!"ˆqBc ’cC™ˆ E’ £IœJ²³DA;tkabber-0.11.1/pixmaps/stars/docking/available-chat.gif0000644000175000017500000000055210563064247022312 0ustar sergeisergeiGIF89a¥7ÿ‹ÿÿ‘ÿ’ÿ•ÿ—ÿ˜ÿ™ÿ›ÿŸÿ ÿ¤ÿ¥ÿ¦ÿ§ÿ©ÿ­ÿ®ÿ¯ÿ°ÿ±ÿ²ÿ³ÿ´ÿµÿ·ÿ¸ÿ¹ÿºÿ»ÿ½ÿÂÿÃÿÄÿÆÿÇÿÈÿÉÿÐÿÑÿÒÿÕÿÖÿ×ÿØÿÜÿÝÿßÿåÿæÿçÿòÿóÿõÿÿËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊ!þCreated with The GIMP!ù?,nÀŸpH,È$’D y*ÊÓŠ…*y$È“+&{¡B˜†ÍF©`´šŒEÚ<ã¡(›Ñb+’æ~L-00.' cdB6"&)*'ˆ}?c’cC™ˆ E’ £IœJ²³DA;tkabber-0.11.1/pixmaps/stars/docking/invisible.gif0000644000175000017500000000055010563064247021437 0ustar sergeisergeiGIF89a¥%‹‹ŠŽŽŽ‘‘’’’””“–––™™™››šžžžžžŸŸŸ  Ÿ¡¡¡¢¢¡£££¥¥¤¦¦¥©©¨©©©ªª©««ª¬¬«¬¬¬°°°±±°²²±´´³µµ´··¶¸¸·¹¹¸¼¼»½½¼½½½ÄÄÃÅÅÄËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊËËÊ!þCreated with The GIMP!ù?,lÀŸpH,È$²R‘@JÌf“±@HLòd&C©D¬l@£Qˆcy ã¡Mq.n8Y(ÉxB"c{?%†qBc cC—† E¡IšJ°±DA;tkabber-0.11.1/pixmaps/stars/docking/available.gif0000644000175000017500000000055310563064247021376 0ustar sergeisergeiGIF89a¥>ÿÿ†ÿ‰ÿŠÿÿ“ÿ”ÿ•ÿ–ÿ˜ÿ™ÿšÿ›ÿžÿŸÿ¢ÿ£ÿ¤ÿ§ÿ¨ÿ©ÿ«ÿ¬ÿ®ÿ±ÿ²ÿ³ÿ´ÿµÿ¶ÿ·ÿ¸ÿ¹ÿºÿ¼ÿ½ÿ¿ÿÀÿÁÿÂÿÃÿÄÿÆÿÉÿÊÿËÿÌÿÏÿÐÿÑÿÒÿÓÿÔÿ×ÿÜÿÞÿßÿàÿáÿåÿçÿëËËÊËËÊ!þCreated with The GIMP!ù?,oÀŸpH,È$Òã ™XÊËdbá”\ÈËc¡pT>*@ìL„"¢9ÅrãaG’ Œ †‹ A  )cdB%‰~?c+$“c7=Cš‰+26¡©rid6”à!,v$;tkabber-0.11.1/pixmaps/stars/roster/available-dnd.gif0000644000175000017500000000020410563064247022032 0ustar sergeisergeiGIF89aÂs…— ¨ºË Ý&&ÿ33!ù,IxºÜjÆ1øŠu¶DUˆ'ÊGL7œè96Ä ¼ð²n`‚,Õ€’Ï—“´·ßŒq„½t¥V µZt>¡©rid6”à!,v$;tkabber-0.11.1/pixmaps/stars/roster/conference-available.gif0000644000175000017500000000030610563064247023377 0ustar sergeisergeiGIF89aã ÿðâ&ŽÔ<ÆYÆ\Nœ¸„“ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!þCreated with The GIMP!ù,ZðÉùÆ ˜ž}²äG"& 6"(2vSˆEa ¤‰DNÌõ—ÜP@(¨:W!ˆFRò·œÐãÃ…žE­( ÷ƈeX쥣"Ö‡ó;r<Û8³ñD;tkabber-0.11.1/pixmaps/stars/roster/available-away.gif0000644000175000017500000000023510563064247022232 0ustar sergeisergeiGIF89aÂrž‰®¡¾¸ÎÐÞçîÿÿ@|!þCreated with The GIMP!ù,IxºÜ À1ø‚u6D„Ê'L7œè96Â@¼ð²na„,Õ†’Ï—“´·ßŒq„½t¥V µZt>¡©rid6”à!,v$;tkabber-0.11.1/pixmaps/stars/roster/group-opened.gif0000644000175000017500000000017210563064247021757 0ustar sergeisergeiGIF89aã TTTjjjpppvvv|||‚‚‚¯¯¯µµµºººóóóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù ,'ðÉI«½8ëÍ+ø`X@`žÁxÂ@†Š’È àßýÀ ð;tkabber-0.11.1/pixmaps/stars/roster/available-chat.gif0000644000175000017500000000023510563064247022210 0ustar sergeisergeiGIF89aÂÿžÿ®ÿ¾ÿÎÿÞÿîÿÿÿ€!þCreated with The GIMP!ù,IxºÜ À1ø‚u6D„Ê'L7œè96Â@¼ð²na„,Õ†’Ï—“´·ßŒq„½t¥V µZt>¡©rid6”à!,v$;tkabber-0.11.1/pixmaps/stars/roster/invisible.gif0000644000175000017500000000023510563064247021337 0ustar sergeisergeiGIF89aˆˆ‡˜˜—§§§···ÇÇÇ×××çççhhg!þCreated with The GIMP!ù,IxºÜ À1ø‚u6D„Ê'L7œè96Â@¼ð²na„,Õ†’Ï—“´·ßŒq„½t¥V µZt>¡©rid6”à!,v$;tkabber-0.11.1/pixmaps/stars/roster/available.gif0000644000175000017500000000023510563064247021273 0ustar sergeisergeiGIF89aÂÿÿÿžÿ®ÿ½ÿÍÿÜÿ€!þCreated with The GIMP!ù,IxºÜjÆ1øŠu¶DUˆ'ÊGL7œè96Ä ¼ð²n`‚,Õ€’Ï—“´·ßŒq„½t¥V µZt>¡©rid6”à!,v$;tkabber-0.11.1/pixmaps/stars/roster/stalker.gif0000644000175000017500000000020410563064247021014 0ustar sergeisergeiGIF89aŸ>Ÿ¯^¯¿~¿ÏžÏß¾ßïÞïÿÿÿÿÿÿ!ù,IxºÜ À1ø‚u6D„Ê'L7œè96Â@¼ð²na„,Õ†’Ï—“´·ßŒq„½t¥V µZt>¡©rid6”à!,v$;tkabber-0.11.1/pixmaps/stars/roster/group-closed.gif0000644000175000017500000000017310563064247021757 0ustar sergeisergeiGIF89aã TTTlllqqqvvv{{{€€€¬¬¬±±±¶¶¶ëëëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù ,(ðÉI«½8g +à`7 å Gz¢¸^P$tmä5ïùžp(‰;tkabber-0.11.1/pixmaps/stars/roster/unavailable.gif0000644000175000017500000000023510563064247021636 0ustar sergeisergeiGIF89aÂgggxxw‰‰ˆ™™˜ªª©ºººËËÊhhg!þCreated with The GIMP!ù,IxºÜjÆ1øŠu¶DUˆ'ÊGL7œè96Ä ¼ð²n`‚,Õ€’Ï—“´·ßŒq„½t¥V µZt>¡©rid6”à!,v$;tkabber-0.11.1/pixmaps/stars/roster/conference-unavailable.gif0000644000175000017500000000026010563064247023741 0ustar sergeisergeiGIF89aã TTTeeeuuu………†††•••–––¦¦¦¶¶¶ÆÆÆÖÖÖççççççççççççççç!ù,]ðÉù”¢˜¦²ä "" 6è1vSˆEa ¤yÄ0sý!7‚`( T…«0ÁàHR™N¨”ÚqáèÙ~·ä2Š9NÿD‡˜JÄúp€HŽçòí[u;tkabber-0.11.1/pixmaps/stars/icondef.xml0000644000175000017500000001365010572331547017504 0ustar sergeisergei Stars 1.0 Tkabber's Stars Iconset. Serge Yudin 2006-09-11 toolbar/add-user tkabber/toolbar-add-user.gif toolbar/disco tkabber/toolbar-disco.gif toolbar/join-conference tkabber/toolbar-join-conference.gif toolbar/show-offline tkabber/toolbar-show-offline.gif toolbar/show-online tkabber/toolbar-show-online.gif browser/client roster/available.gif browser/user roster/available.gif browser/conference roster/conference-available.gif browser/headline services/rss_online.gif docking/chat docking/available-chat.gif docking/available docking/available.gif docking/away docking/available-away.gif docking/xa docking/available-xa.gif docking/dnd docking/available-dnd.gif docking/invisible docking/invisible.gif docking/unavailable docking/unavailable.gif docking/message docking/message.gif docking/message-personal docking/message-personal.gif docking/message-server docking/message-server.gif roster/user/chat roster/available-chat.gif roster/user/available roster/available.gif roster/user/away roster/available-away.gif roster/user/xa roster/available-xa.gif roster/user/dnd roster/available-dnd.gif roster/user/invisible roster/invisible.gif roster/user/unavailable roster/unavailable.gif roster/user/unsubscribed roster/stalker.gif roster/user/error roster/unavailable.gif roster/conference/available roster/conference-available.gif roster/conference/unavailable roster/conference-unavailable.gif roster/group/closed roster/group-closed.gif roster/group/opened roster/group-opened.gif services/rss/away services/rss_away.gif services/rss/chat services/rss_chat.gif services/rss/dnd services/rss_dnd.gif services/rss/unavailable services/rss_offline.gif services/rss/available services/rss_online.gif services/rss/xa services/rss_xa.gif chat/bookmark/red tkabber/chat-bookmark.gif chat/bookmark/green tkabber/chat-bookmark1.gif xaddress/info tkabber/xaddress.gif tkabber-0.11.1/pixmaps/feather22/0000755000175000017500000000000011076120366015767 5ustar sergeisergeitkabber-0.11.1/pixmaps/feather22/roster/0000755000175000017500000000000011076120366017305 5ustar sergeisergeitkabber-0.11.1/pixmaps/feather22/roster/available-xa.gif0000644000175000017500000000052710110221066022311 0ustar sergeisergeiGIF89aò333UUU«««ÿÿÿÿÿÿ!ù,þhff†fff83f†fffhff†f6fhfF„Dffhff†fffHDD‚fffhffƒcFDHDb†fffh6f†DDD(ff†ff6hfD„DDbhff†f6fHDE„$ffhff†fFDXD$†fffhff†FTD(ff†ffF„EDbhFf†QUhFE„$f3hfQ…UUAX$$†fffUR…R%hff†6fQ(%R‚bfh63†fQRXURfffhff†%U(`†fffhff%URff†fffhf…"fhff†fffh%‚ffhff†fff €fffhff†ffHb†fffhff†fff†fffhf–;tkabber-0.11.1/pixmaps/feather22/roster/available-dnd.gif0000644000175000017500000000063110110221066022442 0ustar sergeisergeiGIF89aó333fffƒa ÿÿÿÿÿÿÿÿÿ!ù,þ!„B!„Æ€!„B!„D!4B!! !„B!BHˆR @!ˆB¡1¥ÀR @!„B„(¥”B!„B!$J¥”B!„D!QÊ)¥„ B!„BH”O) „B!ˆBH”S @A„B!„€*žR @ „P0Ð*§”‚c „‚1Æ<€B¡` !ÆcÂ!B¡`ˆ!Äh@!4Æ@Á`ˆ1ÆB"„B¡`ˆ1˜B!„‚¡`ˆ1Ä„D!„B¡` G!& „B!B¡`1!ˆB!„BAÂ!„B"„B€!„B!„‚¡@@!„D!„Š;tkabber-0.11.1/pixmaps/feather22/roster/available-away.gif0000644000175000017500000000052710110221066022642 0ustar sergeisergeiGIF89aò333QQQfff)%¿ÿÿÿÿÿÿÿ!ù,þxww‡www83w‡wwwxww‡w7wxwG„Dwwxww‡wwwHTU€wwwxwwƒsGUXUp‡wwwx7w‡TUUww‡ww7xwT…UUpxww‡w7wHUV…wwxww‡wGUhU‡wwwxww‡WeUww‡wwW…VUpx7w‡afxWV…w3xwa†ff1h‡wwwfb†b&xww‡7wa(&b‚pwx73‡wabhfbwwwxww‡&f(q‡wwwxww&fbww‡wwwxw†"wxww‡wwwx&‚wwxww‡www €wwwxww‡wwhr‡wwwxww‡www‡wwwxw—;tkabber-0.11.1/pixmaps/feather22/roster/available-chat.gif0000644000175000017500000000052710110221066022620 0ustar sergeisergeiGIF89aòfff)%¿ÿÿÿÿÿÿ!ù,þXUU…UUUU…UUUXUU…UUXU%‚"UUXUU…UUU(23€UUUXUUQ%383P…UUUXU…233UU…UUXU2ƒ33PXUU…UU(34ƒUUXUU…U%3H3…UUUX…%C3UU…U@HDƒ43PXU…@DDHD0ƒUXU@„DH…UUUX@D„DDDPU…U@HD@„@DX…U@DH@„DUXUU…@DHD„UUXU„DDHD€UUUXU@„@DHU…UUUX@D€@DUU…UUUDD„DUXUU…UUDD€PUUXUU…UUU…UUUXU•;tkabber-0.11.1/pixmaps/feather22/roster/invisible.gif0000644000175000017500000000050110110221066021737 0ustar sergeisergeiGIF89añˆˆˆÿÿÿ!ù,þ”(Q¢D‰F”(Q¢D‰%JT(Q¢Ä„ %J”(Q¢D‰JT(Q¢D‰FT(Q¢B‰%J”QbD‰#J”(Q¢B‰ %J”Q¢D‰JŒ(Q¢B‰%J”(Q¡D…#J”(Q¢D‰ %FT(Q¢D… #JŒ¨PbD‰%F”¨PbĈ %&”¨P¢D‰ %&Œ(Q¢Äˆ %FT¨P¢D‰ %FŒ˜P¡Âˆ%&Œ(1bD‰ J”(Q¢D‰ JŒ˜P¢D‰%JT¨PbĈ%J”(Q¢Äˆ J”(Q¢D‰%FL¨P¢D‰%J”(1a„%J”(Q¢D‰ %&”(Q¢D‰%JT˜0¢D‰%J”(;tkabber-0.11.1/pixmaps/feather22/roster/available.gif0000644000175000017500000000063110110221066021677 0ustar sergeisergeiGIF89aó333fff)%¿ÿƒa ÿÿÿÿÿÿÿÿ!ù,þ!„B!„„€!„B!„D!$B¡1à!„B!Bh B@!ˆB!!„@B@!„B „Ð „B!„B!4„B!„D¡AÈ!„„ B!„Bh! „B!ˆBhC@A„B!„€"B@ „P0Ð"‡‚B „‚1Æ<€B¡` )ÆcÂ!B¡`Š)Åh@!$„@Á`Š1ÆB"„B¡`Š1°B!„‚¡`Š1Å„D!„B¡``G)& „B!B¡`J1!ˆB!„BAD!„B"„B€!„B!„‚¡@@!„D!„Š;tkabber-0.11.1/pixmaps/feather22/roster/unavailable.gif0000644000175000017500000000052710110221066022246 0ustar sergeisergeiGIF89aò333UUU¬¬¬ÿÿÿÿÿÿ!ù,þhff†fff83f†fffhff†f6fhfF„Dffhff†fffHDD‚fffhffƒcFDHDb†fffh6f†DDD(ff†ff6hfD„DDbhff†f6VHDE„$ffhff†f6DXD$†fffhff†FTD(ff†ffF„EDbhFf†ADhFE„$f3hfA„DDAX$$†fffDB„B%hff†6fA($B‚bfh63†fABHDBfffhff†$D(`†fffhff$DBff†fffhf„"fhff†fffh$‚ffhff†fff €fffhff†ffHb†fffhff†fff†fffhf–;tkabber-0.11.1/pixmaps/feather22/icondef.xml0000644000175000017500000000246410366753724020141 0ustar sergeisergei Feather 22 1.0 Tkabber's Feather 22 Iconset. 2006-01-21 roster/user/chat roster/available-chat.gif roster/user/available roster/available.gif roster/user/away roster/available-away.gif roster/user/xa roster/available-xa.gif roster/user/dnd roster/available-dnd.gif roster/user/invisible roster/invisible.gif roster/user/unavailable roster/unavailable.gif roster/user/error roster/unavailable.gif tkabber-0.11.1/pixmaps/default-blue/0000755000175000017500000000000011076120366016556 5ustar sergeisergeitkabber-0.11.1/pixmaps/default-blue/docking/0000755000175000017500000000000011076120366020174 5ustar sergeisergeitkabber-0.11.1/pixmaps/default-blue/docking/tkabber.ico0000644000175000017500000004771610607765131022325 0ustar sergeisergei°h¶hh† hîhVh¾h&"hŽ'hö, ¨^2 ¨; ¨®C(VL(~M(¦N( ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ( tŸ-¿" Ã*Ä/È3Í箥íÁ»öÄ´ïÇÀñÉÂõÌÁòÌÅóÏÇõÒÉ                ûÿùÿùÿðÿàà?à?à?àððøøüþÿ( tŸ-¿" Ä/Æ=)ÎA&ÒG)ÊG3ØR2ÙU5ÛY8Ý]<ß_>箥íÁ»öÄ´ïÇÀñÉÂõÌÁòÌÅóÏÇõÒÉÿÿÿ                 ûÿùÿùðàààààððøøüþÿ(  tf aŸ-¿" Ä/Æ=)ÎA&ÒG)ÊG3ØU5ÙU5ÛY8Ý]<ß_>箥íÁ»öÄ´ÝÛïÇÀñÉÂõÌÁòÌÅóÏÇééììõÒÉîîððóó÷÷ÿÿÿÿRÿÿ[ÿÿ—ÿÿ¶ÿÿÿÿÿ   ### %(%#')'# "$&$!  ûÿùÇùƒðƒàààààððøøüþÿ(  iŽÄÍèßòÿÿÆ##ÌÙ##Óÿ##ãÿô##ë##ÿ''ÿ++ÿ<<Ø<<æ33ÿ<<í66ÿ99ÿ;;ÿAAÿ‘‘㉉ÿššÿ¦¦êªªîªªñªªôªª÷ªªûÿÿÿ '''''' ! ''' "'''''' ## ''$''''''%&&   ûÿùÿùðàààààððøøüþÿ( :::MMMNNNOOOPPP^^^```uuu¢¢¢¤¤¤¦¦¦¬¬¬±±±²²²³³³´´´¶¶¶···¸¸¸¼¼¼ÄÄÄÇÇÇÈÈÈÉÉÉËËËÐÐÐÑÑÑÓÓÓÖÖÖ×××ÚÚÚÜÜÜÝÝÝÿÿÿ""""""  """ """""""" """"""    !!!!ûÿùÿùðàààààððøøüþÿ( :::OOObbbfffhhhjjjoooqqqtttvvvxxxyyy€€€„„„………‡‡‡‰‰‰‹‹‹ŒŒŒ‘‘‘“““———™™™ššš²²²¾¾¾ÁÁÁÅÅÅÆÆÆÈÈÈÊÊÊÌÌÌ$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $$$$$$$$$ $$$$$$$$$! $$$$$$$$$" $$$$$$$$$## $$$$$$$$$  $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ûÿùÿùÿðÿàà?à?à?àððøøüþÿ( :::OOOVVVWWWXXXYYYZZZ[[[lllˆˆˆ¶¶¶···½½½ÃÃÃÆÆÆÇÇÇÈÈÈÊÊÊËËËÌÌÌÍÍÍÏÏÏÐÐÐÓÓÓÙÙÙàààâââäääæææèèèéééëëëíííîîîòòòóóóôôô÷÷÷ùùùûûûüüüþþþÿÿÿ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++  +++++++++ "+++++++++$+++++++++ #&+++++++++! '+++++++++$#%(++++++++++&'()*++++++++++()**+++++++++++++++ûÿùÿùÿðÿàà?à?à?àððøøüþÿ( ÿ=ÿ?ÿ?ÿ?ÿ@óCÿAÿBëFÿBÿD ÿE üG ÿGÿIÿIüKÿJùLÿM‚gÿNÿOÿPÿPÿQ¢eðTmpöTÁ`ÿRÿS\uÿU!²hÿZ'ÿZ(ÿ\*­n%÷^* s(¸p+Q†'ÿa1ôd1ÿb2ÿe6÷h7x„0E.8•. 4J’3T4ÿm@Ë{>ÿoCÿqF@:ÿsH«ŠFÉ„JÿxNaœBÿxOJ CJ¢D|˜H”IóRÿ|TP¤JV¤Lÿ€YN¨LU¦NV§Nÿ‚\†žVý…_ÿ†aL±Uÿˆdq«Xÿ‹gV²ZЍ^s­^ÿŽl¬¢dÿlV¶^®c`¶d\¸d[ºe`¹g`ºg†³jÿ–wÿ—wØ¢toºlXÀjÿšzÁªuaÂpmÂttÂwÿ¢†9Ônò¦…Ȳ‚iÈ|ÿ¥ŠhÉ{þ¦ŠkÉ|¨¼ƒlÊ~ê­‰~Ç€ø©ÿ©Žkσ̹¼ŒoІŠÊˆç·–ÿ±™¸Ã’rÖ¡Ë’tÖŽÿµžx֮ɘwØ’xØ“ö»¢ÿ¹¤ÿº¤ðÀ¥|Ü™þ½©üÀ¬Yë”àžÿÁ®ÿ®ÓΪƒâ¢±Ùª´ÙªÿÆ´…䦅æ§ÿÈ·ÿȸï͵ˆæªÂÙ±øË¾ÿ̼›å°òÏÄÀß·ÅÞ¸‘ë³ÿÓÆ•ï¸þÖÉÁ误¯¯¯¯¯¯¯¯¯¯¯¯¯¯'# ¯¯¯¯¯¯ "./EKB*¯¯¯¯$9AFg`VD(  ¯¯¯-)Js©£‚p†…m^I1Sƒ—¡®˜¦„‰vaM6!UŽ¥ “¨šŒxbL5¯J«¥–ˆ|~‹r_H2¯¯,nœŸ­¤udjl\C+¯¯¯OŠ’§{[J]R;¯¯¯¯3hqyiYN@@@çBàDÌ<'FFFGGGâOãOâP(AbJJJÛYÛbÛcWWWÕk6PtXXX,O|ÕtÔv]]]Ãm#Άφggghhh`iulllNf…É—ªcurrrao‚NltttuuuNn“vx|~~~ `édÞg솆†'rÛlîX€¯3wÏŠŠŠ$rà‹‹‹rñ’…¬'{ç'|ç"xô’†°5äb¾3„ê5„ê*€ø.„ú<Ší0‡û?ŒíNŽå3‰ü4Šý5Œý6þG’ï7ŽþN˜ñW˜îP˜ñTœóXžóZ ôa¤ög¦ñf¨÷k¬ùx¯ðm­ùq°úu²ûw´ümmmmmmmmmmmmmmmmmmmmmmmmmm m)mmmm(! %.8<@m+'  %.7;@Em2,# "-0/5:Gmm*IM3mm4$AF1mmmmW^_mmmmm?=>mmmPKJmmmmmmmBHLmmb`\VTmmmmmmRSUXmgfdcammmmmYZ[]mlkjiemmmmmQN&DmhO69CmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmÿÿÿÀƒÃããáÁÁÁãƒÿÇÿÿ( @ÿ=ÿ?ÿBéHÿHçLÿB¬ZÿRõT´[ ÿM6u ¶ddn…dLsþH'õQÿXôY¯jÓ]ÿR&/„qƒo"?jzÿ\#Èf+þX3±r¤p(ÿ_*A‰!‡x*m„"™y(ÿc2D&Èt,Ðm7;‘'èi7Þl:)–+ÿm0F5^Ž.t‹,ÿi=K”0E”5;˜4R”7ßtCCš2H—8&¥)ÿt=ÿpGFœAI :y–?ÿzFÿvOD¢?Q¢C…•J;¨A‚™GH¦DÁŒL°ŽO¬NÿOÿ}WO¦LÚ‰Ub¥K9®Kî‡[SªPÿƒ^G­OMªSÄ•ST¬Rªš[R±Pÿ‰cÓ–Z£\˜¢[ä’`S±Ze¯XHµZøf° aU´]Q·Y8¾WE»YX¸Xþp]¶\ÿ‘j!ÇRh±d^µeY¸aUºfQ¿dÿ•wÿ™q^½fõ™vÀ§u_½oþšzZÀlŒµqؤx»¨{¸­s¢°wPÅmnÀmÿ}É©{dÄm^Äpz½uó¤|XÅt@ÏkþŸ†ÿ¤‚Ú­~mÆugÆxİ„-ÚidËwø§‰þ¦‹²¹„ͲŠð¬nÍÿªh΂É„ÿ­ÝµŒþª–uÍ…qωÿ°“mÔˆtԆƽšÿ²›úµšuÔŽ’ÐŒq׋Rà…žÍ”ñ¸Ÿrד컞6ê…yØ’±Ë™ÿ» ÿ¸¦ÞÁ¡ÔĤ}Ü–“ÕxÞšþ¾¨ÙœŠÜ˜ó¾²†Þ¹Ó¡ÿÁ¬‚á›êƪñǦöïþó`후â¤<ø–ÿƶÿË·×Ô´âиæ®ÿɾçÌÁ²à®ÓسÄݳŒë­ýÏ¿‡í°ÐÛ¹ŽëµòÏÈ–í´ÿÓÃÚÝÀüÔÈ“ò»ô£ùȵöÌòèçðóñøûùââââââââââââââââââââââââââââââââââââââââââââââââââââââââ ââââââââââââââ -25+$âââââââââââ"',DN??:& âââââââââ"3333K`VSVND âââââââ 33==BB^qek`SN) ââââââ35#âââL‚²ÌÈØÇ¾Ã¸¤›ŠŠs”¡—zq`N95# ââââ3j‹±ÌÇÃÚáàÖ‹sl[_{zeeV>+âââââ!J}£À²¸¾ÚßßÍ‚sjTMdˆqZH++ââââââ 5n𹳤 ¤¤»“sj[TAYrfUC6âââââââ>pžª‹‹“‹yyj[TA=YhbF7 âââââââââ.Q€|°vsl[[TMQgÑjØmZZZ*P‚ÔvOšÑbbb°Ms·Έɉiiijjjˑƕ©elpppÈ™Zk„Èš+aªqqqMlÆŸ&b³0f¬Pn‘_Åvvv¥bwwwVäWåYå{{{[æSu€€€ aé m bꃃƒfë3tÈh쇇‡jík‰qãŠŠŠ‹‹‹sänïtäoŒuä4zÕqñ wå!wåtòuò)yè'{ç(|ç"wô#xô+~è,è%zõ4ã-€è%{öe½'}ö0‚ém‰Ç(~÷3„ê)€÷5…ë+ø+‚ø-ƒù9ˆì-„ù:‰ì.…ú‘Æ/…ú0†û>‹í1‡û?Œí1ˆû2ˆü@î2‰ü3‰üBŽî3ŠüDî4‹ý5Œý6þ7þF’ï7Žþ7ŽÿH“ï8Žÿ8ÿI”ðt–ÝašÞK•ðmÕM–ñO—ñQ™òSšòS›óT›óUœóVóWžóYžô[ ô\¡õ^¢õ_£õ`¤öa¤öb¥öc¦÷d¦÷e¨÷f¨÷h©øhªøiªøj«øk¬ùl¬ùm­ùn®ùo®úp¯úq¯úq°úr°úr±ûs±ût²ûu²ûu³ûv³üw´üxµüyµüz¶ü{·ý|¸ý}¸ý¹þºþÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ+$ ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ741*" Ü .5:@IRÜÜÜÜ<9741*"  .5:@DPVY]ÜÜA=9741*"  .5:@DPVY]adÜEA=9740)#  .5:@DPVY]adfÜÜGA=9740)# !.5:@DPVY]adfgÜÜKGA=3,&%)# ÜÜ5:?DPVY]adfglÜÜÜK>QŽŽ[;ÜÜÜ:?DP(-//IlÜÜÜÜÜBCÁÁÁÁÁ§#ÜÜÜÜÜÜP8‡‡‡‡LDÜÜÜÜÜÜÜÜ‚¯¯¯¯¯ÜÜÜÜÜÜÜÜÜOrrrrFÜÜÜÜÜÜÜÜhep}“–ÜÜÜÜÜÜÜÜÜÜÜÜÜ`\TSUÜÜÜÜÜÜÜ„zuqjmÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜWZ^ckÜÜÜÜÜ£›“Œ†yvÜÜÜÜÜÜÜÜÜÜÜÜÜbiosx~ƒÜÜÜܲ®¬© ™‘ŠÜÜÜÜÜÜÜÜÜÜÜÜÜw{€…ˆ‹ÜÜÜÜ»¸¶´±­«¦ ÜÜÜÜÜÜÜÜÜÜÜt‡‰”—šÜÜÜÆÄ¿½º·µ³°ÜÜÜÜÜÜÜÜÜÜÜH’•˜šœžÜÜÏÍÊÈÆÃÀ¾¼¹ÜÜÜÜÜÜÜÜÜ6œžžž¡¡ÜÜÕÔÓÑÎÌÉÇŨÜÜÜÜÜÜÜÜÜžžŸ¡¢¢¤¥ÜÜÙØ×ÖÕÓÒÐÎËÜÜÜÜÜÜÜÜÜ|¢¢n MMÜÜÛÚªN'''2XJÜÜÜÜÜÜÜÜÜ_M ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÿÿÿÿÿÿÿÿÿÿÿÿÿÀÿÿ€€€€ÀàððàüÀÿþ€ü€ü€?ø?øðððððø€üÀÿÿà?ÿÿüÿÿÿÿÿÿÿÿÿÿÿÿÿ( @ææ!æ"æ#æ$æ&Ó)æ'æ(æ+é,æ-æ.æ/æ0æ1æ3æ4æ6æ7æ8æ9æ:æ<ì;æ=æ>æ?æ@æAæBæCïCõBæE=ZæFèFæGñEæHîGæIïHëIæJæKæLæMçMéMæOæPæQäRæRÑVóPÓVÚUæSÿOæTâUàVæUÙXßSæVÿRåXæXæYüUìXøVÿUÿVæ[à]æ\ýXöZö[æ_æaæbÀgæcÜ\æd;QeåeæeÒbægÿ[ÿcæhãjæjælçlÔnænên®kæoæpæqæsÙ^0ÎmÖkÓzæyÕmæzëe*ÿtåÑu%Æs/ÿv/ós?ÿy/§|Uÿ/ó}:·~Pÿƒ/þˆ.Ƀ\ø‡Oÿ‰O÷‰_ø‰_þ–fµ—…ª™ý¤]Á§”æ¬ÿ¨ݬ‘á²ì±”é¶ÿÉŸÐÇÂÑÉÃÕÌÈòÕ¿ÿÓ¿ûÜÏÿêßÿìßøïéýóïõóòûôïÿôïöõóÿÿÿ¤¤¤¤¤¤#¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤#¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤#¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤##¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤##¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤#[rnU<¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤‹jubG-¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤cŠxmT4"¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤Z„•yZ>&¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤7UY—‘O<&¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤&U\ŸqF/¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤Pep¢ŽB<&$¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤>Xn~ ^@/.¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤0NdW–“:6$&5¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤$0>vžLJGHGA.>¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤0(/2|£†Q1/..-/>¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤&&.)‡¡{K.0¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤"*'ˆ¡}9 3¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤%!‰›‚ "¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤,Mœƒ .¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤.+aw”€.¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤.SŒo *¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤  .¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤. "/¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤.".¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤.-&"$*/¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ýÿÿÿýÿÿÿýÿÿÿüÿÿÿüÿÿÿüÿÿþÿÿüÿÿüÿÿøÿø?ÿôÿüÿüÿüÿüÿüÿüÿþÿþÿÿÿ€?ÿ€ÿÀÿàÿðÿøÿüÿþÿÿ€ÿÿà?ÿÿÿÿ( qqquuu{{{………ˆˆˆŠŠŠ¶¶¶ººº¼¼¼¾¾¾ÂÂÂÅÅÅÉÉÉÍÍÍÿeT3"!ÿÿjª˜ˆwpÿÿjUUUwpÿÿkUUUWpÿÿkUUˆ‡pÿÿkUUUˆpÿÿl»ºªˆ€ÿÿlUUUY€ÿÿmUU»ªÿÿmUUUº ÿÿmUUU[ ÿÿnUUÜ˰ÿÿnîÝṴ̈ÿÿnîíÕUÀÿÿnîîÝÝÀÿÿeT3"!ÿÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ( qqquuu{{{†††ŠŠŠµµµàààåååêêêíííñññõõõøøøüüüÿUD3"!ÿÿY™ˆˆwpÿÿYfffwpÿÿZfffgpÿÿZffˆ‡pÿÿ[fffˆpÿÿ[»ª™ˆ€ÿÿ\fffh€ÿÿ\ffª™€ÿÿ]fff©ÿÿ]fffjÿÿ^ff˺ ÿÿ^îÝÌË ÿÿ^îíÖf°ÿÿ^îîÝÌÀÿÿUD3"!ÿÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ( jvo|u‚y‡}Œ²Èïÿ&ïÿ.ïþ9ñþEñþUñþbòþkòþÿUD3"ÿÿZ™ˆ‡wpÿÿZfffwpÿÿ[fffgpÿÿ[ff™ˆpÿÿ[fff˜€ÿÿ\Ë»ª™ÿÿ\fffjÿÿ\ff»ª ÿÿ]fffº ÿÿ]fffk°ÿÿ^ffÌ»°ÿÿ^íÝḬ̀ÿÿ^îÝÖfÀÿÿ^îîÝÜÀÿÿUD3"ÿÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀtkabber-0.11.1/pixmaps/default-blue/docking/available-dnd.gif0000644000175000017500000000054010607765131023351 0ustar sergeisergeiGIF89a¥'i ŽÄÍèßòÿÿÆÌ##ÙÓ##ÿã##ÿôë##ÿ##ÿ''ÿ++Ø<<æ<<ÿ33í<<ÿ66ÿ99ÿ;;ÿAAã‘‘ÿ‰‰ÿššê¦¦îªªñªªôªª÷ªªûªªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù?,}ÀŸpH,Ȥr¹8Ì¢€Cå¢Bf»½Fʆ2ñ~!OÅan&4 MÑV "&SäPO %„…„~$'Ž~ ## †'‘H "ŽšG ! —„£J ¡¢¤HW††K·XF}½ÀÁÂGA;tkabber-0.11.1/pixmaps/default-blue/docking/available-away.gif0000644000175000017500000000055710563064247023556 0ustar sergeisergeiGIF89a¥7t$$$-Ÿ "¿////Ä<<<@@@)=Æ&AÎ)GÒNNNOOO3GÊ9NÍ2RØ:QÐ```bbb>_ßF]ÕCcàjjjMfÚUgÔQlÞqqqtttNséRvêatÛ|||}}}f|ß‚‚‚^…òd…ìbˆòq‰çk”úr”ôx”îsžÿ¥®ç»Áí´ÄöÀÇïÂÉñÁÌõÅÌòÇÏóÉÒõÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù?,ŒÀŸpH,Ȥr¹,8 Ìb¡Em ¢Â‚j»½F &Ô eò~A,ØécnbR³ÆÒV86GRO5$ %~ !47’“#~227 "7~1““~/œ’J. #©’KW% À}XÌXÏÐÑJA;tkabber-0.11.1/pixmaps/default-blue/docking/available-chat.gif0000644000175000017500000000056310563064247023531 0ustar sergeisergeiGIF89a¥7t-Ÿ "¿/Ä)=ÆGGG&AÎ)GÒ3GÊ.KÓ9NÍ2RØ:QÐ^]]>_ßF]ÕCcàMfÚUgÔQlÞNséRvêatÛf|ß^…òd…ìbˆòq‰çk”úr”ôx”îsžÿ¥®ç»Áí´ÄöÛÝÀÇïÂÉñÁÌõÅÌòÇÏóééììÉÒõîîððóó÷÷ÿÿÿÿÿÿRÿÿ[ÿÿ—ÿÿ¶ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù?,ÀŸpH,Ȥr¹8Ì¢D¢BAg»½F™g“ñ~-Ÿ‘¦bnF8'NäÑV (,…8˜) -.-v(0242/‹H && 15751—G %+363+¤F " 1º±G!W$*$¼½^ÊÆFfÉÌÍXÓÔÕÕA;tkabber-0.11.1/pixmaps/default-blue/docking/available.gif0000644000175000017500000000052010563064247022605 0ustar sergeisergeiGIF89a¥*t-Ÿ "¿*Ã/Ä3È!<Í)=Æ&AÎ)GÒ3GÊ.KÓ9NÍ2RØ:QÐ>_ßF]ÕCcàMfÚUgÔQlÞNséRvêatÛf|ß^…òd…ìbˆòq‰çk”úr”ôx”îsžÿ¥®ç»Áí´ÄöÀÇïÂÉñÁÌõÅÌòÇÏóÉÒõÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ!ù?,mÀŸpH,Ȥr¹ 8ÌbD¢Â@g»½F™g“ñ~-Ÿ‘¦bnF8&NäÑV(©¥QO( }H'†‡%%ŽG $•F " G!¤H©ª¬¥X°±²²A;tkabber-0.11.1/pixmaps/default-blue/roster/0000755000175000017500000000000011076120366020074 5ustar sergeisergeitkabber-0.11.1/pixmaps/default-blue/roster/available-dnd.gif0000644000175000017500000000052310607765131023252 0ustar sergeisergeiGIF89aÕ(ÿÿÿŽi ÿ33ÿ;;ñªªûªªÌ##Ùôÿ''ÿ##ÿÿ66æ<<ÄÍèã‘‘ÿ++í<<ò÷ªªôªªÿššÆÿAAã##ÿÿ‰‰Ø<<ꦦë##ÿÿ99ßÿÓ##!ù(,p@”p(Äd±À, ”Ca:}BŒiÁ°^;ÅäM ŽŒ£1*ŠÃAaqG%¢KÀïó£%†‡Q  …~‰E'!…‡†’( |šD˜™›BO~~I®PPvDA;tkabber-0.11.1/pixmaps/default-blue/roster/available-away.gif0000644000175000017500000000054410563064247023452 0ustar sergeisergeiGIF89aÕ8ÿÿÿ-Ÿtk”úsžÿOOO}}}NNNQlÞjjj<<_ß)GÒ&AÎRvêttt»Áíx”îÇÏóÀÇïF]Õbbb2RØ9NÍ|||!ù8,@œp( Äd‘À$”ÃÀ`:}BMJc±^[0ÐÇãM&™Rf¢*‰H$QsGW¢©@, Q,(!3Š‹Q  47 Q62'‹‹Q/& ”.Š D#¡ŠIO ¸vP8ÄCA;tkabber-0.11.1/pixmaps/default-blue/roster/available-chat.gif0000644000175000017500000000054710563064247023433 0ustar sergeisergeiGIF89aÕ8-Ÿt^]]ÿÿk”úsžÿGGGÛÝ^…òQlÞbˆòÿÿR:QÐÿÿ—3GÊÂÉñÉÒõîîììÿÿCcàq‰çÇÏóRvêÿÿÿF]ÕÀÇï&AÎd…ì "¿>_ßÿÿ¶.KÓ÷÷/Ä¥®çMfÚf|ß´ÄöÁÌõx”îÿÿ[UgÔéé9NÍatÛ)GÒÅÌò)=Æóó2RØððr”ôNsé»Áí!ù8,„@œp(ÄdÑÀ4”C@a:}B‰Em‘°^1©SÇæM*”¥ò)ŠHD1 JÀ«t1…4xo.0"*2„E  8-+# œ7±œB$1O,³´VÁ½8^ÀÃÄPCA;tkabber-0.11.1/pixmaps/default-blue/roster/available.gif0000644000175000017500000000050310563064247022506 0ustar sergeisergeiGIF89aÕ*t-Ÿk”úsžÿ)GÒbˆò3GÊQlÞCcàÉÒõÂÉñ^…ò:QÐq‰çr”ô3È2RØUgÔ/ÄÀÇïNs饮çf|ß´ÄöÅÌò*Ã9NÍ!<ÍÁÌõRvêx”î»Áí&AÎatÛ "¿d…ìMfÚF]ÕÇÏó)=Æ>_ß.KÓ!ù*,`@•p( ÄdqÀ”À`:}B‹‚£°°^;žËˆâM N*‡DâqG $“%E°A!%~E …*Œ"ŒB'šCŸ ¢›PCA;tkabber-0.11.1/pixmaps/default-blue/icondef.xml0000644000175000017500000000274710607765131020725 0ustar sergeisergei Default Blue 2.1a Tkabber's Default Blue Style 2006-09-19 Artem Bannikov docking/chat docking/available-chat.gif docking/available docking/available.gif docking/away docking/available-away.gif docking/dnd docking/available-dnd.gif docking/tkabber docking/tkabber.ico roster/user/chat roster/available-chat.gif roster/user/available roster/available.gif roster/user/away roster/available-away.gif roster/user/dnd roster/available-dnd.gif tkabber-0.11.1/messages.tcl0000644000175000017500000006631711011604626015047 0ustar sergeisergei# $Id: messages.tcl 1410 2008-05-11 14:58:30Z sergei $ namespace eval message { variable msgid 0 variable headid 0 variable options custom::defvar message_dest_list {} \ [::msgcat::mc "List of message destination JIDs."] \ -group Hidden custom::defgroup Messages [::msgcat::mc "Message and Headline options."] \ -group Tkabber disco::register_feature jabber:x:oob } proc message::process_message {connid from id type is_subject subject body err thread priority x} { switch -- $type { normal { show_dialog $connid $from $id $type $subject $body $thread $priority $x return stop } } return } hook::add process_message_hook \ [namespace current]::message::process_message 98 proc message::show_dialog {connid from id type subject body thread priority x {replyP 1}} { variable msgid if {$type == "normal"} { ::message_archive::log_message \ $from [jlib::connection_jid $connid] \ $subject $body $x } set mw .msgshow[incr msgid] toplevel $mw -class Message wm group $mw . if {$replyP} { set title [format [::msgcat::mc "Message from %s"] $from] } else { set title [format [::msgcat::mc "Extras from %s"] $from] } wm title $mw $title wm iconname $mw $title wm withdraw $mw frame $mw.bottom pack $mw.bottom -side bottom -fill x if {$replyP} { set bbox [ButtonBox $mw.bottom.buttons -spacing 10 -padx 10] $bbox add -text [::msgcat::mc "Reply"] \ -command [list message::send $mw -connection $connid] $bbox add -text [::msgcat::mc "Chat"] \ -command "chat::open_to_user $connid [list $from] destroy $mw" $bbox add -text [::msgcat::mc "Close"] -command [list destroy $mw] bind $mw "ButtonBox::invoke $bbox 0" bind $mw "ButtonBox::invoke $bbox 2" pack $bbox -side right -fill x -padx 2m -pady 2m } else { ButtonBox $mw.bottom.buttons -spacing 0 -padx 10 $mw.bottom.buttons add -text [::msgcat::mc "Close"] -command [list destroy $mw] bind $mw "ButtonBox::invoke $mw.bottom.buttons 0" bind $mw "ButtonBox::invoke $mw.bottom.buttons 0" } pack $mw.bottom.buttons -side right -fill x -padx 2m -pady 2m set sep [Separator::create $mw.sep -orient horizontal] pack $sep -pady 1m -fill x -side bottom frame $mw.frame pack $mw.frame -side top -fill both -expand yes -padx 2m -pady 2m label $mw.thread -text $thread if {$replyP} { set title [::msgcat::mc "Message from:"] } else { set title [::msgcat::mc "Extras from:"] } frame $mw.title pack $mw.title -side top -anchor w -fill x -expand yes -in $mw.frame grid columnconfigure $mw.title 1 -weight 1 if {[llength [jlib::connections]] > 1} { label $mw.title.lconnection -text [::msgcat::mc "Received by:"] label $mw.title.connection -text " [jlib::connection_jid $connid]" grid $mw.title.lconnection -row 0 -column 0 -sticky e grid $mw.title.connection -row 0 -column 1 -sticky w } label $mw.title.lab -text $title menubutton $mw.title.mb -text $from -menu $mw.title.mb.menu subject_menu $mw.title.mb.menu $connid $from message grid $mw.title.lab -row 1 -column 0 -sticky e grid $mw.title.mb -row 1 -column 1 -sticky w foreach tag [bind Menubutton] { if {[string first 1 $tag] >= 0} { regsub -all 1 $tag 3 new bind $mw.title.mb $new [bind Menubutton $tag] } } frame $mw.tspace pack $mw.tspace -side top -fill x -pady 0.5m -in $mw.frame frame $mw.rf grid columnconfigure $mw.rf 1 -weight 1 set row 0 if {$replyP || (![cequal $subject ""])} { label $mw.rf.lsubj -text [::msgcat::mc "Subject:"] entry $mw.rf.subj $mw.rf.subj insert 0 $subject if {[info tclversion] >= 8.4} { set bgcolor [lindex [$mw.rf.subj configure -background] 4] $mw.rf.subj configure -state readonly -readonlybackground $bgcolor } else { $mw.rf.subj configure -state disabled } grid $mw.rf.lsubj -row 0 -column 0 -sticky e grid $mw.rf.subj -row 0 -column 1 -sticky ew incr row } pack $mw.rf -side top -anchor w -fill x -in $mw.frame frame $mw.rspace pack $mw.rspace -side top -fill x -in $mw.frame -pady 0.5m incr row set last $row hook::run message_process_x_hook row body \ $mw.rf $x $connid $from $id $type $replyP if {(!$replyP) && ($row == $last)} { destroy $mw return } # Ignore messages with empty body and no (or unsupported, e.g. jabber:x:event) extras if {[cequal $body ""] && ($row == $last)} { destroy $mw return } ScrolledWindow $mw.rsw text $mw.rbody -width 60 -height 8 -wrap word ::richtext::config $mw.rbody -using {url emoticon stylecode} ::richtext::render_message $mw.rbody $body "" $mw.rbody configure -state disabled pack $mw.rsw -side top -fill both -expand yes -in $mw.frame pack $mw.rbody -side top -fill both -expand yes -in $mw.rsw $mw.rsw setwidget $mw.rbody if {$replyP} { button $mw.cite -text [::msgcat::mc "Quote"] -command [list message::quote $mw $body] pack $mw.cite -side top -anchor e -in $mw.frame frame $mw.f grid columnconfigure $mw.f 1 -weight 1 #label $mw.f.lto -text To: Entry $mw.f.to -dropenabled 1 -droptypes {JID {}} \ -dropcmd [list message::jiddropcmd] $mw.f.to insert 0 $from label $mw.f.lsubj -text [::msgcat::mc "Reply subject:"] entry $mw.f.subj regsub {(^Re: )*} $subject {Re: } subject $mw.f.subj insert 0 $subject #grid $mw.f.lto -row 0 -column 0 -sticky e #grid $mw.f.to -row 0 -column 1 -sticky ew grid $mw.f.lsubj -row 1 -column 0 -sticky e grid $mw.f.subj -row 1 -column 1 -sticky ew pack $mw.f -side top -anchor w -fill x -in $mw.frame frame $mw.space pack $mw.f -side top -anchor w -fill x -in $mw.frame -pady 1m ScrolledWindow $mw.sw pack $mw.sw -in $mw.frame -side top -fill both -expand yes textUndoable $mw.body -width 60 -height 8 -wrap word pack $mw.body -side top -fill both -expand yes -in $mw.sw bind $mw.body "ButtonBox::invoke $bbox 0 break" $mw.sw setwidget $mw.body focus $mw.body hook::run open_message_post_hook $mw $connid $from } BWidget::place $mw 0 0 center wm deiconify $mw } proc message::quote {mw body} { regsub -all {(^|\n)} $body {\1> } body $mw.body insert 0.0 $body $mw.body insert insert "\n" } proc message::process_x {rowvar bodyvar f x connid from id type replyP} { upvar 2 $rowvar row upvar 2 $bodyvar body foreach xa $x { jlib::wrapper:splitxml $xa tag vars isempty chdata children set xmlns [jlib::wrapper:getattr $vars xmlns] switch -- $xmlns \ jabber:x:oob { set row [process_x_oob $f $children $row $from] } \ $::NS(data) { if {![lempty $children]} { process_x_data $f $connid $from $xa } } \ } return } hook::add message_process_x_hook message::process_x 99 proc message::process_x_oob {f x row from} { set desc "" set url "" foreach item $x { jlib::wrapper:splitxml $item tag vars isempty chdata children switch -- $tag { desc - url { set $tag $chdata } } } if {[cequal $url ""]} { return $row } if {[cequal $desc ""]} { set desc $url } label $f.luser$row -text [::msgcat::mc "Attached URL:"] render_url $f.user$row $url $desc -bg [get_conf $f -bg] grid $f.luser$row -row $row -column 0 -sticky e grid $f.user$row -row $row -column 1 -sticky ew incr row return $row } proc message::process_x_data {f connid from x} { data::draw_window [list $x] [list message::send_x_data $connid $from] } proc message::send_x_data {connid to w restags} { #set f $w.fields #set restags [data::get_tags $f] jlib::send_msg $to -xlist $restags -connection $connid destroy $w } proc message::send_dialog_item {m connid jid} { $m add command -label [::msgcat::mc "Send message..."] \ -command [list message::send_dialog \ -to $jid -connection $connid] } hook::add roster_jid_popup_menu_hook message::send_dialog_item 15 hook::add message_dialog_menu_hook message::send_dialog_item 15 hook::add search_popup_menu_hook message::send_dialog_item 15 hook::add roster_create_groupchat_user_menu_hook message::send_dialog_item 15 package require sha1 proc message::generate_thread {from to} { return [sha1::sha1 $from$to[rand 1000000000]] } proc message::send_dialog {args} { variable msgid variable message_dest_list variable send_dialog_connid if {[lempty [jlib::connections]]} return set to "" set subject "" set group 0 set cstate normal foreach {opt val} $args { switch -- $opt { -to { set to $val } -subject { set subject $val } -thread { set thread $val } -group { set group $val } -connection { set connid $val set cstate disabled } } } if {![info exists connid]} { if {$group} { set connid [jlib::route ""] } else { set connid [jlib::route $to] } } set mw .msgsend[incr msgid] toplevel $mw -class Message wm group $mw . set send_dialog_connid($mw) [jlib::connection_jid $connid] if {![info exists thread]} { set thread [generate_thread $send_dialog_connid($mw) $to] } if {$group} { if {$to != ""} { set title [format [::msgcat::mc "Send message to group %s"] $to] } else { set title [::msgcat::mc "Send message to group"] } } else { if {$to != ""} { set title [format [::msgcat::mc "Send message to %s"] $to] } else { set title [::msgcat::mc "Send message"] } } wm title $mw $title wm iconname $mw $title wm withdraw $mw #frame $mw.subj #label $mw.subj.lab -text Subject: #entry $mw.subj.entry #$mw.subj.entry insert 0 $subject #pack $mw.subj.lab $mw.subj.entry -side left #pack $mw.subj -side top -anchor w frame $mw.bottom pack $mw.bottom -side bottom -fill x set bbox [ButtonBox $mw.bottom.buttons -spacing 10 -padx 10] $bbox add -text [::msgcat::mc "Send"] \ -command [list message::send $mw -group $group -connection $connid] $bbox add -text [::msgcat::mc "Cancel"] -command [list destroy $mw] bind $mw "ButtonBox::invoke $bbox 0" bind $mw "ButtonBox::invoke $bbox 1" pack $bbox -side right -fill x -padx 2m -pady 2m set sep [Separator::create $mw.sep -orient horizontal] pack $sep -pady 1m -fill x -side bottom label $mw.thread -text $thread frame $mw.frame pack $mw.frame -side top -fill both -expand yes -padx 2m -pady 2m frame $mw.f grid columnconfigure $mw.f 1 -weight 1 set connections {} if {[llength [jlib::connections]] > 1} { foreach c [jlib::connections] { lappend connections [jlib::connection_jid $c] } label $mw.f.lconnection -text [::msgcat::mc "From: "] ComboBox $mw.f.connection \ -textvariable [namespace current]::send_dialog_connid($mw) \ -values $connections \ -state $cstate grid $mw.f.lconnection -row 0 -column 0 -sticky e grid $mw.f.connection -row 0 -column 1 -sticky ew } if {$group} { # TODO reflect changes in connid label $mw.f.lto -text [::msgcat::mc "Group: "] ComboBox $mw.f.to -text $to \ -values [roster::get_groups $connid \ -nested $::ifacetk::roster::options(nested) \ -delimiter $::ifacetk::roster::options(nested_delimiter) \ -undefined 1] } else { label $mw.f.lto -text [::msgcat::mc "To: "] ComboBox $mw.f.to -text $to \ -dropenabled 1 -droptypes {JID {}} \ -dropcmd [list message::jiddropcmd] \ -values $message_dest_list } label $mw.f.lsubj -text [::msgcat::mc "Subject: "] entry $mw.f.subj $mw.f.subj insert 0 $subject grid $mw.f.lto -row 1 -column 0 -sticky e grid $mw.f.to -row 1 -column 1 -sticky ew grid $mw.f.lsubj -row 2 -column 0 -sticky e grid $mw.f.subj -row 2 -column 1 -sticky ew pack $mw.f -side top -anchor w -fill x -in $mw.frame frame $mw.space pack $mw.f -side top -anchor w -fill x -in $mw.frame -pady 1m ScrolledWindow $mw.sw pack $mw.sw -in $mw.frame -side top -fill both -expand yes textUndoable $mw.body -width 60 -height 8 -wrap word pack $mw.body -side top -fill both -expand yes -in $mw.sw bind $mw.body "ButtonBox::invoke $bbox 0 break" $mw.sw setwidget $mw.body if {$to != ""} { focus $mw.f.subj } else { focus $mw.f.to } hook::run open_message_post_hook $mw $connid $to BWidget::place $mw 0 0 center wm deiconify $mw } proc message::send0 {mw args} { variable send_dialog_connid foreach c [jlib::connections] { if {[jlib::connection_jid $c] == $send_dialog_connid($mw)} { set connid $c } } unset send_dialog_connid($mw) if {![info exists connid]} { eval [list send $mw] $args } else { eval [list send $mw -connection $connid] $args } } proc message::send {mw args} { variable message_dest_list set group 0 foreach {opt val} $args { switch -- $opt { -group { set group $val } -connection { set connid $val } } } set jid [$mw.f.to cget -text] if {$group} { set jids [roster::get_group_jids $connid $jid \ -nested $::ifacetk::roster::options(nested) \ -delimiter $::ifacetk::roster::options(nested_delimiter)] } else { set message_dest_list [update_combo_list $message_dest_list $jid 20] set jids [list $jid] if {![info exists connid]} { set connid [jlib::route $jid] } } set thread [$mw.thread cget -text] set subj [$mw.f.subj get] set body [$mw.body get 1.0 {end -1 chars}] foreach jid $jids { if {!$group || [::roster::itemconfig $connid $jid -isuser]} { send_msg $jid -type normal \ -subject $subj -body $body -thread $thread \ -connection $connid } } destroy $mw } proc message::send_msg {to args} { array set params [list -xlist {}] array set params $args set command [list jlib::send_msg $to] set xs $params(-xlist) unset params(-xlist) if {![info exists params(-connection)]} { set params(-connection) [jlib::route $to] } if {[info exists params(-body)]} { set log_body $params(-body) foreach tag [list signed encrypted] { if {[cequal [info commands ::ssj::${tag}:output] ""]} { continue } if {[catch { ssj::${tag}:output $params(-connection) $params(-body) $to } chdata]} { debugmsg message "ssj::${tag}:output: $chdata" return [list error ssj] } if {![cequal $chdata ""]} { lappend xs [jlib::wrapper:createtag x \ -vars "xmlns jabber:x:$tag" -chdata $chdata] if {[cequal $tag encrypted]} { set params(-body) [::msgcat::mc "This message is encrypted."] } } } } else { set log_body "" } if {[info exists params(-subject)]} { set log_subject $params(-subject) } else { set log_subject "" } if {[llength $xs] > 0} { lappend command -xlist $xs } foreach {k v} [array get params] { lappend command $k $v } eval $command if {(![info exists params(-type)]) || ($params(-type) == "normal") } { ::message_archive::log_message \ [jlib::connection_jid $params(-connection)] \ $to $log_subject $log_body $xs } return [list success $xs] } proc message::jiddropcmd {target source pos op type data} { set jid [lindex $data 1] $target delete 0 end $target insert 0 $jid } ############################################################################### proc message::show_subscribe_dialog {connid from type x args} { variable msgid if {$type != "subscribe"} return set status "" foreach {opt val} $args { switch -- $opt { -status { set status $val } default { debugmsg message \ "SHOW_SUBSCRIBE_MESSAGE: unknown option $opt $val" } } } set mw .subscshow[incr msgid] toplevel $mw -class Message wm group $mw . wm withdraw $mw set title [format [::msgcat::mc "Subscription request from %s"] $from] wm title $mw $title wm iconname $mw $title set bbox [ButtonBox $mw.buttons -spacing 0 -padx 10 -default 0] $bbox add -text [::msgcat::mc "Approve subscription"] \ -command [list [namespace current]::subscribe $mw $connid $from] $bbox add -text [::msgcat::mc "Decline subscription"] \ -command [list [namespace current]::unsubscribe $mw $connid $from] bind $mw "ButtonBox::invoke $bbox default" bind $mw "ButtonBox::invoke $bbox 1" pack $bbox -side bottom -anchor e -padx 2m -pady 2m set sep [Separator::create $mw.sep -orient horizontal] pack $sep -pady 1m -fill x -side bottom frame $mw.frame pack $mw.frame -side top -fill both -expand yes -padx 2m -pady 2m frame $mw.subj pack $mw.subj -side top -anchor w -fill x -expand yes -in $mw.frame grid columnconfigure $mw.subj 1 -weight 1 if {[llength [jlib::connections]] > 1} { label $mw.subj.lconnection -text [::msgcat::mc "Received by:"] label $mw.subj.connection -text " [jlib::connection_jid $connid]" grid $mw.subj.lconnection -row 0 -column 0 -sticky e grid $mw.subj.connection -row 0 -column 1 -sticky w } label $mw.subj.lab -text [::msgcat::mc "Subscription request from:"] menubutton $mw.subj.mb -text $from -menu $mw.subj.mb.menu subject_menu $mw.subj.mb.menu $connid $from subscribe grid $mw.subj.lab -row 1 -column 0 -sticky e grid $mw.subj.mb -row 1 -column 1 -sticky w foreach tag [bind Menubutton] { if {[string first 1 $tag] >= 0} { regsub -all 1 $tag 3 new bind $mw.subj.mb $new [bind Menubutton $tag] } } frame $mw.space pack $mw.space -side top -fill x -pady 0.5m -in $mw.frame ScrolledWindow $mw.sw pack $mw.sw -side top -fill both -expand yes -in $mw.frame text $mw.body -width 60 -height 8 -wrap word $mw.body insert 0.0 $status $mw.body configure -state disabled pack $mw.body -side bottom -fill both -expand yes -in $mw.sw $mw.sw setwidget $mw.body BWidget::place $mw 0 0 center wm deiconify $mw } hook::add client_presence_hook message::show_subscribe_dialog ############################################################################### proc message::show_unsubscribed_dialog {connid from type x args} { variable msgid if {$type != "unsubscribed"} return MessageDlg .unsubscribed[incr msgid] -aspect 50000 -icon info \ -title [::msgcat::mc "Unsubscribed from %s" $from] \ -message [::msgcat::mc "You are unsubscribed from %s" $from] \ -type user -buttons {ok} -default 0 -cancel 0 } hook::add client_presence_hook message::show_unsubscribed_dialog ############################################################################### proc message::subscribe {mw connid jid} { jlib::send_presence -to $jid -type subscribed -connection $connid switch -- [roster::itemconfig $connid \ [tolower_node_and_domain $jid] -subsc] { {} - none - from { message::send_subscribe_dialog $jid -connection $connid } } destroy $mw } ############################################################################### proc message::unsubscribe {mw connid jid} { ::roster::remove_item $connid [tolower_node_and_domain $jid] destroy $mw } ############################################################################### proc message::destroy_subscription_dialogs {connid jid name groups subsc ask} { switch -- $subsc { both - from {} default { return } } foreach mw [winfo children .] { if {![string match .subscshow* $mw]} continue set curjid [$mw.subj.mb cget -text] if {$curjid == $jid} { destroy $mw } } } hook::add roster_push_hook message::destroy_subscription_dialogs ############################################################################### proc message::disco_popup_menu {m bw tnode data parentdata} { lassign $data type connid jid node switch -- $type { item { set identities [disco::get_jid_identities $connid $jid $node] foreach id $identities { if {[jlib::wrapper:getattr $id category] == "client"} { subject_menu $m $connid $jid message break } } } } } hook::add disco_node_menu_hook message::disco_popup_menu ############################################################################### proc message::subject_menu {m connid jid type} { if {[winfo exists $m]} { destroy $m } menu $m -tearoff 0 hook::run message_dialog_menu_hook $m $connid $jid return $m } ############################################################################### proc message::add_separator {m connid jid} { $m add separator } hook::add message_dialog_menu_hook \ [namespace current]::message::add_separator 40 hook::add message_dialog_menu_hook \ [namespace current]::message::add_separator 50 ############################################################################### proc message::add_subscribe_menu_item {m connid jid} { set chatid [chat::chatid $connid [node_and_server_from_jid $jid]] if {[chat::is_groupchat $chatid]} { set real_jid [muc::get_real_jid $connid $jid] if {$real_jid != ""} { set jid $real_jid set state normal } else { set state disabled } } else { set state normal } set user [node_and_server_from_jid $jid] if {[roster::itemconfig $connid $user -subsc] != ""} { set state disabled } $m add command -label [::msgcat::mc "Add user to roster..."] \ -state $state \ -command [list message::send_subscribe_dialog $user \ -connection $connid] } hook::add chat_create_user_menu_hook \ [namespace current]::message::add_subscribe_menu_item 35 hook::add message_dialog_menu_hook \ [namespace current]::message::add_subscribe_menu_item 35 hook::add search_popup_menu_hook \ [namespace current]::message::add_subscribe_menu_item 35 ############################################################################### proc message::send_subscribe_dialog {to args} { variable msgid variable send_subscribe_connid if {[lempty [jlib::connections]]} return set cstate normal foreach {opt val} $args { switch -- $opt { -connection { set connid $val set cstate disabled } } } if {![info exists connid]} { set connid [jlib::route $to] } set send_subscribe_connid [jlib::connection_jid $connid] set mw .subscsend[incr msgid] toplevel $mw -class Message wm group $mw . wm withdraw $mw if {[cequal $to ""]} { set title [::msgcat::mc "Send subscription request"] } else { set title [format [::msgcat::mc "Send subscription request to %s"] $to] } wm title $mw $title wm iconname $mw $title set bbox [ButtonBox $mw.buttons -spacing 0 -padx 10 -default 0] $bbox add -text [::msgcat::mc "Request subscription"] \ -command [list message::send_subscribe0 $mw] $bbox add -text [::msgcat::mc "Cancel"] -command [list destroy $mw] bind $mw "ButtonBox::invoke $bbox default" bind $mw "ButtonBox::invoke $bbox 1" pack $bbox -side bottom -anchor e -padx 2m -pady 2m set sep [Separator::create $mw.sep -orient horizontal] pack $sep -pady 1m -fill x -side bottom frame $mw.frame pack $mw.frame -side top -fill both -expand yes -padx 2m -pady 2m frame $mw.subj pack $mw.subj -side top -anchor w -fill x -expand yes -in $mw.frame grid columnconfigure $mw.subj 1 -weight 1 set connections {} if {[llength [jlib::connections]] > 1} { foreach c [jlib::connections] { lappend connections [jlib::connection_jid $c] } label $mw.subj.lconnection -text [::msgcat::mc "From: "] ComboBox $mw.subj.connection \ -textvariable [namespace current]::send_subscribe_connid \ -values $connections \ -state $cstate grid $mw.subj.lconnection -row 0 -column 0 -sticky e grid $mw.subj.connection -row 0 -column 1 -sticky ew } label $mw.subj.lab -text [::msgcat::mc "Send request to: "] entry $mw.subj.entry $mw.subj.entry insert 0 $to grid $mw.subj.lab -row 1 -column 0 -sticky e grid $mw.subj.entry -row 1 -column 1 -sticky ew frame $mw.space pack $mw.space -side top -fill x -in $mw.frame -pady 0.5m ScrolledWindow $mw.sw pack $mw.sw -side top -fill both -expand yes -in $mw.frame textUndoable $mw.body -width 60 -height 8 -wrap word $mw.body insert 0.0 [::msgcat::mc "I would like to add you to my roster."] pack $mw.body -side top -fill both -expand yes -in $mw.sw $mw.sw setwidget $mw.body focus $mw.subj.entry BWidget::place $mw 0 0 center wm deiconify $mw } ############################################################################### proc message::send_subscribe0 {mw} { variable send_subscribe_connid foreach c [jlib::connections] { if {[jlib::connection_jid $c] == $send_subscribe_connid} { set connid $c } } if {![info exists connid]} { send_subscribe $mw } else { send_subscribe $mw -connection $connid } } ############################################################################### proc message::send_subscribe {mw args} { set jid [$mw.subj.entry get] foreach {opt val} $args { switch -- $opt { -connection { set connid $val } } } if {![info exists connid]} { set connid [jlib::route $jid] } jlib::send_presence -to $jid -type subscribe \ -stat [$mw.body get 1.0 end] \ -connection $connid jlib::send_iq set \ [jlib::wrapper:createtag query \ -vars {xmlns jabber:iq:roster} \ -subtags [list [jlib::wrapper:createtag item \ -vars [list jid $jid]]]] \ -command "itemedit::show_dialog \ [list $connid [tolower_node_and_domain $jid]] ;#" \ -connection $connid destroy $mw } ############################################################################### proc message::resubscribe_menu_item {m connid jid} { set rjid [roster::find_jid $connid $jid] if {$rjid == ""} { set state disabled } else { set state normal } set mm [menu $m.subscription -tearoff 0] $mm add command -label [::msgcat::mc "Request subscription"] \ -command [list jlib::send_presence \ -to $rjid \ -type subscribe \ -connection $connid] $mm add command -label [::msgcat::mc "Grant subscription"] \ -command [list jlib::send_presence \ -to $rjid \ -type subscribed \ -connection $connid] $m add cascad -label [::msgcat::mc "Subscription"] \ -menu $mm \ -state $state } hook::add roster_jid_popup_menu_hook message::resubscribe_menu_item 30 hook::add roster_service_popup_menu_hook message::resubscribe_menu_item 30 ############################################################################### # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/search.tcl0000644000175000017500000002643210752133252014502 0ustar sergeisergei# $Id: search.tcl 1373 2008-02-05 19:19:06Z sergei $ namespace eval search { set winid 0 set show_all 0 } proc search::open {jid args} { variable winid foreach {opt val} $args { switch -- $opt { -connection { set connid $val } } } if {![info exists connid]} { return -code error "search::open: -connection is mandatory" } set sw .search$winid toplevel $sw -cursor watch wm group $sw . set title [format [::msgcat::mc "Search in %s"] $jid] wm title $sw $title wm iconname $sw $title wm transient $sw . if {$::tcl_platform(platform) == "macintosh"} { catch { unsupported1 style $sw floating sideTitlebar } } elseif {$::aquaP} { ::tk::unsupported::MacWindowStyle style $sw dBoxProc } wm resizable $sw 0 0 wm withdraw $sw ButtonBox $sw.bbox -spacing 0 -padx 10 -default 0 $sw.bbox add -text [::msgcat::mc "OK"] \ -command [list search::search $sw $connid $jid] \ -state disabled $sw.bbox add -text [::msgcat::mc "Cancel"] -command [list destroy $sw] pack $sw.bbox -padx 2m -pady 2m -anchor e -side bottom bind $sw [list ButtonBox::invoke $sw.bbox default] bind $sw [list ButtonBox::invoke $sw.bbox 1] Separator::create $sw.sep -orient horizontal pack $sw.sep -side bottom -fill x -pady 1m frame $sw.fields -class Search pack $sw.fields -expand yes -fill both -anchor nw -padx 2m -pady 2m jlib::send_iq get \ [jlib::wrapper:createtag query \ -vars [list xmlns jabber:iq:search]] \ -to $jid -command [list search::recv_fields $sw $jid] \ -connection $connid incr winid } proc search::recv_fields {sw jid res child} { debugmsg search "$res $child" if {![cequal $res OK]} { destroy $sw MessageDlg ${sw}_err -aspect 50000 -icon error \ -message [format [::msgcat::mc "Search: %s"] \ [error_to_string $child]] \ -type user -buttons ok -default 0 -cancel 0 return } jlib::wrapper:splitxml $child tag vars isempty chdata children if {[cequal [jlib::wrapper:getattr $vars xmlns] jabber:iq:search]} { set focus [data::fill_fields $sw.fields $children] } $sw configure -cursor {} $sw.bbox itemconfigure 0 -state normal if {$focus != ""} { focus $focus } update idletasks wm deiconify $sw } proc search::search {sw connid jid} { variable data $sw configure -cursor watch $sw.bbox itemconfigure 0 -state disabled set restags [data::get_tags $sw.fields] jlib::send_iq set \ [jlib::wrapper:createtag query \ -vars [list xmlns jabber:iq:search] \ -subtags $restags] \ -to $jid -command [list search::recv_items $sw $jid $connid] \ -connection $connid } proc search::recv_items {sw jid connid res child} { variable lastsort debugmsg search "$res $child" if {![winfo exists $sw]} { return } if {![cequal $res OK]} { $sw configure -cursor {} $sw.bbox itemconfigure 0 -text [::msgcat::mc "Try again"] \ -command [list search::search_again $sw $jid $connid errormsg] \ -state normal $sw.bbox itemconfigure 1 -text [::msgcat::mc "Close"] if {[winfo exists $sw.errormsg]} { destroy $sw.errormsg } message $sw.errormsg -aspect 50000 \ -text [format [::msgcat::mc "An error occurred when searching in %s\n\n%s"] \ $jid [error_to_string $child]] pack $sw.errormsg -expand yes -fill both -after $sw.fields -anchor nw -padx 1c -pady 1c pack forget $sw.fields return } wm withdraw $sw set rw [toplevel ${sw}results] wm group $rw . set title [format [::msgcat::mc "Search in %s"] $jid] wm title $rw $title wm iconname $rw $title wm withdraw $rw ButtonBox $rw.bbox -spacing 0 -padx 10 -default 0 $rw.bbox add -text [::msgcat::mc "Search again"] \ -command "destroy [list $rw] search::search_again [list $sw] [list $jid] [list $connid]" $rw.bbox add -text [::msgcat::mc "Close"] -command "destroy [list $rw] destroy [list $sw]" pack $rw.bbox -padx 2m -pady 2m -anchor e -side bottom bind $rw [list ButtonBox::invoke $rw.bbox default] bind $rw [list ButtonBox::invoke $rw.bbox 1] Separator::create $rw.sep -orient horizontal pack $rw.sep -side bottom -fill x -pady 1m set sww [ScrolledWindow $rw.items] ::mclistbox::mclistbox $sww.listbox \ -resizeonecolumn 1 \ -labelanchor w \ -width 90 \ -height 16 pack $sww -expand yes -fill both -anchor nw -padx 2m -pady 2m $sww setwidget $sww.listbox set lastsort($sww.listbox) "" bind $sww.listbox +[list [namespace current]::delete_lastsort $sww.listbox] bind $sww.listbox <3> \ "[namespace current]::select_and_popup_menu [list $sww.listbox] \ \[$sww.listbox nearest \[::mclistbox::convert %W -y %y\]\] \ $connid" bindscroll $sww $sww.listbox set reported_fields [data::get_reported_fields $sw.fields] jlib::wrapper:splitxml $child tag vars isempty chdata children if {[cequal [jlib::wrapper:getattr $vars xmlns] jabber:iq:search]} { set rows [fill_mclistbox $rw $jid $sww.listbox $reported_fields $children] } if {$rows <= 0} { pack forget $sww message $rw.errormsg -aspect 50000 \ -text [format [::msgcat::mc "Search in %s: No matching items found"] $jid] pack $rw.errormsg -expand yes -fill both -anchor nw -padx 1c -pady 1c } elseif {$rows <= 12} { $sww.listbox configure -height [expr {$rows - ($rows % 4) + 4}] } wm deiconify $rw } proc search::delete_lastsort {id} { variable lastsort if {[info exists lastsort($id)]} { unset lastsort($id) } } proc search::fill_mclistbox_x {sw jid w reported_fields items} { variable show_all set width(0) 3 set name(0) N $w column add N -label " [::msgcat::mc #] " set row 0 set col 1 foreach item $items { jlib::wrapper:splitxml $item tag vars isempty chdata children switch -- $tag { title { if {$chdata != ""} { wm title $sw $chdata wm iconname $sw $chdata } } reported { set reported_fields {} foreach field $children { jlib::wrapper:splitxml $field tag vars isempty chdata children1 set lname [jlib::wrapper:getattr $vars "var"] set label_name($lname) [jlib::wrapper:getattr $vars "label"] lappend reported_fields $lname } } item { foreach field $children { jlib::wrapper:splitxml $field tag vars isempty chdata children1 if {$tag == "field"} { set var [jlib::wrapper:getattr $vars "var"] foreach value $children1 { jlib::wrapper:splitxml $value tag vars isempty chdata children1 if {($tag == "value") && ($chdata != "")} { if {$show_all || ([lsearch -exact $reported_fields $var] != -1)} { if {![info exists fieldcol($var)]} { set fieldcol($var) $col if {[info exists label_name($var)]} { set l $label_name($var) } else { set l $var } set width($col) [string length " $l "] set name($col) $var $w column add $var -label " $l " $w label bind $var "[namespace current]::sort %W $var" set lasttag $var incr col } set data($fieldcol($var),$row) $chdata debugmsg search "$var $chdata" } } } } } set data(0,$row) [expr {$row + 1}] incr row } default {} } } finalize_mclistbox $w $row $col name data width } proc search::finalize_mclistbox {w row col n d wi} { upvar $n name upvar $d data upvar $wi width $w column add lastcol -label "" -width 0 $w configure -fillcolumn lastcol for {set j 0} {$j < $row} {incr j} { set datalist {} for {set i 0} {$i < $col} {incr i} { if {[info exists data($i,$j)]} { set wd [string length " $data($i,$j) "] if {$wd > $width($i)} { set width($i) $wd } lappend datalist " $data($i,$j) " } else { lappend datalist "" } } lappend datalist "" $w insert end $datalist } for {set i 0} {$i < $col} {incr i} { $w column configure $name($i) -width $width($i) } return $row } proc search::fill_mclistbox {sw jid w reported_fields items} { variable show_all foreach item $items { jlib::wrapper:splitxml $item tag vars isempty chdata children if {$tag == "x" && [jlib::wrapper:getattr $vars xmlns] == "jabber:x:data"} { return [fill_mclistbox_x $sw $jid $w $reported_fields $children] } } set width(0) 3 set name(0) N $w column add N -label " [::msgcat::mc #] " set fieldcol(jid) 1 set width(1) 5 set name(1) jid $w column add jid -label " jid " $w label bind jid "[namespace current]::sort %W jid" set row 0 set col 2 foreach item $items { jlib::wrapper:splitxml $item tag vars isempty chdata children switch -- $tag { item { set itemjid [jlib::wrapper:getattr $vars jid] set data(1,$row) $itemjid foreach field $children { jlib::wrapper:splitxml $field tag vars isempty \ chdata children1 if {$chdata != ""} { if {$show_all || ([lsearch -exact $reported_fields $tag] != -1)} { if {![info exists fieldcol($tag)]} { set fieldcol($tag) $col set width($col) [string length " $tag "] set name($col) $tag $w column add $tag -label " $tag " $w label bind $tag "[namespace current]::sort %W $tag" set lasttag $tag incr col } set data($fieldcol($tag),$row) $chdata debugmsg search "$tag $chdata" } } } set data(0,$row) [expr {$row + 1}] incr row } default {} } } finalize_mclistbox $w $row $col name data width } proc search::sort {w tag} { variable lastsort set data [$w get 0 end] set index [lsearch -exact [$w column names] $tag] if {$lastsort($w) != $tag} { set result [lsort -dictionary -index $index $data] set lastsort($w) $tag } else { set result [lsort -decreasing -dictionary -index $index $data] set lastsort($w) "" } set result1 {} set i 0 foreach row $result { lappend result1 [lreplace $row 0 0 " [incr i] "] } $w delete 0 end eval $w insert end $result1 } proc search::search_again {sw jid connid {delwidget ""}} { $sw configure -cursor {} if {![cequal $delwidget ""]} { pack $sw.fields -expand yes -fill both -after $sw.$delwidget -anchor nw -padx 2m -pady 2m pack forget $sw.$delwidget $sw.bbox itemconfigure 0 -text [::msgcat::mc "OK"] \ -command [list search::search $sw $connid $jid] \ -state normal $sw.bbox itemconfigure 1 -text [::msgcat::mc "Cancel"] } else { $sw.bbox itemconfigure 0 -state normal wm deiconify $sw } } proc search::select_and_popup_menu {w index connid} { $w selection clear 0 end $w selection set $index set jid [string trim [lindex [$w get $index] 1]] if {[winfo exists [set m .searchpopupmenu]]} { destroy $m } menu $m -tearoff 0 hook::run search_popup_menu_hook $m $connid $jid tk_popup $m [winfo pointerx .] [winfo pointery .] } proc search::add_separator {m connid jid} { $m add separator } hook::add search_popup_menu_hook \ [namespace current]::search::add_separator 40 hook::add search_popup_menu_hook \ [namespace current]::search::add_separator 50 hook::add postload_hook \ [list disco::browser::register_feature_handler jabber:iq:search \ [namespace current]::search::open \ -desc [list * [::msgcat::mc "Search"]]] tkabber-0.11.1/plugins/0000755000175000017500000000000011076120366014205 5ustar sergeisergeitkabber-0.11.1/plugins/pep/0000755000175000017500000000000011076120366014771 5ustar sergeisergeitkabber-0.11.1/plugins/pep/user_activity.tcl0000644000175000017500000005247711021566426020407 0ustar sergeisergei# $Id: user_activity.tcl 1447 2008-06-04 19:29:26Z sergei $ # Implementation of XEP-0107 "User activity" namespace eval activity { variable node http://jabber.org/protocol/activity variable substatus variable activity variable options custom::defvar options(auto-subscribe) 0 \ [::msgcat::mc "Auto-subscribe to other's user activity notifications."] \ -command [namespace current]::register_in_disco \ -group PEP -type boolean variable m2d variable d2m array set m2d [list \ doing_chores [::msgcat::mc "doing chores"] \ buying_groceries [::msgcat::mc "buying groceries"] \ cleaning [::msgcat::mc "cleaning"] \ cooking [::msgcat::mc "cooking"] \ doing_maintenance [::msgcat::mc "doing maintenance"] \ doing_the_dishes [::msgcat::mc "doing the dishes"] \ doing_the_laundry [::msgcat::mc "doing the laundry"] \ gardening [::msgcat::mc "gardening"] \ running_an_errand [::msgcat::mc "running an errand"] \ walking_the_dog [::msgcat::mc "walking the dog"] \ drinking [::msgcat::mc "drinking"] \ having_a_beer [::msgcat::mc "having a beer"] \ having_coffee [::msgcat::mc "having coffee"] \ having_tea [::msgcat::mc "having tea"] \ eating [::msgcat::mc "eating"] \ having_a_snack [::msgcat::mc "having a snack"] \ having_breakfast [::msgcat::mc "having breakfast"] \ having_dinner [::msgcat::mc "having dinner"] \ having_lunch [::msgcat::mc "having lunch"] \ exercising [::msgcat::mc "exercising"] \ cycling [::msgcat::mc "cycling"] \ hiking [::msgcat::mc "hiking"] \ jogging [::msgcat::mc "jogging"] \ playing_sports [::msgcat::mc "playing sports"] \ running [::msgcat::mc "running"] \ skiing [::msgcat::mc "skiing"] \ swimming [::msgcat::mc "swimming"] \ working_out [::msgcat::mc "working out"] \ grooming [::msgcat::mc "grooming"] \ at_the_spa [::msgcat::mc "at the spa"] \ brushing_teeth [::msgcat::mc "brushing teeth"] \ getting_a_haircut [::msgcat::mc "getting a haircut"] \ shaving [::msgcat::mc "shaving"] \ taking_a_bath [::msgcat::mc "taking a bath"] \ taking_a_shower [::msgcat::mc "taking a shower"] \ having_appointment [::msgcat::mc "having appointment"] \ inactive [::msgcat::mc "inactive"] \ day_off [::msgcat::mc "day off"] \ hanging_out [::msgcat::mc "hanging out"] \ on_vacation [::msgcat::mc "on vacation"] \ scheduled_holiday [::msgcat::mc "scheduled holiday"] \ sleeping [::msgcat::mc "sleeping"] \ relaxing [::msgcat::mc "relaxing"] \ gaming [::msgcat::mc "gaming"] \ going_out [::msgcat::mc "going out"] \ partying [::msgcat::mc "partying"] \ reading [::msgcat::mc "reading"] \ rehearsing [::msgcat::mc "rehearsing"] \ shopping [::msgcat::mc "shopping"] \ socializing [::msgcat::mc "socializing"] \ sunbathing [::msgcat::mc "sunbathing"] \ watching_tv [::msgcat::mc "watching tv"] \ watching_a_movie [::msgcat::mc "watching a movie"] \ talking [::msgcat::mc "talking"] \ in_real_life [::msgcat::mc "in real life"] \ on_the_phone [::msgcat::mc "on the phone"] \ on_video_phone [::msgcat::mc "on video phone"] \ traveling [::msgcat::mc "traveling"] \ commuting [::msgcat::mc "commuting"] \ cycling [::msgcat::mc "cycling"] \ driving [::msgcat::mc "driving"] \ in_a_car [::msgcat::mc "in a car"] \ on_a_bus [::msgcat::mc "on a bus"] \ on_a_plane [::msgcat::mc "on a plane"] \ on_a_train [::msgcat::mc "on a train"] \ on_a_trip [::msgcat::mc "on a trip"] \ walking [::msgcat::mc "walking"] \ working [::msgcat::mc "working"] \ coding [::msgcat::mc "coding"] \ in_a_meeting [::msgcat::mc "in a meeting"] \ studying [::msgcat::mc "studying"] \ writing [::msgcat::mc "writing"] \ ] foreach m [array names m2d] { set d2m($m2d($m)) $m } unset m array set subtypes [list \ doing_chores \ {buying_groceries cleaning cooking doing_maintenance doing_the_dishes doing_the_laundry gardening running_an_errand walking_the_dog} \ drinking \ {having_a_beer having_coffee having_tea} \ eating \ {having_a_snack having_breakfast having_dinner having_lunch} \ exercising \ {cycling hiking jogging playing_sports running skiing swimming working_out} \ grooming \ {at_the_spa brushing_teeth getting_a_haircut shaving taking_a_bath taking_a_shower} \ having_appointment {} \ inactive \ {day_off hanging_out on_vacation scheduled_holiday sleeping} \ relaxing \ {gaming going_out partying reading rehearsing shopping socializing sunbathing watching_tv watching_a_movie} \ talking \ {in_real_life on_the_phone on_video_phone} \ traveling \ {commuting cycling driving in_a_car on_a_bus on_a_plane on_a_train on_a_trip walking} \ working \ {coding in_a_meeting studying writing} \ ] pubsub::register_event_notification_handler $node \ [namespace current]::process_activity_notification hook::add user_activity_notification_hook \ [namespace current]::notify_via_status_message hook::add finload_hook \ [namespace current]::on_init 60 hook::add connected_hook \ [namespace current]::on_connect_disconnect hook::add disconnected_hook \ [namespace current]::on_connect_disconnect hook::add roster_jid_popup_menu_hook \ [namespace current]::add_roster_pep_menu_item hook::add roster_user_popup_info_hook \ [namespace current]::provide_roster_popup_info hook::add userinfo_hook \ [namespace current]::provide_userinfo disco::register_feature $node } proc activity::register_in_disco {args} { variable options variable node if {$options(auto-subscribe)} { disco::register_feature $node+notify } else { disco::unregister_feature $node+notify } } proc activity::add_roster_pep_menu_item {m connid jid} { set rjid [roster::find_jid $connid $jid] if {$rjid == ""} { set rjid [node_and_server_from_jid $jid] } set pm [pep::get_roster_menu_pep_submenu $m $connid $rjid] set mm [menu $pm.activity -tearoff no] $pm add cascade -menu $mm \ -label [::msgcat::mc "User activity"] $mm add command \ -label [::msgcat::mc "Subscribe"] \ -command [list [namespace current]::subscribe $connid $rjid] $mm add command \ -label [::msgcat::mc "Unsubscribe"] \ -command [list [namespace current]::unsubscribe $connid $rjid] hook::run roster_pep_user_activity_menu_hook $mm $connid $rjid } proc activity::subscribe {connid jid args} { variable node variable substatus set to [node_and_server_from_jid $jid] set cmd [linsert $args 0 [namespace current]::subscribe_result $connid $to] pep::subscribe $to $node \ -connection $connid \ -command $cmd set substatus($connid,$to) sent-subscribe } proc activity::unsubscribe {connid jid args} { variable node variable substatus set to [node_and_server_from_jid $jid] set cmd [linsert $args 0 [namespace current]::unsubscribe_result $connid $to] pep::unsubscribe $to $node \ -connection $connid \ -command $cmd set substatus($connid,$to) sent-unsubscribe } # Err may be one of: OK, ERR and DISCONNECT proc activity::subscribe_result {connid jid res child args} { variable substatus set cmd "" foreach {opt val} $args { switch -- $opt { -command { set cmd $val } default { return -code error "unknown option: $opt" } } } switch -- $res { OK { set substatus($connid,$jid) from } ERR { set substatus($connid,$jid) error } default { return } } if {$cmd != ""} { lappend cmd $jid $res $child eval $cmd } } proc activity::unsubscribe_result {connid jid res child args} { variable substatus variable activity set cmd "" foreach {opt val} $args { switch -- $opt { -command { set cmd $val } default { return -code error "unknown option: $opt" } } } if {[string equal $res OK]} { set substatus($connid,$jid) none array unset activity *,$jid } if {$cmd != ""} { lappend cmd $jid $res $child eval $cmd } } proc activity::provide_roster_popup_info {var connid user} { variable substatus variable activity variable m2d upvar 0 $var info set jid [node_and_server_from_jid $user] if {[info exists activity(activity,$connid,$jid)]} { set m $activity(activity,$connid,$jid) if {[info exists m2d($m)]} { set status $m2d($m) } else { set status $m debugmsg pubsub "Failed to found description for user activity \"$m\"\ -- discrepancies with XEP-0108?" } set m $activity(subactivity,$connid,$jid) if {[info exists m2d($m)]} { append status [format " (%s)" $m2d($m)] } elseif {$m != ""} { append status [format " (%s)" $m] debugmsg pubsub "Failed to found description for user subactivity \"$m\"\ -- discrepancies with XEP-0108?" } if {[info exists activity(text,$connid,$jid)] && $activity(text,$connid,$jid) != ""} { append status ": " $activity(text,$connid,$jid) } append info [::msgcat::mc "\n\tActivity: %s" $status] } elseif {[info exists substatus($connid,$jid)]} { append info [::msgcat::mc "\n\tUser activity subscription: %s" \ $substatus($connid,$jid)] } else { return } } proc activity::process_activity_notification {connid jid items} { variable node variable activity set newactivity "" set newsubactivity "" set newtext "" set retract false set parsed false foreach item $items { jlib::wrapper:splitxml $item tag vars isempty chdata children switch -- $tag { retract { set retract true } default { foreach iactivity $children { jlib::wrapper:splitxml $iactivity tag1 vars1 isempty1 \ chdata1 children1 if {![string equal $tag1 activity]} continue set xmlns [jlib::wrapper:getattr $vars1 xmlns] if {![string equal $xmlns $node]} continue set parsed true foreach i $children1 { jlib::wrapper:splitxml $i tag2 vars2 isempty2 \ chdata2 children2 switch -- $tag2 { text { set newtext $chdata2 } default { set newactivity $tag2 foreach i2 $children2 { jlib::wrapper:splitxml $i2 tag3 vars3 \ isempty3 chdata3 children3 set newsubactivity $tag3 } } } } } } } } if {$parsed} { set activity(activity,$connid,$jid) $newactivity set activity(subactivity,$connid,$jid) $newsubactivity set activity(text,$connid,$jid) $newtext hook::run user_activity_notification_hook \ $connid $jid $newactivity $newsubactivity $newtext } elseif {$retract} { catch {unset activity(activity,$connid,$jid)} catch {unset activity(subactivity,$connid,$jid)} catch {unset activity(text,$connid,$jid)} hook::run user_activity_notification_hook $connid $jid "" "" "" } } proc activity::notify_via_status_message {connid jid activity subactivity text} { variable m2d set contact [::roster::itemconfig $connid $jid -name] if {$contact == ""} { set contact $jid } if {$activity == ""} { set msg [::msgcat::mc "%s's activity is unset" $contact] } elseif {[info exists m2d($activity)]} { set msg [::msgcat::mc "%s's activity changed to %s" $contact $m2d($activity)] if {$text != ""} { append msg ": $text" } } else { set msg [::msgcat::mc "%s's activity changed to %s" $contact $activity] if {$text != ""} { append msg ": $text" } } set_status $msg } proc activity::publish {connid activity subactivity args} { variable node set text "" set callback "" foreach {opt val} $args { switch -- $opt { -reason { set text $val } -command { set callback $val } } } if {$subactivity == ""} { set content [list [jlib::wrapper:createtag $activity]] } else { set content [list [jlib::wrapper:createtag $activity \ -subtags [list [jlib::wrapper:createtag \ $subactivity]]]] } if {$text != ""} { lappend content [jlib::wrapper:createtag text -chdata $text] } set cmd [list pep::publish_item $node activity \ -connection $connid \ -payload [list [jlib::wrapper:createtag activity \ -vars [list xmlns $node] \ -subtags $content]]] if {$callback != ""} { lappend cmd -command $callback } eval $cmd } proc activity::unpublish {connid args} { variable node set callback "" foreach {opt val} $args { switch -- $opt { -command { set callback $val } } } set cmd [list pep::delete_item $node activity \ -notify true \ -connection $connid] if {$callback != ""} { lappend cmd -command $callback } eval $cmd } proc activity::on_init {} { set m [pep::get_main_menu_pep_submenu] set mm [menu $m.activity -tearoff $::ifacetk::options(show_tearoffs)] $m add cascade -menu $mm \ -label [::msgcat::mc "User activity"] $mm add command -label [::msgcat::mc "Publish user activity..."] \ -state disabled \ -command [namespace current]::show_publish_dialog $mm add command -label [::msgcat::mc "Unpublish user activity"] \ -state disabled \ -command [namespace current]::show_unpublish_dialog $mm add checkbutton -label [::msgcat::mc "Auto-subscribe to other's user activity"] \ -variable [namespace current]::options(auto-subscribe) } proc activity::on_connect_disconnect {args} { set mm [pep::get_main_menu_pep_submenu].activity set idx [expr {$::ifacetk::options(show_tearoffs) ? 1 : 0}] switch -- [llength [jlib::connections]] { 0 { $mm entryconfigure $idx -state disabled $mm entryconfigure [incr idx] \ -label [::msgcat::mc "Unpublish user activity"] \ -state disabled } 1 { $mm entryconfigure $idx -state normal $mm entryconfigure [incr idx] \ -label [::msgcat::mc "Unpublish user activity"] \ -state normal } default { $mm entryconfigure $idx -state normal $mm entryconfigure [incr idx] \ -label [::msgcat::mc "Unpublish user activity..."] \ -state normal } } } proc activity::show_publish_dialog {} { variable d2m variable activityvalue variable activityreason variable myjid set w .user_activity if {[winfo exists $w]} { destroy $w } set connids [jlib::connections] if {[llength $connids] == 0} { NonmodalMessageDlg [epath] \ -aspect 50000 \ -icon error \ -title [::msgcat::mc "Error"] \ -message [::msgcat::mc "Publishing is only possible\ while being online"] return } Dialog $w -title [::msgcat::mc "User activity"] \ -modal none -separator 1 -anchor e -default 0 -cancel 1 -parent . $w add -text [::msgcat::mc "Publish"] \ -command [list [namespace current]::do_publish $w] $w add -text [::msgcat::mc "Cancel"] -command [list destroy $w] set f [$w getframe] set connjids [list [::msgcat::mc "All"]] foreach connid $connids { lappend connjids [jlib::connection_jid $connid] } set myjid [lindex $connjids 0] label $f.ccap -text [::msgcat::mc "Use connection:"] ComboBox $f.conn -editable false \ -values $connjids \ -textvariable [namespace current]::myjid label $f.acap -text [::msgcat::mc "Activity:"] ComboBox $f.activity -editable false \ -values [lsort [major_activities]] \ -textvariable [namespace current]::activityvalue \ -modifycmd [list [namespace current]::update_combobox $f.sactivity] label $f.sacap -text [::msgcat::mc "Subactivity:"] ComboBox $f.sactivity -editable false \ -values {} \ -textvariable [namespace current]::subactivityvalue label $f.rcap -text [::msgcat::mc "Reason:"] entry $f.reason -textvariable [namespace current]::activityreason update_combobox $f.sactivity if {[llength $connjids] > 1} { grid $f.ccap -row 0 -column 0 -sticky e grid $f.conn -row 0 -column 1 -sticky ew } grid $f.acap -row 1 -column 0 -sticky e grid $f.activity -row 1 -column 1 -sticky ew grid $f.sacap -row 2 -column 0 -sticky e grid $f.sactivity -row 2 -column 1 -sticky ew grid $f.rcap -row 3 -column 0 -sticky e grid $f.reason -row 3 -column 1 -sticky ew grid columnconfigure $f 1 -weight 1 $w draw } proc activity::major_activities {} { variable m2d variable subtypes set res {} foreach activity [array names subtypes] { lappend res $m2d($activity) } return $res } proc activity::update_combobox {combo} { variable m2d variable d2m variable subtypes variable activityvalue variable subactivityvalue set subactivityvalue "" set res [list ""] if {[info exists d2m($activityvalue)] && \ [info exists subtypes($d2m($activityvalue))]} { foreach activity $subtypes($d2m($activityvalue)) { lappend res $m2d($activity) } } $combo configure -values $res } proc activity::do_publish {w} { variable d2m variable activityvalue variable subactivityvalue variable activityreason variable myjid if {$activityvalue == ""} { NonmodalMessageDlg [epath] \ -aspect 50000 \ -icon error \ -title [::msgcat::mc "Error"] \ -message [::msgcat::mc "Cannot publish empty activity"] return } if {$subactivityvalue == ""} { set sub "" } else { set sub $d2m($subactivityvalue) } foreach connid [jlib::connections] { if {[string equal $myjid [jlib::connection_jid $connid]] || \ [string equal $myjid [::msgcat::mc "All"]]} { publish $connid $d2m($activityvalue) $sub \ -reason $activityreason \ -command [namespace current]::publish_result break } } unset activityvalue subactivityvalue activityreason myjid destroy $w } # $res is one of: OK, ERR, DISCONNECT proc activity::publish_result {res child} { switch -- $res { ERR { set error [error_to_string $child] } default { return } } NonmodalMessageDlg [epath] \ -aspect 50000 \ -icon error \ -title [::msgcat::mc "Error"] \ -message [::msgcat::mc "User activity publishing failed: %s" $error] } proc activity::show_unpublish_dialog {} { variable myjid set w .user_activity if {[winfo exists $w]} { destroy $w } set connids [jlib::connections] if {[llength $connids] == 0} { NonmodalMessageDlg [epath] \ -aspect 50000 \ -icon error \ -title [::msgcat::mc "Error"] \ -message [::msgcat::mc "Unpublishing is only possible\ while being online"] return } Dialog $w -title [::msgcat::mc "User activity"] \ -modal none -separator 1 -anchor e -default 0 -cancel 1 -parent . $w add -text [::msgcat::mc "Unpublish"] \ -command [list [namespace current]::do_unpublish $w] $w add -text [::msgcat::mc "Cancel"] -command [list destroy $w] set f [$w getframe] set connjids [list [::msgcat::mc "All"]] foreach connid $connids { lappend connjids [jlib::connection_jid $connid] } set myjid [lindex $connjids 0] label $f.ccap -text [::msgcat::mc "Use connection:"] ComboBox $f.conn -editable false \ -values $connjids \ -textvariable [namespace current]::myjid if {[llength $connjids] > 1} { grid $f.ccap -row 0 -column 0 -sticky e grid $f.conn -row 0 -column 1 -sticky ew } grid columnconfigure $f 1 -weight 1 if {[llength $connids] == 1} { do_unpublish $w } else { $w draw } } proc activity::do_unpublish {w} { variable myjid foreach connid [jlib::connections] { if {[string equal $myjid [jlib::connection_jid $connid]] || \ [string equal $myjid [::msgcat::mc "All"]]} { unpublish $connid \ -command [namespace current]::unpublish_result break } } unset myjid destroy $w } # $res is one of: OK, ERR, DISCONNECT proc activity::unpublish_result {res child} { switch -- $res { ERR { if {[lindex [error_type_condition $child] 1] == "item-not-found"} { return } set error [error_to_string $child] } default { return } } NonmodalMessageDlg [epath] \ -aspect 50000 \ -icon error \ -title [::msgcat::mc "Error"] \ -message [::msgcat::mc "User activity unpublishing failed: %s" $error] } proc activity::provide_userinfo {notebook connid jid editable} { variable activity variable m2d variable ::userinfo::userinfo if {$editable} return set barejid [node_and_server_from_jid $jid] if {![info exists activity(activity,$connid,$barejid)]} return if {[info exists m2d($activity(activity,$connid,$barejid))]} { set userinfo(activity,$jid) $m2d($activity(activity,$connid,$barejid)) } else { set userinfo(activity,$jid) $activity(activity,$connid,$barejid) } if {[info exists m2d($activity(subactivity,$connid,$barejid))]} { set userinfo(subactivity,$jid) $m2d($activity(subactivity,$connid,$barejid)) } else { set userinfo(subactivity,$jid) $activity(subactivity,$connid,$barejid) } if {[info exists activity(text,$connid,$barejid)]} { set userinfo(activityreason,$jid) $activity(text,$connid,$barejid) } else { set userinfo(activityreason,$jid) "" } set f [pep::get_userinfo_dialog_pep_frame $notebook] set mf [userinfo::pack_frame $f.activity [::msgcat::mc "User activity"]] userinfo::pack_entry $jid $mf 0 activity [::msgcat::mc "Activity"]: userinfo::pack_entry $jid $mf 1 subactivity [::msgcat::mc "Subactivity"]: userinfo::pack_entry $jid $mf 2 activityreason [::msgcat::mc "Reason"]: } # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/plugins/pep/user_tune.tcl0000644000175000017500000004333511021566426017517 0ustar sergeisergei# $Id: user_tune.tcl 1447 2008-06-04 19:29:26Z sergei $ # Implementation of XEP-0118 "User Tune" namespace eval tune { variable node http://jabber.org/protocol/tune variable substatus variable tune custom::defvar options(auto-subscribe) 0 \ [::msgcat::mc "Auto-subscribe to other's user tune notifications."] \ -command [namespace current]::register_in_disco \ -group PEP -type boolean pubsub::register_event_notification_handler $node \ [namespace current]::process_tune_notification hook::add user_tune_notification_hook \ [namespace current]::notify_via_status_message hook::add finload_hook \ [namespace current]::on_init 60 hook::add connected_hook \ [namespace current]::on_connect_disconnect hook::add disconnected_hook \ [namespace current]::on_connect_disconnect hook::add roster_jid_popup_menu_hook \ [namespace current]::add_roster_pep_menu_item hook::add roster_user_popup_info_hook \ [namespace current]::provide_roster_popup_info hook::add userinfo_hook \ [namespace current]::provide_userinfo disco::register_feature $node } proc tune::get {connid jid what {default ""}} { variable tune upvar 0 tune($what,$connid,$jid) v if {[info exists v]} { return $v } else { return $default } } proc tune::get_all {connid jid arrayVar} { variable tune upvar 1 $arrayVar a foreach tag {artist length source title track uri rating} { if {[info exists tune($tag,$connid,$jid)]} { set a($tag) $tune($tag,$connid,$jid) } } } proc tune::register_in_disco {args} { variable options variable node if {$options(auto-subscribe)} { disco::register_feature $node+notify } else { disco::unregister_feature $node+notify } } proc tune::add_roster_pep_menu_item {m connid jid} { set rjid [roster::find_jid $connid $jid] if {$rjid == ""} { set rjid [node_and_server_from_jid $jid] } set pm [pep::get_roster_menu_pep_submenu $m $connid $rjid] set mm [menu $pm.tune -tearoff no] $pm add cascade -menu $mm \ -label [::msgcat::mc "User tune"] $mm add command \ -label [::msgcat::mc "Subscribe"] \ -command [list [namespace current]::subscribe $connid $rjid] $mm add command \ -label [::msgcat::mc "Unsubscribe"] \ -command [list [namespace current]::unsubscribe $connid $rjid] hook::run roster_pep_user_tune_menu_hook $mm $connid $rjid } proc tune::subscribe {connid jid args} { variable node variable substatus set to [node_and_server_from_jid $jid] set cmd [linsert $args 0 [namespace current]::subscribe_result $connid $to] pep::subscribe $to $node \ -connection $connid \ -command $cmd set substatus($connid,$to) sent-subscribe } proc tune::unsubscribe {connid jid args} { variable node variable substatus set to [node_and_server_from_jid $jid] set cmd [linsert $args 0 [namespace current]::unsubscribe_result $connid $to] pep::unsubscribe $to $node \ -connection $connid \ -command $cmd set substatus($connid,$to) sent-unsubscribe } # Err may be one of: OK, ERR and DISCONNECT proc tune::subscribe_result {connid jid res child args} { variable substatus set cmd "" foreach {opt val} $args { switch -- $opt { -command { set cmd $val } default { return -code error "unknown option: $opt" } } } switch -- $res { OK { set substatus($connid,$jid) from } ERR { set substatus($connid,$jid) error } default { return } } if {$cmd != ""} { lappend cmd $jid $res $child eval $cmd } } proc tune::unsubscribe_result {connid jid res child args} { variable substatus variable tune set cmd "" foreach {opt val} $args { switch -- $opt { -command { set cmd $val } default { return -code error "unknown option: $opt" } } } if {[string equal $res OK]} { set substatus($connid,$jid) none forget_user_tune $connid $jid } if {$cmd != ""} { lappend cmd $jid $res $child eval $cmd } } proc tune::provide_roster_popup_info {var connid user} { variable substatus variable tune upvar 0 $var info set jid [node_and_server_from_jid $user] if {[info exists tune(available,$connid,$jid)]} { append info [::msgcat::mc "\n\tTune: %s - %s" \ [get $connid $jid artist ?] \ [get $connid $jid title ?]] } elseif {[info exists substatus($connid,$jid)]} { append info [::msgcat::mc "\n\tUser tune subscription: %s" \ $substatus($connid,$jid)] } else { return } } proc tune::process_tune_notification {connid jid items} { variable node variable tune set retract 0 set parsed 0 set nelems 0 foreach item $items { jlib::wrapper:splitxml $item tag vars isempty chdata children switch -- $tag { retract { set retract true } default { foreach itune $children { jlib::wrapper:splitxml $itune tag1 vars1 isempty1 chdata1 children1 if {![string equal $tag1 tune]} continue set xmlns [jlib::wrapper:getattr $vars1 xmlns] if {![string equal $xmlns $node]} continue set parsed true foreach i $children1 { jlib::wrapper:splitxml $i tag2 vars2 isempty2 chdata2 children2 switch -- $tag2 { artist - length - source - title - track - uri - rating { set $tag2 $chdata2 incr nelems } } } } } } } if {$parsed} { if {$nelems > 0} { foreach tag {artist length source title track uri rating} { if {[info exists $tag]} { set tune($tag,$connid,$jid) [set $tag] } else { catch {unset tune($tag,$connid,$jid)} } } set tune(available,$connid,$jid) "" hook::run user_tune_notification_hook $connid $jid published } else { # "stop" command forget_user_tune $connid $jid hook::run user_tune_notification_hook $connid $jid stopped } } elseif {$retract} { forget_user_tune $connid $jid hook::run user_tune_notification_hook $connid $jid retracted } } proc tune::forget_user_tune {connid jid} { variable tune foreach tag {artist length source title track uri rating} { catch {unset tune($tag,$connid,$jid)} } catch {unset tune(available,$connid,$jid)} } proc tune::notify_via_status_message {connid jid event} { variable tune set contact [::roster::itemconfig $connid $jid -name] if {$contact == ""} { set contact $jid } switch -- $event { published { set msg [::msgcat::mc "%s's tune changed to %s - %s" \ $contact \ [get $connid $jid artist ?] \ [get $connid $jid title ?]] } retracted { set msg [::msgcat::mc "%s's tune is unset" $contact] } stopped { set msg [::msgcat::mc "%s's tune has stopped playing" $contact] } } set_status $msg } proc tune::publish {connid args} { variable node set seen 0 set stop 0 set callback "" while {[llength $args] > 0} { set opt [lpop args] switch -- $opt { -artist - -title - -track - -length - -source - -uri - -rating { set [string trimleft $opt -] [lpop args] incr seen } -stop { set stop 1 } -command { set callback [lpop args] } default { return -code error "Bad option \"$opt\":\ must be one of -artist, -title, -track, -length,\ -source, -uri, -rating, -stop or -command" } } } if {$stop} { if {$seen > 0} { return -code error "-stop cannot be combined with options\ other than -command" } set content [list] } else { set content [list] foreach tag {artist length source title track uri rating} { if {[info exists $tag] && [set $tag] != ""} { lappend content [jlib::wrapper:createtag $tag \ -chdata [set $tag]] } } } set cmd [list pep::publish_item $node tune \ -connection $connid \ -payload [list [jlib::wrapper:createtag tune \ -vars [list xmlns $node] \ -subtags $content]]] if {$callback != ""} { lappend cmd -command $callback } eval $cmd } proc tune::unpublish {connid args} { variable node set callback "" foreach {opt val} $args { switch -- $opt { -command { set callback $val } } } set cmd [list pep::delete_item $node tune \ -notify true \ -connection $connid] if {$callback != ""} { lappend cmd -command $callback } eval $cmd } proc tune::on_init {} { set m [pep::get_main_menu_pep_submenu] set mm [menu $m.tune -tearoff $::ifacetk::options(show_tearoffs)] $m add cascade -menu $mm \ -label [::msgcat::mc "User tune"] $mm add command -label [::msgcat::mc "Publish user tune..."] \ -state disabled \ -command [namespace current]::show_publish_dialog $mm add command -label [::msgcat::mc "Unpublish user tune"] \ -state disabled \ -command [namespace current]::show_unpublish_dialog $mm add checkbutton -label [::msgcat::mc "Auto-subscribe to other's user tune"] \ -variable [namespace current]::options(auto-subscribe) } proc tune::on_connect_disconnect {args} { set mm [pep::get_main_menu_pep_submenu].tune set idx [expr {$::ifacetk::options(show_tearoffs) ? 1 : 0}] switch -- [llength [jlib::connections]] { 0 { $mm entryconfigure $idx -state disabled $mm entryconfigure [incr idx] \ -label [::msgcat::mc "Unpublish user tune"] \ -state disabled } 1 { $mm entryconfigure $idx -state normal $mm entryconfigure [incr idx] \ -label [::msgcat::mc "Unpublish user tune"] \ -state normal } default { $mm entryconfigure $idx -state normal $mm entryconfigure [incr idx] \ -label [::msgcat::mc "Unpublish user tune..."] \ -state normal } } } proc tune::show_publish_dialog {} { variable tuneartist variable tunetitle variable tunetrack variable tunelength variable tunesource variable tuneuri variable tunerating variable tunestop 0 variable myjid set w .user_tune if {[winfo exists $w]} { destroy $w } set connids [jlib::connections] if {[llength $connids] == 0} { NonmodalMessageDlg [epath] \ -aspect 50000 \ -icon error \ -title [::msgcat::mc "Error"] \ -message [::msgcat::mc "Publishing is only possible\ while being online"] return } Dialog $w -title [::msgcat::mc "User tune"] \ -modal none -separator 1 -anchor e -default 0 -cancel 1 -parent . $w add -text [::msgcat::mc "Publish"] \ -command [list [namespace current]::do_publish $w] $w add -text [::msgcat::mc "Cancel"] -command [list destroy $w] set f [$w getframe] set connjids [list [::msgcat::mc "All"]] foreach connid $connids { lappend connjids [jlib::connection_jid $connid] } set myjid [lindex $connjids 0] label $f.ccap -text [::msgcat::mc "Use connection:"] ComboBox $f.conn -editable false \ -values $connjids \ -textvariable [namespace current]::myjid label $f.lartist -text [::msgcat::mc "Artist:"] entry $f.artist -textvariable [namespace current]::tuneartist label $f.ltitle -text [::msgcat::mc "Title:"] entry $f.title -textvariable [namespace current]::tunetitle label $f.ltrack -text [::msgcat::mc "Track:"] entry $f.track -textvariable [namespace current]::tunetrack label $f.llength -text [::msgcat::mc "Length:"] entry $f.length -textvariable [namespace current]::tunelength label $f.lsource -text [::msgcat::mc "Source:"] entry $f.source -textvariable [namespace current]::tunesource label $f.luri -text [::msgcat::mc "URI:"] entry $f.uri -textvariable [namespace current]::tuneuri label $f.lrating -text [::msgcat::mc "Rating:"] spinbox $f.rating -from 1 -to 10 \ -textvariable [namespace current]::tunerating \ -validate all -validatecommand [namespace code {validate_rating %P}] set tunerating "" ;# otherwise spinbox forces it to be 1 checkbutton $f.stop \ -variable [namespace current]::tunestop \ -text [::msgcat::mc "Publish \"playback stopped\" instead"] \ -command [list [namespace current]::adjust_publish_controls $f] if {[llength $connjids] > 1} { grid $f.ccap -row 0 -column 0 -sticky e grid $f.conn -row 0 -column 1 -sticky ew } grid $f.lartist $f.artist grid $f.ltitle $f.title grid $f.ltrack $f.track grid $f.llength $f.length grid $f.lsource $f.source grid $f.luri $f.uri grid $f.lrating $f.rating grid $f.stop - -sticky w grid $f.lartist $f.ltitle $f.ltrack $f.llength \ $f.lsource $f.luri $f.lrating -sticky e grid $f.artist $f.title $f.track $f.length \ $f.source $f.uri $f.rating -sticky ew grid columnconfigure $f 1 -weight 1 bind $w [list [namespace current]::cleanup_publish_dialog $w %W] $w draw } proc tune::validate_rating {newvalue} { expr {$newvalue == "" || ([string is integer $newvalue] && 1 <= $newvalue && $newvalue <= 10)} } proc tune::adjust_publish_controls {f} { variable tunestop if {$tunestop} { set state disabled } else { set state normal } foreach control [list \ $f.lartist $f.artist \ $f.ltitle $f.title \ $f.ltrack $f.track \ $f.llength $f.length \ $f.lsource $f.source \ $f.luri $f.uri \ $f.lrating $f.rating] { $control configure -state $state } } proc tune::do_publish {w} { variable tuneartist variable tunetitle variable tunetrack variable tunelength variable tunesource variable tuneuri variable tunerating variable tunestop variable myjid foreach connid [jlib::connections] { if {[string equal $myjid [jlib::connection_jid $connid]] || \ [string equal $myjid [::msgcat::mc "All"]]} { if {$tunestop} { publish $connid \ -stop \ -command [namespace current]::publish_result } else { publish $connid \ -artist $tuneartist \ -title $tunetitle \ -track $tunetrack \ -length $tunelength \ -source $tunesource \ -uri $tuneuri \ -rating $tunerating \ -command [namespace current]::publish_result } break } } destroy $w } proc tune::cleanup_publish_dialog {w1 w2} { if {![string equal $w1 $w2]} return variable tuneartist variable tunetitle variable tunetrack variable tunelength variable tunesource variable tuneuri variable tunerating variable tunestop variable myjid foreach v [info vars] { unset $v } } # $res is one of: OK, ERR, DISCONNECT proc tune::publish_result {res child} { switch -- $res { ERR { set error [error_to_string $child] } default { return } } NonmodalMessageDlg [epath] \ -aspect 50000 \ -icon error \ -title [::msgcat::mc "Error"] \ -message [::msgcat::mc "User tune publishing failed: %s" $error] } proc tune::show_unpublish_dialog {} { variable myjid set w .user_tune if {[winfo exists $w]} { destroy $w } set connids [jlib::connections] if {[llength $connids] == 0} { NonmodalMessageDlg [epath] \ -aspect 50000 \ -icon error \ -title [::msgcat::mc "Error"] \ -message [::msgcat::mc "Unpublishing is only possible\ while being online"] return } Dialog $w -title [::msgcat::mc "User tune"] \ -modal none -separator 1 -anchor e -default 0 -cancel 1 -parent . $w add -text [::msgcat::mc "Unpublish"] \ -command [list [namespace current]::do_unpublish $w] $w add -text [::msgcat::mc "Cancel"] -command [list destroy $w] set f [$w getframe] set connjids [list [::msgcat::mc "All"]] foreach connid $connids { lappend connjids [jlib::connection_jid $connid] } set myjid [lindex $connjids 0] label $f.ccap -text [::msgcat::mc "Use connection:"] ComboBox $f.conn -editable false \ -values $connjids \ -textvariable [namespace current]::myjid if {[llength $connjids] > 1} { grid $f.ccap -row 0 -column 0 -sticky e grid $f.conn -row 0 -column 1 -sticky ew } grid columnconfigure $f 1 -weight 1 if {[llength $connids] == 1} { do_unpublish $w } else { $w draw } } proc tune::do_unpublish {w} { variable myjid foreach connid [jlib::connections] { if {[string equal $myjid [jlib::connection_jid $connid]] || \ [string equal $myjid [::msgcat::mc "All"]]} { unpublish $connid \ -command [namespace current]::unpublish_result break } } unset myjid destroy $w } # $res is one of: OK, ERR, DISCONNECT proc tune::unpublish_result {res child} { switch -- $res { ERR { if {[lindex [error_type_condition $child] 1] == "item-not-found"} { return } set error [error_to_string $child] } default { return } } NonmodalMessageDlg [epath] \ -aspect 50000 \ -icon error \ -title [::msgcat::mc "Error"] \ -message [::msgcat::mc "User tune unpublishing failed: %s" $error] } proc tune::provide_userinfo {notebook connid jid editable} { variable tune variable m2d variable ::userinfo::userinfo if {$editable} return set barejid [node_and_server_from_jid $jid] if {![info exists tune(available,$connid,$barejid)]} return foreach tag {artist length source title track uri rating} { if {[info exists tune($tag,$connid,$barejid)]} { set userinfo(tune$tag,$jid) $tune($tag,$connid,$barejid) } else { set userinfo(tune$tag,$jid) "" } } set f [pep::get_userinfo_dialog_pep_frame $notebook] set mf [userinfo::pack_frame $f.tune [::msgcat::mc "User tune"]] userinfo::pack_entry $jid $mf 0 tuneartist [::msgcat::mc "Artist:"] userinfo::pack_entry $jid $mf 1 tunetitle [::msgcat::mc "Title:"] userinfo::pack_entry $jid $mf 2 tunetrack [::msgcat::mc "Track:"] userinfo::pack_entry $jid $mf 3 tunelength [::msgcat::mc "Length:"] userinfo::pack_entry $jid $mf 4 tunesource [::msgcat::mc "Source:"] userinfo::pack_entry $jid $mf 5 tuneuri [::msgcat::mc "URI:"] userinfo::pack_entry $jid $mf 6 tunerating [::msgcat::mc "Rating:"] } # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/plugins/pep/user_mood.tcl0000644000175000017500000004122211021566426017473 0ustar sergeisergei# $Id: user_mood.tcl 1447 2008-06-04 19:29:26Z sergei $ # Implementation of XEP-0107 "User mood" # Based on Version 1.1 (2007-06-04). namespace eval mood { variable node http://jabber.org/protocol/mood variable substatus variable mood variable options custom::defvar options(auto-subscribe) 0 \ [::msgcat::mc "Auto-subscribe to other's user mood notifications."] \ -command [namespace current]::register_in_disco \ -group PEP -type boolean variable m2d variable d2m array set m2d [list \ afraid [::msgcat::mc "afraid"] \ amazed [::msgcat::mc "amazed"] \ angry [::msgcat::mc "angry"] \ annoyed [::msgcat::mc "annoyed"] \ anxious [::msgcat::mc "anxious"] \ aroused [::msgcat::mc "aroused"] \ ashamed [::msgcat::mc "ashamed"] \ bored [::msgcat::mc "bored"] \ brave [::msgcat::mc "brave"] \ calm [::msgcat::mc "calm"] \ cold [::msgcat::mc "cold"] \ confused [::msgcat::mc "confused"] \ contented [::msgcat::mc "contented"] \ cranky [::msgcat::mc "cranky"] \ curious [::msgcat::mc "curious"] \ depressed [::msgcat::mc "depressed"] \ disappointed [::msgcat::mc "disappointed"] \ disgusted [::msgcat::mc "disgusted"] \ distracted [::msgcat::mc "distracted"] \ embarrassed [::msgcat::mc "embarrassed"] \ excited [::msgcat::mc "excited"] \ flirtatious [::msgcat::mc "flirtatious"] \ frustrated [::msgcat::mc "frustrated"] \ grumpy [::msgcat::mc "grumpy"] \ guilty [::msgcat::mc "guilty"] \ happy [::msgcat::mc "happy"] \ hot [::msgcat::mc "hot"] \ humbled [::msgcat::mc "humbled"] \ humiliated [::msgcat::mc "humiliated"] \ hungry [::msgcat::mc "hungry"] \ hurt [::msgcat::mc "hurt"] \ impressed [::msgcat::mc "impressed"] \ in_awe [::msgcat::mc "in_awe"] \ in_love [::msgcat::mc "in_love"] \ indignant [::msgcat::mc "indignant"] \ interested [::msgcat::mc "interested"] \ intoxicated [::msgcat::mc "intoxicated"] \ invincible [::msgcat::mc "invincible"] \ jealous [::msgcat::mc "jealous"] \ lonely [::msgcat::mc "lonely"] \ mean [::msgcat::mc "mean"] \ moody [::msgcat::mc "moody"] \ nervous [::msgcat::mc "nervous"] \ neutral [::msgcat::mc "neutral"] \ offended [::msgcat::mc "offended"] \ playful [::msgcat::mc "playful"] \ proud [::msgcat::mc "proud"] \ relieved [::msgcat::mc "relieved"] \ remorseful [::msgcat::mc "remorseful"] \ restless [::msgcat::mc "restless"] \ sad [::msgcat::mc "sad"] \ sarcastic [::msgcat::mc "sarcastic"] \ serious [::msgcat::mc "serious"] \ shocked [::msgcat::mc "shocked"] \ shy [::msgcat::mc "shy"] \ sick [::msgcat::mc "sick"] \ sleepy [::msgcat::mc "sleepy"] \ stressed [::msgcat::mc "stressed"] \ surprised [::msgcat::mc "surprised"] \ thirsty [::msgcat::mc "thirsty"] \ worried [::msgcat::mc "worried"] \ ] foreach m [array names m2d] { set d2m($m2d($m)) $m } unset m pubsub::register_event_notification_handler $node \ [namespace current]::process_mood_notification hook::add user_mood_notification_hook \ [namespace current]::notify_via_status_message hook::add finload_hook \ [namespace current]::on_init 60 hook::add connected_hook \ [namespace current]::on_connect_disconnect hook::add disconnected_hook \ [namespace current]::on_connect_disconnect hook::add roster_jid_popup_menu_hook \ [namespace current]::add_roster_pep_menu_item hook::add roster_user_popup_info_hook \ [namespace current]::provide_roster_popup_info hook::add userinfo_hook \ [namespace current]::provide_userinfo disco::register_feature $node } proc mood::register_in_disco {args} { variable options variable node if {$options(auto-subscribe)} { disco::register_feature $node+notify } else { disco::unregister_feature $node+notify } } proc mood::add_roster_pep_menu_item {m connid jid} { set rjid [roster::find_jid $connid $jid] if {$rjid == ""} { set rjid [node_and_server_from_jid $jid] } set pm [pep::get_roster_menu_pep_submenu $m $connid $rjid] set mm [menu $pm.mood -tearoff no] $pm add cascade -menu $mm \ -label [::msgcat::mc "User mood"] $mm add command \ -label [::msgcat::mc "Subscribe"] \ -command [list [namespace current]::subscribe $connid $rjid] $mm add command \ -label [::msgcat::mc "Unsubscribe"] \ -command [list [namespace current]::unsubscribe $connid $rjid] hook::run roster_pep_user_mood_menu_hook $mm $connid $rjid } proc mood::subscribe {connid jid args} { variable node variable substatus set to [node_and_server_from_jid $jid] set cmd [linsert $args 0 [namespace current]::subscribe_result $connid $to] pep::subscribe $to $node \ -connection $connid \ -command $cmd set substatus($connid,$to) sent-subscribe } proc mood::unsubscribe {connid jid args} { variable node variable substatus set to [node_and_server_from_jid $jid] set cmd [linsert $args 0 [namespace current]::unsubscribe_result $connid $to] pep::unsubscribe $to $node \ -connection $connid \ -command $cmd set substatus($connid,$to) sent-unsubscribe } # Err may be one of: OK, ERR and DISCONNECT proc mood::subscribe_result {connid jid res child args} { variable substatus set cmd "" foreach {opt val} $args { switch -- $opt { -command { set cmd $val } default { return -code error "unknown option: $opt" } } } switch -- $res { OK { set substatus($connid,$jid) from } ERR { set substatus($connid,$jid) error } default { return } } if {$cmd != ""} { lappend cmd $jid $res $child eval $cmd } } proc mood::unsubscribe_result {connid jid res child args} { variable substatus variable mood set cmd "" foreach {opt val} $args { switch -- $opt { -command { set cmd $val } default { return -code error "unknown option: $opt" } } } if {[string equal $res OK]} { set substatus($connid,$jid) none catch {unset mood(mood,$connid,$jid)} catch {unset mood(text,$connid,$jid)} } if {$cmd != ""} { lappend cmd $jid $res $child eval $cmd } } proc mood::provide_roster_popup_info {var connid user} { variable substatus variable mood variable m2d upvar 0 $var info set jid [node_and_server_from_jid $user] if {[info exists mood(mood,$connid,$jid)]} { set m $mood(mood,$connid,$jid) if {[info exists m2d($m)]} { set status $m2d($m) } else { set status $m debugmsg pubsub "Failed to found description for user mood \"$m\"\ -- discrepancies with XEP-0107?" } if {[info exists mood(text,$connid,$jid)] && $mood(text,$connid,$jid) != ""} { append status ": " $mood(text,$connid,$jid) } append info [::msgcat::mc "\n\tMood: %s" $status] } elseif {[info exists substatus($connid,$jid)]} { append info [::msgcat::mc "\n\tUser mood subscription: %s" \ $substatus($connid,$jid)] } else { return } } proc mood::process_mood_notification {connid jid items} { variable node variable mood set newmood "" set newtext "" set retract false set parsed false foreach item $items { jlib::wrapper:splitxml $item tag vars isempty chdata children switch -- $tag { retract { set retract true } default { foreach imood $children { jlib::wrapper:splitxml $imood tag1 vars1 isempty1 chdata1 children1 if {![string equal $tag1 mood]} continue set xmlns [jlib::wrapper:getattr $vars1 xmlns] if {![string equal $xmlns $node]} continue set parsed true foreach i $children1 { jlib::wrapper:splitxml $i tag2 vars2 isempty2 chdata2 children2 switch -- $tag2 { text { set newtext $chdata2 } default { set newmood $tag2 } } } } } } } if {$parsed} { set mood(mood,$connid,$jid) $newmood set mood(text,$connid,$jid) $newtext hook::run user_mood_notification_hook $connid $jid $newmood $newtext } elseif {$retract} { catch {unset mood(mood,$connid,$jid)} catch {unset mood(text,$connid,$jid)} hook::run user_mood_notification_hook $connid $jid "" "" } } proc mood::notify_via_status_message {connid jid mood text} { variable m2d set contact [::roster::itemconfig $connid $jid -name] if {$contact == ""} { set contact $jid } if {$mood == ""} { set msg [::msgcat::mc "%s's mood is unset" $contact] } elseif {[info exists m2d($mood)]} { set msg [::msgcat::mc "%s's mood changed to %s" $contact $m2d($mood)] if {$text != ""} { append msg ": $text" } } else { set msg [::msgcat::mc "%s's mood changed to %s" $contact $mood] if {$text != ""} { append msg ": $text" } } set_status $msg } proc mood::publish {connid mood args} { variable node set text "" set callback "" foreach {opt val} $args { switch -- $opt { -reason { set text $val } -command { set callback $val } } } set content [list [jlib::wrapper:createtag $mood]] if {$text != ""} { lappend content [jlib::wrapper:createtag text -chdata $text] } set cmd [list pep::publish_item $node mood \ -connection $connid \ -payload [list [jlib::wrapper:createtag mood \ -vars [list xmlns $node] \ -subtags $content]]] if {$callback != ""} { lappend cmd -command $callback } eval $cmd } proc mood::unpublish {connid args} { variable node set callback "" foreach {opt val} $args { switch -- $opt { -command { set callback $val } } } set cmd [list pep::delete_item $node mood \ -notify true \ -connection $connid] if {$callback != ""} { lappend cmd -command $callback } eval $cmd } proc mood::on_init {} { set m [pep::get_main_menu_pep_submenu] set mm [menu $m.mood -tearoff $::ifacetk::options(show_tearoffs)] $m add cascade -menu $mm \ -label [::msgcat::mc "User mood"] $mm add command -label [::msgcat::mc "Publish user mood..."] \ -state disabled \ -command [namespace current]::show_publish_dialog $mm add command -label [::msgcat::mc "Unpublish user mood"] \ -state disabled \ -command [namespace current]::show_unpublish_dialog $mm add checkbutton -label [::msgcat::mc "Auto-subscribe to other's user mood"] \ -variable [namespace current]::options(auto-subscribe) } proc mood::on_connect_disconnect {args} { set mm [pep::get_main_menu_pep_submenu].mood set idx [expr {$::ifacetk::options(show_tearoffs) ? 1 : 0}] switch -- [llength [jlib::connections]] { 0 { $mm entryconfigure $idx -state disabled $mm entryconfigure [incr idx] \ -label [::msgcat::mc "Unpublish user mood"] \ -state disabled } 1 { $mm entryconfigure $idx -state normal $mm entryconfigure [incr idx] \ -label [::msgcat::mc "Unpublish user mood"] \ -state normal } default { $mm entryconfigure $idx -state normal $mm entryconfigure [incr idx] \ -label [::msgcat::mc "Unpublish user mood..."] \ -state normal } } } proc mood::show_publish_dialog {} { variable d2m variable moodvalue variable moodreason variable myjid set w .user_mood if {[winfo exists $w]} { destroy $w } set connids [jlib::connections] if {[llength $connids] == 0} { NonmodalMessageDlg [epath] \ -aspect 50000 \ -icon error \ -title [::msgcat::mc "Error"] \ -message [::msgcat::mc "Publishing is only possible\ while being online"] return } Dialog $w -title [::msgcat::mc "User mood"] \ -modal none -separator 1 -anchor e -default 0 -cancel 1 -parent . $w add -text [::msgcat::mc "Publish"] \ -command [list [namespace current]::do_publish $w] $w add -text [::msgcat::mc "Cancel"] -command [list destroy $w] set f [$w getframe] set connjids [list [::msgcat::mc "All"]] foreach connid $connids { lappend connjids [jlib::connection_jid $connid] } set myjid [lindex $connjids 0] label $f.ccap -text [::msgcat::mc "Use connection:"] ComboBox $f.conn -editable false \ -values $connjids \ -textvariable [namespace current]::myjid label $f.mcap -text [::msgcat::mc "Mood:"] ComboBox $f.mood -editable false \ -values [lsort [array names d2m]] \ -textvariable [namespace current]::moodvalue label $f.rcap -text [::msgcat::mc "Reason:"] entry $f.reason -textvariable [namespace current]::moodreason if {[llength $connjids] > 1} { grid $f.ccap -row 0 -column 0 -sticky e grid $f.conn -row 0 -column 1 -sticky ew } grid $f.mcap -row 1 -column 0 -sticky e grid $f.mood -row 1 -column 1 -sticky ew grid $f.rcap -row 2 -column 0 -sticky e grid $f.reason -row 2 -column 1 -sticky ew grid columnconfigure $f 1 -weight 1 $w draw } proc mood::do_publish {w} { variable d2m variable moodvalue variable moodreason variable myjid if {$moodvalue == ""} { NonmodalMessageDlg [epath] \ -aspect 50000 \ -icon error \ -title [::msgcat::mc "Error"] \ -message [::msgcat::mc "Cannot publish empty mood"] return } foreach connid [jlib::connections] { if {[string equal $myjid [jlib::connection_jid $connid]] || \ [string equal $myjid [::msgcat::mc "All"]]} { publish $connid $d2m($moodvalue) \ -reason $moodreason \ -command [namespace current]::publish_result break } } unset moodvalue moodreason myjid destroy $w } # $res is one of: OK, ERR, DISCONNECT proc mood::publish_result {res child} { switch -- $res { ERR { set error [error_to_string $child] } default { return } } NonmodalMessageDlg [epath] \ -aspect 50000 \ -icon error \ -title [::msgcat::mc "Error"] \ -message [::msgcat::mc "User mood publishing failed: %s" $error] } proc mood::show_unpublish_dialog {} { variable myjid set w .user_mood if {[winfo exists $w]} { destroy $w } set connids [jlib::connections] if {[llength $connids] == 0} { NonmodalMessageDlg [epath] \ -aspect 50000 \ -icon error \ -title [::msgcat::mc "Error"] \ -message [::msgcat::mc "Unpublishing is only possible\ while being online"] return } Dialog $w -title [::msgcat::mc "User mood"] \ -modal none -separator 1 -anchor e -default 0 -cancel 1 -parent . $w add -text [::msgcat::mc "Unpublish"] \ -command [list [namespace current]::do_unpublish $w] $w add -text [::msgcat::mc "Cancel"] -command [list destroy $w] set f [$w getframe] set connjids [list [::msgcat::mc "All"]] foreach connid $connids { lappend connjids [jlib::connection_jid $connid] } set myjid [lindex $connjids 0] label $f.ccap -text [::msgcat::mc "Use connection:"] ComboBox $f.conn -editable false \ -values $connjids \ -textvariable [namespace current]::myjid if {[llength $connjids] > 1} { grid $f.ccap -row 0 -column 0 -sticky e grid $f.conn -row 0 -column 1 -sticky ew } grid columnconfigure $f 1 -weight 1 if {[llength $connids] == 1} { do_unpublish $w } else { $w draw } } proc mood::do_unpublish {w} { variable myjid foreach connid [jlib::connections] { if {[string equal $myjid [jlib::connection_jid $connid]] || \ [string equal $myjid [::msgcat::mc "All"]]} { unpublish $connid \ -command [namespace current]::unpublish_result break } } unset myjid destroy $w } # $res is one of: OK, ERR, DISCONNECT proc mood::unpublish_result {res child} { switch -- $res { ERR { if {[lindex [error_type_condition $child] 1] == "item-not-found"} { return } set error [error_to_string $child] } default { return } } NonmodalMessageDlg [epath] \ -aspect 50000 \ -icon error \ -title [::msgcat::mc "Error"] \ -message [::msgcat::mc "User mood unpublishing failed: %s" $error] } proc mood::provide_userinfo {notebook connid jid editable} { variable mood variable m2d variable ::userinfo::userinfo if {$editable} return set barejid [node_and_server_from_jid $jid] if {![info exists mood(mood,$connid,$barejid)]} return set userinfo(mood,$jid) $m2d($mood(mood,$connid,$barejid)) if {[info exists mood(text,$connid,$barejid)]} { set userinfo(moodreason,$jid) $mood(text,$connid,$barejid) } else { set userinfo(moodreason,$jid) "" } set f [pep::get_userinfo_dialog_pep_frame $notebook] set mf [userinfo::pack_frame $f.mood [::msgcat::mc "User mood"]] userinfo::pack_entry $jid $mf 0 mood [::msgcat::mc "Mood"]: userinfo::pack_entry $jid $mf 1 moodreason [::msgcat::mc "Reason"]: } # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/plugins/pep/user_location.tcl0000644000175000017500000003464011021566426020353 0ustar sergeisergei# $Id$ # Implementation of XEP-0080 "User Location" namespace eval geoloc { variable node http://jabber.org/protocol/geoloc variable substatus variable geoloc custom::defvar options(auto-subscribe) 0 \ [::msgcat::mc "Auto-subscribe to other's user location notifications."] \ -command [namespace current]::register_in_disco \ -group PEP -type boolean pubsub::register_event_notification_handler $node \ [namespace current]::process_geoloc_notification hook::add user_geoloc_notification_hook \ [namespace current]::notify_via_status_message hook::add finload_hook \ [namespace current]::on_init 60 hook::add connected_hook \ [namespace current]::on_connect_disconnect hook::add disconnected_hook \ [namespace current]::on_connect_disconnect hook::add roster_jid_popup_menu_hook \ [namespace current]::add_roster_pep_menu_item hook::add roster_user_popup_info_hook \ [namespace current]::provide_roster_popup_info hook::add userinfo_hook \ [namespace current]::provide_userinfo disco::register_feature $node variable fields [list alt area bearing building country datum \ description error floor lat locality lon \ postalcode region room speed street text \ timestamp uri] array set labels [list alt [::msgcat::mc "Altitude:"] \ area [::msgcat::mc "Area:"] \ bearing [::msgcat::mc "Bearing:"] \ building [::msgcat::mc "Building:"] \ country [::msgcat::mc "Country:"] \ datum [::msgcat::mc "GPS datum:"] \ description [::msgcat::mc "Description:"] \ error [::msgcat::mc "Horizontal GPS error:"] \ floor [::msgcat::mc "Floor:"] \ lat [::msgcat::mc "Latitude:"] \ locality [::msgcat::mc "Locality:"] \ lon [::msgcat::mc "Longitude:"] \ postalcode [::msgcat::mc "Postal code:"] \ region [::msgcat::mc "Region:"] \ room [::msgcat::mc "Room:"] \ speed [::msgcat::mc "Speed:"] \ street [::msgcat::mc "Street:"] \ text [::msgcat::mc "Text:"] \ timestamp [::msgcat::mc "Timestamp:"] \ uri [::msgcat::mc "URI:"]] } proc geoloc::register_in_disco {args} { variable options variable node if {$options(auto-subscribe)} { disco::register_feature $node+notify } else { disco::unregister_feature $node+notify } } proc geoloc::add_roster_pep_menu_item {m connid jid} { set rjid [roster::find_jid $connid $jid] if {$rjid == ""} { set rjid [node_and_server_from_jid $jid] } set pm [pep::get_roster_menu_pep_submenu $m $connid $rjid] set mm [menu $pm.geoloc -tearoff no] $pm add cascade -menu $mm \ -label [::msgcat::mc "User location"] $mm add command \ -label [::msgcat::mc "Subscribe"] \ -command [list [namespace current]::subscribe $connid $rjid] $mm add command \ -label [::msgcat::mc "Unsubscribe"] \ -command [list [namespace current]::unsubscribe $connid $rjid] hook::run roster_pep_user_geoloc_menu_hook $mm $connid $rjid } proc geoloc::subscribe {connid jid args} { variable node variable substatus set to [node_and_server_from_jid $jid] set cmd [linsert $args 0 [namespace current]::subscribe_result $connid $to] pep::subscribe $to $node \ -connection $connid \ -command $cmd set substatus($connid,$to) sent-subscribe } proc geoloc::unsubscribe {connid jid args} { variable node variable substatus set to [node_and_server_from_jid $jid] set cmd [linsert $args 0 [namespace current]::unsubscribe_result $connid $to] pep::unsubscribe $to $node \ -connection $connid \ -command $cmd set substatus($connid,$to) sent-unsubscribe } # Err may be one of: OK, ERR and DISCONNECT proc geoloc::subscribe_result {connid jid res child args} { variable substatus set cmd "" foreach {opt val} $args { switch -- $opt { -command { set cmd $val } default { return -code error "unknown option: $opt" } } } switch -- $res { OK { set substatus($connid,$jid) from } ERR { set substatus($connid,$jid) error } default { return } } if {$cmd != ""} { lappend cmd $jid $res $child eval $cmd } } proc geoloc::unsubscribe_result {connid jid res child args} { variable substatus variable geoloc variable fields set cmd "" foreach {opt val} $args { switch -- $opt { -command { set cmd $val } default { return -code error "unknown option: $opt" } } } if {[string equal $res OK]} { set substatus($connid,$jid) none foreach f $fields { catch {unset geoloc($f,$connid,$jid)} } } if {$cmd != ""} { lappend cmd $jid $res $child eval $cmd } } proc geoloc::provide_roster_popup_info {var connid user} { variable substatus variable geoloc upvar 0 $var info set jid [node_and_server_from_jid $user] if {[info exists geoloc(title,$connid,$jid)]} { append info [::msgcat::mc "\n\tLocation: %s : %s" \ $geoloc(lat,$connid,$jid) \ $geoloc(lon,$connid,$jid)] } elseif {[info exists substatus($connid,$jid)]} { append info [::msgcat::mc "\n\tUser location subscription: %s" \ $substatus($connid,$jid)] } else { return } } proc geoloc::process_geoloc_notification {connid jid items} { variable node variable geoloc variable fields foreach f $fields { set $f "" } set retract false set parsed false foreach item $items { jlib::wrapper:splitxml $item tag vars isempty chdata children switch -- $tag { retract { set retract true } default { foreach igeoloc $children { jlib::wrapper:splitxml $igeoloc tag1 vars1 isempty1 chdata1 children1 if {![string equal $tag1 geoloc]} continue set xmlns [jlib::wrapper:getattr $vars1 xmlns] if {![string equal $xmlns $node]} continue set parsed true foreach i $children1 { jlib::wrapper:splitxml $i tag2 vars2 isempty2 chdata2 children2 if {[lsearch -exact $fields $tag2] >= 0} { set $tag2 $chdata2 } } } } } } if {$parsed} { foreach f $fields { set geoloc($f,$connid,$jid) [set $f] } hook::run user_geoloc_notification_hook $connid $jid $lat $lon } elseif {$retract} { foreach f $fields { catch {unset geoloc($f,$connid,$jid)} } hook::run user_geoloc_notification_hook $connid $jid "" "" } } proc geoloc::notify_via_status_message {connid jid lat lon} { set contact [::roster::itemconfig $connid $jid -name] if {$contact == ""} { set contact $jid } if {$lat == "" && $lon == ""} { set msg [::msgcat::mc "%s's location is unset" $contact] } else { set msg [::msgcat::mc "%s's location changed to %s : %s" \ $contact $lat $lon] } set_status $msg } proc geoloc::publish {connid args} { variable node variable fields foreach f $fields { set $f "" } set callback "" foreach {opt val} $args { switch -- $opt { -command { set callback $val } default { set opt [string trimleft $opt -] if {[lsearch -exact $fields $opt] >= 0} { set $opt $val } } } } set content {} foreach f $fields { if {[set $f] != ""} { lappend content [jlib::wrapper:createtag $f -chdata [set $f]] } } set cmd [list pep::publish_item $node geoloc \ -connection $connid \ -payload [list [jlib::wrapper:createtag geoloc \ -vars [list xmlns $node] \ -subtags $content]]] if {$callback != ""} { lappend cmd -command $callback } eval $cmd } proc geoloc::unpublish {connid args} { variable node set callback "" foreach {opt val} $args { switch -- $opt { -command { set callback $val } } } set cmd [list pep::delete_item $node geoloc \ -notify true \ -connection $connid] if {$callback != ""} { lappend cmd -command $callback } eval $cmd } proc geoloc::on_init {} { set m [pep::get_main_menu_pep_submenu] set mm [menu $m.geoloc -tearoff $::ifacetk::options(show_tearoffs)] $m add cascade -menu $mm \ -label [::msgcat::mc "User location"] $mm add command -label [::msgcat::mc "Publish user location..."] \ -state disabled \ -command [namespace current]::show_publish_dialog $mm add command -label [::msgcat::mc "Unpublish user location"] \ -state disabled \ -command [namespace current]::show_unpublish_dialog $mm add checkbutton -label [::msgcat::mc "Auto-subscribe to other's user location"] \ -variable [namespace current]::options(auto-subscribe) } proc geoloc::on_connect_disconnect {args} { set mm [pep::get_main_menu_pep_submenu].geoloc set idx [expr {$::ifacetk::options(show_tearoffs) ? 1 : 0}] switch -- [llength [jlib::connections]] { 0 { $mm entryconfigure $idx -state disabled $mm entryconfigure [incr idx] \ -label [::msgcat::mc "Unpublish user location"] \ -state disabled } 1 { $mm entryconfigure $idx -state normal $mm entryconfigure [incr idx] \ -label [::msgcat::mc "Unpublish user location"] \ -state normal } default { $mm entryconfigure $idx -state normal $mm entryconfigure [incr idx] \ -label [::msgcat::mc "Unpublish user location..."] \ -state normal } } } proc geoloc::show_publish_dialog {} { variable fields variable labels variable myjid foreach ff $fields { variable geoloc$ff } set w .user_geoloc if {[winfo exists $w]} { destroy $w } set connids [jlib::connections] if {[llength $connids] == 0} { NonmodalMessageDlg [epath] \ -aspect 50000 \ -icon error \ -title [::msgcat::mc "Error"] \ -message [::msgcat::mc "Publishing is only possible\ while being online"] return } Dialog $w -title [::msgcat::mc "User location"] \ -modal none -separator 1 -anchor e -default 0 -cancel 1 -parent . $w add -text [::msgcat::mc "Publish"] \ -command [list [namespace current]::do_publish $w] $w add -text [::msgcat::mc "Cancel"] -command [list destroy $w] set f [$w getframe] set connjids [list [::msgcat::mc "All"]] foreach connid $connids { lappend connjids [jlib::connection_jid $connid] } set myjid [lindex $connjids 0] label $f.ccap -text [::msgcat::mc "Use connection:"] ComboBox $f.conn -editable false \ -values $connjids \ -textvariable [namespace current]::myjid if {[llength $connjids] > 1} { grid $f.ccap -row 0 -column 0 -sticky e grid $f.conn -row 0 -column 1 -sticky ew } set row 1 foreach ff $fields { label $f.l$ff -text $labels($ff) entry $f.$ff -textvariable [namespace current]::geoloc$ff grid $f.l$ff -row $row -column 0 -sticky e grid $f.$ff -row $row -column 1 -sticky ew incr row } grid columnconfigure $f 1 -weight 1 $w draw } proc geoloc::do_publish {w} { variable fields variable myjid foreach ff $fields { variable geoloc$ff } set args {} foreach ff $fields { lappend args -$ff [set geoloc$ff] } foreach connid [jlib::connections] { if {[string equal $myjid [jlib::connection_jid $connid]] || \ [string equal $myjid [::msgcat::mc "All"]]} { eval [list publish $connid \ -command [namespace current]::publish_result] \ $args break } } foreach ff $fields { unset geoloc$ff } unset myjid destroy $w } # $res is one of: OK, ERR, DISCONNECT proc geoloc::publish_result {res child} { switch -- $res { ERR { set error [error_to_string $child] } default { return } } NonmodalMessageDlg [epath] \ -aspect 50000 \ -icon error \ -title [::msgcat::mc "Error"] \ -message [::msgcat::mc "User location publishing failed: %s" $error] } proc geoloc::show_unpublish_dialog {} { variable myjid set w .user_geoloc if {[winfo exists $w]} { destroy $w } set connids [jlib::connections] if {[llength $connids] == 0} { NonmodalMessageDlg [epath] \ -aspect 50000 \ -icon error \ -title [::msgcat::mc "Error"] \ -message [::msgcat::mc "Unpublishing is only possible\ while being online"] return } Dialog $w -title [::msgcat::mc "User location"] \ -modal none -separator 1 -anchor e -default 0 -cancel 1 -parent . $w add -text [::msgcat::mc "Unpublish"] \ -command [list [namespace current]::do_unpublish $w] $w add -text [::msgcat::mc "Cancel"] -command [list destroy $w] set f [$w getframe] set connjids [list [::msgcat::mc "All"]] foreach connid $connids { lappend connjids [jlib::connection_jid $connid] } set myjid [lindex $connjids 0] label $f.ccap -text [::msgcat::mc "Use connection:"] ComboBox $f.conn -editable false \ -values $connjids \ -textvariable [namespace current]::myjid if {[llength $connjids] > 1} { grid $f.ccap -row 0 -column 0 -sticky e grid $f.conn -row 0 -column 1 -sticky ew } grid columnconfigure $f 1 -weight 1 if {[llength $connids] == 1} { do_unpublish $w } else { $w draw } } proc geoloc::do_unpublish {w} { variable myjid foreach connid [jlib::connections] { if {[string equal $myjid [jlib::connection_jid $connid]] || \ [string equal $myjid [::msgcat::mc "All"]]} { unpublish $connid \ -command [namespace current]::unpublish_result break } } unset myjid destroy $w } # $res is one of: OK, ERR, DISCONNECT proc geoloc::unpublish_result {res child} { switch -- $res { ERR { if {[lindex [error_type_condition $child] 1] == "item-not-found"} { return } set error [error_to_string $child] } default { return } } NonmodalMessageDlg [epath] \ -aspect 50000 \ -icon error \ -title [::msgcat::mc "Error"] \ -message [::msgcat::mc "User location unpublishing failed: %s" $error] } proc geoloc::provide_userinfo {notebook connid jid editable} { variable geoloc variable m2d variable ::userinfo::userinfo variable fields variable labels if {$editable} return set barejid [node_and_server_from_jid $jid] if {![info exists geoloc(alt,$connid,$barejid)]} return foreach ff $fields { set userinfo(geoloc$ff,$jid) $geoloc($ff,$connid,$barejid) } set f [pep::get_userinfo_dialog_pep_frame $notebook] set mf [userinfo::pack_frame $f.geoloc [::msgcat::mc "User location"]] set row 0 foreach ff $fields { userinfo::pack_entry $jid $mf $row geoloc$ff $labels($ff) incr row } } # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/plugins/windows/0000755000175000017500000000000011076120366015677 5ustar sergeisergeitkabber-0.11.1/plugins/windows/taskbar.tcl0000644000175000017500000001257311054503013020030 0ustar sergeisergei# $Id: taskbar.tcl 1488 2008-08-25 10:14:35Z sergei $ # MS Windows taskbar and tray icon support. # Requires Winico package # (http://tktable.sourceforge.net/winico/winico.html) ########################################################################## if {![cequal $::interface tk]} return if {[catch { package require Winico }]} return ########################################################################## namespace eval taskbar { variable s2p array set s2p [list blank 0 \ available 1 \ away 2 \ chat 3 \ dnd 4 \ xa 5 \ unavailable 6 \ invisible 7 \ browser 8 \ group 9 \ browser32 10 \ group32 11 \ available32 12 \ message1 13 \ message2 14 \ message3 15] variable options custom::defvar options(enable) 1 \ [::msgcat::mc "Enable windows tray icon."] \ -group Systray -type boolean \ -command [namespace code enable_disable] } ########################################################################## # # Systray icons # ########################################################################## proc taskbar::set_current_theme {} { variable icon variable s2p global userstatus set newicon [winico createfrom [pixmaps::get_filename docking/tkabber]] if {[info exists icon]} { set oldicon $icon set icon $newicon # Change taskbar icon: winico taskbar add $newicon # TODO ideally there should be a call to [enable_disable] # instead but the latter relies on the existence of some # windows (i.e. it's called from finload_hook) while this # proc is called for the first time earlier in the loading # sequence... configure .tray $userstatus # Change icons of all mapped toplevels: foreach w [wm stackorder .] { win_icon_setup $w } winico delete $oldicon } else { set icon $newicon } } hook::add set_theme_hook [namespace current]::taskbar::set_current_theme ########################################################################## proc taskbar::enable_disable {args} { variable options set m .tray if {$options(enable) && ![winfo exists $m]} { ifacetk::systray::create $m \ -createcommand [namespace code create] \ -configurecommand [namespace code configure] \ -destroycommand [namespace code destroy] } elseif {!$options(enable) && [winfo exists $m]} { ifacetk::systray::destroy $m } } hook::add finload_hook [namespace current]::taskbar::enable_disable ########################################################################## proc taskbar::create {m} { variable icon variable s2p set m [ifacetk::systray::popupmenu .tray] winico taskbar add $icon -pos $s2p(unavailable) \ -callback [namespace code [list callback $m %m %x %y]] \ -text [ifacetk::systray::balloon_text] } ########################################################################## proc taskbar::configure {m status} { variable icon variable s2p if {[info exists icon] && ![cequal $icon ""]} { winico taskbar modify $icon -pos $s2p($status) \ -text [ifacetk::systray::balloon_text] } } ########################################################################## proc taskbar::destroy {m} { variable icon if {[info exists icon] && ![cequal $icon ""]} { winico taskbar delete $icon ::destroy $m } } ########################################################################## proc taskbar::callback {m event x y} { switch -- $event { WM_LBUTTONUP { ifacetk::systray::restore } WM_MBUTTONUP { ifacetk::systray::withdraw } WM_RBUTTONUP { $m post $x $y } } } ########################################################################## # # Window & taskbar icons # ########################################################################## proc taskbar::win_icons {} { variable icon variable s2p winico setwindow . $icon small $s2p(unavailable) winico setwindow . $icon big $s2p(available32) trace variable ::curuserstatus w [namespace code update] bind all +[namespace code { if {[string equal [winfo toplevel %W] %W]} { win_icon_setup %W } }] } hook::add finload_hook [namespace current]::taskbar::win_icons ########################################################################## proc taskbar::win_icon_setup {w} { variable icon variable s2p global userstatus if {[cequal $icon ""]} return # Special case for the main window (which is also the roster # window in windowed UI mode) -- it shows the current # user status in its window icon: if {[string equal $w .]} { winico setwindow $w $icon small $s2p($userstatus) winico setwindow $w $icon big $s2p(available32) return } switch -- [winfo class $w] { Chat { winico setwindow $w $icon small $s2p(group) winico setwindow $w $icon big $s2p(group32) } JDisco { winico setwindow $w $icon small $s2p(browser) winico setwindow $w $icon big $s2p(browser32) } default { winico setwindow $w $icon small $s2p(available) winico setwindow $w $icon big $s2p(available32) } } } ########################################################################## proc taskbar::update {name1 {name2 ""} {op ""}} { global curuserstatus variable icon variable s2p winico setwindow . $icon small $s2p($curuserstatus) } ########################################################################## # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/plugins/windows/console.tcl0000644000175000017500000000170110661011076020040 0ustar sergeisergei# $Id: console.tcl 1188 2007-08-16 09:00:46Z sergei $ # Add a console menu item under windows namespace eval console { variable showConsole 0 hook::add finload_hook [namespace current]::add_console_menu console eval { bind . { consoleinterp eval {set ::plugins::console::showConsole 1} } bind . { consoleinterp eval {set ::plugins::console::showConsole 0} } } } proc console::add_console_menu {} { catch { set ndx [.menubar index [::msgcat::mc "Help"]] set menu [.menubar entrycget $ndx -menu] $menu add separator $menu add checkbutton -label [::msgcat::mc "Show console"] \ -command [namespace current]::show_console \ -variable [namespace current]::showConsole show_console } } proc console::show_console {} { variable showConsole if {$showConsole} { console show } else { console hide } } tkabber-0.11.1/plugins/windows/mousewheel.tcl0000644000175000017500000000173010602263326020557 0ustar sergeisergei# $Id: mousewheel.tcl 1068 2007-03-27 18:47:50Z sergei $ namespace eval mousewheel { } proc mousewheel::convert_to_button {modifier d x y} { switch -- $modifier { shift { set scroll_up <> set scroll_down <> } default { set scroll_up <> set scroll_down <> } } if {$d < 0} { for {set i 0} {$i > $d} {incr i -120} { event generate [winfo containing $x $y] $scroll_down } } else { for {set i 0} {$i < $d} {incr i 120} { event generate [winfo containing $x $y] $scroll_up } } } bind Text " " bind ListBox " " bind Text " " bind ListBox " " bind all \ [list [namespace current]::mousewheel::convert_to_button none %D %X %Y] bind all +break bind all \ [list [namespace current]::mousewheel::convert_to_button shift %D %X %Y] bind all +break tkabber-0.11.1/plugins/richtext/0000755000175000017500000000000011076120366016037 5ustar sergeisergeitkabber-0.11.1/plugins/richtext/urls.tcl0000644000175000017500000002017611014607652017536 0ustar sergeisergei# $Id: urls.tcl 1440 2008-05-20 17:51:38Z sergei $ # "Rich text" framework -- processing of URLs. option add *urlforeground blue widgetDefault option add *urlactiveforeground red widgetDefault option add *urlcursor hand2 widgetDefault namespace eval urls { variable options variable urlid 0 # TODO add user:pass@ match # TODO sync TLDs with http://www.icann.org/tlds/app-index.htm set url_regexp { (^|\s) ([^\w\d]*) ( (?: (?: ftp|https?)://[-\w]+(\.\w[-\w]*)* | (?: [a-z0-9][-a-z0-9]* \. )+ (?: com | edu | biz | gov | in(?:t|fo) | mil | net | org | name | aero | arpa | coop | museum | pro | travel | asia | [a-z][a-z] ) ) (?: : \d+ )? (?: (?: / [^.,?!:;"'<>()\[\]{}\s\x7F-\xFF]* )? (?: [.,?!:;]+ [^.,?!:;"'<>()\[\]{}\s\x7F-\xFF]+ )* )? ) ([^\w\d]*) (\s|$) } } proc urls::process_urls {atLevel accName} { upvar #$atLevel $accName chunks set out {} foreach {s type tags} $chunks { if {$type != "text"} { # pass through lappend out $s $type $tags continue } set ix 0; set us 0; set ue 0 while {[spot_url $s $ix us ue]} { if {$us - $ix > 0} { # dump chunk before URL: lappend out [string range $s $ix [expr {$us - 1}]] $type $tags } set title [string range $s $us $ue] set url [make_url $title] lappend out $url url $tags ::richtext::property_update url:title,$url $title set ix [expr {$ue + 1}] } if {[string length $s] - $ix > 0} { # dump chunk after URL: lappend out [string range $s $ix end] $type $tags } } set chunks $out } proc urls::spot_url {what at startVar endVar} { variable url_regexp set matched [regexp -expanded -nocase -indices \ -start $at -- $url_regexp $what -> _ _ bounds] if {!$matched} { return false } upvar 1 $startVar us $endVar ue lassign $bounds us ue return true } proc urls::make_url {title} { if {[regexp -nocase {^(ftp|https?)://} $title]} { return $title } if {[regexp -nocase {^ftp} $title]} { return "ftp://$title" } return "http://$title" } proc urls::encode_url {url} { set utf8_url [encoding convertto utf-8 $url] set len [string length $utf8_url] set encoded_url "" for {set i 0} {$i < $len} {incr i} { binary scan $utf8_url @${i}c sym set sym [expr {$sym & 0xFF}] if {$sym >= 128 || $sym <= 32} { append encoded_url [format "%%%02X" $sym] } else { append encoded_url [binary format c $sym] } } return $encoded_url } # Renders a rich text chunk of type "url" in the rich text widget. # # Accepts several trailing options: # -title TITLE -- allows to "hide" the actual URL # and display its title instead; # other options are passed to [config_url], see below. # # An URL is physically represented by pieces of text between tags: # # [actual URL] title or URL # # That is: # * The "url" tag is always present and it covers all the URL text; # * The "href_N" tag (whth auto-generated integer part N) is also # always pesent. It contains also the URL itself, if the URL title # is not specified, or that URL title; # * The "uri" tag is present only if the URL title was specified, and # then this tag denotes the actuall hidden URL and it then appears # earlier in the text that the related "href_N" tag. proc urls::render_url {w type url tags args} { variable options variable urlid set privtag href_$urlid $w tag configure $privtag -foreground $options(foreground) -underline 1 set url_start [$w index {end - 1 char}] set title [url_get_title $url $args] if {$title != {}} { set uri_tag [list [list uri $url]] set url $title set show_hints true } else { set uri_tag [list] set show_hints false } $w insert end $url [lfuse $tags [list $privtag] $uri_tag] $w tag add $type $url_start {end - 1 char} $w tag bind $privtag \ [list ::richtext::highlighttext \ $w $privtag $options(activeforeground) $options(cursor)] $w tag bind $privtag \ [list ::richtext::highlighttext \ $w $privtag $options(foreground) [lindex [$w configure -cursor] 3]] if {$show_hints} { $w tag bind $privtag \ +[list [namespace current]::balloon $w $privtag enter %x %y %X %Y] $w tag bind $privtag \ +[list [namespace current]::balloon $w $privtag motion %x %y %X %Y] $w tag bind $privtag \ +[list [namespace current]::balloon $w $privtag leave %x %y %X %Y] } # Default URL action: config_url $w $privtag \ -command [list [namespace current]::browse_url %W %x %y] eval {config_url $w $privtag} $args incr urlid return $privtag ;# to allow further configuration of this tag } proc urls::balloon {w tag action x y X Y} { switch -- $action { enter { ::balloon::default_balloon $w:$tag enter $X $Y -text [get_url $w $x $y] } motion { ::balloon::default_balloon $w:$tag motion $X $Y -text [get_url $w $x $y] } leave { ::balloon::default_balloon $w:$tag leave $X $Y } } } # Tries to find the title for the URL $url either in the $options # (which are usually those passed to [render_url] or among the # properties of the message being processed. proc urls::url_get_title {url options} { array set opts $options if {[info exists opts(-title)]} { set title $opts(-title) } elseif {[::richtext::property_exists url:title,$url]} { set title [::richtext::property_get url:title,$url] } else { set title "" } return $title } # Configures a URL $tag rendered in a text widget $w. # This tag is either a metatag "url" or some other tag # returned by the [render_url] proc. # $args should be a list of option/value pairs. # Supported options: # -command: invoke this command when the URL is clicked with LMB; # replaces any existing command bound to the URL. # -add-command: same as -command, but preserves the existing command. # any number of commands can be assotiated with a URL this way. proc urls::config_url {w tag args} { foreach {key val} $args { switch -- $key { -command { $w tag bind $tag $val } -add-command { $w tag bind $tag +$val } } } } # Passes a URL containing the $x,$y point in the text widget $w # to the system-dependent browser program. # The URL undergoes W3C-urlencoding first, to be ASCII-clean. proc urls::browse_url {w x y} { browseurl [encode_url [get_url $w $x $y]] } # Returns a URL containing the $x,$y point in the text widget $w: proc urls::get_url {w x y} { set tags [$w tag names "@$x,$y"] set idx [lsearch $tags href_*] if {$idx < 0} return set idx1 [lsearch $tags uri*] if {$idx1 >= 0} { return [lindex [lindex $tags $idx1] 1] } else { lassign [$w tag prevrange url "@$x,$y"] a b return [$w get $a $b] } } # Copies an URL under $x,$y in $w into CLIPBOARD: proc urls::copy_url {w x y} { clipboard clear -displayof $w clipboard append -displayof $w [get_url $w $x $y] } proc urls::add_chat_win_popup_menu {m chatwin X Y x y} { set tags [$chatwin tag names "@$x,$y"] set idx [lsearch $tags href_*] if {$idx >= 0} { $m add command -label [::msgcat::mc "Copy URL to clipboard"] \ -command [list [namespace current]::copy_url $chatwin $x $y] } } hook::add chat_win_popup_menu_hook \ [namespace current]::urls::add_chat_win_popup_menu 10 proc urls::configure_richtext_widget {w} { variable options set options(foreground) [option get $w urlforeground Text] set options(activeforeground) [option get $w urlactiveforeground Text] set options(cursor) [option get $w urlcursor Text] # "uri" -- tag for "hidden" URLs (presented as their alt. text): $w tag configure uri -elide 1 } namespace eval urls { ::richtext::register_entity url \ -configurator [namespace current]::configure_richtext_widget \ -parser [namespace current]::process_urls \ -renderer [namespace current]::render_url \ -parser-priority 50 ::richtext::entity_state url 1 } # vim:ts=8:sts=4:sw=4:noet tkabber-0.11.1/plugins/richtext/chatlog.tcl0000644000175000017500000000410511014607652020164 0ustar sergeisergei# $Id: chatlog.tcl 1440 2008-05-20 17:51:38Z sergei $ # This is a (pretty much eclectic) framework to support various highlights # in chat messages. It registers a rich text entity "chatlog" and provides # for configuring a text widget to be ready to display highlights. # On the other hand, detection of such highlights is done elsewhere -- in the # already existing bits of code (that is, handling /me messages, server messages, # MUC subjects, etc). There are plans to eventually move such code to # this "chatlog" plugin. # NOTE that "real" configurable chat highlights are handled by the # highlights.tcl rich text plugin. namespace eval chatlog { } # This proc provides for reconfiguration of the chatlog tags. # It is intended to be used for post-configuration of the rich text # widgets when creating them to server as chat log windows, # since chatlog windows allow the customization of these parameters # via the Tk option database. proc chatlog::config {w args} { foreach {opt val} $args { switch -- $opt { -theyforeground { $w tag configure they -foreground $val } -meforeground { $w tag configure me -foreground $val } -serverlabelforeground { $w tag configure server_lab -foreground $val } -serverforeground { $w tag configure server -foreground $val } -infoforeground { $w tag configure info -foreground $val } -errforeground { $w tag configure err -foreground $val } -highlightforeground { $w tag configure highlight -foreground $val } default { return -code error "[namespace current]::config:\ Unknown option: $opt" } } } } proc chatlog::configure_richtext_widget {w} { # TODO do we need to provide some defaults? $w tag configure they $w tag configure me $w tag configure server_lab $w tag configure server $w tag configure info $w tag configure err } namespace eval chatlog { ::richtext::register_entity chatlog \ -configurator [namespace current]::configure_richtext_widget ::richtext::entity_state chatlog 1 } # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/plugins/richtext/stylecodes.tcl0000644000175000017500000001260611014607652020726 0ustar sergeisergei# $Id: stylecodes.tcl 1440 2008-05-20 17:51:38Z sergei $ namespace eval stylecodes { variable options ::custom::defgroup Stylecodes \ [::msgcat::mc "Handling of \"stylecodes\".\ Stylecodes are (groups of) special formatting symbols\ used to emphasize parts of the text by setting them\ with boldface, italics or underlined styles,\ or as combinations of these."] \ -group {Rich Text} \ -group Chat ::custom::defvar options(emphasize) 1 \ [::msgcat::mc "Emphasize stylecoded messages using different fonts."] \ -type boolean -group Stylecodes \ -command [namespace current]::update_config ::custom::defvar options(hide_markup) 1 \ [::msgcat::mc "Hide characters comprising stylecode markup."] \ -type boolean -group Stylecodes \ -command [namespace current]::update_config } proc stylecodes::process_stylecodes {atLevel accName} { upvar #$atLevel $accName chunks set out {} foreach {s type tags} $chunks { if {$type != "text"} { # pass through lappend out $s $type $tags continue } foreach elem [scan_stylecodes $s $type $tags {* / _ -}] { lappend out $elem } } set chunks $out } proc stylecodes::scan_stylecodes {what type tags stylecodes} { set len [string length $what] set out {} set si 0 for {set ix 0} {$ix < $len} {incr ix} { set startOK true set sc [spot_highlight $what $stylecodes ix startOK] if {$sc == {}} continue lassign $sc ls le ms me rs re pat if {$ls - $si > 0} { # dump the text before opening stylecode block: lappend out [string range $what $si [expr {$ls - 1}]] $type $tags } set sctags [stylecodes->tags $pat] # dump opening stylecode block: lappend out [string range $what $ls $le] stylecode [lfuse $tags $sctags] # dump highlighted text: lappend out [string range $what $ms $me] $type [lfuse $tags $sctags] # dump closing stylecode block: lappend out [string range $what $rs $re] stylecode [lfuse $tags $sctags] set si $ix } if {[string length $what] - $si > 0} { lappend out [string range $what $si end] $type $tags } return $out } proc stylecodes::spot_highlight {what stylecodes ixVar startOKVar} { upvar 1 $ixVar ix $startOKVar startOK set ls $ix set pattern {} while {[eat_stylecode $what $ix stylecodes pattern startOK]} { incr ix } set startOK false if {$ix == $ls} return if {[is_scbreak [string index $what $ix]]} return ;# stylecode break after stylecode # found opening stylecode block. # create pattern for ending stylecode block and seek for it: set pat [join $pattern ""] set rs [string first $pat $what $ix] if {$rs == -1} { return {} } # found closing stylecode block. if {$rs - $ix == 0} { return {} } ;# empty highlight if {[is_scbreak [string index $what [expr {$rs - 1}]]]} { # stylecode break before return } if {[string first \n [string range $what $ix $rs]] != -1} { # intervening newline return {} } set patlen [string length $pat] if {![is_scbreak [string index $what [expr {$rs + $patlen}]]]} { # no proper break after closing stylecode block return {} } set le [expr {$ls + $patlen - 1}] set ms [expr {$ls + $patlen}] set me [expr {$rs - 1}] set re [expr {$rs + $patlen - 1}] # skip past the closing stylecode block set ix [expr {$re + 1}] return [list $ls $le \ $ms $me \ $rs $re \ $pat] } proc stylecodes::eat_stylecode {what at scodesVar patVar startOKVar} { upvar 1 $scodesVar scodes $patVar pat $startOKVar startOK set ix 0 set c [string index $what $at] foreach sc $scodes { if {$c == $sc} { if {!$startOK} { return false } set scodes [lreplace $scodes $ix $ix] set pat [linsert $pat 0 $c] return true } incr ix } set startOK [is_scbreak $c] return false } proc stylecodes::is_scbreak {c} { expr {[string is space $c] || [string is punct $c]} } proc stylecodes::stylecodes->tags {pattern} { set out {} array set tags {* bold / italic _ underlined - overstricken} foreach sc [split $pattern ""] { lappend out $tags($sc) } return $out } proc stylecodes::render_stylecode {w type piece tags} { $w insert end $piece \ [richtext::fixup_tags [concat $type $tags] {{bold italic}}] } proc stylecodes::configure_richtext_widget {w} { variable options if {$options(emphasize)} { $w tag configure stylecode -elide $options(hide_markup) $w tag configure bold -font $::ChatBoldFont $w tag configure italic -font $::ChatItalicFont $w tag configure bold_italic -font $::ChatBoldItalicFont $w tag configure underlined -underline 1 $w tag configure overstricken -overstrike 1 } else { $w tag configure stylecode -elide 0 $w tag configure bold -font $::ChatFont $w tag configure italic -font $::ChatFont $w tag configure bold_italic -font $::ChatFont $w tag configure underlined -underline 0 $w tag configure overstricken -overstrike 0 } } proc stylecodes::update_config {args} { foreach w [::richtext::textlist] { configure_richtext_widget $w } } namespace eval stylecodes { ::richtext::register_entity stylecode \ -configurator [namespace current]::configure_richtext_widget \ -parser [namespace current]::process_stylecodes \ -renderer [namespace current]::render_stylecode \ -parser-priority 80 ::richtext::entity_state stylecode 1 } # vim:ts=8:sts=4:sw=4:noet tkabber-0.11.1/plugins/richtext/highlight.tcl0000644000175000017500000000742310567663515020534 0ustar sergeisergei# $Id: highlight.tcl 968 2007-02-23 22:14:37Z sergei $ namespace eval highlight { custom::defgroup Highlight [::msgcat::mc "Groupchat message highlighting plugin options."] \ -group Chat \ -group {Rich Text} custom::defvar options(enable_highlighting) 1 \ [::msgcat::mc "Enable highlighting plugin."] \ -type boolean -group Highlight \ -command [namespace current]::on_state_changed custom::defvar options(highlight_nick) 1 \ [::msgcat::mc "Highlight current nickname in messages."] \ -type boolean -group Highlight custom::defvar options(highlight_substrings) {} \ [::msgcat::mc "Substrings to highlight in messages."] \ -type string -group Highlight custom::defvar options(highlight_whole_words) 1 \ [::msgcat::mc "Highlight only whole words in messages."] \ -type boolean -group Highlight } proc highlight::configure_richtext_widget {w} { # TODO some defaults may be? $w tag configure highlight } proc highlight::process_highlights {atLevel accVar} { upvar #$atLevel $accVar chunks variable options set subs [split $options(highlight_substrings) " "] if {$options(highlight_nick) && [::richtext::property_exists mynick]} { lappend subs [::richtext::property_get mynick] } set out {} foreach {s type tags} $chunks { if {$type != "text"} { # pass through lappend out $s $type $tags continue } set ts 0 foreach {ms me} [spot_highlights $s $subs] { # Write out text before current highlight, if any: if {$ts < $ms} { lappend out [string range $s $ts [expr {$ms - 1}]] $type $tags } # Write out current highlight: lappend out [string range $s $ms $me] highlight $tags set ts [expr {$me + 1}] } # Write out text after the last highlight, if any: if {[string length $s] - $ts > 0} { lappend out [string range $s $ts end] $type $tags } } set chunks $out } proc highlight::spot_highlights {s subs} { variable options set words [textutil::splitx $s {([\t \r\n]+)}] set ind_end 0 set stop_ind [string length $s] set ranges {} set found 1 while {$found && $ind_end < $stop_ind} { set found 0 set ind $ind_end foreach str $subs { set len [string length $str] if {$len > 0 && [set match [string first $str $s $ind]] >= 0} { if {!$options(highlight_whole_words) || \ (![string is wordchar -strict [string index $s [expr {$match - 1}]]] && \ ![string is wordchar -strict [string index $s [expr {$match + $len}]]])} { if {!$found} { set found 1 set ind_start $match set ind_end [expr {$match + $len}] } elseif {$match < $ind_start} { set ind_start $match set ind_end [expr {$match + $len}] } } } } if {$found} { lappend ranges $ind_start [expr {$ind_end - 1}] } } return $ranges } proc highlight::render_highlight {w type piece tags} { $w insert end $piece [lfuse $type $tags] } # The following procedure reports highlighting inside URLs too proc highlight::check_highlighted_message {vpersonal nick body} { variable options upvar 2 $vpersonal personal set subs [split $options(highlight_substrings) " "] if {$options(highlight_nick)} { lappend subs $nick } if {![lempty [spot_highlights $body $subs]]} { set personal 1 } } hook::add check_personal_message_hook \ [namespace current]::highlight::check_highlighted_message proc highlight::on_state_changed {args} { variable options ::richtext::entity_state highlight $options(enable_highlighting) } namespace eval highlight { ::richtext::register_entity highlight \ -configurator [namespace current]::configure_richtext_widget \ -parser [namespace current]::process_highlights \ -renderer [namespace current]::render_highlight \ -parser-priority 60 on_state_changed } # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/plugins/richtext/emoticons.tcl0000644000175000017500000003711610706602252020551 0ustar sergeisergei# $Id: emoticons.tcl 1277 2007-10-21 07:50:02Z sergei $ catch {package require vfs::zip} namespace eval emoticons { variable themes variable emoticons ;# mapping from text mnemonics to images variable images ;# reference counts of images variable txtdefaults ;# default textual representation variable lasttext "" variable lastX variable lastY variable faces_regexp "" variable options ::custom::defgroup Emoticons \ [::msgcat::mc "Handling of \"emoticons\".\ Emoticons (also known as \"smileys\")\ are small pictures resembling a human face\ used to represent user's emotion. They are\ typed in as special mnemonics like :)\ or can be inserted using menu."]\ -group {Rich Text} \ -group Chat ::custom::defvar options(show_emoticons) 1 \ [::msgcat::mc "Show images for emoticons."] \ -type boolean -group Emoticons \ -command [namespace current]::toggle_emoticons set options(no_theme) [::msgcat::mc "None"] set options(active_theme) $options(no_theme) custom::defvar options(theme) "" \ [::msgcat::mc "Tkabber emoticons theme. To make new theme visible\ for Tkabber put it to some subdirectory of %s." \ [file join $::configdir emoticons]] \ -group Emoticons -type options \ -values [list "" $options(no_theme)] \ -command [namespace current]::on_theme_changed custom::defvar options(match_whole_word) 1 \ [::msgcat::mc "Use only whole words for emoticons."] \ -group Emoticons -type boolean custom::defvar options(handle_lol) 0 \ [::msgcat::mc "Handle ROTFL/LOL smileys -- those like :))) --\ by \"consuming\" all that parens and rendering the\ whole word with appropriate icon."] \ -group Emoticons -type boolean \ -command [namespace current]::on_regex_mode_changed # The [enable_subsystem] proc called by postload_hook # completes initialization, if needed. } proc emoticons::add {face image} { variable options variable emoticons variable images variable faces_regexp if {$face == ""} { return -code error "Empty emoticon mnemonic for image \"$image\"" } if {![info exists images($image)]} { set images($image) 0 } if {[info exists emoticons($face)]} { incr images($emoticons($face)) -1 } set emoticons($face) $image incr images($image) if {$faces_regexp != ""} { append faces_regexp | } append faces_regexp [re_escape $face] if {$options(handle_lol)} { append faces_regexp + } } proc emoticons::get {word} { variable emoticons if {[info exists emoticons($word)]} { return $emoticons($word) } else { return "" } } proc emoticons::put {txt word} { variable emoticons if {[info exists emoticons($word)]} { $txt image create end -image $emoticons($word) $txt tag add emoticon_image "end-2char" } } # Clears all arrays related to emoticons # and sets logical reference counts of images to zero. # NOTE that it does not actually frees unused images. # Call [sweep] or [load_dir] (which calls [sweep]) after # calling [clear]. proc emoticons::clean {} { variable images variable emoticons variable txtdefaults variable faces_regexp # Prepare for loading: array unset emoticons * array unset txtdefaults * set faces_regexp "" # Set refcount to 0 on all images: foreach iname [array names images] { set images($iname) 0 } } # Sweeps out orphaned (not used anymore) physical images (i.e. those # with logical refcounts less or equal than 0. # NOTE that images which are still physically in use (by Tk) are not # deleted in 8.4+. proc emoticons::sweep {} { variable images variable txtdefaults foreach iname [array names images] { if {$images($iname) < 1} { # Work around Tcl 8.3 which lacks [image inuse] (always kill in this case): if {[catch {image inuse $iname} keep]} { set keep 0 } if {! $keep} { delete_image $iname unset images($iname) if {[info exists txtdefaults($iname)]} { unset txtdefaults($iname) } } } } } # For backward compatibility: namespace eval ::emoteicons {} proc ::emoteicons::load_dir {dir} \ [list eval [list [namespace current]::emoticons::load_dir] \$dir] # Loads a new set of emoticons, adding them to the existing set, # replacing any existing emoticons with the same mnemonics: proc emoticons::load_dir {dir} { variable images variable faces_regexp if {$dir != ""} { set icondef_path [file join $dir icondef.xml] if {![file isfile $icondef_path]} { ### TODO: some error messages return } set f [open $icondef_path] set icondef [read $f] close $f set faces_regexp "" set parser [jlib::wrapper:new "#" "#" \ [list [namespace current]::parse_icondef $dir]] jlib::wrapper:elementstart $parser stream:stream {} {} jlib::wrapper:parser $parser parse $icondef jlib::wrapper:parser $parser configure -final 0 jlib::wrapper:free $parser } # Sweep out orphaned images: sweep } proc emoticons::parse_icondef {dir xmldata} { jlib::wrapper:splitxml $xmldata tag vars isempty chdata children if {$tag != "icondef"} { # TODO: error message return } foreach child $children { parse_item $dir $child } } proc emoticons::parse_item {dir item} { jlib::wrapper:splitxml $item tag vars isempty chdata children switch -- $tag { name {} version {} description {} author {} creation {} meta {} icon { parse_icon $dir $children } } } proc emoticons::parse_icon {dir items} { variable txtdefaults variable images set faces {} set txtdefault "" set graphic "" foreach item $items { jlib::wrapper:splitxml $item tag vars isempty chdata children switch -- $tag { text { if {$chdata == ""} continue ;# skip empty element lappend faces $chdata if {$txtdefault == "" || \ [jlib::wrapper:getattr $vars default] == "true"} { set txtdefault $chdata } } object { switch -glob -- [jlib::wrapper:getattr $vars mime] { image/* {set graphic $chdata} } } graphic { # For compatibility with older versions of icondef.xml switch -glob -- [jlib::wrapper:getattr $vars type] { image/* {set graphic $chdata} } } sound {} } } #debugmsg emoticons "E: $graphic; $txts" if {$graphic == "" || [llength $faces] == 0} return # Work around absence of default face: if {$txtdefault == ""} { set txtdefault [lindex $faces 0] } set iname [imagename $txtdefault] # TODO what if more than one face match existing images? foreach face $faces { set icon [imagename $face] if {[info exists images($icon)]} { set iname $icon break } } create_image $iname [file join $dir $graphic] set images($iname) 0 ;# Initial refcount is zero since it'll bumped by successive [add]s: foreach face $faces { add $face $iname } set txtdefaults($iname) $txtdefault } # Constructs a name for the emoticon image from its mnemonic. # Since [image] creates a command with the name of the image, we # add our namespace as a prefix. proc emoticons::imagename {mnemonic} { return [namespace current]::emoticon_$mnemonic } proc emoticons::create_image {name file} { image create photo $name -file $file return $name } proc emoticons::delete_image {name} { image delete $name } proc emoticons::show_menu {iw} { variable txtdefaults set imgs [array names txtdefaults] if {[llength $imgs] == 0} return set m .emoticonsmenu if {[winfo exists $m]} { destroy $m } menu $m -tearoff 0 set rows [expr {floor(sqrt([llength $imgs]))}] set row 0 foreach img $imgs { if {$row >= $rows} { $m add command -image $img -columnbreak 1 \ -label $txtdefaults($img) \ -command [list [namespace current]::insert $iw \ $txtdefaults($img)] set row 1 } else { $m add command -image $img \ -label $txtdefaults($img) \ -command [list [namespace current]::insert $iw \ $txtdefaults($img)] incr row } } bind $m \ [list [namespace current]::balloon $m enter %X %Y %x %y] bind $m \ [list [namespace current]::balloon $m motion %X %Y %x %y] bind $m \ [list [namespace current]::balloon $m leave %X %Y %x %y] tk_popup $m [winfo pointerx .] [winfo pointery .] } # trying to get motion events in a menu is problematic... proc emoticons::balloon {w action X Y x y} { variable lasttext variable lastX variable lastY if {[cequal [set index [$w index @$x,$y]] none]} { if {![cequal $lasttext ""]} { balloon::default_balloon $w:$lasttext leave $lastX $lastY } return } set text [$w entrycget $index -label] switch -- $action { motion { if {![cequal $text $lasttext]} { if {![cequal $lasttext ""]} { balloon::default_balloon $w:$lasttext leave $lastX $lastY } balloon::default_balloon $w:$text enter [set lastX $X] \ [set lastY $Y] \ -text [set lasttext $text] } } leave { set lasttext "" } } balloon::default_balloon $w:$text $action $X $Y -text $text } proc emoticons::insert {iw text} { set p "" switch -- [$iw get "insert - 1 chars"] { "" - " " - "\n" {} default { if {![cequal [$iw index "insert -1 chars"] 1.0]} { set p " " } } } $iw insert insert "$p$text " } event add <> event add <> if {$::tcl_platform(platform) == "windows"} { # workaround for shortcuts in russian keyboard layout event add <> } proc emoticons::setup_bindings {chatid type} { set iw [chat::input_win $chatid] bind $iw <> \ [list [namespace current]::show_menu $iw] bind $iw <> +break } proc emoticons::process_emoticons {atLevel accName} { upvar #$atLevel $accName chunks set out {} foreach {s type tags} $chunks { if {$type != "text"} { # pass through lappend out $s $type $tags continue } set ix 0; set fs 0; set fe 0 while {[spot_face $s $ix fs fe]} { if {$fs - $ix > 0} { # dump chunk before emoticon: lappend out [string range $s $ix [expr {$fs - 1}]] $type $tags } # dump emoticon: lappend out [string range $s $fs $fe] emoticon $tags set ix [expr {$fe + 1}] } if {[string length $s] - $ix > 0} { # dump chunk after emoticon: lappend out [string range $s $ix end] $type $tags } } set chunks $out } proc emoticons::spot_face {what at fsVar feVar} { variable options variable faces_regexp if {$faces_regexp == ""} {return false} upvar 1 $fsVar fs $feVar fe foreach inds [regexp -all -inline -indices -start $at -- $faces_regexp $what] { lassign $inds fsv fev if {!$options(match_whole_word) || \ ([string is space [string index $what [expr {$fsv-1}]]] && \ [string is space [string index $what [expr {$fev+1}]]])} { set fs $fsv set fe $fev return true } } return false } proc emoticons::render_emoticon {w type word tags} { variable options if {$options(handle_lol)} { set word [string_collapseright $word] } if {[get $word] != {}} { $w insert end $word emoticon put $w $word } else { $w insert end $word } } # TODO good candidate to go outside: proc emoticons::re_escape {s} { return [string map {\\ \\\\ * \\* . \\. [ \\[ ] \\] \{ \\{ \} \\} ( \\( ) \\) | \\| ? \\? $ \\$ ^ \\^ + \\+} $s] } proc emoticons::configure_richtext_widget {w} { variable options if {$options(show_emoticons)} { $w tag configure emoticon -elide 1 $w tag configure emoticon_image -elide 0 } else { $w tag configure emoticon -elide 0 $w tag configure emoticon_image -elide 1 } } proc emoticons::toggle_emoticons {args} { foreach w [::richtext::textlist] { configure_richtext_widget $w } } proc emoticons::enumerate_available_themes {} { set dirs [concat \ [glob -nocomplain -directory [fullpath emoticons] *] \ [glob -nocomplain -directory [file join $::configdir emoticons] *]] foreach dir $dirs { enumerate_theme [namespace current]::themes $dir } } proc emoticons::enumerate_theme {varName dir} { set icondef_path [file join $dir icondef.xml] if {[file isfile $icondef_path]} { set thdir $dir } elseif {![catch {::vfs::zip::Mount $dir $dir} mount_fd] && \ ![catch {lindex [glob $dir/*/icondef.xml] 0} icondef_path]} { set thdir [file dirname $icondef_path] } else { return } if {![catch {open $icondef_path} f]} { set icondef [read $f] close $f } else { catch {::vfs::zip::Unmount $mount_fd $dir} return } set parser [jlib::wrapper:new "#" "#" \ [list [namespace current]::get_theme_name $varName $thdir]] jlib::wrapper:elementstart $parser stream:stream {} {} jlib::wrapper:parser $parser parse $icondef jlib::wrapper:parser $parser configure -final 0 jlib::wrapper:free $parser } proc emoticons::get_theme_name {varName dir xmldata} { upvar #0 $varName themes jlib::wrapper:splitxml $xmldata tag vars isempty cdata children if {$tag == "name"} { set themes($cdata) $dir return 1 } foreach child $children { if {[get_theme_name $varName $dir $child]} { return 1 } } return 0 } # Gets called when options(theme) changes proc emoticons::on_theme_changed {args} { variable options if {$options(active_theme) != $options(theme)} { clean load_dir $options(theme) } } proc emoticons::find_themes {} { variable options variable themes set values {} array unset themes * enumerate_available_themes set theme_names [lsort [array names themes]] set idx [lsearch -exact $theme_names Default] if {$idx > 0} { set theme_names [linsert [lreplace $theme_names $idx $idx] 0 Default] } foreach theme $theme_names { lappend values $themes($theme) $theme } set values [linsert $values 0 "" $options(no_theme)] set idx [lsearch -exact $theme_names $options(theme)] if {$idx >= 0} { set theme [lindex $theme_names $idx] } else { set idx [lsearch -exact $theme_names Default] if {$idx >= 0} { set theme [lindex $theme_names [expr {$idx - 1}]] } else { set theme "" } } ::custom::configvar [namespace current]::options(theme) -values $values } proc emoticons::enable_subsystem {} { find_themes on_theme_changed ::richtext::entity_state emoticon 1 } proc emoticons::disable_subsystem {} { ::richtext::entity_state emoticon 0 } proc emoticons::on_regex_mode_changed {args} { rebuild_faces_regex } proc emoticons::rebuild_faces_regex {} { variable options variable emoticons variable faces_regexp set faces_regexp "" foreach face [array names emoticons] { if {$faces_regexp != ""} { append faces_regexp | } append faces_regexp [re_escape $face] if {$options(handle_lol)} { append faces_regexp + } } } # Returns a string with its rightmost repeated characters collapsed into one. # TODO good candidate to go into utils.tcl proc emoticons::string_collapseright {s} { set c [string index $s end] set s [string trimright $s $c] append s $c return $s } namespace eval emoticons { ::hook::add postload_hook [namespace current]::enable_subsystem 40 ::hook::add open_chat_post_hook [namespace current]::setup_bindings ::richtext::register_entity emoticon \ -configurator [namespace current]::configure_richtext_widget \ -parser [namespace current]::process_emoticons \ -renderer [namespace current]::render_emoticon \ -parser-priority 70 } # vim:ts=8:sts=4:sw=4:noet tkabber-0.11.1/plugins/general/0000755000175000017500000000000011076120366015622 5ustar sergeisergeitkabber-0.11.1/plugins/general/headlines.tcl0000644000175000017500000006500711054503013020260 0ustar sergeisergei# $Id: headlines.tcl 1488 2008-08-25 10:14:35Z sergei $ ############################################################################# namespace eval headlines { variable headid 0 variable headlines array set headlines {} variable options variable trees {} custom::defvar send_jids {} \ [::msgcat::mc "List of JIDs to whom headlines have been sent."] \ -group Hidden custom::defvar options(cache) 0 \ [::msgcat::mc "Cache headlines on exit and restore on start."] \ -group Messages -type boolean custom::defvar options(multiple) 0 \ [::msgcat::mc "Display headlines in single/multiple windows."] \ -group Messages -type options \ -values [list 0 [::msgcat::mc "Single window"] \ 1 [::msgcat::mc "One window per bare JID"] \ 2 [::msgcat::mc "One window per full JID"]] custom::defvar options(display_subject_only) 1 \ [::msgcat::mc "Do not display headline descriptions as tree nodes."] \ -group Messages -type boolean custom::defvar options(timestamp_format) {[%R] } \ [::msgcat::mc "Format of timestamp in headline tree view. Set to\ empty string if you don't want to see timestamps."] \ -group Messages -type string custom::defvar options(show_balloons) 0 \ [::msgcat::mc "Show balloons with headline messages over tree nodes."] \ -group Messages -type boolean } ############################################################################# package require md5 ############################################################################# proc headlines::process_message {connid from id type is_subject subject body err thread priority x} { switch -- $type { headline { show $connid $from $type $subject $body $thread $priority $x return stop } } return } hook::add process_message_hook \ [namespace current]::headlines::process_message ############################################################################# proc headlines::get_win {connid from} { variable options switch -- $options(multiple) { 0 { return .headlines } 1 { return .headlines_[jid_to_tag [node_and_server_from_jid $from]] } default { return .headlines_[jid_to_tag $from] } } } ############################################################################# proc headlines::get_tree {connid from} { set hw [get_win $connid $from] return $hw.tree } ############################################################################# proc headlines::open_window {connid from} { global tcl_platform variable options variable trees set hw [get_win $connid $from] if {[winfo exists $hw]} return switch -- $options(multiple) { 0 { set title [::msgcat::mc "Headlines"] set tabtitle [::msgcat::mc "Headlines"] } 1 { set user [node_and_server_from_jid $from] set title [format [::msgcat::mc "%s Headlines"] $user] set tabtitle [node_from_jid $from] } default { set title [format [::msgcat::mc "%s Headlines"] $from] set tabtitle [node_from_jid $from]/[resource_from_jid $from] } } set tw [get_tree $connid $from] if {[lsearch -exact $trees $tw] < 0} { lappend trees $tw } add_win $hw -title $title -tabtitle $tabtitle \ -raisecmd [list focus $tw] \ -class JDisco PanedWin $hw.pw -side right -pad 0 -width 4 pack $hw.pw -fill both -expand yes set uw [PanedWinAdd $hw.pw -weight 1] set dw [PanedWinAdd $hw.pw -weight 1] frame $dw.date label $dw.date.label -anchor w -text [::msgcat::mc "Date:"] entry $dw.date.ts \ -takefocus 0 \ -highlightthickness 0 \ -relief flat pack $dw.date -fill x pack $dw.date.label -side left pack $dw.date.ts -side left -fill x -expand yes frame $dw.from label $dw.from.label -anchor w -text [::msgcat::mc "From:"] entry $dw.from.jid \ -takefocus 0 \ -highlightthickness 0 \ -relief flat pack $dw.from -fill x pack $dw.from.label -side left pack $dw.from.jid -side left -fill x -expand yes frame $dw.subject label $dw.subject.lsubj -anchor w -text [::msgcat::mc "Subject:"] text $dw.subject.subj \ -height 1 \ -takefocus 0 \ -highlightthickness 0 \ -relief flat \ -state disabled \ -background [lindex [$dw.subject configure -background] 4] pack $dw.subject -fill x pack $dw.subject.lsubj -side left pack $dw.subject.subj -side left -fill x -expand yes foreach ent [list $dw.date.ts $dw.from.jid] { if {[catch {$ent configure -state readonly}]} { $ent configure -state disabled } } if {![info exists options(seencolor)]} { if {[string equal $tcl_platform(platform) unix] && \ ![string equal [option get $hw disabledForeground JDisco] ""]} { set options(seencolor) [option get $hw disabledForeground JDisco] } else { set options(seencolor) [option get $hw featurecolor JDisco] } } if {![info exists options(unseencolor)]} { set options(unseencolor) [option get $hw fill JDisco] } set sw [ScrolledWindow $uw.sw] Tree $tw -deltax 16 -deltay 18 \ -selectcommand [list [namespace current]::update_body \ $dw.date.ts $dw.from.jid $dw.subject.subj $hw.body] $sw setwidget $tw pack $sw -side top -expand yes -fill both $tw bindText [list [namespace current]::select_popup $hw] $tw bindText \ [list [namespace current]::action browse $hw] balloon::setup $tw -command [list [namespace current]::balloon $hw] # HACK bind $tw.c \ "[namespace current]::action browse $hw \[$tw selection get\]" bind $tw.c \ "[namespace current]::action delete $hw \[$tw selection get\]" bindscroll $tw.c set dsw [ScrolledWindow $dw.sw] text $hw.body -height 12 -state disabled \ -wrap word -takefocus 1 ::richtext::config $hw.body -using url $dsw setwidget $hw.body pack $dsw -expand yes -fill both -anchor nw bind $hw.body [list focus %W] foreach ww [list $hw.body $dw.date.ts $dw.from.jid $dw.subject.subj] { bind $ww [list Tree::_keynav up $tw] bind $ww [list Tree::_keynav down $tw] bind $ww [list Tree::_keynav left $tw] bind $ww [list Tree::_keynav right $tw] } hook::run open_headlines_post_hook $hw $tw $uw $dw } ############################################################################# proc headlines::show {connid from type subject body thread priority x {data {}}} { variable headid variable headlines variable trees variable options set subject [string trim $subject] set body [string trim $body] set desc "" set url "" set seconds [jlib::x_delay $x] foreach extra $x { jlib::wrapper:splitxml $extra tag vars isempty chdata children switch -- [jlib::wrapper:getattr $vars xmlns] { jabber:x:oob { foreach item $children { jlib::wrapper:splitxml $item tag vars isempty chdata children switch -- $tag { desc - url { set $tag [string trim $chdata] } } } } } } if {[string equal $subject ""] && [string equal $body ""] && \ [string equal $desc ""] && [string equal $url ""]} { # Ignore an empty message return } if {[string equal $subject ""]} { set subject $desc } else { if {$options(display_subject_only)} { set desc $subject } } if {$subject == ""} { set dsubject [::msgcat::mc ""] } else { set dsubject $subject } if {$desc == ""} { set ddesc [::msgcat::mc ""] } else { set ddesc $desc } set hw [get_win $connid $from] if {![winfo exists $hw]} { open_window $connid $from } set tw [get_tree $connid $from] if {$options(multiple) > 1} { set text $dsubject } else { set text $from } set fnode [str2node $text] if {![$tw exists $fnode]} { $tw insert end root $fnode -text [string map [list "\n" " "] $text] -open 1 \ -image browser/headline \ -fill $options(seencolor) \ -data [list type from text $text unseen 0] } if {($options(multiple) > 1) || ([string equal $subject $desc])} { set snode $fnode } else { set snode $fnode-subject-[str2node $dsubject] if {![$tw exists $snode]} { $tw insert end $fnode $snode -text [string map [list "\n" " "] $dsubject] -open 1 \ -image browser/headline \ -fill $options(seencolor) \ -data [list type subject text $subject unseen 0] } } set anode $fnode-article-[incr headid] if {[$tw exists $anode]} { $tw delete $anode } array set props [list type article unseen 1 seconds $seconds] array set props $data array set props [list text $desc url $url body $body] set nodetext \ [clock format $props(seconds) -format $options(timestamp_format)] append nodetext [string map [list "\n" " "] $ddesc] $tw insert end $snode $anode -text $nodetext -open 1 \ -fill $options(seencolor) \ -data [array get props] if {$props(unseen)} { $tw itemconfigure $anode -fill $options(unseencolor) } set headlines($anode) [list $connid $from $type $subject $body $thread $priority $x] update $tw $anode tab_set_updated $hw 1 message } ############################################################################# proc headlines::str2node {string} { set utf8str [encoding convertto utf-8 $string] if {[catch { ::md5::md5 -hex $utf8str } ret]} { return [::md5::md5 $utf8str] } else { return $ret } } ############################################################################# proc headlines::update_body {wdate wfrom wsubj wbody tw node} { variable headlines if {[catch { array set props [$tw itemcget $node -data] }] || ![info exists props(type)] || \ $props(type) != "article"} { set from "" set subj "" set body "" set date "" set url "" } else { set from [lindex $headlines($node) 1] set subj [string map [list "\n" " "] $props(text)] set body $props(body) set date [clock format $props(seconds)] set url $props(url) } foreach {w s} [list $wdate $date \ $wfrom $from] { $w configure -state normal $w delete 0 end $w insert 0 $s if {[catch {$w configure -state readonly}]} { $w configure -state disabled } } $wsubj configure -state normal $wsubj delete 0.0 end $wsubj insert 0.0 $subj $wsubj delete {end - 1 char} $wsubj mark set sel_start end $wsubj mark set sel_end 0.0 $wsubj configure -state disabled $wbody configure -state normal $wbody delete 0.0 end ::richtext::render_message $wbody "$body\n\n" "" if {$url != ""} { ::plugins::urls::render_url $wbody url $url {} \ -title [::msgcat::mc "Read on..."] \ -add-command [namespace code [list action markseen \ [winfo parent $tw] $node]] } $wbody mark set sel_start end $wbody mark set sel_end 0.0 $wbody configure -state disabled } ############################################################################# proc headlines::update_menu {menu num} { variable send_jids set ind 3 if {$num} { $menu delete $ind [expr $ind + $num - 1] } foreach jid $send_jids { $menu insert $ind command \ -label [format [::msgcat::mc "Forward to %s"] $jid] \ -command "[namespace current]::forward3 [list $menu] [list $jid] \ \$[namespace current]::headwindow \$[namespace current]::headnode" incr ind } } ############################################################################# namespace eval headlines { if {[winfo exists [set m .h1popmenu]]} { destroy $m } menu $m -tearoff 0 $m add command -label [::msgcat::mc "Browse"] \ -command "[namespace current]::action browse \ \$[namespace current]::headwindow \$[namespace current]::headnode" $m add separator $m add command -label [::msgcat::mc "Forward..."] \ -command "[namespace current]::action forward \ \$[namespace current]::headwindow \$[namespace current]::headnode" $m add separator $m add command -label [::msgcat::mc "Copy headline to clipboard"] \ -command "[namespace current]::action copy_headline \ \$[namespace current]::headwindow \$[namespace current]::headnode" $m add command -label [::msgcat::mc "Copy URL to clipboard"] \ -command "[namespace current]::action copy_url \ \$[namespace current]::headwindow \$[namespace current]::headnode" $m add command -label [::msgcat::mc "Toggle seen"] \ -command "[namespace current]::action toggle \ \$[namespace current]::headwindow \$[namespace current]::headnode" $m add command -label [::msgcat::mc "Delete"] \ -command "[namespace current]::action delete \ \$[namespace current]::headwindow \$[namespace current]::headnode" hook::add finload_hook [list [namespace current]::update_menu $m 0] if {[winfo exists [set m .h2popmenu]]} { destroy $m } menu $m -tearoff 0 $m add command -label [::msgcat::mc "Sort"] \ -command "[namespace current]::action sort \ \$[namespace current]::headwindow \$[namespace current]::headnode" $m add command -label [::msgcat::mc "Sort by date"] \ -command "[namespace current]::action datesort \ \$[namespace current]::headwindow \$[namespace current]::headnode" $m add command -label [::msgcat::mc "Mark all seen"] \ -command "[namespace current]::action markseen \ \$[namespace current]::headwindow \$[namespace current]::headnode" $m add command -label [::msgcat::mc "Mark all unseen"] \ -command "[namespace current]::action markunseen \ \$[namespace current]::headwindow \$[namespace current]::headnode" $m add command -label [::msgcat::mc "Delete seen"] \ -command "[namespace current]::action deleteseen \ \$[namespace current]::headwindow \$[namespace current]::headnode" $m add command -label [::msgcat::mc "Delete all"] \ -command "[namespace current]::action delete \ \$[namespace current]::headwindow \$[namespace current]::headnode" } ############################################################################# proc headlines::select_popup {hw node} { variable headwindow variable headnode $hw.tree selection set $node if {[catch { array set props [[set tw $hw.tree] itemcget $node -data] }]} { return } set headwindow $hw set headnode $node switch -- $props(type) { article { set hm .h1popmenu } default { set hm .h2popmenu } } tk_popup $hm [winfo pointerx .] [winfo pointery .] } ############################################################################# proc headlines::action {action hw node} { variable headlines variable options if {[catch { array set props [[set tw $hw.tree] itemcget $node -data] }]} { return } switch -glob -- $props(type)/$action { article/browse { if {$props(url) != ""} { browseurl $props(url) } if {$props(unseen)} { set props(unseen) 0 $tw itemconfigure $node -fill $options(seencolor) -data [array get props] update $tw $node } } article/forward { forward .h1popmenu $tw $node } article/copy_headline { clipboard clear -displayof $hw clipboard append -displayof $hw "$props(text)\n$props(body)\n$props(url)" } article/copy_url { clipboard clear -displayof $hw clipboard append -displayof $hw $props(url) } article/toggle { if {$props(unseen)} { set props(unseen) 0 set myfill $options(seencolor) } else { set props(unseen) 1 set myfill $options(unseencolor) } $tw itemconfigure $node -fill $myfill -data [array get props] update $tw $node } article/markseen { set props(unseen) 0 $tw itemconfigure $node -fill $options(seencolor) -data [array get props] update $tw $node } article/markunseen { set props(unseen) 1 $tw itemconfigure $node -fill $options(unseencolor) -data [array get props] update $tw $node } */delete { set props(unseen) 0 $tw itemconfigure $node -fill $options(seencolor) -data [array get props] update $tw $node # Deduce the node to select after $node is deleted: # Next sibling is tried first, then previous, then parent node. set p [$tw parent $node] set end [expr {[llength [$tw nodes $p]] - 1}] set ix [$tw index $node] if {$ix < $end} { set next [$tw nodes $p [incr ix]] } elseif {$ix > 0} { set next [$tw nodes $p [incr ix -1]] } else { set next $p } $tw delete $node if {![string equal $next root]} { $tw selection set $next } } article/deleteseen { if {$props(unseen) == 0} { action delete $hw $node } } from/markseen - subject/markseen { foreach child [$tw nodes $node] { action markseen $hw $child } } from/markunseen - subject/markunseen { foreach child [$tw nodes $node] { action markunseen $hw $child } } from/deleteseen - subject/deleteseen { if {$props(unseen) > 0} { foreach child [$tw nodes $node] { action deleteseen $hw $child } } else { action delete $hw $node } } from/sort - subject/sort { set children {} foreach child [$tw nodes $node] { catch { unset props } array set props [$tw itemcget $child -data] lappend children [list $child $props(text)] } set neworder {} foreach child [lsort -index 1 $children] { lappend neworder [lindex $child 0] } $tw reorder $node $neworder foreach child [$tw nodes $node] { action $action $hw $child } } from/datesort - subject/datesort { set children {} set seconds [clock seconds] foreach child [$tw nodes $node] { catch { unset props } set props(seconds) $seconds array set props [$tw itemcget $child -data] lappend children [list $child $props(seconds)] } set neworder {} foreach child [lsort -decreasing -index 1 $children] { lappend neworder [lindex $child 0] } $tw reorder $node $neworder foreach child [$tw nodes $node] { action $action $hw $child } } default { } } } ############################################################################# proc headlines::update {tw node} { variable options for {set parent [$tw parent $node]} \ {![string equal $parent root]} \ {set parent [$tw parent $parent]} { set unseen 0 foreach child [$tw nodes $parent] { catch { unset props } array set props [$tw itemcget $child -data] incr unseen $props(unseen) } catch { unset props } array set props [$tw itemcget $parent -data] set props(unseen) $unseen set text $props(text) if {$text == ""} { set text [::msgcat::mc ""] } set myfill $options(seencolor) if {$unseen > 0} { append text " ($unseen)" set myfill $options(unseencolor) } $tw itemconfigure $parent -text $text -fill $myfill \ -data [array get props] } } ############################################################################# proc headlines::balloon {hw node} { variable options if {!$options(show_balloons)} { return [list $hw:$node ""] } if {[catch {array set props [$hw.tree itemcget $node -data]}]} { return [list $hw:$node ""] } set width [expr {[winfo width $hw.tree] * 0.8}] if {$width < 400} { set width 400 } switch -- $props(type) { article { if {![string equal $props(body) ""]} { return [list $hw:$node $props(body) -width $width] } } } return [list $hw:$node ""] } ############################################################################# proc headlines::save {} { variable options variable trees if {!$options(cache)} { return } if {[catch { open [set file1 [file join $::configdir headlines1.tcl]] \ { WRONLY CREAT TRUNC } } fd]} { debugmsg headlines "unable to open $file: $fd" return } fconfigure $fd -encoding utf-8 set code [catch { foreach tw $trees { save_aux $tw root $fd } } result] catch { close $fd } if {$code} { debugmsg headlines $result catch { file delete $file1 } return } set renameP 0 if {![file exists [set file [file join $::configdir headlines.tcl]]]} { } elseif {[file size $file] == 0} { catch { file delete -force $file } } else { set renameP 1 catch { file rename -force $file \ [set file0 [file join $::configdir headlines0.tcl]] } } if {![catch { file rename $file1 $file } result]} { return } debugmsg headlines "unable to rename $file1 to $file: $result" if {($renameP) && ([catch { file rename -force $file0 $file } result])} { debugmsg headlines "unable to rename $file0 back to $file: $result" } catch { file delete $file1 } return } ############################################################################# proc headlines::save_aux {tw node fd} { variable headlines if {![winfo exists $tw]} { return } if {[llength [set children [$tw nodes $node]]] > 0} { foreach child $children { save_aux $tw $child $fd } } elseif {([info exists headlines($node)]) \ && (![catch { array set props [$tw itemcget $node -data] }])} { puts $fd [concat [list [namespace current]::show] \ $headlines($node) [list [array get props]]] } } ############################################################################# proc headlines::restore {} { variable options if {$options(cache)} { if {[file exists [set file [file join $::configdir headlines.tcl]]]} { catch { set fd [open $file "r"] fconfigure $fd -encoding utf-8 uplevel #0 [read $fd] close $fd } } } return "" } ############################################################################# proc headlines::forward3 {menu to tw node} { variable send_jids if {[catch { array set props [$tw.tree itemcget $node -data] } errmsg]} { return } # TODO: connid message::send_msg $to -type headline \ -subject $props(text) \ -body $props(body) \ -xlist [list [jlib::wrapper:createtag x \ -vars [list xmlns jabber:x:oob] \ -subtags [list [jlib::wrapper:createtag url \ -chdata $props(url)] \ [jlib::wrapper:createtag desc \ -chdata $props(text)]]]] set len [llength $send_jids] set send_jids [update_combo_list $send_jids $to 10] update_menu $menu $len } ############################################################################# proc headlines::forward2 {menu tw node} { global forward_hl variable send_jids if {[catch { array set props [$tw itemcget $node -data] } errmsg]} { return } set len [llength $send_jids] set _send_jids $send_jids foreach choice [array names forward_hl] { if {$forward_hl($choice)} { lassign $choice connid to message::send_msg $to -type headline \ -subject $props(text) \ -body $props(body) \ -xlist [list [jlib::wrapper:createtag x \ -vars [list xmlns jabber:x:oob] \ -subtags [list [jlib::wrapper:createtag url \ -chdata $props(url)] \ [jlib::wrapper:createtag desc \ -chdata $props(text)]]]] \ -connection $connid set _send_jids [update_combo_list $_send_jids $to 10] } } set send_jids $_send_jids update_menu $menu $len } ############################################################################# proc headlines::forward {menu tw node} { global forward_hl set gw .forward_headline catch { destroy $gw } set choices {} set balloons {} foreach c [jlib::connections] { foreach choice [roster::get_jids $c] { if {![string equal [roster::itemconfig $c $choice -category] conference]} { lappend choices [list $c $choice] [roster::get_label $c $choice] lappend balloons [list $c $choice] $choice } } } if {[llength $choices] == 0} { MessageDlg ${gw}_err -aspect 50000 -icon info \ -message [::msgcat::mc "No users in roster..."] -type user \ -buttons ok -default 0 -cancel 0 return } CbDialog $gw [::msgcat::mc "Forward headline"] \ [list [::msgcat::mc "Send"] "[namespace current]::forward2 [list $menu] \ [list $tw] \ [list $node] destroy $gw" \ [::msgcat::mc "Cancel"] [list destroy $gw]] \ forward_hl $choices $balloons } ############################################################################# hook::add finload_hook [namespace current]::headlines::restore hook::add quit_hook [namespace current]::headlines::save ############################################################################# proc headlines::restore_window {from connid jid} { open_window $connid $from } ############################################################################# # TODO: Work with changes in options(multiple) proc headlines::save_session {vsession} { upvar 2 $vsession session global usetabbar # We don't need JID at all, so make it empty (special case) set user "" set server "" set resource "" # TODO if {!$usetabbar} return set prio 0 foreach page [.nb pages] { set path [ifacetk::nbpath $page] if {[string equal $path .headlines]} { lappend session [list $prio $user $server $resource \ [list [namespace current]::restore_window ""] \ ] } if {[regexp {^.headlines_(.*)} $path -> tag]} { set jid [tag_to_jid $tag] lappend session [list $prio $user $server $resource \ [list [namespace current]::restore_window $jid] \ ] } incr prio } } hook::add save_session_hook [namespace current]::headlines::save_session ############################################################################# tkabber-0.11.1/plugins/general/offline.tcl0000644000175000017500000002530310752133252017751 0ustar sergeisergei namespace eval offline { set ::NS(offline) "http://jabber.org/protocol/offline" custom::defvar options(flexible_retrieval) 0 \ [::msgcat::mc "Retrieve offline messages using POP3-like protocol."] \ -type boolean -group Messages } proc offline::request_headers {connid} { variable options if {$options(flexible_retrieval)} { jlib::send_iq get \ [jlib::wrapper:createtag offline \ -vars [list xmlns $::NS(offline)]] \ -command [list [namespace current]::receive_headers $connid] \ -connection $connid } } hook::add connected_hook [namespace current]::offline::request_headers 9 proc offline::receive_headers {connid res child} { if {$res != "OK"} { return } fill_tree $connid $child } proc offline::open_window {} { global tcl_platform variable options set w .offline_messages if {[winfo exists $w]} { return } add_win $w -title [::msgcat::mc "Offline Messages"] \ -tabtitle [::msgcat::mc "Offline Messages"] \ -raisecmd [list focus $w.tree] \ -class JDisco if {![info exists options(seencolor)]} { if {[cequal $tcl_platform(platform) unix] && \ ![string equal [option get $w disabledForeground JDisco] ""]} { set options(seencolor) [option get $w disabledForeground JDisco] } else { set options(seencolor) [option get $w featurecolor JDisco] } } if {![info exists options(unseencolor)]} { set options(unseencolor) [option get $w fill JDisco] } set sw [ScrolledWindow $w.sw] set tw [Tree $w.tree -deltax 16 -deltay 18 -dragenabled 0] $sw setwidget $tw pack $sw -side top -expand yes -fill both $tw bindText \ [list [namespace current]::message_popup $tw] $tw bindText \ [list [namespace current]::message_action fetch $tw] # HACK bind $tw.c \ "[namespace current]::message_action fetch $tw \[$tw selection get\]" bindscroll $tw.c } proc offline::fill_tree {connid child} { jlib::wrapper:splitxml $child tag vars isempty chdata children if {[lempty $children]} { return } set w .offline_messages if {![winfo exists $w]} { open_window } set tw $w.tree foreach ch $children { jlib::wrapper:splitxml $ch tag1 vars1 isempty1 chdata1 children1 switch -- $tag1 { item { set node [jlib::wrapper:getattr $vars1 node] set from [jlib::wrapper:getattr $vars1 from] set category [jlib::wrapper:getattr $vars1 category] set type [jlib::wrapper:getattr $vars1 type] add_message $tw $connid $node $from $category $type } } } } package require md5 proc offline::add_message {tw connid node from category type} { variable options set jid [jlib::connection_jid $connid] set fnode [str2node $jid] if {![$tw exists $fnode]} { $tw insert end root $fnode -text $jid -open 1 \ -fill $options(unseencolor) -image browser/user \ -data [list type jid connid $connid jid $jid unseen 1] } set snode [str2node $node] if {![$tw exists $snode]} { if {$type == ""} { set t "" } else { set t " ($type)" } $tw insert end $fnode $snode -text "$category$t from $from \[$node\]" -open 1 \ -fill $options(unseencolor) \ -data [list type node connid $connid jid $jid node $node \ from $from category $category type $type unseen 1] message_update $tw $snode } } proc offline::str2node {string} { set utf8str [encoding convertto utf-8 $string] if {[catch { ::md5::md5 -hex $utf8str } ret]} { return [::md5::md5 $utf8str] } else { return $ret } } proc offline::message_popup {tw node} { $tw selection set $node if {[catch { array set props [$tw itemcget $node -data] }]} { return } set m .offline_popup_menu if {[winfo exists $m]} { destroy $m } menu $m -tearoff 0 switch -- $props(type) { jid { $m add command -label [::msgcat::mc "Sort by from"] \ -command [list [namespace current]::message_action sortfrom $tw $node] $m add command -label [::msgcat::mc "Sort by node"] \ -command [list [namespace current]::message_action sortnode $tw $node] $m add command -label [::msgcat::mc "Sort by type"] \ -command [list [namespace current]::message_action sorttype $tw $node] $m add command -label [::msgcat::mc "Fetch unseen messages"] \ -command [list [namespace current]::message_action fetchunseen $tw $node] $m add command -label [::msgcat::mc "Fetch all messages"] \ -command [list [namespace current]::message_action fetch $tw $node] $m add command -label [::msgcat::mc "Purge seen messages"] \ -command [list [namespace current]::message_action purgeseen $tw $node] $m add command -label [::msgcat::mc "Purge all messages"] \ -command [list [namespace current]::message_action purge $tw $node] } node { $m add command -label [::msgcat::mc "Fetch message"] \ -command [list [namespace current]::message_action fetch $tw $node] $m add command -label [::msgcat::mc "Purge message"] \ -command [list [namespace current]::message_action purge $tw $node] } default { return } } tk_popup $m [winfo pointerx .] [winfo pointery .] } proc offline::message_action {action tw node} { variable options if {[catch { array set props [$tw itemcget $node -data] }]} { return } switch -glob -- $props(type)/$action { node/fetch { jlib::send_iq get \ [jlib::wrapper:createtag offline \ -vars [list xmlns $::NS(offline)] \ -subtags [list [jlib::wrapper:createtag item \ -vars [list action view \ node $props(node)]]]] \ -connection $props(connid) \ -command [list [namespace current]::action_result $action $tw $node] } node/purge { jlib::send_iq set \ [jlib::wrapper:createtag offline \ -vars [list xmlns $::NS(offline)] \ -subtags [list [jlib::wrapper:createtag item \ -vars [list action remove \ node $props(node)]]]] \ -connection $props(connid) \ -command [list [namespace current]::action_result $action $tw $node] } jid/fetch { jlib::send_iq get \ [jlib::wrapper:createtag offline \ -vars [list xmlns $::NS(offline)] \ -subtags [list [jlib::wrapper:createtag fetch]]] \ -connection $props(connid) \ -command [list [namespace current]::action_result $action $tw $node] } jid/purge { jlib::send_iq set \ [jlib::wrapper:createtag offline \ -vars [list xmlns $::NS(offline)] \ -subtags [list [jlib::wrapper:createtag purge]]] \ -connection $props(connid) \ -command [list [namespace current]::action_result $action $tw $node] } jid/fetchunseen { set q 0 set items {} foreach child [$tw nodes $node] { catch { array unset props1 } if {![catch { array set props1 [$tw itemcget $child -data] }] && \ $props1(unseen) > 0} { lappend items [jlib::wrapper:createtag item \ -vars [list action view \ node $props1(node)]] } else { set q 1 } } if {$q} { if {![lempty $items]} { jlib::send_iq get \ [jlib::wrapper:createtag offline \ -vars [list xmlns $::NS(offline)] \ -subtags $items] \ -connection $props(connid) \ -command [list [namespace current]::action_result $action $tw $node] } } else { message_action fetch $tw $node } } jid/purgeseen { if {$props(unseen) > 0} { set items {} foreach child [$tw nodes $node] { catch { array unset props1 } if {![catch { array set props1 [$tw itemcget $child -data] }]} { if {$props1(unseen) == 0} { lappend items [jlib::wrapper:createtag item \ -vars [list action remove \ node $props1(node)]] } } } if {![lempty $items]} { jlib::send_iq set \ [jlib::wrapper:createtag offline \ -vars [list xmlns $::NS(offline)] \ -subtags $items] \ -connection $props(connid) \ -command [list [namespace current]::action_result $action $tw $node] } } else { message_action purge $tw $node } } jid/sortfrom { sort_nodes $tw $node from } jid/sortnode { sort_nodes $tw $node node } jid/sorttype { sort_nodes $tw $node category type } default { } } } proc offline::sort_nodes {tw node type {subtype ""}} { set children {} foreach child [$tw nodes $node] { catch { unset props } array set props [$tw itemcget $child -data] if {$subtype == ""} { lappend children [list $child $props($type)] } else { lappend children \ [list $child [list $props($type) $props($subtype)]] } } set neworder {} foreach child [lsort -index 1 $children] { lappend neworder [lindex $child 0] } $tw reorder $node $neworder } proc offline::action_result {action tw node res child} { variable options if {$res != "OK"} { return } if {[catch { array set props [$tw itemcget $node -data] }]} { return } switch -glob -- $props(type)/$action { node/fetch - node/fetchunseen { if {$props(unseen)} { set props(unseen) 0 $tw itemconfigure $node -fill $options(seencolor) \ -data [array get props] message_update $tw $node } } node/purge { set props(unseen) 0 $tw itemconfigure $node -fill $options(seencolor) \ -data [array get props] message_update $tw $node $tw delete $node } node/purgeseen { if {!$props(unseen)} { action_result purge $tw $node OK {} } } jid/fetch - jid/fetchunseen { foreach child [$tw nodes $node] { action_result $action $tw $child OK {} } } jid/purge - jid/purgeseen { foreach child [$tw nodes $node] { action_result $action $tw $child OK {} } if {[lempty [$tw nodes $node]]} { $tw delete $node } } default { } } } proc offline::message_update {tw node} { variable options for {set parent [$tw parent $node]} \ {![cequal $parent root]} \ {set parent [$tw parent $parent]} { set unseen 0 foreach child [$tw nodes $parent] { catch { unset props } array set props [$tw itemcget $child -data] incr unseen $props(unseen) } catch { unset props } array set props [$tw itemcget $parent -data] set props(unseen) $unseen set text $props(jid) set myfill $options(seencolor) if {$unseen > 0} { append text " ($unseen)" set myfill $options(unseencolor) } $tw itemconfigure $parent -text $text -fill $myfill \ -data [array get props] } } tkabber-0.11.1/plugins/general/session.tcl0000644000175000017500000000617310611463741020021 0ustar sergeisergei# $Id: session.tcl 1119 2007-04-18 18:48:01Z sergei $ # Save, open Tkabber sessions ############################################################################# # # Session is a list of {priority user server resource script} # namespace eval session { variable session_file [file join $::configdir session.tcl] custom::defgroup State [::msgcat::mc "Tkabber save state options."] \ -group Tkabber custom::defvar options(save_on_exit) 0 \ [::msgcat::mc "Save state on Tkabber exit."] \ -type boolean -group State custom::defvar options(open_on_start) 0 \ [::msgcat::mc "Load state on Tkabber start."] \ -type boolean -group State } ############################################################################# proc session::save_session {} { variable session_file set session {} hook::run save_session_hook session set fd [open $session_file w] fconfigure $fd -encoding utf-8 puts $fd $session close $fd } ############################################################################# proc session::save_session_on_exit {} { variable options if {$options(save_on_exit)} { save_session } } hook::add quit_hook [namespace current]::session::save_session_on_exit ############################################################################# proc session::open_session {} { variable session_file set session_script_list {} catch { set fd [open $session_file r] fconfigure $fd -encoding utf-8 set session_script_list [read $fd] close $fd } foreach script [lsort -integer -index 0 $session_script_list] { lassign $script priority user server resource command if {($user != "") || ($server != "") || ($resource != "")} { # HACK. It works if called before any JID is connected set connid [jlib::new -user $user \ -server $server \ -resource $resource] } else { set connid "" } after idle [list eval $command [list $connid $user@$server/$resource]] } } ############################################################################# proc session::open_session_on_start {} { variable options if {$options(open_on_start)} { open_session } } hook::add finload_hook [namespace current]::session::open_session_on_start 90 ############################################################################# proc session::setup_menu {} { if {![cequal $::interface tk] && ![cequal $::interface ck]} return catch { set m [.mainframe getmenu tkabber] set ind [expr {[$m index [::msgcat::mc "Chats"]] + 1}] set mm .session_menu menu $mm -tearoff $::ifacetk::options(show_tearoffs) $mm add command -label [::msgcat::mc "Save state"] \ -command [namespace current]::save_session $mm add checkbutton -label [::msgcat::mc "Save state on exit"] \ -variable [namespace current]::options(save_on_exit) $mm add checkbutton -label [::msgcat::mc "Load state on start"] \ -variable [namespace current]::options(open_on_start) $m insert $ind cascade -label [::msgcat::mc "State"] -menu $mm } } hook::add finload_hook [namespace current]::session::setup_menu 60 ############################################################################# tkabber-0.11.1/plugins/general/remote.tcl0000644000175000017500000006036211011554251017621 0ustar sergeisergei# $Id: remote.tcl 1408 2008-05-11 11:29:45Z sergei $ # Implementation of Remote Controlling Clients (XEP-0146) # via Ad-Hoc Commands (XEP-0050) for Tkabber. # namespace eval ::remote { array set commands {} array set sessions {} set prefix "::remote::sessions" custom::defgroup {Remote Control} \ [::msgcat::mc "Remote control options."] -group Tkabber custom::defvar options(enable) 1 \ [::msgcat::mc "Enable remote control."] \ -type boolean -group {Remote Control} custom::defvar options(accept_from_myjid) 1 \ [::msgcat::mc "Accept connections from my own JID."] \ -type boolean -group {Remote Control} custom::defvar options(accept_list) "" \ [::msgcat::mc "Accept connections from the listed JIDs."] \ -type string -group {Remote Control} #custom::defvar options(show_my_resources) 1 \ # [::msgcat::mc "Show my own resources in the roster."] \ # -type boolean -group {Remote Control} } namespace eval ::remote::sessions {} ############################################ proc ::remote::allow_remote_control {connid from} { variable options if {!$options(enable)} { return 0 } set from [string tolower $from] set myjid [string tolower \ [node_and_server_from_jid \ [jlib::connection_jid $connid]]] set bare_from [string tolower [node_and_server_from_jid $from]] if {$options(accept_from_myjid) && [cequal $myjid $bare_from]} { return 1 } set accept_list [split [string tolower $options(accept_list)] " "] if {$bare_from != "" && [lsearch -exact $accept_list $bare_from] >= 0} { return 1 } return 0 } ############################################ # Register and announce commands via disco proc ::remote::register_command {node command name args} { variable commands set commands(command,$node) $command set commands(name,$node) $name lappend commands(nodes) $node ::disco::register_subnode $node \ [namespace current]::common_command_infoitems_handler $name } proc ::remote::common_command_infoitems_handler {type connid from lang xmllist} { variable commands if {![allow_remote_control $connid $from]} { return {error cancel not-allowed} } jlib::wrapper:splitxml $xmllist tag vars isempty chdata children set node [jlib::wrapper:getattr $vars node] if {![cequal $node ""] && [info exists commands(command,$node)]} { if {[cequal $type info]} { return \ [list [jlib::wrapper:createtag identity \ -vars [list category automation \ type command-node \ name [::trans::trans $lang \ $commands(name,$node)]]] \ [jlib::wrapper:createtag feature \ -vars [list var $::NS(commands)]]] } else { return {} } } else { return {error modify bad-request} } } proc ::remote::commands_list_handler {type connid from lang xmllist} { variable commands if {![allow_remote_control $connid $from]} { return {error cancel not-allowed} } set myjid [jlib::connection_jid $connid] switch -- $type { items { set items {} foreach node $commands(nodes) { lappend items [jlib::wrapper:createtag item \ -vars [list jid $myjid \ node $node \ name [::trans::trans $lang \ $commands(name,$node)]]] } return $items } info { return [list [jlib::wrapper:createtag identity \ -vars [list category automation \ type command-list \ name [::trans::trans $lang \ "Remote control"]]]] } } return {} } ::disco::register_feature $::NS(commands) ::disco::register_node $::NS(commands) \ ::remote::commands_list_handler [::trans::trans "Remote control"] ####################################### # Base engine. proc ::remote::clear_session {session node} { variable commands variable sessions if {![info exists commands(command,$node)]} return $commands(command,$node) $session cancel {} upvar 0 $session state catch {unset sessions($state(connid),$state(from),$state(node),$state(id))} catch {unset $session} } proc ::remote::create_session {node connid from lang} { variable commands variable sessions variable prefix if {![info exists commands(command,$node)]} return set id [rand 1000000000] while {[info exists sesssions($connid,$from,$node,$id)]} { set id [rand 1000000000] } set counter 1 while {[info exists "${prefix}::${counter}"]} { incr counter } set session "${prefix}::${counter}" upvar 0 $session state set state(id) $id set state(connid) $connid set state(from) $from set state(node) $node set state(lang) $lang set sessions($connid,$from,$node,$id) $session return $session } proc ::remote::command_set_handler {connid from lang child} { variable commands variable sessions if {![allow_remote_control $connid $from]} { return {error cancel not-allowed} } jlib::wrapper:splitxml $child tag vars isempty chdata children set node [jlib::wrapper:getattr $vars node] set action [jlib::wrapper:getattr $vars action] set id [jlib::wrapper:getattr $vars sessionid] if {![info exists commands(command,$node)]} { return {error cancel item-not-found} } if {[cequal $id ""]} { # We use lang only when create session. # Probably it would be better to use it after every request. set session [create_session $node $connid $from $lang] } else { if {![info exists sessions($connid,$from,$node,$id)]} { return [get_error modify bad-request bad-sessionid] } set session $sessions($connid,$from,$node,$id) } upvar 0 $session state set id $state(id) if {[cequal $action cancel]} { clear_session $session $node return [list result [jlib::wrapper:createtag command \ -vars [list xmlns $::NS(commands) \ sessionid $id \ node $node \ status canceled]]] } set result [$commands(command,$node) $session $action $children] set status [lindex $result 0] switch -- $status { error { set error_type [lindex $result 1] if {![cequal $error_type "modify"]} { clear_session $session $node } return $result } completed { clear_session $session $node } executing {} default { clear_session $session $node return {error wait internal-server-error} } } return [list result [jlib::wrapper:createtag command \ -vars [list xmlns $::NS(commands) \ sessionid $id \ node $node \ status $status] \ -subtags [lrange $result 1 end]]] } iq::register_handler set command $::NS(commands) ::remote::command_set_handler proc ::remote::get_error {type general {specific ""}} { set res [list error $type $general] if {![cequal $specific ""]} { lappend res -application-specific \ [jlib::wrapper:createtag $specific \ -vars [list xmlns $::NS(commands)]] } return $res } ############################################ # Common functions for command implementations. # Scheduler for one-step dialogs and wizards proc ::remote::standart_scheduler {steps prefix session action children} { upvar 0 $session state if {[cequal $action cancel]} { for {set i 1} {$i <= $steps} {incr i} { ${prefix}clear_step$i $session } return } if {![info exists state(step)] } { # First step if {[cequal $action "execute"] || [cequal $action ""]} { set state(step) 1 return [${prefix}get_step$state(step) $session] } else { return [::remote::get_error modify bad-request bad-action] } } elseif { ($state(step) < $steps) && ($state(step) > 0) } { # Inner step if {[cequal $action "next"] || [cequal $action "execute"] || [cequal $action ""]} { set res [${prefix}set_step$state(step) $session $children] if {[cequal [lindex $res 0] error]} { return $res } incr state(step) return [${prefix}get_step$state(step) $session] } elseif {[cequal $action "prev"]} { incr state(step) -1 ${prefix}clear_step$state(step) $session return [${prefix}get_step$state(step) $session] } elseif {[cequal $action "complete"]} { set res [${prefix}set_step$state(step) $session $children] if {[cequal [lindex $res 0] error]} { return $res } return [${prefix}get_finish $session] } else { return [::remote::get_error modify bad-request bad-action] } } elseif { $state(step) == $steps } { # Last step if {[cequal $action complete] || [cequal $action execute] || [cequal $action ""]} { set res [${prefix}set_step$state(step) $session $children] if {[cequal [lindex $res 0] error]} { return $res } return [${prefix}get_finish $session] } elseif {[cequal $action "prev"]} { incr state(step) -1 ${prefix}clear_step$state(step) $session return [${prefix}get_step$state(step) $session] } else { return [::remote::get_error modify bad-request bad-action] } } else { return {error wait internal-server-error} } } # Parse form result and returns array with values, check for correct form type proc ::remote::standart_parseresult {children_b form_type} { set result {} foreach child $children_b { jlib::wrapper:splitxml $child tag vars isempty chdata children set xmlns [jlib::wrapper:getattr $vars xmlns] set type [jlib::wrapper:getattr $vars type] if {![cequal $tag x] || ![cequal $xmlns $::NS(data)]} { continue } if {![cequal $type submit]} { return [::remote::get_error modify bad-request bad-payload] } foreach field [::data::parse_xdata_results $children -hidden 1] { lassign $field var type label values if {[cequal $var FORM_TYPE]} { if {![cequal [lindex $values 0] $form_type]} { return [::remote::get_error modify bad-request bad-payload] } } else { lappend result $var $values } } } return $result } ############################ #Change status namespace eval ::remote::change_status {} proc ::remote::change_status::scheduler {session action children} { return [::remote::standart_scheduler 1 "[namespace current]::" \ $session $action $children] } ::remote::register_command "http://jabber.org/protocol/rc#set-status" \ ::remote::change_status::scheduler [::trans::trans "Change status"] # step1: # send standart form proc ::remote::change_status::get_step1 {session} { global userstatus global textstatus global userpriority upvar 0 $session state set lang $state(lang) set fields {} lappend fields [data::createfieldtag hidden \ -var FORM_TYPE \ -values "http://jabber.org/protocol/rc"] lappend fields [data::createfieldtag title \ -value [::trans::trans $lang "Change Status"]] lappend fields [data::createfieldtag instructions \ -value [::trans::trans $lang \ "Choose status, priority, and\ status message"]] set options {} foreach {status statusdesc} \ [list available [::trans::trans $lang "Available"] \ chat [::trans::trans $lang "Free to chat"] \ away [::trans::trans $lang "Away"] \ xa [::trans::trans $lang "Extended away"] \ dnd [::trans::trans $lang "Do not disturb"] \ unavailable [::trans::trans $lang "Unavailable"]] { lappend options [list $status $statusdesc] } lappend fields [data::createfieldtag list-single \ -var status \ -label [::trans::trans $lang "Status"] \ -required 1 \ -value $userstatus \ -options $options] lappend fields [data::createfieldtag text-single \ -var status-priority \ -label [::trans::trans $lang "Priority"] \ -value $userpriority \ -required 1] lappend fields [data::createfieldtag text-multi \ -var status-message \ -label [::trans::trans $lang "Message"] \ -values [split $textstatus "\n"]] return [list executing [jlib::wrapper:createtag x \ -vars [list xmlns $::NS(data) \ type form] \ -subtags $fields]] } proc ::remote::change_status::set_step1 {session children} { upvar 0 $session state set result [remote::standart_parseresult $children \ "http://jabber.org/protocol/rc"] if {[cequal [lindex $result 0] error]} { return $result } array set params $result if {![info exists params(status)] || \ ![info exists params(status-priority)] || \ ![info exists ::statusdesc($params(status))] || \ [catch {expr int($params(status-priority))}]} { return [::remote::get_error modify bad-request bad-payload] } set state(textstatus) {} catch { set state(textstatus) \ [join $params(status-message) "\n"] } set state(userstatus) \ [lindex $params(status) 0] set state(userpriority) \ [lindex $params(status-priority) 0] return {} } proc ::remote::change_status::clear_step1 {session} {} # finish: # change status # report proc ::remote::change_status::get_finish {session} { global userstatus global textstatus global userpriority upvar 0 $session state set lang $state(lang) set textstatus $state(textstatus) set userpriority $state(userpriority) set userstatus $state(userstatus) return [list completed [jlib::wrapper:createtag note \ -vars {type info} \ -chdata \ [::trans::trans $lang \ "Status was changed successfully"]]] } ############################ # Leave groupchats namespace eval ::remote::leave_groupchats {} proc ::remote::leave_groupchats::scheduler {session action children} { return [::remote::standart_scheduler 1 "[namespace current]::" $session $action $children] } ::remote::register_command "http://jabber.org/protocol/rc#leave-groupchats" \ ::remote::leave_groupchats::scheduler [::trans::trans "Leave groupchats"] # step1: # allow users to choose which chats to leave proc ::remote::leave_groupchats::get_step1 {session} { upvar 0 $session state set options {} set lang $state(lang) set connid $state(connid) foreach chatid [lfilter chat::is_groupchat [chat::opened $connid]] { set jid [chat::get_jid $chatid] if {![cequal [get_jid_presence_info show $connid $jid] ""]} { set nick [get_our_groupchat_nick $chatid] lappend options [list $jid [format [::trans::trans $lang "%s at %s"] \ $nick $jid]] } } if {[llength $options] == 0} { return [list completed [jlib::wrapper:createtag note \ -vars {type info} \ -chdata [::trans::trans $lang \ "No groupchats to leave"]]] } set fields {} lappend fields [data::createfieldtag hidden \ -var FORM_TYPE \ -values "http://jabber.org/protocol/rc"] lappend fields [data::createfieldtag title \ -value [::trans::trans $lang "Leave Groupchats"]] lappend fields [data::createfieldtag instructions \ -value [::trans::trans $lang \ "Choose groupchats you want to leave"]] lappend fields [data::createfieldtag boolean \ -var x-all \ -label [::trans::trans $lang "Leave all groupchats"] \ -value 0] lappend fields [data::createfieldtag list-multi \ -var groupchats \ -label [::trans::trans $lang "Groupchats"] \ -required 1 \ -options $options] lappend fields [data::createfieldtag text-single \ -var x-reason \ -label [::trans::trans $lang "Reason"]] return [list executing [jlib::wrapper:createtag x \ -vars [list xmlns $::NS(data) \ type form] \ -subtags $fields]] } proc ::remote::leave_groupchats::set_step1 {session children} { upvar 0 $session state set result [remote::standart_parseresult $children \ "http://jabber.org/protocol/rc"] if {[cequal [lindex $result 0] error]} { return $result } array set params $result if {![info exists params(groupchats)]} { return [::remote::get_error modify bad-request bad-payload] } set state(all) [lindex $params(x-all) 0] set state(groupchats) $params(groupchats) set state(reason) "" catch { set state(reason) [lindex $params(x-reason) 0] } return {} } proc ::remote::leave_groupchats::clear_step1 {session} {} # finish step # leave groupchats. # report proc ::remote::leave_groupchats::get_finish {session} { upvar 0 $session state set args [list -connection $state(connid)] set lang $state(lang) if {![cequal $state(reason) ""]} { lappend args -stat $state(reason) } # "all" workaround, will be removed soon if $state(all) { set connid $state(connid) set state(groupchats) "" foreach chatid [lfilter chat::is_groupchat [chat::opened $connid]] { set jid [chat::get_jid $chatid] if {![cequal [get_jid_presence_info show $connid $jid] ""]} { lappend state(groupchats) $jid } } } foreach jid $state(groupchats) { eval [list send_presence unavailable -to $jid] $args } return [list completed [jlib::wrapper:createtag note \ -vars {type info} \ -chdata [::trans::trans $lang \ "Groupchats were leaved\ successfully"]]] } ################################ # Forward unread messages namespace eval ::remote::forward { array set unread {} } proc ::remote::forward::scheduler {session action children} { return [::remote::standart_scheduler 1 "[namespace current]::" $session $action $children] } ::remote::register_command "http://jabber.org/protocol/rc#forward" \ ::remote::forward::scheduler [::trans::trans "Forward unread messages"] # step1: # form with list of unreaded correspondence proc ::remote::forward::get_step1 {session} { upvar 0 $session state variable unread set options {} set lang $state(lang) set connid $state(connid) foreach id [array names unread] { lassign $id type chatid if {![cequal [chat::get_connid $chatid] $connid]} continue set jid [chat::get_jid $chatid] set name [::roster::itemconfig $connid \ [::roster::find_jid $connid $jid] \ -name] if {![cequal $name ""]} { set name [format "%s (%s)" $name $jid] } else { set name $jid } set count [llength $unread($id)] switch -- $type { chat { set msg [::trans::trans $lang "%s: %s chat message(s)"] } groupchat { set msg [::trans::trans $lang "%s: %s groupchat message(s)"] } headline { set msg [::trans::trans $lang "%s: %s headline message(s)"] } normal { set msg [::trans::trans $lang "%s: %s normal message(s)"] } default { set msg [::trans::trans $lang "%s: %s unknown message(s)"] } } lappend options [list $id [format $msg $name $count]] } if {[llength $options] == 0} { return [list completed [jlib::wrapper:createtag note \ -vars {type info} \ -chdata \ [::trans::trans $lang \ "There are no unread messages"]]] } set fields {} lappend fields [data::createfieldtag hidden \ -var FORM_TYPE \ -values "tkabber:plugins:remote:forward_form"] lappend fields [data::createfieldtag title \ -value [::trans::trans $lang \ "Forward Unread Messages"]] lappend fields [data::createfieldtag instructions \ -value [::trans::trans $lang \ "Choose chats or groupchats from which you\ want to forward messages"]] lappend fields [data::createfieldtag boolean \ -var all \ -label [::trans::trans $lang "Forward all messages"] \ -value 0] lappend fields [data::createfieldtag list-multi \ -var chats \ -label [::trans::trans $lang "Forward messages from"] \ -required 1 \ -options $options] return [list executing [jlib::wrapper:createtag x \ -vars [list xmlns $::NS(data) \ type form] \ -subtags $fields]] } proc ::remote::forward::set_step1 {session children} { upvar 0 $session state set result [remote::standart_parseresult $children \ "tkabber:plugins:remote:forward_form"] if {[cequal [lindex $result 0] error]} { return $result } array set params $result if {![info exists params(chats)]} { return [::remote::get_error modify bad-request bad-payload] } set state(all) [lindex $params(all) 0] set state(chats) $params(chats) return {} } proc ::remote::forward::clear_step1 {session} {} # finish: # forward selected unread messages # report proc ::remote::forward::get_finish {session} { upvar 0 $session state variable unread set connid $state(connid) set lang $state(lang) set oto [jlib::connection_jid $connid] set target $state(from) # "all" workaround, will be removed soon if $state(all) { set state(chats) {} foreach id [array names unread] { lassign $id type chatid if {![cequal [chat::get_connid $chatid] $connid]} continue lappend state(chats) $id } } foreach id $state(chats) { forward_messages $id $connid $oto $target } return [list completed \ [jlib::wrapper:createtag note \ -vars {type info} \ -chdata [::trans::trans $lang \ "Unread messages were forwarded\ successfully"]]] } ############################# # Forward namespace # forwards messages # leaves marks that they were forwarded. # cleanup arrays proc ::remote::forward::forward_messages {id connid oto target} { variable unread variable msgdata lassign $id type chatid if {![info exists unread($id)]} { return } foreach elem $unread($id) { switch -- $type { groupchat - chat { lassign $elem date ofrom body x } normal { lassign $msgdata($elem) date ofrom body x } } lappend x [jlib::wrapper:createtag addresses \ -vars [list xmlns $::NS(xaddress)] \ -subtags [list [jlib::wrapper:createtag address \ -vars [list type ofrom \ jid $ofrom]] \ [jlib::wrapper:createtag address \ -vars [list type oto \ jid $oto]]]] lappend x [jlib::wrapper:createtag x \ -vars [list xmlns "jabber:x:delay" \ stamp $date]] jlib::send_msg $target -body $body \ -type $type \ -xlist $x \ -connection $connid switch -- $type { normal { set lab \ [Label $elem.forwlab \ -text [::msgcat::mc \ "This message was forwarded to %s" \ $target]] pack $lab -anchor w -fill none -expand no -before $elem.title catch {unset msgdata($elem)} } } } catch {unset unread($id)} switch -- $type { groupchat - chat { after idle \ [list ::chat::add_message $chatid $ofrom info \ [::msgcat::mc "All unread messages were forwarded to %s." \ $target] \ {}] } } } # store message into the unread if type == chat proc ::remote::forward::draw_message_handler {chatid from type body extras} { variable unread if {[ifacetk::chat_window_is_active $chatid]} return if {![lcontain {chat groupchat} $type]} return # if {![cequal chat $type]} return set date [clock format [clock seconds] -format "%Y%m%dT%H:%M:%S" -gmt 1] set message [list $date $from $body $extras] set id [list $type $chatid] lappend unread($id) $message return 0 } hook::add draw_message_hook ::remote::forward::draw_message_handler 19 # clear list of unread messages with type == chat proc ::remote::forward::trace_number_msg {var1 chatid mode} { variable unread if { $::ifacetk::number_msg($chatid) == 0 } { set type $::chat::chats(type,$chatid) set id [list $type $chatid] catch {unset unread($id)} } } trace variable ::ifacetk::number_msg r ::remote::forward::trace_number_msg # store message with type == normal proc ::remote::forward::message_process_x \ {rowvar bodyvar f x connid from id type replyP} { upvar 2 $rowvar row upvar 2 $bodyvar body variable unread variable msgdata if {!$replyP || [cequal $type error]} { return } set id [list normal [chat::chatid $connid $from]] if {![info exists unread($id)]} { set unread($id) {} } set msgwin [winfo toplevel $f] bindtags $msgwin [concat [bindtags $msgwin] tag$msgwin] bind tag$msgwin \ +[list [namespace current]::on_msgwin_destroy $msgwin $id] lappend unread($id) $msgwin set date [clock format [clock seconds] -format "%Y%m%dT%H:%M:%S" -gmt 1] set msgdata($msgwin) [list $date $from $body $x] return } hook::add message_process_x_hook ::remote::forward::message_process_x # clear chat message with type == normal if it was closed proc ::remote::forward::on_msgwin_destroy {msgwin id} { variable unread variable msgdata if {![info exists unread($id)]} return if {[set index [lsearch -exact $unread($id) $msgwin]] >= 0} { set unread($id) [lreplace $unread($id) $index $index] catch {unset msgdata($msgwin)} } if { [llength $unread($id)] == 0 } { catch {unset unread($id)} } } tkabber-0.11.1/plugins/general/jitworkaround.tcl0000644000175000017500000000315310573560443021237 0ustar sergeisergei# $Id: jitworkaround.tcl 1024 2007-03-07 15:58:27Z sergei $ ############################################################################### # JIT workaround: when receving stanza with name attribute and # roster item doesn't have name, fill the name # namespace eval jitworkaround {} proc jitworkaround::process_subscribed {connid from type x args} { variable names if {$type != "subscribed"} return set newname "" foreach {opt val} $args { switch -- $opt { -name { set newname $val } } } if {$newname == ""} return set jid [roster::find_jid $connid $from] if {$jid == ""} { set names($connid,$from) $newname } elseif {[roster::itemconfig $connid $jid -name] == ""} { roster::itemconfig $connid $jid -name $newname roster::send_item $connid $jid ::redraw_roster } } hook::add client_presence_hook \ [namespace current]::jitworkaround::process_subscribed ############################################################################### proc jitworkaround::set_received_name {connid jid name groups subsc ask} { variable names if {$subsc == "remove"} return if {[info exists names($connid,$jid)]} { if {[roster::itemconfig $connid $jid -name] == ""} { roster::itemconfig $connid $jid -name $names($connid,$jid) roster::send_item $connid $jid } unset names($connid,$jid) } } hook::add roster_item_hook \ [namespace current]::jitworkaround::set_received_name 60 hook::add roster_push_hook \ [namespace current]::jitworkaround::set_received_name 60 ############################################################################### tkabber-0.11.1/plugins/general/tkcon.tcl0000644000175000017500000000257610661011076017452 0ustar sergeisergei# $id$ # # if you're running tkabber under the tkcon package # # http://tkcon.sourceforge.net # # e.g., # # % tkcon.tcl -name tkabber -exec "" -root .tkconn -main "source tkabber.tcl" # # or if tkcon is installed as a Tcl package and can be sourced via # [package require] (tkcon isn't loaded at start, so it doesn't waste resources # if it's unneeded) # if {[lempty [package versions tkcon]] && \ [llength [info commands ::tkcon::*]] <= 0} { return } namespace eval tkcon { variable onceP 1 variable showP 0 } proc tkcon::add_tkcon_to_tkabber_menu {args} { catch { set ndx [.menubar index [::msgcat::mc "Help"]] set menu [.menubar entrycget $ndx -menu] $menu add separator $menu add checkbutton -label [::msgcat::mc "Show TkCon console"] \ -command [namespace current]::show_console \ -variable [namespace current]::showP show_console } } proc tkcon::show_console {} { variable onceP variable showP if {[llength [info commands ::tkcon::*]] <= 0} { package require tkcon } if {$showP} { tkcon show if {$onceP} { wm protocol $::tkcon::PRIV(root) WM_DELETE_WINDOW \ [namespace current]::hide_console set onceP 0 } } else { tkcon hide } } proc tkcon::hide_console {} { variable showP tkcon hide set showP 0 } hook::add finload_hook [namespace current]::tkcon::add_tkcon_to_tkabber_menu tkabber-0.11.1/plugins/general/xaddress.tcl0000644000175000017500000001643511011554251020145 0ustar sergeisergei# $Id: xaddress.tcl 1408 2008-05-11 11:29:45Z sergei $ # # Implementation of XEP-0033: Extended Stanza Addressing # # The sender address is rewritten, but the original address is stored # in an additional element: # # set ::NS(xaddress) "http://jabber.org/protocol/address" set ::NS(xaddress_store) "tkabber:xaddress:store" namespace eval ::xaddress { set xaddrinfoid 0 array set names [list \ ofrom [::msgcat::mc "Original from"] \ oto [::msgcat::mc "Original to"] \ replyto [::msgcat::mc "Reply to"] \ replyroom [::msgcat::mc "Reply to room"] \ noreply [::msgcat::mc "No reply"] \ to [::msgcat::mc "To"] \ cc [::msgcat::mc "Carbon copy"] \ bcc [::msgcat::mc "Blind carbon copy"] \ ] } ####################################################### # Common procs proc ::xaddress::parse_xaddress_fields {xe {elems {}}} { jlib::wrapper:splitxml $xe tag vars isempty chdata children if {![cequal [jlib::wrapper:getattr $vars xmlns] $::NS(xaddress)]} { return {} } if {![cequal $tag addresses]} { return {} } set res {} foreach child $children { jlib::wrapper:splitxml $child tag1 vars1 isempty1 chdata1 children1 if {![cequal $tag1 address]} continue set type [jlib::wrapper:getattr $vars1 type] if {![lempty $elems] && ![lcontain $elems $type]} continue set params {} foreach elem {jid node uri descr delivered} { set value [jlib::wrapper:getattr $vars1 $elem] if {![cequal $value ""]} { lappend params $elem $value } } lappend res $type $params } return $res } proc ::xaddress::format_addressinfo_tooltip {type from real_from reason fields} { variable names set lines {} switch -- $reason { ofrom { lappend lines \ [::msgcat::mc "This message was forwarded by %s\n" \ $real_from] } #replyto - #replyroom { # lappend lines \ # [::msgcat::mc "This message was sent by %s\n" $real_from] #} } lappend lines [::msgcat::mc "Extended addressing fields:"] foreach {type params} $fields { array set arparams $params if {[info exists names($type)]} { set line " $names($type):" } else { set line " $type:" } if {[info exists arparams(descr)]} { append line " <$arparams(descr)>" } if {[info exists arparams(jid)]} { append line " $arparams(jid)" if {[info exists arparams(node)]} { append line " [$arparams(node)]" } } elseif {[info exists arparams(uri)]} { append line " $arparams(uri)" } lappend lines $line array unset arparams } return [join $lines "\n"] } ###################################################### # Replace original jid. Read README.xaddress proc ::xaddress::modify_from \ {vconnid vfrom vid vtype vis_subject vsubject \ vbody verr vthread vpriority vx} { upvar 2 $vfrom from upvar 2 $vtype type upvar 2 $vx x # those types are supported at now. if {![lcontain {chat normal groupchat ""} $type]} return set newx {} foreach xe $x { jlib::wrapper:splitxml $xe tag vars isempty chdata children if {[cequal [jlib::wrapper:getattr $vars xmlns] $::NS(xaddress_store)]} { # The other side tries to forge a sender sddress } else { lappend newx $xe } } set x $newx foreach xe $x { jlib::wrapper:splitxml $xe tag vars isempty chdata children if {[cequal [set res [parse_xaddress_fields $xe {ofrom}]] {}]} continue # FIX: now we get only first but what if there are several ofrom fields? lassign $res reason vars1 set ofrom [jlib::wrapper:getattr $vars1 jid] if {[cequal $ofrom ""]} return set x [linsert $x 0 [jlib::wrapper:createtag x \ -vars [list xmlns $::NS(xaddress_store) \ from $from \ reason $reason]]] set from $ofrom return } } hook::add rewrite_message_hook ::xaddress::modify_from ##################################################################### # Draw special icon and tooltip for xaddress messages in the chat. proc ::xaddress::draw_xaddress {chatid from type body x} { variable xaddrinfoid set chatw [chat::chat_win $chatid] set real_from "" set reason "" foreach xe $x { jlib::wrapper:splitxml $xe tag vars isempty chdata children set xmlns [jlib::wrapper:getattr $vars xmlns] if {[cequal $xmlns $::NS(xaddress_store)] && [cequal $tag x]} { set real_from [jlib::wrapper:getattr $vars from] set reason [jlib::wrapper:getattr $vars reason] continue } if {[cequal [set fields [parse_xaddress_fields $xe]] {}]} continue incr xaddrinfoid set label \ [Label $chatw.xaddrinfo$xaddrinfoid \ -image xaddress/info/green \ -helptext [format_addressinfo_tooltip \ $type $from $real_from $reason $fields] \ -helptype balloon \ -bg [$chatw cget -background]] $chatw window create end -window $label break } } hook::add draw_message_hook ::xaddress::draw_xaddress 6 ########################################################## # Draw xaddress fields in the new message dialog proc ::xaddress::process_x_data {rowvar bodyvar f x connid from id type replyP} { upvar 2 $rowvar row upvar 2 $bodyvar body variable names if {!$replyP || [cequal $type error]} { return } set title [join [lrange [split $f .] 0 end-1] .].title foreach xe $x { jlib::wrapper:splitxml $xe tag vars isempty chdata children set xmlns [jlib::wrapper:getattr $vars xmlns] # if "from" was modified draw reason and real_from if {[cequal $xmlns $::NS(xaddress_store)] && [cequal $tag x]} { set real_from [jlib::wrapper:getattr $vars from] set reason [jlib::wrapper:getattr $vars reason] switch -- $reason { ofrom { grid [Label $title.flabel \ -text [::msgcat::mc "Forwarded by:"]] \ -column 0 -row 2 -sticky e grid [Label $title.fjid -text $real_from] \ -column 1 -row 2 -sticky w } } continue } if {[cequal [set fields [parse_xaddress_fields $xe]] {}]} continue # draw most important xaddress fields set other_fields {} foreach {type params} $fields { array unset aparams array set aparams $params switch -- $type { noreply - replyroom - replyto { if {![info exist aparams(jid)]} { lappend other_fields $type $params continue } set text "" if {[info exists aparams(descr)]} { append text "<$aparams(descr)> " } append text $aparams(jid) if {[info exists aparams(node)]} { append text " [$aparams(node)]" } grid [Label $f.lxaddr${row} \ -text $names($type):] \ -column 0 -row $row -sticky e grid [Label $f.xaddr${row} -text $text] \ -column 1 -row $row -sticky w incr row } default { lappend other_fields $type $params } } } # draw rest in tooltip if {[expr [llength $other_fields] > 0]} { set label \ [Label $title.xaddrinfo \ -image xaddress/info/green \ -helptext [format_addressinfo_tooltip \ $type $from "" "" $other_fields] \ -helptype balloon \ -bg [$title cget -background]] grid $label -row 1 -column 4 -sticky e } } return } hook::add message_process_x_hook ::xaddress::process_x_data tkabber-0.11.1/plugins/general/xcommands.tcl0000644000175000017500000002711210752133252020320 0ustar sergeisergei# $Id: xcommands.tcl 1373 2008-02-05 19:19:06Z sergei $ # # Ad-Hoc Commands support (XEP-0050) # ########################################################################## namespace eval xcommands { set winid 0 } ########################################################################## proc xcommands::execute {jid node args} { set category automation foreach {key val} $args { switch -- $key { -category { set category $val } -connection { set connid $val } } } if {![info exists connid]} { return -code error "Option -connection is mandatory" } if {$category != "automation"} return set vars [list xmlns $::NS(commands) action execute] if {$node != ""} { lappend vars node $node } jlib::send_iq set \ [jlib::wrapper:createtag command \ -vars $vars] \ -command [list [namespace current]::execute_result $connid $jid $node] \ -to $jid \ -connection $connid } ########################################################################## proc xcommands::execute_result {connid jid node res child} { variable winid if {[cequal $res ERR]} { incr winid set w .xcommands_err$winid if {[winfo exists $w]} { destroy $w } MessageDlg $w -aspect 50000 -icon error \ -message [format \ [::msgcat::mc "Error executing command: %s"] \ [error_to_string $child]] \ -type user -buttons ok -default 0 -cancel 0 return } jlib::wrapper:splitxml $child tag vars isempty chdata children set node [jlib::wrapper:getattr $vars node] set sessionid [jlib::wrapper:getattr $vars sessionid] set status [jlib::wrapper:getattr $vars status] draw_window $connid $jid $node $sessionid $status $children } ########################################################################## proc xcommands::draw_window {connid jid node sessionid status xmldata} { variable winid lassign [find_note $xmldata] type note lassign [find_actions $xmldata] actions execute # Only jabber:x:data payloads are supported set xdata [find_xdata $xmldata] switch -- $status { executing - completed { } canceled - default { return } } incr winid set w .xcommands$winid if {[winfo exists $w]} { destroy $w } Dialog $w -modal none -separator 1 -anchor e -class XData \ -default 0 -cancel 1 set geometry [option get $w geometry XData] if {$geometry != ""} { wm geometry $w $geometry } set sw [ScrolledWindow $w.sw] set sf [ScrollableFrame $w.fields -constrainedwidth yes] set f [$sf getframe] $sw setwidget $sf set nf [frame $w.note] pack_note $nf $type $note set focus [data::fill_fields $f $xdata] switch -- $status { executing { if {[lempty $actions] || \ ([llength $actions] == 1 && [lcontain $actions complete])} { $w add -text [::msgcat::mc "Submit"] \ -command [list [namespace current]::execute_window \ $w $connid $jid $node $sessionid complete \ [list [namespace current]::complete_result]] $w add -text [::msgcat::mc "Cancel"] \ -command [list [namespace current]::cancel_window \ $w $connid $jid $node $sessionid] $w configure -default 0 set cancel 1 } else { $w add -text [::msgcat::mc "Prev"] \ -state disabled \ -command [list [namespace current]::execute_window \ $w $connid $jid $node $sessionid prev \ [list [namespace current]::next_result]] $w add -text [::msgcat::mc "Next"] \ -state disabled \ -command [list [namespace current]::execute_window \ $w $connid $jid $node $sessionid next \ [list [namespace current]::next_result]] $w add -text [::msgcat::mc "Finish"] \ -state disabled \ -command [list [namespace current]::execute_window \ $w $connid $jid $node $sessionid complete \ [list [namespace current]::complete_result]] $w add -text [::msgcat::mc "Cancel"] \ -command [list [namespace current]::cancel_window \ $w $connid $jid $node $sessionid] set_default_button $w $actions $execute set cancel 3 } } completed { $w add -text [::msgcat::mc "Close"] \ -command [list [namespace current]::close_window $w] $w configure -default 0 set cancel 0 } } # Can't configure -cancel option because of bug in BWidget # $w configure -cancel $cancel bind $w "$w invoke $cancel" bind $w [list data::cleanup $f] bindscroll $f $sf #pack [Separator $w.sep] -side bottom -fill x -pady 1m pack $nf -side top -expand no -fill x -padx 2m -pady 0m -in [$w getframe] pack $sw -side top -expand yes -fill both -padx 2m -pady 2m -in [$w getframe] update idletasks $nf configure -width [expr {[winfo reqwidth $f] + [winfo pixels $f 1c]}] if {$focus != ""} { $w draw $focus } else { $w draw } return $w } ########################################################################## proc xcommands::execute_window {w connid jid node sessionid action cmd} { # Send requested data and wait for result set vars [list xmlns $::NS(commands) sessionid $sessionid action $action] if {$node != ""} { lappend vars node $node } set f [$w.fields getframe] jlib::send_iq set \ [jlib::wrapper:createtag command \ -vars $vars \ -subtags [data::get_tags $f]] \ -command [list $cmd $w $connid $jid $node $sessionid] \ -to $jid \ -connection $connid } ########################################################################## proc xcommands::pack_note {fr type note} { set mf $fr.msg if {[winfo exists $mf]} { destroy $mf } if {$note == ""} return switch -- $type { warn { set msg [::msgcat::mc "Warning:"] } error { set msg [::msgcat::mc "Error:"] } default { set msg [::msgcat::mc "Info:"] } } message $mf -text "$msg $note" -aspect 50000 -width 0 pack $mf } ########################################################################## proc xcommands::set_default_button {bbox actions execute} { set default -1 foreach action $actions { switch -- $action { prev { $bbox itemconfigure 0 -state normal if {$default == -1} { set default 0 } } next { $bbox itemconfigure 1 -state normal set default 1 } complete { $bbox itemconfigure 2 -state normal if {$default == -1 || $default == 0} { set default 2 } } } } if {$default != -1} { $bbox configure -default $default } else { $bbox itemconfigure 1 -state normal $bbox configure -default 1 } switch -- $execute { prev { $bbox itemconfigure 0 -state normal $bbox configure -default 0 } next { $bbox itemconfigure 1 -state normal $bbox configure -default 1 } complete { $bbox itemconfigure 2 -state normal $bbox configure -default 2 } } } ########################################################################## proc xcommands::next_result {w connid jid node sessionid res child} { variable winid set f [$w.fields getframe] foreach cw [winfo children $f] { destroy $cw } data::cleanup $f if {[cequal $res ERR]} { incr winid set w .xcommands_err$winid if {[winfo exists $w]} { destroy $w } MessageDlg $w -aspect 50000 -icon error \ -message [format \ [::msgcat::mc "Error executing command: %s"] \ [error_to_string $child]] \ -type user -buttons ok -default 0 -cancel 0 return } # TODO jlib::wrapper:splitxml $child tag vars isempty chdata children set node [jlib::wrapper:getattr $vars node] set sessionid [jlib::wrapper:getattr $vars sessionid] set status [jlib::wrapper:getattr $vars status] destroy $w draw_window $connid $jid $node $sessionid $status $children } ########################################################################## proc xcommands::complete_result {w connid jid node sessionid res child} { variable winid if {[cequal $res ERR]} { incr winid set w .xcommands_err$winid if {[winfo exists $w]} { destroy $w } MessageDlg $w -aspect 50000 -icon error \ -message [format \ [::msgcat::mc "Error completing command: %s"] \ [error_to_string $child]] \ -type user -buttons ok -default 0 -cancel 0 return } # TODO jlib::wrapper:splitxml $child tag vars isempty chdata children set node [jlib::wrapper:getattr $vars node] set sessionid [jlib::wrapper:getattr $vars sessionid] set status [jlib::wrapper:getattr $vars status] switch -- $status { executing - completed { } canceled - default { return } } lassign [find_note $children] type note lassign [find_actions $children] actions execute # Only jabber:x:data payloads are supported set xdata [find_xdata $children] set f [$w.fields getframe] foreach cw [winfo children $f] { destroy $cw } data::cleanup $f set nf $w.note pack_note $nf $type $note set focus [data::fill_fields $f $xdata] destroy $w draw_window $connid $jid $node $sessionid $status $children } ########################################################################## proc xcommands::cancel_window {w connid jid node sessionid} { # Send cancelling stanza and ignore reply or error set vars [list xmlns $::NS(commands) sessionid $sessionid action cancel] if {$node != ""} { lappend vars node $node } jlib::send_iq set \ [jlib::wrapper:createtag command -vars $vars] \ -to $jid \ -connection $connid set f [$w.fields getframe] data::cleanup $f destroy $w } ########################################################################## proc xcommands::close_window {w} { set f [$w.fields getframe] data::cleanup $f destroy $w } ########################################################################## proc xcommands::find_actions {xmldata} { set actions {} set execute next foreach child $xmldata { jlib::wrapper:splitxml $child tag vars isempty chdata children if {$tag == "actions"} { if {[jlib::wrapper:isattr $vars execute]} { set execute [jlib::wrapper:getattr $vars execute] } foreach child1 $children { jlib::wrapper:splitxml $child1 tag1 vars1 isempty1 chdata1 children1 switch -- $tag1 { prev - next - complete { lappend actions $tag1 } } } if {![lcontain $actions $execute]} { set execute next } } } return [list $actions $execute] } ########################################################################## proc xcommands::find_xdata {xmldata} { set xdata {} foreach child $xmldata { jlib::wrapper:splitxml $child tag vars isempty chdata children if {[jlib::wrapper:getattr $vars xmlns] == $::NS(data)} { lappend xdata $child } } return $xdata } ########################################################################## proc xcommands::find_note {xmldata} { set note "" set type info foreach child $xmldata { jlib::wrapper:splitxml $child tag vars isempty chdata children if {$tag == "note"} { set note [string trim $chdata] set type [jlib::wrapper:getattr $vars type] switch -- $type { info - warn - error { } default { set type info } } } } return [list $type $note] } ########################################################################## proc xcommands::register_namespace {} { disco::browser::register_feature_handler $::NS(commands) \ [namespace current]::execute -node 1 \ -desc [list automation [::msgcat::mc "Execute command"]] disco::register_featured_node $::NS(commands) $::NS(commands) \ [::msgcat::mc "Commands"] } hook::add postload_hook [namespace current]::xcommands::register_namespace ########################################################################## tkabber-0.11.1/plugins/general/rawxml.tcl0000644000175000017500000003343411014021262017632 0ustar sergeisergei# $Id: rawxml.tcl 1429 2008-05-18 12:36:02Z sergei $ option add *RawXML.inforeground DarkRed widgetDefault option add *RawXML.outforeground DarkBlue widgetDefault option add *RawXML.intagforeground DarkRed widgetDefault option add *RawXML.inattrforeground DarkRed widgetDefault option add *RawXML.invalueforeground Purple4 widgetDefault option add *RawXML.incdataforeground SteelBlue widgetDefault option add *RawXML.outtagforeground DarkMagenta widgetDefault option add *RawXML.outattrforeground DarkMagenta widgetDefault option add *RawXML.outvalueforeground DarkGreen widgetDefault option add *RawXML.outcdataforeground DarkBlue widgetDefault option add *RawXML.inputheight 4 widgetDefault namespace eval rawxml { custom::defgroup Plugins [::msgcat::mc "Plugins options."] -group Tkabber custom::defgroup RawXML \ [::msgcat::mc "Options for Raw XML Input module,\ which allows you to monitor\ incoming/outgoing traffic from connection to server and send\ custom XML stanzas."] -group Plugins -tag "Raw XML Input" #set options(pretty_print) 0 custom::defvar options(pretty_print) 0 \ [::msgcat::mc "Pretty print incoming and outgoing XML stanzas."] \ -group RawXML -type boolean #set options(indent) 2 custom::defvar options(indent) 2 \ [::msgcat::mc "Indentation for pretty-printed XML subtags."] \ -group RawXML -type integer set pass 0 variable tabs } proc rawxml::handle_inout {connid text prefix tag} { variable options variable pass set w .rawxml if {![winfo exists $w]} return if {$options(pretty_print) && ($tag != "out" || $pass)} { set pass 0 return } set dump $w.dump $dump configure -state normal set scroll [expr {[lindex [$dump yview] 1] == 1}] set id "($connid)" catch {set id "($connid,[jlib::connection_jid $connid])"} $dump insert end \ "$prefix$id:\n" {} \ "$text" $tag if {![$dump compare "end -1 chars linestart" == "end -1 chars"]} { $dump insert end "\n" } if {$scroll} { after idle [list $dump yview moveto 1] } $dump configure -state disabled } proc rawxml::handle_inout_x {connid xml prefix tag} { variable options variable pass set w .rawxml if {![winfo exists $w]} return if {!$options(pretty_print)} return if {$tag == "out"} {set pass 1} set dump $w.dump $dump configure -state normal set scroll [expr {[lindex [$dump yview] 1] == 1}] set id "($connid)" catch {set id "($connid,[jlib::connection_jid $connid])"} $dump insert end "$prefix$id:\n" pretty_print $dump $xml "" $tag if {![$dump compare "end -1 chars linestart" == "end -1 chars"]} { $dump insert end "\n" } if {$scroll} { $dump see end } $dump configure -state disabled } proc rawxml::pretty_print {t xmldata prefix tag {xmlns jabber:client}} { variable options variable tabs jlib::wrapper:splitxml $xmldata tagname vars isempty chdata subtags set vars1 {} foreach {attr value} $vars { if {$attr == "xmlns"} { if {$value == $xmlns} { continue } else { set xmlns $value } } lappend vars1 $attr $value } $t insert end "$prefix<" {} $tagname ${tag}tag if {[llength $vars1] != 0} { #set attrprefix ${prefix}[string repeat " " \ # [expr {[clength $tagname] + 2}]] set arr_index "$prefix<$tagname " if {![info exists tabs($arr_index)]} { set tabs($arr_index) [font measure [$t cget -font] $arr_index] } $t tag configure $arr_index -tabs [list $tabs($arr_index)] set vars2 [lassign $vars1 attr value] $t insert end \ " $attr" ${tag}attr \ "=" {} \ "'[jlib::wrapper:xmlcrypt $value]'" ${tag}value foreach {attr value} $vars2 { $t insert end \ "\n\t$attr" [list ${tag}attr $arr_index]\ "=" {} \ "'[jlib::wrapper:xmlcrypt $value]'" ${tag}value } } if {$chdata == "" && [llength $subtags] == 0} { $t insert end "/>\n" return } else { $t insert end ">" } if {$subtags == {}} { $t insert end [jlib::wrapper:xmlcrypt $chdata] ${tag}cdata $t insert end "\n" } else { $t insert end "\n" foreach subdata $subtags { pretty_print $t $subdata \ $prefix[string repeat " " $options(indent)] $tag \ $xmlns } $t insert end "$prefix\n" } } proc ::LOG_INPUT {connid t} \ "[namespace current]::rawxml::handle_inout \$connid \$t IN in" proc ::LOG_OUTPUT {connid t} \ "[namespace current]::rawxml::handle_inout \$connid \$t OUT out" proc ::LOG_INPUT_XML {connid x} \ "[namespace current]::rawxml::handle_inout_x \$connid \$x IN in" proc ::LOG_OUTPUT_XML {connid x} \ "[namespace current]::rawxml::handle_inout_x \$connid \$x OUT out" proc rawxml::open_window {} { set w .rawxml if {[winfo exists $w]} { return } add_win $w -title [::msgcat::mc "Raw XML"] \ -tabtitle [::msgcat::mc "Raw XML"] \ -class RawXML \ -raisecmd [list focus $w.input] \ -raise 1 set tools [frame $w.tools] pack $tools -side top -anchor w -fill x checkbutton $tools.pp -text [::msgcat::mc "Pretty print XML"] \ -variable [namespace current]::options(pretty_print) pack $tools.pp -side left -anchor w menubutton $tools.templates -text [::msgcat::mc "Templates"] \ -relief $::tk_relief \ -menu .rawxml.tools.templates.root pack $tools.templates -side left -anchor w create_template_menu button $tools.clear -text [::msgcat::mc "Clear"] \ -command " [list $w.dump] configure -state normal [list $w.dump] delete 0.0 end [list $w.dump] configure -state disabled " pack $tools.clear -side left -anchor w PanedWin $w.pw -side right -pad 0 -width 4 pack $w.pw -fill both -expand yes set uw [PanedWinAdd $w.pw -weight 1 -minsize 100] set dw [PanedWinAdd $w.pw -weight 0 -minsize 32] set isw [ScrolledWindow $w.isw -scrollbar vertical] pack $isw -side bottom -fill both -expand yes -in $dw set input [textUndoable $w.input \ -height [option get $w inputheight RawXML]] $isw setwidget $input [winfo parent $dw] configure -height [winfo reqheight $input] set sw [ScrolledWindow $w.sw -scrollbar vertical] pack $sw -side top -fill both -expand yes -in $uw set dump [text $w.dump] $sw setwidget $dump $dump configure -state disabled bind $input " [namespace current]::send_xml break" $dump tag configure in \ -foreground [option get $w inforeground RawXML] $dump tag configure out \ -foreground [option get $w outforeground RawXML] $dump tag configure intag \ -foreground [option get $w intagforeground RawXML] $dump tag configure inattr \ -foreground [option get $w inattrforeground RawXML] $dump tag configure invalue \ -foreground [option get $w invalueforeground RawXML] $dump tag configure incdata \ -foreground [option get $w incdataforeground RawXML] $dump tag configure outtag \ -foreground [option get $w outtagforeground RawXML] $dump tag configure outattr \ -foreground [option get $w outattrforeground RawXML] $dump tag configure outvalue \ -foreground [option get $w outvalueforeground RawXML] $dump tag configure outcdata \ -foreground [option get $w outcdataforeground RawXML] variable history bind $input \ [list [namespace current]::history_move 1] bind $input \ [list [namespace current]::history_move -1] set history(stack) [list {}] set history(pos) 0 regsub -all %W [bind Text ] $dump prior_binding regsub -all %W [bind Text ] $dump next_binding bind $input $prior_binding bind $input $next_binding bind $input $prior_binding bind $input $next_binding hook::run open_rawxml_post_hook $w } proc rawxml::history_move {shift} { variable history set newpos [expr $history(pos) + $shift] if {!($newpos < 0 || $newpos >= [llength $history(stack)])} { set iw .rawxml.input set body [$iw get 1.0 "end -1 chars"] if {$history(pos) == 0} { set history(stack) \ [lreplace $history(stack) 0 0 $body] } set history(pos) $newpos set newbody [lindex $history(stack) $newpos] $iw delete 1.0 end $iw insert 0.0 $newbody } } proc rawxml::send_xml {} { variable history set input .rawxml.input set xml [$input get 0.0 "end - 1c"] lvarpush history(stack) $xml 1 set history(pos) 0 if {[llength [::jlib::connections]] == 0} { return -code error [::msgcat::mc "Not connected"] } else { set connid [lindex [::jlib::connections] 0] jlib::outmsg $xml -connection $connid } $input delete 1.0 end } proc rawxml::setup_menu {} { catch { set m [.mainframe getmenu admin] $m add command -label [::msgcat::mc "Open raw XML window"] \ -command [namespace current]::open_window } } hook::add finload_hook [namespace current]::rawxml::setup_menu proc rawxml::add_template_group {parent group name} { set m .rawxml.tools.templates.$group set mparent .rawxml.tools.templates.$parent if {![winfo exists $m]} { menu $m -tearoff 0 } $mparent add cascade -label $name -menu $m } proc rawxml::add_template {group name xmldata} { set m .rawxml.tools.templates.$group set input .rawxml.input $m add command -label $name \ -command [list [namespace current]::pretty_print \ $input $xmldata "" template] } proc rawxml::create_template_menu {} { if {[winfo exists .rawxml.tools.templates.root]} { destroy .rawxml.tools.templates.root } else { menu .rawxml.tools.templates.root -tearoff 0 } add_template_group root message [::msgcat::mc "Message"] add_template message [::msgcat::mc "Normal message"] \ [jlib::wrapper:createtag message \ -vars {to "" type normal} \ -subtags [list [jlib::wrapper:createtag body -chdata " "]]] add_template message [::msgcat::mc "Chat message"] \ [jlib::wrapper:createtag message \ -vars {to "" type chat} \ -subtags [list [jlib::wrapper:createtag body -chdata " "]]] add_template message [::msgcat::mc "Headline message"] \ [jlib::wrapper:createtag message \ -vars {to "" type headline} \ -subtags [list [jlib::wrapper:createtag subject -chdata " "] \ [jlib::wrapper:createtag body -chdata " "] \ [jlib::wrapper:createtag x \ -vars {xmlns jabber:x:oob} \ -subtags [list [jlib::wrapper:createtag url -chdata " "] \ [jlib::wrapper:createtag desc -chdata " "]]]]] add_template_group root presence [::msgcat::mc "Presence"] add_template presence [::msgcat::mc "Available presence"] \ [jlib::wrapper:createtag presence \ -vars {to ""} \ -subtags [list \ [jlib::wrapper:createtag status -chdata " "] \ [jlib::wrapper:createtag show -chdata " "] \ ]] add_template presence [::msgcat::mc "Unavailable presence"] \ [jlib::wrapper:createtag presence \ -vars {to "" type unavailable} \ -subtags [list \ [jlib::wrapper:createtag status -chdata " "] \ ]] add_template_group root iq [::msgcat::mc "IQ"] add_template iq [::msgcat::mc "Generic IQ"] \ [jlib::wrapper:createtag iq \ -vars {to "" type "" id ""} \ -subtags [list \ [jlib::wrapper:createtag query \ -vars {xmlns ""}]]] add_template iq "jabber:iq:time get" \ [jlib::wrapper:createtag iq \ -vars {to "" type get id ""} \ -subtags [list \ [jlib::wrapper:createtag query \ -vars {xmlns jabber:iq:time}]]] add_template iq "jabber:iq:version get" \ [jlib::wrapper:createtag iq \ -vars {to "" type get id ""} \ -subtags [list \ [jlib::wrapper:createtag query \ -vars {xmlns jabber:iq:version}]]] add_template iq "jabber:iq:last get" \ [jlib::wrapper:createtag iq \ -vars {to "" type get id ""} \ -subtags [list \ [jlib::wrapper:createtag query \ -vars {xmlns jabber:iq:last}]]] add_template_group iq pubsub [::msgcat::mc "Pub/sub"] pubsub_template [::msgcat::mc "Create node"] set \ [jlib::wrapper:createtag create \ -vars {node ""}] pubsub_template [::msgcat::mc "Publish node"] set \ [jlib::wrapper:createtag publish \ -vars {node ""} \ -subtags [list [jlib::wrapper:createtag item]]] pubsub_template [::msgcat::mc "Retract node"] set \ [jlib::wrapper:createtag retract \ -vars {node ""} \ -subtags [list [jlib::wrapper:createtag item]]] pubsub_template [::msgcat::mc "Subscribe to a node"] set \ [jlib::wrapper:createtag subscribe \ -vars {node "" jid ""}] pubsub_template [::msgcat::mc "Unsubscribe from a node"] set \ [jlib::wrapper:createtag unsubscribe \ -vars {node "" jid ""}] pubsub_template [::msgcat::mc "Get items"] get \ [jlib::wrapper:createtag items \ -vars {node ""}] } proc rawxml::pubsub_template {name type subtag} { add_template pubsub $name \ [jlib::wrapper:createtag iq \ -vars [list to "" type $type id ""] \ -subtags [list \ [jlib::wrapper:createtag pubsub \ -vars [list xmlns \ http://jabber.org/protocol/pubsub] \ -subtags [list $subtag]]]] } ############################################################################## proc rawxml::restore_window {args} { open_window } proc rawxml::save_session {vsession} { upvar 2 $vsession session global usetabbar # We don't need JID at all, so make it empty (special case) set user "" set server "" set resource "" # TODO if {!$usetabbar} return set prio 0 foreach page [.nb pages] { set path [ifacetk::nbpath $page] if {[string equal $path .rawxml]} { lappend session [list $prio $user $server $resource \ [list [namespace current]::restore_window] \ ] } incr prio } } hook::add save_session_hook [namespace current]::rawxml::save_session # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/plugins/general/sound.tcl0000644000175000017500000002401611076045704017463 0ustar sergeisergei# $Id: sound.tcl 1514 2008-10-17 08:24:36Z sergei $ namespace eval ::sound { set snack 1 if {[catch { package require snack 2.0 }]} { debugmsg tkabber \ "Unable to load the Snack package, so no sound support!\ The Snack package is available at http://www.speech.kth.se/snack/index.html" set snack 0 } custom::defgroup Sound [::msgcat::mc "Sound options."] -group Tkabber variable options variable groupchat_may_notify if {[catch { set vfs [string match tclvfs* [file system [fullpath sound]]] }]} { set vfs 0 } custom::defvar options(mute) 0 \ [::msgcat::mc "Mute sound notification."] \ -type boolean -group Sound custom::defvar options(notify_online) 1 \ [::msgcat::mc "Use sound notification only when being available."] \ -type boolean -group Sound variable mute 0 custom::defvar options(mute_groupchat_delayed) 1 \ [::msgcat::mc "Mute sound when displaying delayed groupchat messages."] \ -type boolean -group Sound custom::defvar options(mute_chat_delayed) 0 \ [::msgcat::mc "Mute sound when displaying delayed personal chat messages."] \ -type boolean -group Sound custom::defvar options(mute_if_focus) 0 \ [::msgcat::mc "Mute sound if Tkabber window is focused."] \ -type boolean -group Sound # One could use external play program instead of Snack custom::defvar options(external_play_program) "" \ [::msgcat::mc "External program, which is to be executed to play sound.\ If empty, Snack library is used (if available) to play sound."] \ -type string -group Sound # Params for external play program custom::defvar options(external_play_program_options) "" \ [::msgcat::mc "Options for external play program"] \ -type string -group Sound custom::defvar options(connected_sound) \ [fullpath sounds default connected.wav] \ [::msgcat::mc "Sound to play when connected to Jabber server."] \ -command [list [namespace current]::load_sound_file connected] \ -type file -group Sound custom::defvar options(disconnected_sound) \ [fullpath sounds default disconnected.wav] \ [::msgcat::mc "Sound to play when disconnected from Jabber server."] \ -command [list [namespace current]::load_sound_file disconnected] \ -type file -group Sound custom::defvar options(presence_available_sound) \ [fullpath sounds default presence_available.wav] \ [::msgcat::mc "Sound to play when available presence is received."] \ -command [list [namespace current]::load_sound_file presence_available] \ -type file -group Sound custom::defvar options(presence_unavailable_sound) \ [fullpath sounds default presence_unavailable.wav] \ [::msgcat::mc "Sound to play when unavailable presence is received."] \ -command [list [namespace current]::load_sound_file presence_unavailable] \ -type file -group Sound custom::defvar options(chat_my_message_sound) \ [fullpath sounds default chat_my_message.wav] \ [::msgcat::mc "Sound to play when sending personal chat message."] \ -command [list [namespace current]::load_sound_file chat_my_message] \ -type file -group Sound custom::defvar options(chat_their_message_sound) \ [fullpath sounds default chat_their_message.wav] \ [::msgcat::mc "Sound to play when personal chat message is received."] \ -command [list [namespace current]::load_sound_file chat_their_message] \ -type file -group Sound custom::defvar options(groupchat_server_message_sound) \ [fullpath sounds default groupchat_server_message.wav] \ [::msgcat::mc "Sound to play when groupchat server message is received."] \ -command [list [namespace current]::load_sound_file groupchat_server_message] \ -type file -group Sound custom::defvar options(groupchat_my_message_sound) \ [fullpath sounds default groupchat_my_message.wav] \ [::msgcat::mc "Sound to play when groupchat message from me is received."] \ -command [list [namespace current]::load_sound_file groupchat_my_message] \ -type file -group Sound custom::defvar options(groupchat_their_message_sound) \ [fullpath sounds default groupchat_their_message.wav] \ [::msgcat::mc "Sound to play when groupchat message is received."] \ -command [list [namespace current]::load_sound_file groupchat_their_message] \ -type file -group Sound custom::defvar options(groupchat_their_message_to_me_sound) \ [fullpath sounds default chat_their_message.wav] \ [::msgcat::mc "Sound to play when highlighted (usually addressed personally)\ groupchat message is received."] \ -command [list [namespace current]::load_sound_file groupchat_their_message_to_me] \ -type file -group Sound variable play_id "" variable play_priority 0 # Do not allow play sound very often custom::defvar options(delay) 200 \ [::msgcat::mc "Time interval before playing next sound (in milliseconds)."] \ -type integer -group Sound hook::add finload_hook [namespace current]::setup_menu hook::add on_change_user_presence_hook \ [namespace current]::presence_notify 100 hook::add change_our_presence_post_hook [namespace current]::mute_setup 100 hook::add connected_hook [namespace current]::connected_notify 100 hook::add predisconnected_hook [namespace current]::disconnected_notify 100 hook::add postload_hook [namespace current]::sound_setup 100 hook::add draw_message_hook [namespace current]::chat_message_notify 19 } proc ::sound::setup_menu {} { variable options if {![cequal $::interface tk] && ![cequal $::interface ck]} return catch { set m [.mainframe getmenu tkabber] set ind [expr {[$m index [::msgcat::mc "Chats"]] + 1}] set mm .sound_menu menu $mm -tearoff $::ifacetk::options(show_tearoffs) $mm add checkbutton -label [::msgcat::mc "Mute sound"] \ -variable [namespace current]::options(mute) $mm add checkbutton -label [::msgcat::mc "Notify only when available"] \ -variable [namespace current]::options(notify_online) $m insert $ind cascade -label [::msgcat::mc "Sound"] \ -menu $mm } } proc ::sound::load_sound_file {name args} { variable snack variable options variable sounds if {[file exist $options(${name}_sound)]} { set sounds($name) $options(${name}_sound) if {$snack} { catch { snack::sound $sounds($name) -file $sounds($name) } } } else { set sounds($name) "" } } proc ::sound::sound_setup {} { variable options variable groupchat_may_notify variable sounds foreach name [list groupchat_server_message groupchat_my_message \ groupchat_their_message chat_my_message \ chat_their_message connected disconnected \ presence_available presence_unavailable \ groupchat_their_message_to_me] { load_sound_file $name } } proc ::sound::play {name {priority 0}} { global userstatus variable snack variable options variable play_id variable play_priority if {($name == "")} return if {$play_id != ""} { if {$priority >= $play_priority} { return } else { after cancel $play_id } } if {$options(delay) > 0} { set play_id [after $options(delay) [list set [namespace current]::play_id {}]] } set play_priority $priority if {$options(external_play_program) == ""} { if {![info exist $name]} { catch { snack::sound $name -file $name } } catch { $name play -block 0 } } else { catch { eval "exec $options(external_play_program) $options(external_play_program_options) [list $name] &" } } } proc ::sound::chat_message_notify {chatid from type body extras} { variable options variable sounds if {[is_mute]} return set delayed 0 foreach xelem $extras { jlib::wrapper:splitxml $xelem tag vars isempty chdata children if {[cequal [jlib::wrapper:getattr $vars xmlns] jabber:x:delay]} { set delayed 1 } } switch -- $type { groupchat { if {$delayed && $options(mute_groupchat_delayed)} { return } if {[cequal [chat::get_jid $chatid] $from]} { play $sounds(groupchat_server_message) } elseif {[chat::is_our_jid $chatid $from]} { play $sounds(groupchat_my_message) } else { set mynick [chat::get_nick [chat::get_connid $chatid] \ [chat::our_jid $chatid] $type] if {[check_message $mynick $body]} { play $sounds(groupchat_their_message_to_me) -1 } else { play $sounds(groupchat_their_message) } } } chat { if {$delayed && $options(mute_chat_delayed)} { return } foreach xelem $extras { jlib::wrapper:splitxml $xelem tag vars isempty chdata children # Don't play sound if this 'empty' tag is present. It indicates # messages history in chat window. if {[cequal $tag ""] && \ [cequal [jlib::wrapper:getattr $vars xmlns] tkabber:x:nolog]} { return } } if {[chat::is_our_jid $chatid $from]} { play $sounds(chat_my_message) } elseif {$from == ""} { play $sounds(groupchat_server_message) } else { play $sounds(chat_their_message) -1 } } } } proc ::sound::presence_notify {name status} { variable options variable sounds if {[is_mute]} return if {$status == "available" || $status == "chat"} { play $sounds(presence_available) } else { play $sounds(presence_unavailable) } } proc ::sound::mute_setup {status} { variable options variable mute if {$options(notify_online)} { switch -- $status { available - chat { set mute 0 } default { set mute 1 } } } else { set mute 0 } } proc ::sound::connected_notify {connid} { variable options variable sounds if {[is_mute]} return play $sounds(connected) 1 } proc ::sound::disconnected_notify {connid} { variable options variable sounds if {[is_mute]} return if {$connid == {}} { if {[llength [jlib::connections]] > 0} { play $sounds(disconnected) 1 } } else { if {[lsearch -exact [jlib::connections] $connid] >= 0} { play $sounds(disconnected) 1 } } } proc ::sound::is_mute {} { variable snack variable options variable mute expr {(($options(external_play_program) == "") && !$snack) || \ $options(mute) || \ $mute || \ ($options(mute_if_focus) && [focus -displayof .] != "")} } tkabber-0.11.1/plugins/general/autoaway.tcl0000644000175000017500000001203010615103406020146 0ustar sergeisergei# $Id: autoaway.tcl 1125 2007-04-29 11:52:38Z sergei $ namespace eval autoaway { variable options variable savestatus "" variable savetext "" variable savepriority 0 } proc autoaway::load {} { global tcl_platform global idle_command if {[catch {tk inactive}] || ([tk inactive] < 0)} { switch -- $tcl_platform(platform) { macintosh { set idle_command [namespace current]::AquaIdleTime } unix { if {$::aquaP} { set idle_command [namespace current]::AquaIdleTime } elseif {[catch { package require tkXwin }]} { return } else { set idle_command tkXwin::idletime } } windows { if {![catch { package require tkinactive }]} { set idle_command tkinactive } elseif {![catch { package require tclWinidle }]} { set idle_command tclWinidle::idletime } else { return } } default { return } } } else { set idle_command {tk inactive} } custom::defgroup AutoAway \ [::msgcat::mc "Options for module that automatically marks\ you as away after idle threshold."] \ -group Tkabber custom::defvar options(awaytime) 5 \ [::msgcat::mc "Idle threshold in minutes after that\ Tkabber marks you as away."] \ -group AutoAway -type integer custom::defvar options(xatime) 15 \ [::msgcat::mc "Idle threshold in minutes after that\ Tkabber marks you as extended away."] \ -group AutoAway -type integer custom::defvar options(status) \ [::msgcat::mc "Automatically away due to idle"] \ [::msgcat::mc "Text status, which is set when\ Tkabber is moving to away state."] \ -group AutoAway -type string custom::defvar options(drop_priority) 1 \ [::msgcat::mc "Set priority to 0 when moving to extended away state."] \ -group AutoAway -type boolean hook::add connected_hook [namespace current]::after_idle hook::add disconnected_hook [namespace current]::after_idle_cancel } proc autoaway::after_idle {args} { after cancel [namespace current]::after_idle after_idle_aux if {$::aquaP} { set msec 1000 } else { set msec 250 } after $msec [namespace current]::after_idle } proc autoaway::after_idle_cancel {args} { variable options variable savestatus variable savetext variable savepriority global userstatus textstatus userpriority if {[jlib::connections] == {}} { if {![cequal $savestatus ""]} { if {$options(drop_priority) && ($userpriority >= 0)} { set userpriority $savepriority } set savepriority 0 set textstatus $savetext set savetext "" set userstatus $savestatus set savestatus "" } after cancel [namespace current]::after_idle } } proc autoaway::after_idle_aux {} { variable options variable savestatus variable savetext variable savepriority global idle_command global userstatus textstatus userpriority if {($options(awaytime) <= 0) && ($options(xatime) <= 0)} { return } set idletime [eval $idle_command] if {$idletime < [expr {$options(awaytime)*60*1000}]} { if {![cequal $savestatus ""]} { if {$options(drop_priority) && ($userpriority >= 0)} { set userpriority $savepriority } set savepriority 0 set textstatus $savetext set savetext "" set userstatus $savestatus set savestatus "" set_status [::msgcat::mc "Returning from auto-away"] } return } switch -- $userstatus { available - chat { set savestatus $userstatus set savetext $textstatus set savepriority $userpriority if {![cequal $options(status) ""]} { set textstatus $options(status) } if {$idletime >= [expr {$options(xatime)*60*1000}]} { if {$options(drop_priority) && ($userpriority >= 0)} { set userpriority 0 } set userstatus xa set_status [::msgcat::mc "Moving to extended away"] } else { set userstatus away set_status [::msgcat::mc "Starting auto-away"] } return } away { if {(![cequal $savestatus ""]) && \ ($idletime >= [expr {$options(xatime)*60*1000}])} { set savepriority $userpriority if {![cequal $options(status) ""]} { set textstatus $options(status) } if {$options(drop_priority) && ($userpriority >= 0)} { set userpriority 0 } set userstatus xa set_status [::msgcat::mc "Moving to extended away"] return } } default { } } if {![cequal $savestatus ""]} { set_status [format [::msgcat::mc "Idle for %s"] [format_time [expr {$idletime/1000}]]] } } proc autoaway::AquaIdleTime {} { catch { set line [read [set fd [open {|ioreg -x -c IOHIDSystem}]]] } close $fd expr {"0x[lindex [regexp -inline {"HIDIdleTime" = (?:0x|<)([[:xdigit:]]+)} \ $line] 1]"/1000000} } autoaway::load # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/plugins/general/copy_jid.tcl0000644000175000017500000000367711045370624020143 0ustar sergeisergei# $Id: copy_jid.tcl 1480 2008-08-03 17:57:40Z sergei $ # Copy JID to clipboard ############################################################################### namespace eval copy_jid {} ############################################################################### proc copy_jid::copy {m jid} { clipboard clear -displayof $m clipboard append -displayof $m $jid } ############################################################################### proc copy_jid::add_menu_item {m connid jid} { $m add command \ -label [::msgcat::mc "Copy JID to clipboard"] \ -command [list [namespace current]::copy $m $jid] } proc copy_jid::add_muc_menu_item {m connid jid} { set real_jid [::muc::get_real_jid $connid $jid] if {$real_jid != ""} { $m add command \ -label [::msgcat::mc "Copy real JID to clipboard"] \ -command [list [namespace current]::copy $m $real_jid] } else { $m add command \ -label [::msgcat::mc "Copy real JID to clipboard"] \ -state disabled } } hook::add roster_create_groupchat_user_menu_hook \ [namespace current]::copy_jid::add_menu_item 44 hook::add roster_create_groupchat_user_menu_hook \ [namespace current]::copy_jid::add_muc_menu_item 44.5 hook::add chat_create_user_menu_hook \ [namespace current]::copy_jid::add_menu_item 44 hook::add chat_create_conference_menu_hook \ [namespace current]::copy_jid::add_menu_item 44 hook::add roster_jid_popup_menu_hook \ [namespace current]::copy_jid::add_menu_item 44 hook::add roster_conference_popup_menu_hook \ [namespace current]::copy_jid::add_menu_item 44 hook::add roster_service_popup_menu_hook \ [namespace current]::copy_jid::add_menu_item 44 hook::add message_dialog_menu_hook \ [namespace current]::copy_jid::add_menu_item 44 hook::add search_popup_menu_hook \ [namespace current]::copy_jid::add_menu_item 44 ############################################################################### # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/plugins/general/ispell.tcl0000644000175000017500000002301411015004476017612 0ustar sergeisergei# $Id: ispell.tcl 1442 2008-05-21 11:36:30Z sergei $ ############################################################################# package require textutil ############################################################################# namespace eval ispell { custom::defgroup Plugins [::msgcat::mc "Plugins options."] \ -group Tkabber custom::defgroup Ispell [::msgcat::mc "Spell check options."] \ -group Plugins variable options custom::defvar options(enable) 0 \ [::msgcat::mc "Enable spellchecker in text input windows."] \ -type boolean \ -group Ispell \ -command [namespace current]::stop custom::defvar options(executable) /usr/bin/ispell \ [::msgcat::mc "Path to the ispell executable."] \ -group Ispell \ -command [namespace current]::stop custom::defvar options(command_line) "" \ [::msgcat::mc "Ispell options. See ispell manual for\ details.\n\nExamples:\n -d russian\n -d german -T\ latin1\n -C -d english"] \ -type string \ -group Ispell \ -command [namespace current]::stop custom::defvar options(dictionary_encoding) "" \ [::msgcat::mc "Ispell dictionary encoding. If it is empty,\ system encoding is used."] \ -type string \ -group Ispell \ -command [namespace current]::stop custom::defvar options(check_every_symbol) 0 \ [::msgcat::mc "Check spell after every entered symbol."] \ -type boolean \ -group Ispell \ -command [namespace current]::stop variable misspelled variable word_id 0 option add *Text.errorColor Red widgetDefault option add *Text.comboColor Blue widgetDefault } ############################################################################# proc ispell::stop {args} { variable pipe catch {close $pipe} catch {unset pipe} } ############################################################################# proc ispell::start {} { variable options variable pipe set pipe [open "|[list $options(executable)] -a $options(command_line)" r+] set version [gets $pipe] if {[cequal $version ""]} { stop return } fconfigure $pipe -blocking off -buffering line if {![cequal $options(dictionary_encoding) ""]} { fconfigure $pipe -encoding $options(dictionary_encoding) } fileevent $pipe readable [namespace current]::process_filter } ############################################################################# proc ispell::process_filter {} { variable pipe variable response variable current_word variable input_window variable misspelled set word [read $pipe] if {[string length $word] <= 1} { set response $word return } switch -- [string index $word 0] { \- { set misspelled($current_word) combo } \& - \? - \# { set misspelled($current_word) err } default { set misspelled($current_word) ok } } set response $word } ############################################################################# proc ispell::pipe_word {word} { variable options variable pipe variable response variable current_word variable misspelled if {!$options(enable)} return set current_word $word if {![info exist pipe]} { start if {![info exist pipe]} { after idle [list NonmodalMessageDlg .ispell_error \ -aspect 50000 \ -icon error \ -message [::msgcat::mc "Could not start ispell\ server. Check your ispell\ path and dictionary name.\ Ispell is disabled now"]] set options(enable) 0 return } } if {[string length $word] <= 1} { set misspelled($word) ok return } puts $pipe $word vwait [namespace current]::response } ############################################################################# proc ispell::process_word {iw insind} { variable input_window variable misspelled variable word_id set wid $word_id incr word_id set ins [lindex [split $insind .] 1] set line [$iw get "$insind linestart" "$insind lineend"] set wordstart [string wordstart $line $ins] set wordend [expr {[string wordend $line $ins] - 1}] set w [crange $line $wordstart $wordend] $iw mark set ispell_wordstart$wid "insert linestart +$wordstart chars" $iw mark set ispell_wordend$wid \ "insert linestart +$wordend chars +1 chars" if {[info exists misspelled($w)]} { $iw tag remove err ispell_wordstart$wid ispell_wordend$wid $iw tag remove combo ispell_wordstart$wid ispell_wordend$wid $iw tag add $misspelled($w) \ ispell_wordstart$wid ispell_wordend$wid } elseif {[string length $w] > 1} { pipe_word $w if {![winfo exists $iw]} { return 0 } $iw tag remove err ispell_wordstart$wid ispell_wordend$wid $iw tag remove combo ispell_wordstart$wid ispell_wordend$wid if {[info exists misspelled($w)]} { $iw tag add $misspelled($w) \ ispell_wordstart$wid ispell_wordend$wid } } else { $iw tag remove err ispell_wordstart$wid ispell_wordend$wid $iw tag remove combo ispell_wordstart$wid ispell_wordend$wid $iw mark unset ispell_wordstart$wid $iw mark unset ispell_wordend$wid return 0 } $iw mark unset ispell_wordstart$wid $iw mark unset ispell_wordend$wid return 1 } ############################################################################# proc ispell::process_line {iw sym} { variable state variable insert_prev variable options if {![winfo exists $iw]} { return } switch -- $state($iw) { 0 { if {[cequal $sym ""]} { set state($iw) 1 # in state 0 it's more likely that the word is to the left # of cursor position set leftword [process_word $iw [$iw index "$insert_prev -1 chars"]] # but in rare cases (BackSpace) the word could be to the right if {!$leftword} { process_word $iw [$iw index "$insert_prev +0 chars"] } } elseif {![string is wordchar $sym] && ($sym != "\u0008")} { set state($iw) 1 process_word $iw [$iw index "$insert_prev -1 chars"] process_word $iw [$iw index "insert +0 chars"] } elseif {$options(check_every_symbol)} { process_word $iw [$iw index "insert -1 chars"] } } 1 { if {[cequal $sym ""]} { # do nothing } elseif {![string is wordchar $sym]} { process_word $iw [$iw index "$insert_prev -1 chars"] process_word $iw [$iw index "insert +0 chars"] process_word $iw [$iw index "insert -1 chars"] } else { set leftword [process_word $iw [$iw index "insert -1 chars"]] set cur_sym [$iw get "insert" "insert +1 chars"] if {!$leftword && ![string is wordchar $cur_sym]} { set state($iw) 0 } } } } set insert_prev [$iw index "insert"] variable after_id unset after_id($iw) } ############################################################################# proc ispell::clear_ispell {iw} { variable misspelled variable state variable insert_prev set insert_prev [$iw index "insert"] if {[llength [array names misspelled]] > 2048} { array unset misspelled } set state($iw) 0 } ############################################################################# proc ispell::popup_menu {iw x y} { variable response set ind [$iw index @$x,$y] lassign [split $ind .] l i set line [$iw get "$ind linestart" "$ind lineend"] set wordstart [string wordstart $line $i] set wordend [expr {[string wordend $line $i] - 1}] set w [crange $line $wordstart $wordend] pipe_word $w if {[catch { string trim $response } r]} { return } if {[winfo exists [set m .ispellpopupmenu]]} { destroy $m } switch -- [string index $r 0] { \& - \? { regsub -all {: } $r {:} r regsub -all {, } $r {,} r set variants [split [lindex [split $r ":"] 1] ","] menu $m -tearoff 0 foreach var $variants { $m add command -label "$var" \ -command [list [namespace current]::substitute $iw \ $l.$wordstart $l.[expr {$wordend + 1}] \ $var] } tk_popup $m [winfo pointerx .] [winfo pointery .] } \# { menu $m -tearoff 0 $m add command -label [::msgcat::mc "- nothing -"] -command {} tk_popup $m [winfo pointerx .] [winfo pointery .] } default {} } } ############################################################################# proc ispell::substitute {iw wordstart wordend sub} { $iw delete $wordstart $wordend $iw insert $wordstart $sub } ############################################################################# proc ispell::key_process {iw key} { if {$key == 65288} { # BackSpace after_process $iw "\u0008" } elseif {$key >= 65280} { # All nonletters after_process $iw "" } } ############################################################################# proc ispell::after_process {iw sym} { variable state variable after_id if {![info exists state($iw)]} return if {![info exists after_id($iw)]} { set after_id($iw) \ [after idle [list [namespace current]::process_line $iw $sym]] } } hook::add text_on_keypress_hook [namespace current]::ispell::after_process ############################################################################# proc ispell::setup_bindings {iw} { clear_ispell $iw bind $iw [list [namespace current]::key_process $iw %N] bind $iw +[list [namespace current]::clear_ispell $iw] bind $iw <3> [list [namespace current]::popup_menu $iw %x %y] $iw tag configure err -foreground [option get $iw errorColor Text] $iw tag configure combo -foreground [option get $iw comboColor Text] } hook::add text_on_create_hook [namespace current]::ispell::setup_bindings ############################################################################# tkabber-0.11.1/plugins/general/challenge.tcl0000644000175000017500000000277311012353076020255 0ustar sergeisergei# $Id: challenge.tcl 1419 2008-05-13 17:56:14Z sergei $ # # Robot challenge support (XEP-0158) # namespace eval challenge {} ############################################################################### proc challenge::process_x {rowvar bodyvar f x connid from id type replyP} { upvar 2 $rowvar row upvar 2 $bodyvar body set challenge 0 foreach xa $x { jlib::wrapper:splitxml $xa tag vars isempty chdata children set xmlns [jlib::wrapper:getattr $vars xmlns] if {$xmlns != $::NS(challenge)} continue set challenge 1 foreach child $children { jlib::wrapper:splitxml $child tag1 vars1 isempty1 chdata1 children1 set xmlns1 [jlib::wrapper:getattr $vars1 xmlns] if {$xmlns1 == $::NS(data) && ![lempty $children1]} { if {[catch {process_x_data $f $connid $from $child}]} { # Cannot process challenge form, so falling back to a # legacy challenge method if any. # TODO: Show error message to user. set challenge 0 } } } } if {!$challenge} { return } else { set body "" return stop } } hook::add message_process_x_hook [namespace current]::challenge::process_x 10 proc challenge::process_x_data {f connid from x} { data::draw_window [list $x] [list [namespace current]::send_x_data $connid $from] } proc challenge::send_x_data {connid to w restags} { jlib::send_iq set \ [jlib::wrapper:createtag challenge \ -vars [list xmlns $::NS(challenge)] \ -subtags $restags] \ -to $to \ -connection $connid destroy $w } tkabber-0.11.1/plugins/general/clientinfo.tcl0000644000175000017500000000354211014357121020455 0ustar sergeisergei# $Id: clientinfo.tcl 1433 2008-05-19 20:08:49Z sergei $ namespace eval clientinfo { set options(autoask) 0 } # TODO: connid proc clientinfo::add_user_popup_info {infovar connid jid} { variable users upvar 0 $infovar info if {[info exists ::userinfo::userinfo(fn,$jid)] && \ $::userinfo::userinfo(fn,$jid) != ""} { append info [format [::msgcat::mc "\n\tName: %s"] \ $::userinfo::userinfo(fn,$jid)] } elseif {[info exists ::userinfo::userinfo(name,$jid)] && \ $::userinfo::userinfo(name,$jid) != ""} { append info [format [::msgcat::mc "\n\tName: %s"] \ $::userinfo::userinfo(name,$jid)] if {[info exists ::userinfo::userinfo(family,$jid)] && \ $::userinfo::userinfo(family,$jid) != ""} { append info " $::userinfo::userinfo(family,$jid)" } } if {[info exists ::userinfo::userinfo(clientname,$jid)] && \ $::userinfo::userinfo(clientname,$jid) != ""} { append info [format [::msgcat::mc "\n\tClient: %s"] \ $::userinfo::userinfo(clientname,$jid)] if {[info exists ::userinfo::userinfo(clientversion,$jid)]} { append info " $::userinfo::userinfo(clientversion,$jid)" } } if {[info exists ::userinfo::userinfo(os,$jid)] && \ $::userinfo::userinfo(os,$jid) != ""} { append info [format [::msgcat::mc "\n\tOS: %s"] \ $::userinfo::userinfo(os,$jid)] } } hook::add roster_user_popup_info_hook \ [namespace current]::clientinfo::add_user_popup_info proc clientinfo::on_presence {connid from type x args} { variable options variable asked if {!$options(autoask)} return switch -- $type { available { if {![info exists ::userinfo::userinfo(clientname,$from)] && \ ![info exists asked($from)]} { set asked($from) "" userinfo::request_iq version $connid $from } } } } hook::add client_presence_hook \ [namespace current]::clientinfo::on_presence tkabber-0.11.1/plugins/general/stats.tcl0000644000175000017500000001473410736174616017506 0ustar sergeisergei# $Id: stats.tcl 1342 2007-12-31 14:15:42Z sergei $ namespace eval stats {} set ::NS(stats) http://jabber.org/protocol/stats proc stats::open_window {} { variable lastline variable f set w .stats if {[winfo exists $w]} { return } add_win $w -title [::msgcat::mc "Statistics monitor"] \ -tabtitle [::msgcat::mc "Statistics"] \ -class Stats \ -raise 1 #-raisecmd [list focus $w.tree] \ set sw [ScrolledWindow $w.sw] pack $sw -side top -fill both -expand yes set sf [ScrollableFrame $w.sf] $sw setwidget $sf set f [$sf getframe] set i 0 foreach label [list [::msgcat::mc "JID"] \ [::msgcat::mc "Node"] \ [::msgcat::mc "Name "] \ [::msgcat::mc "Value"] \ [::msgcat::mc "Units"]] { set l [label $f.titlelabel$i -text $label] grid $l -row 0 -column $i -sticky w incr i } set i 7 set l [label $f.titlelabel$i -text [::msgcat::mc "Timer"]] grid $l -row 0 -column $i -sticky w -columnspan 2 set lastline 1 } proc stats::add_line {jid node name} { variable data variable lastline variable f set n $lastline incr lastline set l [label $f.ljid$n -text $jid] grid $l -row $n -column 0 -sticky w set l [label $f.lnode$n -text $node] grid $l -row $n -column 1 -sticky w set l [label $f.lname$n -text $name] grid $l -row $n -column 2 -sticky w set l [label $f.lvalue$n \ -textvariable [namespace current]::data(value,$jid,$node,$name)] grid $l -row $n -column 3 -sticky e set l [label $f.lunits$n \ -textvariable [namespace current]::data(units,$jid,$node,$name)] grid $l -row $n -column 4 -sticky w set b [button $f.brequest$n -text [::msgcat::mc "Request"] \ -command [list [namespace current]::request_value \ $jid $node $name]] grid $b -row $n -column 5 -sticky w set b [button $f.bremove$n -text [::msgcat::mc "Remove"] \ -command [list [namespace current]::remove_line \ $n]] grid $b -row $n -column 6 -sticky w set s [Spinbox $f.spin$n 0 1000000000 1 \ [namespace current]::data(tmpperiod,$jid,$node,$name) \ -width 4] trace variable [namespace current]::data(tmpperiod,$jid,$node,$name) w \ [list [namespace current]::unset_timer $n $jid $node $name] grid $s -row $n -column 7 -sticky w catch {unset data(period,$jid,$node,$name)} set b [button $f.bsettimer$n -text [::msgcat::mc "Set"] \ -relief raised \ -command [list [namespace current]::toggle_timer \ $n $jid $node $name]] grid $b -row $n -column 8 -sticky w } proc stats::query_list {jid node args} { set vars [list xmlns $::NS(stats)] if {$node != ""} { lappend vars node $node } jlib::send_iq get [jlib::wrapper:createtag query \ -vars $vars] \ -to $jid \ -connection [jlib::route $jid] \ -command [list [namespace current]::recv_query_list_result $jid $node] } proc stats::recv_query_list_result {jid node res child} { variable data if {![cequal $res OK]} { return } open_window jlib::wrapper:splitxml $child tag vars isempty chdata children foreach item $children { jlib::wrapper:splitxml $item tag1 vars1 isempty1 chdata1 children1 if {$tag1 == "stat"} { set name [jlib::wrapper:getattr $vars1 name] #puts "$jid $node $name" add_line $jid $node $name } } } proc stats::request_value {jid node name} { set vars [list xmlns $::NS(stats)] if {$node != ""} { lappend vars node $node } jlib::send_iq get [jlib::wrapper:createtag query \ -vars $vars \ -subtags [list [jlib::wrapper:createtag stat \ -vars [list name $name]]]] \ -to $jid \ -connection [jlib::route $jid] \ -command [list [namespace current]::recv_values_result $jid $node] } proc stats::recv_values_result {jid node res child} { variable data if {![cequal $res OK]} { return } open_window jlib::wrapper:splitxml $child tag vars isempty chdata children foreach item $children { jlib::wrapper:splitxml $item tag1 vars1 isempty1 chdata1 children1 if {$tag1 == "stat"} { set name [jlib::wrapper:getattr $vars1 name] set value [jlib::wrapper:getattr $vars1 value] set units [jlib::wrapper:getattr $vars1 units] foreach subitem $children1 { jlib::wrapper:splitxml $subitem tag2 vars2 isempty2 \ chdata2 children2 if {$tag2 == "error"} { set error [error_to_string \ [list [jlib::wrapper:getattr $vars2 code] \ $chdata2]] break } } if {[info exists error]} { set data(value,$jid,$node,$name) $error set data(units,$jid,$node,$name) error } else { set data(value,$jid,$node,$name) $value set data(units,$jid,$node,$name) $units } } } } proc stats::remove_line {n} { variable f foreach slave [grid slaves $f -row $n] { destroy $slave } } proc stats::unset_timer {n jid node name args} { variable data variable f if {[info exists data(period,$jid,$node,$name)]} { unset data(period,$jid,$node,$name) $f.bsettimer$n configure -relief raised } } proc stats::toggle_timer {n jid node name} { variable data variable f if {![info exists data(period,$jid,$node,$name)]} { if {[string is integer -strict $data(tmpperiod,$jid,$node,$name)] && \ $data(tmpperiod,$jid,$node,$name) > 0} { set data(period,$jid,$node,$name) $data(tmpperiod,$jid,$node,$name) $f.bsettimer$n configure -relief sunken timer $n $jid $node $name } } else { unset data(period,$jid,$node,$name) $f.bsettimer$n configure -relief raised } } proc stats::timer {n jid node name} { variable data variable f if {![winfo exists $f.spin$n]} return request_value $jid $node $name if {![info exists data(period,$jid,$node,$name)]} return set p $data(period,$jid,$node,$name) after cancel \ [list [namespace current]::timer $n $jid $node $name] if {$p > 0 && [winfo exists $f.spin$n]} { after [expr {$p * 1000}] \ [list [namespace current]::timer $n $jid $node $name] } } proc stats::setup_menu {} { catch { set m [.mainframe getmenu admin] $m add command -label [::msgcat::mc "Open statistics monitor"] \ -command [namespace current]::open_window } } hook::add finload_hook [namespace current]::stats::setup_menu stats::setup_menu hook::add postload_hook \ [list disco::browser::register_feature_handler $::NS(stats) \ [namespace current]::stats::query_list -node 1 \ -desc [list * [::msgcat::mc "Service statistics"]]] tkabber-0.11.1/plugins/general/avatars.tcl0000644000175000017500000001561510701637340017776 0ustar sergeisergei# $Id: avatars.tcl 1244 2007-10-06 07:53:04Z sergei $ if {![cequal $::interface tk]} return package require base64 package require sha1 namespace eval ::avatar { set options(announce) 0 set options(share) 0 } ############################################################################## proc ::avatar::setup_menu {} { catch { #set m [.mainframe getmenu services] #for {set ind [$m index end]} {$ind > 0} {incr ind -1} { # if {[$m type $ind] == "separator"} { # break # } #} set m [.mainframe getmenu plugins] set mm .avatar_menu menu $mm -tearoff $ifacetk::options(show_tearoffs) $mm add checkbutton -label [::msgcat::mc "Announce"] \ -variable avatar::options(announce) $mm add checkbutton -label [::msgcat::mc "Allow downloading"] \ -variable avatar::options(share) $mm add command -label [::msgcat::mc "Send to server"] \ -command {avatar::store_on_server} $m add cascade -label [::msgcat::mc "Avatar"] \ -menu $mm } } hook::add finload_hook ::avatar::setup_menu ############################################################################## proc ::avatar::load_file {filename} { variable avatar variable options image create photo user_avatar -file $filename set f [open $filename] fconfigure $f -translation binary set data [read $f] close $f set avatar(userhash) [sha1::sha1 $data] set avatar(userdata) [base64::encode $data] set options(announce) 1 set options(share) 1 } ############################################################################## proc ::avatar::get_presence_x {varname connid status} { variable avatar variable options upvar 2 $varname var if {$options(announce) && [info exists avatar(userhash)]} { set children [jlib::wrapper:createtag hash -chdata $avatar(userhash)] lappend var [jlib::wrapper:createtag x \ -vars [list xmlns $::NS(xavatar)] \ -subtags [list $children]] } return } hook::add presence_xlist_hook ::avatar::get_presence_x ############################################################################## proc ::avatar::process_presence {connid from type x args} { switch -- $type { available - unavailable { foreach xs $x { jlib::wrapper:splitxml $xs tag vars isempty chdata children if {[jlib::wrapper:getattr $vars xmlns] == $::NS(xavatar)} { set_hash $connid $from $children break } } } } } hook::add client_presence_hook ::avatar::process_presence ############################################################################## proc ::avatar::insert_userinfo {tab connid jid editable} { if {$editable} return set avatar_img [get_image $connid [get_jid_of_user $connid $jid]] if {$avatar_img != ""} { set avatar [$tab insert end avatar -text [::msgcat::mc "Avatar"]] set av [userinfo::pack_frame $avatar.avatar [::msgcat::mc "Avatar"]] label $av.a -image $avatar_img pack $av.a -expand yes -fill both } } hook::add userinfo_hook ::avatar::insert_userinfo 40 ############################################################################## proc ::avatar::set_hash {connid jid children} { variable avatar debugmsg avatar "set hash $connid $jid $children" foreach child $children { jlib::wrapper:splitxml $child tag vars isempty chdata children1 if {$tag == "hash"} { set hash $chdata } } if {[info exists hash]} { if {![info exists avatar(hash,$connid,$jid)] || \ $hash != $avatar(hash,$connid,$jid)} { set avatar(hash,$connid,$jid) $hash set avatar(needupdate,$connid,$jid) 1 } } } ############################################################################## proc ::avatar::get_image {connid jid} { variable avatar debugmsg avatar "$jid; [array name avatar]" if {[info exists avatar(hash,$connid,$jid)]} { if {![info exists avatar(data,$connid,$jid)]} { image create photo avatar$connid@$jid get $connid $jid } elseif {$avatar(needupdate,$connid,$jid)} { get $connid $jid } return avatar$connid@$jid } else { return "" } } ############################################################################## proc ::avatar::get {connid jid} { variable avatar set avatar(needupdate,$connid,$jid) 0 jlib::send_iq get \ [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(iqavatar)]] \ -to $jid -command [list avatar::recv $connid $jid] \ -connection $connid } proc ::avatar::recv {connid jid res child} { variable avatar if {![cequal $res OK]} { jlib::send_iq get [jlib::wrapper:createtag query \ -vars {xmlns storage:client:avatar}] \ -to [node_and_server_from_jid $jid] \ -command [list avatar::recv_from_serv $connid $jid] \ -connection $connid return } jlib::wrapper:splitxml $child tag vars isempty chdata children foreach child1 $children { jlib::wrapper:splitxml $child1 tag1 vars1 isempty1 chdata1 childrens1 if {$tag1 == "data"} { catch { set avatar(data,$connid,$jid) [base64::decode $chdata1] avatar$connid@$jid put $chdata1 } } } } proc ::avatar::recv_from_serv {connid jid res child} { variable avatar if {![cequal $res OK]} { # TODO return } jlib::wrapper:splitxml $child tag vars isempty chdata children foreach child1 $children { jlib::wrapper:splitxml $child1 tag1 vars1 isempty1 chdata1 children1 if {$tag1 == "data"} { catch { set avatar(data,$connid,$jid) [base64::decode $chdata1] avatar$connid@$jid put $chdata1 } } } } ############################################################################## proc ::avatar::store_on_server {args} { variable avatar if {[llength [jlib::connections]] == 0} return foreach {opt val} $args { switch -- $opt { -connection { set connid $val } } } if {![info exists connid]} { set connid [lindex [jlib::connections] 0] } if {![info exists avatar(userdata)]} { MessageDlg .avatar_error -aspect 50000 -icon error \ -message [::msgcat::mc "No avatar to store"] -type user \ -buttons ok -default 0 -cancel 0 return } set restags \ [list [jlib::wrapper:createtag data \ -chdata $avatar(userdata)]] set res [jlib::wrapper:createtag query \ -vars {xmlns storage:client:avatar} \ -subtags $restags] jlib::send_iq set $res -connection $connid } ############################################################################## proc ::avatar::iq_reply {connid from lang child} { variable avatar variable options if {$options(share) && [info exists avatar(userdata)]} { set restags \ [list [jlib::wrapper:createtag data \ -chdata $avatar(userdata)]] set res [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(iqavatar)] \ -subtags $restags] } else { return [list error cancel service-unavailable] } return [list result $res] } iq::register_handler get query $::NS(iqavatar) ::avatar::iq_reply ############################################################################## tkabber-0.11.1/plugins/general/subscribe_gateway.tcl0000644000175000017500000001564510701637340022042 0ustar sergeisergei# $Id: subscribe_gateway.tcl 1244 2007-10-06 07:53:04Z sergei $ namespace eval gateway { variable msgid 0 hook::add roster_service_popup_menu_hook \ [namespace current]::add_menu_item 30 } proc gateway::add_menu_item {m connid jid} { $m add command -label [::msgcat::mc "Add user to roster..."] \ -command [list [namespace current]::subscribe_dialog $connid $jid] } proc gateway::subscribe_dialog {connid service} { variable msgid set mw .gwmsg$msgid toplevel $mw wm group $mw . set title [format [::msgcat::mc "Send subscription at %s"] $service] wm title $mw $title wm iconname $mw $title set bbox [ButtonBox $mw.buttons -spacing 0 -padx 10 -default 0] $bbox add -text [::msgcat::mc "Subscribe"] \ -command [list [namespace current]::send_subscribe $mw $connid $service] $bbox add -text [::msgcat::mc "Cancel"] -command [list destroy $mw] bind $mw "ButtonBox::invoke $bbox default" bind $mw "ButtonBox::invoke $bbox 1" pack $bbox -side bottom -anchor e -padx 2m -pady 2m set sep [Separator::create $mw.sep -orient horizontal] pack $sep -pady 1m -fill x -side bottom frame $mw.frame pack $mw.frame -side top -fill both -expand yes -padx 2m -pady 2m label $mw.prompt pack $mw.prompt -side top -anchor w -in $mw.frame variable $mw.prompt fulljid bind $mw [list catch [list unset [namespace current]::$mw.prompt]] jlib::send_iq get \ [jlib::wrapper:createtag query \ -vars {xmlns jabber:iq:gateway}] \ -to $service \ -command [list [namespace current]::configure_prompt $mw.prompt] \ -connection $connid frame $mw.subj label $mw.subj.lab -text [::msgcat::mc "Send subscription to: "] entry $mw.subj.entry pack $mw.subj.lab -side left pack $mw.subj.entry -side left -fill x -expand yes pack $mw.subj -side top -anchor w -fill x -expand yes -in $mw.frame frame $mw.space pack $mw.space -side top -fill x -in $mw.frame -pady 0.5m ScrolledWindow $mw.sw pack $mw.sw -side top -fill both -expand yes -in $mw.frame textUndoable $mw.body -width 60 -height 8 -wrap word $mw.body insert 0.0 [::msgcat::mc "I would like to add you to my roster."] pack $mw.body -side top -fill both -expand yes -in $mw.sw $mw.sw setwidget $mw.body focus $mw.subj.entry incr msgid } proc gateway::configure_prompt {w res child} { if {![winfo exists $w]} return $w configure \ -text [::msgcat::mc "Enter screenname of contact you want to add"] if {$res != "OK"} { return } jlib::wrapper:splitxml $child tag vars isempty chdata children foreach ch $children { jlib::wrapper:splitxml $ch tag1 vars1 isempty1 chdata1 children1 if {($tag1 == "desc") && ($chdata1 != "")} { $w configure -text $chdata1 variable $w screenname break } } } proc gateway::send_subscribe {mw connid service} { variable $mw.prompt switch -- [set $mw.prompt] { fulljid { $mw.subj.entry insert end "@$service" message::send_subscribe $mw -connection $connid } screenname { set screenname [$mw.subj.entry get] jlib::send_iq set \ [jlib::wrapper:createtag query \ -vars {xmlns jabber:iq:gateway} \ -subtags [list [jlib::wrapper:createtag prompt \ -chdata $screenname]]] \ -to $service \ -command [list [namespace current]::gw_send_subscribe $mw \ "$screenname@$service" \ $connid] \ -connection $connid } } } proc gateway::gw_send_subscribe {mw fallback connid res child} { set jid $fallback if {$res == "OK"} { jlib::wrapper:splitxml $child tag vars isempty chdata children foreach ch $children { jlib::wrapper:splitxml $ch tag1 vars1 isempty1 chdata1 children1 if {($tag1 == "jid" || ($tag1 == "prompt")) && \ ($chdata1 != "")} { set jid $chdata1 break } } } $mw.subj.entry delete 0 end $mw.subj.entry insert 0 $jid message::send_subscribe $mw -connection $connid } proc gateway::convert_jid {jid args} { foreach {opt val} $args { switch -- $opt { -connection {set connid $val} } } if {![info exists connid]} { return -code error "Option -connection mandatory" } jlib::send_iq get \ [jlib::wrapper:createtag query \ -vars {xmlns jabber:iq:gateway}] \ -to $jid \ -command [list [namespace current]::convert_jid_dialog \ $jid $connid] \ -connection $connid } proc gateway::convert_jid_dialog {jid connid res child} { variable msgid if {$res != "OK"} return set w .gwmsg$msgid Dialog $w -title [::msgcat::mc "Screenname conversion"] \ -separator 1 -anchor e -modal none \ -default 0 -cancel 1 set f [$w getframe] $w add -text [::msgcat::mc "Convert"] \ -command [list [namespace current]::convert_screenname $w $connid $jid] $w add -text [::msgcat::mc "Cancel"] -command [list destroy $w] jlib::wrapper:splitxml $child tag vars isempty chdata children set row 0 foreach ch $children { jlib::wrapper:splitxml $ch tag1 vars1 isempty1 chdata1 children1 switch -- $tag1 { desc { if {![winfo exists $f.desc]} { message $f.desc -text $chdata1 -width 15c grid $f.desc -row $row -column 0 \ -columnspan 2 -sticky w -pady 2m } } prompt { if {![winfo exists $f.prompt]} { label $f.lprompt -text [::msgcat::mc "Screenname:"] entry $f.prompt grid $f.lprompt -row $row -column 0 grid $f.prompt -row $row -column 1 -sticky ew -padx 1m } } } incr row } incr msgid $w draw $f.prompt } proc gateway::convert_screenname {w connid jid} { set f [$w getframe] set screenname [$f.prompt get] destroy $w jlib::send_iq set \ [jlib::wrapper:createtag query \ -vars {xmlns jabber:iq:gateway} \ -subtags [list [jlib::wrapper:createtag prompt \ -chdata $screenname]]] \ -to $jid \ -command [list [namespace current]::display_conversion $w $screenname] \ -connection $connid } proc gateway::display_conversion {w screenname res child} { if {$res != "OK"} { NonmodalMessageDlg $w -aspect 50000 -icon error \ -message [format [::msgcat::mc "Error while converting screenname: %s."] \ [error_to_string $child]] } else { set jid "" jlib::wrapper:splitxml $child tag vars isempty chdata children foreach ch $children { jlib::wrapper:splitxml $ch tag1 vars1 isempty1 chdata1 children1 if {($tag1 == "jid" || ($tag1 == "prompt")) && \ ($chdata1 != "")} { set jid $chdata1 break } } NonmodalMessageDlg $w -aspect 50000 \ -title [::msgcat::mc "Screenname conversion"] \ -message [format [::msgcat::mc "Screenname: %s\n\nConverted JID: %s"] \ $screenname $jid] } } hook::add postload_hook \ [list disco::browser::register_feature_handler jabber:iq:gateway \ [namespace current]::gateway::convert_jid \ -desc [list * [::msgcat::mc "Convert screenname"]]] tkabber-0.11.1/plugins/general/caps.tcl0000644000175000017500000001550011033072325017247 0ustar sergeisergei# $Id: caps.tcl 1464 2008-07-03 06:42:29Z sergei $ # Entity capabilities support (XEP-0115) package require sha1 package require md5 package require base64 namespace eval caps { set ::NS(caps) http://jabber.org/protocol/caps variable caps_node "" custom::defgroup Plugins \ [::msgcat::mc "Plugins options."] \ -group Tkabber custom::defgroup Caps \ [::msgcat::mc "Options for entity capabilities plugin."] \ -group Plugins custom::defvar options(enable) 1 \ [::msgcat::mc "Enable announcing entity capabilities in\ every outgoing presence."] \ -group Caps -type boolean custom::defvar options(hash) sha-1 \ [::msgcat::mc "Use the specified function to hash supported\ features list."] \ -group Caps -type options -values {md5 MD5 sha-1 SHA-1} } proc caps::hash {identities features extras hash} { set binidentities {} foreach id $identities { lappend binidentities [encoding convertto utf-8 $id] } set binfeatures {} foreach fe $features { lappend binfeatures [encoding convertto utf-8 $fe] } set binextra {} foreach eform $extras { set bineform {} foreach extra $eform { lassign $extra var type label values switch -- $var/$type { FORM_TYPE/hidden { set form_type [encoding convertto utf-8 [lindex $values 0]] } default { set binex {} foreach val $values { lappend binex [encoding convertto utf-8 $val] } lappend bineform \ [linsert [lsort -ascii $binex] 0 \ [encoding convertto utf-8 $var]] } } } set bineform1 {} foreach ex [lsort -ascii -index 0 $bineform] { lappend bineform1 [join $ex "<"] } lappend binextra [linsert $bineform1 0 $form_type] } set binextra1 {} foreach b [lsort -ascii -index 0 $binextra] { lappend binextra1 [join $b "<"] } set binstr [join [concat [lsort -ascii $binidentities] \ [lsort -ascii $binfeatures] \ $binextra1] "<"] if {[string equal $binstr ""]} { return "" } append binstr "<" switch -- $hash { md5 { if {[catch {::md5::md5 -hex $binstr} hex]} { # Old md5 package. set hex [::md5::md5 $binstr] } set binhash [binary format H32 $hex] } sha-1 { set binhash [binary format H40 [::sha1::sha1 $binstr]] } default { # Unsupported hash type return "" } } return [base64::encode $binhash] } proc caps::info_to_hash {child hash} { set identities {} set features {} set extras {} jlib::wrapper:splitxml $child tag vars isempty chdata children foreach ch $children { jlib::wrapper:splitxml $ch tag1 vars1 isempty1 chdata1 children1 switch -- $tag1 { identity { set category [jlib::wrapper:getattr $vars1 category] set type [jlib::wrapper:getattr $vars1 type] set lang [jlib::wrapper:getattr $vars1 xml:lang] set name [jlib::wrapper:getattr $vars1 name] lappend identities $category/$type/$lang/$name } feature { set var [jlib::wrapper:getattr $vars1 var] if {![string equal $var ""]} { lappend features $var } } x { if {[string equal [jlib::wrapper:getattr $vars1 xmlns] \ $::NS(data)] && \ [string equal [jlib::wrapper:getattr $vars1 type] \ result]} { lappend extras \ [data::parse_xdata_results $children1 -hidden 1] } } } } return [hash $identities $features $extras $hash] } proc caps::get_presence_x {varname connid status} { variable options variable caps_node upvar 2 $varname var if {!$options(enable)} return lassign [disco::info_query_get_handler \ $connid "" \ [jlib::get_lang] \ [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(disco_info)]]] \ res child if {![string equal $res result]} return set ver [info_to_hash $child $options(hash)] if {[string equal $ver ""]} return lappend var [jlib::wrapper:createtag c \ -vars [list xmlns $::NS(caps) \ hash $options(hash) \ node http://tkabber.jabber.ru/ \ ver $ver]] set caps_node http://tkabber.jabber.ru/#$ver return } hook::add presence_xlist_hook [namespace current]::caps::get_presence_x proc caps::disco_reply {varname type node connid from lang child} { variable caps_node upvar 2 $varname res if {$type != "info" || $node != $caps_node} return set res [disco::info_query_get_handler \ $connid "" \ [jlib::get_lang] \ [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(disco_info)]]] if {[string equal [lindex $res 0] result]} { jlib::wrapper:splitxml [lindex $res 1] tag vars isempty chdata children lappend vars node $caps_node lset res 1 [jlib::wrapper:createtag $tag \ -vars $vars \ -chdata $chdata \ -subtags $children] } return stop } hook::add disco_node_reply_hook [namespace current]::caps::disco_reply # TODO match caps hash to a set of features proc caps::process_presence {connid from type x args} { variable htype variable hver switch -- $type { unavailable { catch {unset htype($connid,$from)} catch {unset hver($connid,$from)} } available { foreach xs $x { jlib::wrapper:splitxml $xs tag vars isempty chdata children if {[string equal [jlib::wrapper:getattr $vars xmlns] \ $::NS(caps)]} { set hash [jlib::wrapper:getattr $vars hash] if {[string equal $hash ""]} { set hash sha-1 } set htype($connid,$from) $hash set hver($connid,$from) [jlib::wrapper:getattr $vars ver] return } } # Unset caps if they aren't included in catch {unset htype($connid,$from)} catch {unset hver($connid,$from)} } } } hook::add client_presence_hook [namespace current]::caps::process_presence proc caps::clean {connid} { variable htype variable hver array unset htype $connid,* array unset hver $connid,* } hook::add disconnected_hook [namespace current]::caps::clean proc caps::info_receive \ {connid jid node res identities features extras featured_nodes} { variable hidentities variable hfeatures variable htype variable hver if {![string equal $res OK]} return if {![info exists hver($connid,$jid)]} return set ids {} foreach id $identities { set category [jlib::wrapper:getattr $id category] set type [jlib::wrapper:getattr $id type] if {![string equal $category ""] && ![string equal $type ""]} { lappend ids $category/$type } } set fes {} foreach fe $features { set var [jlib::wrapper:getattr $fe var] if {![string equal $var ""]} { lappend fes $var } } if {![string equal [hash $ids $fes $extras $htype($connid,$jid)] \ $hver($connid,$jid)]} { return } set hidentities($htype($connid,$jid),$hver($connid,$jid)) $ids set hfeatures($htype($connid,$jid),$hver($connid,$jid)) $fes } hook::add disco_info_hook [namespace current]::caps::info_receive tkabber-0.11.1/plugins/general/message_archive.tcl0000644000175000017500000001712411014021262021443 0ustar sergeisergei# $Id: message_archive.tcl 1429 2008-05-18 12:36:02Z sergei $ option add *Messages.listheight 10 widgetDefault namespace eval ::message_archive { variable logdir [file join $::configdir logs] if {![file exists $logdir]} { file mkdir $logdir } variable archive_file [file join $logdir message_archive] variable label array set label [list to [::msgcat::mc "To:"] from [::msgcat::mc "From:"]] variable messages } ############################################################################# proc ::message_archive::str_to_log {str} { return [string map {\\ \\\\ \r \\r \n \\n} $str] } ############################################################################# proc ::message_archive::log_to_str {str} { return [string map {\\\\ \\ \\r \r \\n \n} $str] } ############################################################################# proc ::message_archive::log_message {from to subject body x} { variable archive_file set seconds [jlib::x_delay $x] set ts [clock format $seconds -format "%Y%m%dT%H%M%S"] set fd [open $archive_file a] fconfigure $fd -encoding utf-8 puts $fd [str_to_log [list timestamp $ts id $ts[rand 10000] from $from to $to subject $subject body $body]] close $fd } proc ::message_archive::show_archive {} { variable lastsort variable label variable messages set w .message_archive if {[winfo exists $w]} { return } add_win $w -title [::msgcat::mc "Messages"] \ -tabtitle [::msgcat::mc "Messages"] \ -class Messages \ -raise 1 PanedWin $w.pw -side right -pad 0 -width 4 pack $w.pw -fill both -expand yes set uw [PanedWinAdd $w.pw -weight 0 -minsize 100] set dw [PanedWinAdd $w.pw -weight 1 -minsize 100] frame $dw.title label $dw.title.label -text $label(from) label $dw.title.jid pack $dw.title -fill x pack $dw.title.label -side left pack $dw.title.jid -side left frame $dw.subject label $dw.subject.lsubj -text [::msgcat::mc "Subject:"] label $dw.subject.subj pack $dw.subject -fill x pack $dw.subject.lsubj -side left pack $dw.subject.subj -side left set body [ScrolledWindow $dw.sw] text $body.body -height 20 -state disabled -wrap word pack $body -expand yes -fill both -anchor nw $body setwidget $body.body ::richtext::config $body.body -using {url emoticon stylecode} set sww [ScrolledWindow $w.items] set height [option get $w listheight Messages] ::mclistbox::mclistbox $sww.listbox \ -resizeonecolumn 1 \ -labelanchor w \ -width 90 \ -height $height set l $sww.listbox pack $sww -expand yes -fill both -anchor nw -in $uw $sww setwidget $l [winfo parent $uw] configure \ -height [expr {int( 1.2*($height+1)*[font metrics [$l cget -font] -linespace] )}] set lastsort($l) "" bind $l +[list [namespace current]::delete_lastsort $l] bind $l <1> \ "[namespace current]::select_and_print_body $dw $l \[$l nearest \[::mclistbox::convert %W -y %y\]\]" # bind $l <3> \ # "[namespace current]::select_and_popup_menu $l \[$l nearest \[::mclistbox::convert %W -y %y\]\]" bindscroll $sww $l $l column add N -label " [::msgcat::mc #] " $l column add id -label "" -visible 0 $l column add timestamp -label " [::msgcat::mc Received/Sent] " $l column add dir -label " [::msgcat::mc Dir] " $l column add fromto -label " [::msgcat::mc From/To] " $l column add subject -label " [::msgcat::mc Subject] " array unset messages foreach var {timestamp fromto subject} { $l label bind $var "[namespace current]::sort %W $var" } $l column add lastcol -label "" -width 0 $l configure -fillcolumn lastcol fill_list $l $l see end select_and_print_body $dw $l end } proc ::message_archive::max {a b} { return [expr {$a > $b ? $a : $b}] } proc ::message_archive::fill_list {l} { variable archive_file if {![file exists $archive_file]} { return } foreach i {N timestamp dir fromto subject} { $l column configure $i -width [string length [$l column cget $i -label]] } set hist {} set fd [open $archive_file r] fconfigure $fd -encoding utf-8 while {[gets $fd line] > 0} { catch {fill_row $l [log_to_str $line]} } close $fd } proc ::message_archive::fill_row {l var} { variable messages set connections [jlib::connections] if {[lempty $connections]} { set myjid "" } else { set myjid [jlib::connection_bare_jid [lindex $connections 0]] } foreach i {N id timestamp dir fromto subject} { set width($i) [$l column cget $i -width] } set rownum [$l size] incr rownum set row [list " $rownum "] set width(N) [max [string length " $rownum "] $width(N)] array unset tmp array set tmp $var if {[info exists tmp(id)]} { set id $tmp(id) lappend row $id set width(id) 0 } else { return } if {[info exists tmp(timestamp)]} { set seconds [clock scan $tmp(timestamp) -gmt 0] set str " [clock format $seconds -format {%Y-%m-%d %X}] " lappend row $str set width(timestamp) [max [string length $str] $width(timestamp)] } else { lappend row {} } set q 0 if {[info exists tmp(from)]} { set str [node_and_server_from_jid $tmp(from)] if {$str == $myjid} { set q 1 set fromto to set dir " -> " set messages($id,dir) to } } else { set tmp(from) {} } if {[info exists tmp(to)]} { set str [node_and_server_from_jid $tmp(to)] if {$str == $myjid} { set q 1 set fromto from set dir " <- " set messages($id,dir) from } } else { set tmp(to) {} } if {!$q} { return } else { lappend row $dir set str [node_and_server_from_jid $tmp($fromto)] lappend row " $str " set width(fromto) [max [string length " $str "] $width(fromto)] set messages($id,fromto) $tmp($fromto) } if {[info exists tmp(subject)]} { lappend row " $tmp(subject) " set width(subject) [max [string length " $tmp(subject) "] $width(subject)] set messages($id,subject) $tmp(subject) } else { lappend row {} set messages($id,subject) "" } if {[info exists tmp(body)]} { set messages($id,body) $tmp(body) } else { set messages($id,body) "" } $l insert end $row foreach i {N timestamp id dir fromto subject} { $l column configure $i -width $width($i) } } proc ::message_archive::sort {l tag} { variable lastsort set data [$l get 0 end] set index [lsearch -exact [$l column names] $tag] if {$lastsort($l) != $tag} { set result [lsort -dictionary -index $index $data] set lastsort($l) $tag } else { set result [lsort -decreasing -dictionary -index $index $data] set lastsort($l) "" } set result1 {} set i 0 foreach row $result { lappend result1 [lreplace $row 0 0 " [incr i] "] } $l delete 0 end eval $l insert end $result1 } proc ::message_archive::delete_lastsort {id} { variable lastsort if {[info exists lastsort($id)]} { unset lastsort($id) } } proc ::message_archive::select_and_print_body {w l index} { variable label variable messages $l selection clear 0 end $l selection set $index set id [lindex [$l get $index] 1] if {$id == ""} { return } $w.title.label configure -text $label($messages($id,dir)) $w.title.jid configure -text $messages($id,fromto) $w.subject.subj configure -text $messages($id,subject) $w.sw.body configure -state normal $w.sw.body delete 0.0 end #$w.sw.body insert end $messages($id,body) ::richtext::render_message $w.sw.body $messages($id,body) "" $w.sw.body configure -state disabled } tkabber-0.11.1/plugins/unix/0000755000175000017500000000000011076120366015170 5ustar sergeisergeitkabber-0.11.1/plugins/unix/tktray.tcl0000644000175000017500000000563510674524264017233 0ustar sergeisergei# $Id: tktray.tcl 1232 2007-09-20 17:07:00Z sergei $ # Another Freedesktop systray icon support. # Requires tktray (http://sw4me.com/wiki/Tktray) package ########################################################################## if {![cequal $::interface tk]} return if {[catch { package require tktray }]} return ########################################################################## namespace eval tktray { variable options custom::defvar options(enable) 1 \ [::msgcat::mc "Enable freedesktop system tray icon."] \ -group Systray -type boolean \ -command [namespace code enable_disable] variable s2p foreach {k v} [list available available \ away away \ chat chat \ dnd dnd \ xa xa \ unavailable unavailable \ invisible invisible \ blank blank \ message1 message-server \ message2 message \ message3 message-personal] { set s2p($k) docking/$v } } ########################################################################## proc tktray::enable_disable {args} { variable options set icon .tksi if {$options(enable) && ![winfo exists $icon]} { ifacetk::systray::create $icon \ -createcommand [namespace code create] \ -configurecommand [namespace code configure] \ -destroycommand [namespace code destroy] \ -locationcommand [namespace code location] } elseif {!$options(enable) && [winfo exists $icon]} { ifacetk::systray::destroy $icon } } hook::add finload_hook [namespace current]::tktray::enable_disable ########################################################################## proc tktray::create {icon} { variable s2p tktray::icon $icon -image $s2p(unavailable) set m [ifacetk::systray::popupmenu $icon.menu] bind $icon ifacetk::systray::restore bind $icon ifacetk::systray::withdraw bind $icon [list tk_popup $m %X %Y] balloon::setup $icon -command [list ifacetk::systray::balloon $icon] } ########################################################################## proc tktray::configure {icon status} { variable s2p if {![cequal $icon ""] && [winfo exists $icon]} { $icon configure -image $s2p($status) } } ########################################################################## proc tktray::destroy {icon} { if {![cequal $icon ""] && [winfo exists $icon]} { ::destroy $icon } } ########################################################################## proc tktray::location {icon} { if {![cequal $icon ""] && [winfo exists $icon]} { return [lrange [$icon bbox] 0 1] } else { return {0 0} } } ########################################################################## tkabber-0.11.1/plugins/unix/menu8.4.tcl0000644000175000017500000002252311054223174017073 0ustar sergeisergei# $Id: menu8.4.tcl 1487 2008-08-24 09:14:36Z sergei $ switch -- $::tcl_version { 8.4 - 8.5 - 8.6 {} default {return} } namespace eval :: { proc myMenuButtonDown {args} { global myMenuFlag myMenuMotion eval ::tk::MenuButtonDown $args set myMenuFlag 1 } proc myMenuInvoke {args} { global myMenuFlag myMenuMotion if {$myMenuFlag || $myMenuMotion} { eval ::tk::MenuInvoke $args } set myMenuFlag 0 set myMenuMotion 0 } proc myMenuMotion {args} { global myMenuFlag myMenuMotion eval ::tk::MenuMotion $args set myMenuMotion 1 } proc myMenuLeave {args} { global myMenuFlag myMenuMotion eval ::tk::MenuLeave $args set myMenuMotion 0 } bind Menu {myMenuLeave %W %X %Y %s} bind Menu {myMenuButtonDown %W} bind Menu {myMenuInvoke %W 1} bind Menu {myMenuMotion %W %x %y %s} set myMenuFlag 0 set myMenuMotion 0 # ::tk::MenuNextEntry -- # Activate the next higher or lower entry in the posted menu, # wrapping around at the ends. Disabled entries are skipped. # # Arguments: # menu - Menu window that received the keystroke. # count - 1 means go to the next lower entry, # -1 means go to the next higher entry. proc ::tk::MenuNextEntry {menu count} { global ::tk::Priv if {[string equal [$menu index last] "none"]} { return } set length [expr {[$menu index last]+1}] set quitAfter $length set active [$menu index active] if {[string equal $active "none"]} { set i 0 } else { set i [expr {$active + $count}] } while {1} { if {$quitAfter <= 0} { # We've tried every entry in the menu. Either there are # none, or they're all disabled. Just give up. return } while {$i < 0} { incr i $length } while {$i >= $length} { incr i -$length } if {[catch {$menu entrycget $i -state} state] == 0} { if {[string compare $state "disabled"]} { break } } if {$i == $active} { return } incr i $count incr quitAfter -1 } $menu activate $i ::tk::GenerateMenuSelect $menu if {[string equal [$menu type $i] "cascade"]} { set cascade [$menu entrycget $i -menu] if {[string equal [$menu cget -type] "menubar"] && [string compare $cascade ""]} { # Here we auto-post a cascade. This is necessary when # we traverse left/right in the menubar, but undesirable when # we traverse up/down in a menu. $menu postcascade $i ::tk::MenuFirstEntry $cascade } } } # ::tk::MenuNextMenu -- # This procedure is invoked to handle "left" and "right" traversal # motions in menus. It traverses to the next menu in a menu bar, # or into or out of a cascaded menu. # # Arguments: # menu - The menu that received the keyboard # event. # direction - Direction in which to move: "left" or "right" proc ::tk::MenuNextMenu {menu direction} { global ::tk::Priv # First handle traversals into and out of cascaded menus. if {[string equal $direction "right"]} { set count 1 set parent [winfo parent $menu] set class [winfo class $parent] if {[string equal [$menu type active] "cascade"]} { $menu postcascade active set m2 [$menu entrycget active -menu] if {[string compare $m2 ""]} { ::tk::MenuFirstEntry $m2 } return } else { set parent [winfo parent $menu] while {[string compare $parent "."]} { if {[string equal [winfo class $parent] "Menu"] \ && [string equal [$parent cget -type] "menubar"]} { tk_menuSetFocus $parent ::tk::MenuNextEntry $parent 1 return } set parent [winfo parent $parent] } } } else { set count -1 set m2 [winfo parent $menu] if {[string equal [winfo class $m2] "Menu"]} { if {[string compare [$m2 cget -type] "menubar"]} { $menu activate none ::tk::GenerateMenuSelect $menu tk_menuSetFocus $m2 # This code unposts any posted submenu in the parent. $m2 postcascade none #set tmp [$m2 index active] #$m2 activate none #$m2 activate $tmp return } } } # Can't traverse into or out of a cascaded menu. Go to the next # or previous menubutton, if that makes sense. set m2 [winfo parent $menu] if {[string equal [winfo class $m2] "Menu"]} { if {[string equal [$m2 cget -type] "menubar"]} { tk_menuSetFocus $m2 ::tk::MenuNextEntry $m2 -1 return } } set w $::tk::Priv(postedMb) if {[string equal $w ""]} { return } set buttons [winfo children [winfo parent $w]] set length [llength $buttons] set i [expr {[lsearch -exact $buttons $w] + $count}] while {1} { while {$i < 0} { incr i $length } while {$i >= $length} { incr i -$length } set mb [lindex $buttons $i] if {[string equal [winfo class $mb] "Menubutton"] \ && [string compare [$mb cget -state] "disabled"] \ && [string compare [$mb cget -menu] ""] \ && [string compare [[$mb cget -menu] index last] "none"]} { break } if {[string equal $mb $w]} { return } incr i $count } ::tk::MbPost $mb ::tk::MenuFirstEntry [$mb cget -menu] } # ::tk::MenuFirstEntry -- # Given a menu, this procedure finds the first entry that isn't # disabled or a tear-off or separator, and activates that entry. # However, if there is already an active entry in the menu (e.g., # because of a previous call to ::tk::PostOverPoint) then the active # entry isn't changed. This procedure also sets the input focus # to the menu. # # Arguments: # menu - Name of the menu window (possibly empty). proc ::tk::MenuFirstEntry menu { if {[string equal $menu ""]} { return } tk_menuSetFocus $menu if {[string compare [$menu index active] "none"]} { return } set last [$menu index last] if {[string equal $last "none"]} { return } for {set i 0} {$i <= $last} {incr i} { if {([catch {set state [$menu entrycget $i -state]}] == 0) \ && [string compare $state "disabled"]} { $menu activate $i ::tk::GenerateMenuSelect $menu # Only post the cascade if the current menu is a menubar; # otherwise, if the first entry of the cascade is a cascade, # we can get an annoying cascading effect resulting in a bunch of # menus getting posted (bug 676) if {[string equal [$menu type $i] "cascade"] && \ [string equal [$menu cget -type] "menubar"]} { set cascade [$menu entrycget $i -menu] if {[string compare $cascade ""]} { $menu postcascade $i ::tk::MenuFirstEntry $cascade } } return } } } # ::tk::MenuMotion -- # This procedure is called to handle mouse motion events for menus. # It does two things. First, it resets the active element in the # menu, if the mouse is over the menu. Second, if a mouse button # is down, it posts and unposts cascade entries to match the mouse # position. # # Arguments: # menu - The menu window. # x - The x position of the mouse. # y - The y position of the mouse. # state - Modifier state (tells whether buttons are down). proc ::tk::MenuMotion {menu x y state} { global ::tk::Priv if {[string equal $menu $::tk::Priv(window)]} { if {[string equal [$menu cget -type] "menubar"]} { if {[info exists ::tk::Priv(focus)] && \ [string compare $menu $::tk::Priv(focus)]} { $menu activate @$x,$y ::tk::GenerateMenuSelect $menu } } else { $menu activate @$x,$y ::tk::GenerateMenuSelect $menu } } #debugmsg plugins "MENU: $menu $::tk::Priv(activeMenu) $::tk::Priv(activeItem) $::tk::Priv(focus)" if {(![string equal [$menu cget -type] "menubar"]) || \ ([info exist ::tk::Priv(focus)] && (![cequal $::tk::Priv(focus) ""]) && ($::tk::Priv(activeItem) != "none"))} { myMenuPostCascade $menu } } set myPriv(id) "" set myPriv(delay) 170 set myPriv(activeMenu) "" set myPriv(activeItem) "" proc myMenuPostCascade {menu} { global myPriv if {![cequal $myPriv(id) ""]} { if {($myPriv(activeMenu) == $menu) && ($myPriv(activeItem) == [$menu index active])} { return } else { after cancel $myPriv(id) } } if {[string equal [$menu cget -type] "menubar"]} { $menu postcascade active } else { set myPriv(activeMenu) $menu set myPriv(activeItem) [$menu index active] set myPriv(id) [after $myPriv(delay) "$menu postcascade active"] } } } tkabber-0.11.1/plugins/unix/systray.tcl0000644000175000017500000000556710674524264017437 0ustar sergeisergei# $Id: systray.tcl 1232 2007-09-20 17:07:00Z sergei $ # Freedesktop systray icon support. # Requires Tray package # (ftp://ftp.atmsk.ru/pub/tkabber/tksystray.tar.gz) ########################################################################## if {![cequal $::interface tk]} return if {[catch { package require Tray }]} return ########################################################################## namespace eval systray { variable options custom::defvar options(enable) 1 \ [::msgcat::mc "Enable freedesktop systray icon."] \ -group Systray -type boolean \ -command [namespace code enable_disable] } ########################################################################## proc systray::set_current_theme {} { variable s2p foreach {k v} [list available available \ away away \ chat chat \ dnd dnd \ xa xa \ unavailable unavailable \ invisible invisible \ blank blank \ message1 message-server \ message2 message \ message3 message-personal] { set s2p($k) [pixmaps::get_filename docking/$v] } } hook::add set_theme_hook [namespace current]::systray::set_current_theme ########################################################################## proc systray::enable_disable {args} { variable options set icon .si if {$options(enable) && ![winfo exists $icon]} { ifacetk::systray::create $icon \ -createcommand [namespace code create] \ -configurecommand [namespace code configure] \ -destroycommand [namespace code destroy] } elseif {!$options(enable) && [winfo exists $icon]} { ifacetk::systray::destroy $icon } } hook::add finload_hook [namespace current]::systray::enable_disable ########################################################################## proc systray::create {icon} { variable s2p newti $icon -pixmap $s2p(unavailable) set m [ifacetk::systray::popupmenu $icon.menu] bind $icon ifacetk::systray::restore bind $icon ifacetk::systray::withdraw bind $icon [list tk_popup $m %X %Y] balloon::setup $icon -command [list ifacetk::systray::balloon $icon] } ########################################################################## proc systray::configure {icon status} { variable s2p if {![cequal $icon ""] && [winfo exists $icon]} { configureti $icon -pixmap $s2p($status) } } ########################################################################## proc systray::destroy {icon} { if {![cequal $icon ""] && [winfo exists $icon]} { removeti $icon ::destroy $icon } } ########################################################################## tkabber-0.11.1/plugins/unix/icon.tcl0000644000175000017500000000321011014003203016576 0ustar sergeisergei# $Id: icon.tcl 1427 2008-05-18 10:35:47Z sergei $ # Titlebar icons support. Works with Tk 8.5 or newer. ########################################################################## namespace eval icon { hook::add finload_hook [namespace current]::win_icons } ########################################################################## proc icon::win_icons {} { # Do not load static icon if a WindowMaker dock is used. if {[info exists ::wmaker_dock] && $::wmaker_dock} { return } if {[catch {wm iconphoto . roster/user/unavailable}]} return trace variable ::curuserstatus w [namespace code update_icon] bind all +[namespace code { if {[string equal [winfo toplevel %W] %W]} { win_icon_setup %W } }] } ########################################################################## proc icon::win_icon_setup {w} { if {$w == "."} return switch -- [winfo class $w] { Chat { wm iconphoto $w roster/conference/available } JDisco { wm iconphoto $w roster/user/available } default { wm iconphoto $w roster/user/available } } } ########################################################################## proc icon::update_icon {name1 {name2 ""} {op ""}} { global curuserstatus wm iconphoto . roster/user/$curuserstatus } ########################################################################## proc icon::update_all_icons {} { catch { foreach w [concat . [winfo children .]] { win_icon_setup $w } update_icon curuserstatus } } hook::add set_theme_hook [namespace current]::icon::update_all_icons ########################################################################## tkabber-0.11.1/plugins/unix/menu.tcl0000644000175000017500000002221510173034357016643 0ustar sergeisergei# $Id: menu.tcl 600 2005-01-17 22:15:11Z aleksey $ if {$::tcl_version != "8.3"} return namespace eval :: { proc myMenuButtonDown {args} { global myMenuFlag myMenuMotion eval tkMenuButtonDown $args set myMenuFlag 1 } proc myMenuInvoke {args} { global myMenuFlag myMenuMotion if {$myMenuFlag || $myMenuMotion} { eval tkMenuInvoke $args } set myMenuFlag 0 set myMenuMotion 0 } proc myMenuMotion {args} { global myMenuFlag myMenuMotion eval tkMenuMotion $args set myMenuMotion 1 } proc myMenuLeave {args} { global myMenuFlag myMenuMotion eval tkMenuLeave $args set myMenuMotion 0 } bind Menu {myMenuLeave %W %X %Y %s} bind Menu {myMenuButtonDown %W} bind Menu {myMenuInvoke %W 1} bind Menu {myMenuMotion %W %x %y %s} set myMenuFlag 0 set myMenuMotion 0 # tkMenuNextEntry -- # Activate the next higher or lower entry in the posted menu, # wrapping around at the ends. Disabled entries are skipped. # # Arguments: # menu - Menu window that received the keystroke. # count - 1 means go to the next lower entry, # -1 means go to the next higher entry. proc tkMenuNextEntry {menu count} { global tkPriv if {[string equal [$menu index last] "none"]} { return } set length [expr {[$menu index last]+1}] set quitAfter $length set active [$menu index active] if {[string equal $active "none"]} { set i 0 } else { set i [expr {$active + $count}] } while {1} { if {$quitAfter <= 0} { # We've tried every entry in the menu. Either there are # none, or they're all disabled. Just give up. return } while {$i < 0} { incr i $length } while {$i >= $length} { incr i -$length } if {[catch {$menu entrycget $i -state} state] == 0} { if {[string compare $state "disabled"]} { break } } if {$i == $active} { return } incr i $count incr quitAfter -1 } $menu activate $i tkGenerateMenuSelect $menu if {[string equal [$menu type $i] "cascade"]} { set cascade [$menu entrycget $i -menu] if {[string equal [$menu cget -type] "menubar"] && [string compare $cascade ""]} { # Here we auto-post a cascade. This is necessary when # we traverse left/right in the menubar, but undesirable when # we traverse up/down in a menu. $menu postcascade $i tkMenuFirstEntry $cascade } } } # tkMenuNextMenu -- # This procedure is invoked to handle "left" and "right" traversal # motions in menus. It traverses to the next menu in a menu bar, # or into or out of a cascaded menu. # # Arguments: # menu - The menu that received the keyboard # event. # direction - Direction in which to move: "left" or "right" proc tkMenuNextMenu {menu direction} { global tkPriv # First handle traversals into and out of cascaded menus. if {[string equal $direction "right"]} { set count 1 set parent [winfo parent $menu] set class [winfo class $parent] if {[string equal [$menu type active] "cascade"]} { $menu postcascade active set m2 [$menu entrycget active -menu] if {[string compare $m2 ""]} { tkMenuFirstEntry $m2 } return } else { set parent [winfo parent $menu] while {[string compare $parent "."]} { if {[string equal [winfo class $parent] "Menu"] \ && [string equal [$parent cget -type] "menubar"]} { tk_menuSetFocus $parent tkMenuNextEntry $parent 1 return } set parent [winfo parent $parent] } } } else { set count -1 set m2 [winfo parent $menu] if {[string equal [winfo class $m2] "Menu"]} { if {[string compare [$m2 cget -type] "menubar"]} { $menu activate none tkGenerateMenuSelect $menu tk_menuSetFocus $m2 # This code unposts any posted submenu in the parent. $m2 postcascade none #set tmp [$m2 index active] #$m2 activate none #$m2 activate $tmp return } } } # Can't traverse into or out of a cascaded menu. Go to the next # or previous menubutton, if that makes sense. set m2 [winfo parent $menu] if {[string equal [winfo class $m2] "Menu"]} { if {[string equal [$m2 cget -type] "menubar"]} { tk_menuSetFocus $m2 tkMenuNextEntry $m2 -1 return } } set w $tkPriv(postedMb) if {[string equal $w ""]} { return } set buttons [winfo children [winfo parent $w]] set length [llength $buttons] set i [expr {[lsearch -exact $buttons $w] + $count}] while {1} { while {$i < 0} { incr i $length } while {$i >= $length} { incr i -$length } set mb [lindex $buttons $i] if {[string equal [winfo class $mb] "Menubutton"] \ && [string compare [$mb cget -state] "disabled"] \ && [string compare [$mb cget -menu] ""] \ && [string compare [[$mb cget -menu] index last] "none"]} { break } if {[string equal $mb $w]} { return } incr i $count } tkMbPost $mb tkMenuFirstEntry [$mb cget -menu] } # tkMenuFirstEntry -- # Given a menu, this procedure finds the first entry that isn't # disabled or a tear-off or separator, and activates that entry. # However, if there is already an active entry in the menu (e.g., # because of a previous call to tkPostOverPoint) then the active # entry isn't changed. This procedure also sets the input focus # to the menu. # # Arguments: # menu - Name of the menu window (possibly empty). proc tkMenuFirstEntry menu { if {[string equal $menu ""]} { return } tk_menuSetFocus $menu if {[string compare [$menu index active] "none"]} { return } set last [$menu index last] if {[string equal $last "none"]} { return } for {set i 0} {$i <= $last} {incr i} { if {([catch {set state [$menu entrycget $i -state]}] == 0) \ && [string compare $state "disabled"]} { $menu activate $i tkGenerateMenuSelect $menu # Only post the cascade if the current menu is a menubar; # otherwise, if the first entry of the cascade is a cascade, # we can get an annoying cascading effect resulting in a bunch of # menus getting posted (bug 676) if {[string equal [$menu type $i] "cascade"] && \ [string equal [$menu cget -type] "menubar"]} { set cascade [$menu entrycget $i -menu] if {[string compare $cascade ""]} { $menu postcascade $i tkMenuFirstEntry $cascade } } return } } } # tkMenuMotion -- # This procedure is called to handle mouse motion events for menus. # It does two things. First, it resets the active element in the # menu, if the mouse is over the menu. Second, if a mouse button # is down, it posts and unposts cascade entries to match the mouse # position. # # Arguments: # menu - The menu window. # x - The x position of the mouse. # y - The y position of the mouse. # state - Modifier state (tells whether buttons are down). proc tkMenuMotion {menu x y state} { global tkPriv if {[string equal $menu $tkPriv(window)]} { if {[string equal [$menu cget -type] "menubar"]} { if {[info exists tkPriv(focus)] && \ [string compare $menu $tkPriv(focus)]} { $menu activate @$x,$y tkGenerateMenuSelect $menu } } else { $menu activate @$x,$y tkGenerateMenuSelect $menu } } #debugmsg plugins "MENU: $menu $tkPriv(activeMenu) $tkPriv(activeItem) $tkPriv(focus)" if {(![string equal [$menu cget -type] "menubar"]) || \ ([info exist tkPriv(focus)] && (![cequal $tkPriv(focus) ""]) && ($tkPriv(activeItem) != "none"))} { myMenuPostCascade $menu } } set myPriv(id) "" set myPriv(delay) 170 set myPriv(activeMenu) "" set myPriv(activeItem) "" proc myMenuPostCascade {menu} { global myPriv if {![cequal $myPriv(id) ""]} { if {($myPriv(activeMenu) == $menu) && ($myPriv(activeItem) == [$menu index active])} { return } else { after cancel $myPriv(id) } } if {[string equal [$menu cget -type] "menubar"]} { $menu postcascade active } else { set myPriv(activeMenu) $menu set myPriv(activeItem) [$menu index active] set myPriv(id) [after $myPriv(delay) "$menu postcascade active"] } } } tkabber-0.11.1/plugins/unix/dockingtray.tcl0000644000175000017500000000522710674524264020230 0ustar sergeisergei# $Id: dockingtray.tcl 1232 2007-09-20 17:07:00Z sergei $ # KDE tray icon support. # Requires Tk_Theme package # (http://tkabber.jabber.ru/files/other/Tk_Theme-23.tgz) ########################################################################## if {![cequal $::interface tk]} return if {[catch { package require Tk_Theme }]} return ########################################################################## namespace eval dockingtray { variable s2p foreach {k v} [list available available \ away away \ chat chat \ dnd dnd \ xa xa \ unavailable unavailable \ invisible invisible \ blank blank \ message1 message-server \ message2 message \ message3 message-personal] { set s2p($k) docking/$v } variable options custom::defvar options(enable) 1 \ [::msgcat::mc "Enable KDE tray icon."] \ -group Systray -type boolean \ -command [namespace code enable_disable] } ########################################################################## proc dockingtray::enable_disable {args} { variable options set icon .dockingtray if {$options(enable) && ![winfo exists $icon]} { ifacetk::systray::create $icon \ -createcommand [namespace code create] \ -configurecommand [namespace code configure] \ -destroycommand [namespace code destroy] } elseif {!$options(enable) && [winfo exists $icon]} { ifacetk::systray::destroy $icon } } hook::add finload_hook [namespace current]::dockingtray::enable_disable ########################################################################## proc dockingtray::create {icon} { variable s2p set mb $icon.mb theme:frame $icon -kdesystray label $mb -borderwidth 0 -image $s2p(unavailable) \ -highlightthickness 0 -padx 0 -pady 0 pack $mb set m [ifacetk::systray::popupmenu $icon.menu] bind $mb ifacetk::systray::restore bind $mb ifacetk::systray::withdraw bind $mb [list tk_popup $m %X %Y] balloon::setup $icon -command [list ifacetk::systray::balloon $icon] } ########################################################################## proc dockingtray::configure {icon status} { variable s2p if {![cequal $icon ""] && [winfo exists $icon]} { $icon.mb configure -image $s2p($status) } } ########################################################################## proc dockingtray::destroy {icon} { if {![cequal $icon ""] && [winfo exists $icon]} { ::destroy $icon } } ########################################################################## tkabber-0.11.1/plugins/unix/wmdock.tcl0000644000175000017500000000735210560043361017163 0ustar sergeisergei# $Id: wmdock.tcl 894 2007-01-31 07:36:17Z sergei $ if {![cequal $::interface tk]} return if {![info exists ::wmaker_dock] || !$::wmaker_dock} { return } namespace eval ::wmdock { set save_status unavailable set balloon_msg "" set msgs 0 array set msgsc {} set msg_afterid "" } proc ::wmdock::change_status {status} { variable save_status variable msgs variable balloon_msg if {![winfo exists .icon]} return set save_status $status set balloon_msg $status .icon.c itemconfigure text -text [concat $msgs "msgs"] .icon.c itemconfigure icon -image roster/user/$status } proc ::wmdock::msg_recv {chatid from type body x} { variable msg_afterid variable balloon_msg variable msgs variable msgsc variable icon if {![winfo exists .icon]} return if {[chat::is_our_jid $chatid $from] || ![cequal $type chat]} { return } foreach xelem $x { jlib::wrapper:splitxml $xelem tag vars isempty chdata children # Don't count message if this 'empty' tag is present. It indicates # messages history in chat window. if {[cequal $tag ""] && \ [cequal [jlib::wrapper:getattr $vars xmlns] tkabber:x:nolog]} { return } } set cw [chat::winid $chatid] set page [crange [win_id tab $cw] 1 end] if {$::usetabbar && $page != [.nb raise]} { if {![info exists msgsc($chatid)]} { set msgsc($chatid) 0 } incr msgsc($chatid) 1 incr msgs 1 } # set balloon_msg [concat "Message from" [roster::get_label $from] ] set balloon_msg [format [::msgcat::mc "Message from %s"] $from] after cancel $msg_afterid .icon.c itemconfigure icon -image docking/message .icon.c itemconfigure text -text [format [::msgcat::mc "%s msgs"] $msgs] set msg_afterid [after 5000 ::wmdock::clear_msg_status] } proc ::wmdock::msg_read {path chatid} { variable msgs variable msgsc if {![winfo exists .icon]} return if {[info exists msgsc($chatid)]} { set msgs [expr $msgs - $msgsc($chatid)] unset msgsc($chatid) } .icon.c itemconfigure text -text [format [::msgcat::mc "%s msgs"] $msgs] } proc ::wmdock::presence_recv {who status} { variable msg_afterid variable balloon_msg variable icon if {![winfo exists .icon]} return set balloon_msg [format [::msgcat::mc "%s is %s"] $who $status] after cancel $msg_afterid .icon.c itemconfigure icon -image browser/user set msg_afterid [after 10000 ::wmdock::clear_msg_status] } proc ::wmdock::clear_msg_status {} { variable save_status variable balloon_msg if {![winfo exists .icon]} return set balloon_msg $save_status .icon.c itemconfigure icon -image roster/user/$save_status } proc ::wmdock::showhide {} { if {[wm state .] == "withdrawn"} { wm deiconify . wm state . normal } else { wm withdraw . } } proc ::wmdock::balloon {} { variable balloon_msg return [list .icon $balloon_msg] } proc ::wmdock::create_dock {} { variable balloon_msg if {[cequal [wm iconwindow .] ""]} { toplevel .icon wm iconwindow . .icon } wm command . [file join [pwd] $::argv0] canvas .icon.c -background black -width 52 -height 52 -relief sunken .icon.c create image 26 26 -anchor s \ -image roster/user/unavailable -tag icon .icon.c create text 26 52 -anchor s -text "no" -fill white -tag text pack .icon.c bind .icon <3> ::wmdock::showhide balloon::setup .icon -command [list ::wmdock::balloon] } hook::add postload_hook ::wmdock::create_dock 80 hook::add change_our_presence_post_hook ::wmdock::change_status 15 hook::add draw_message_hook ::wmdock::msg_recv 70 hook::add on_change_user_presence_hook ::wmdock::presence_recv 15 hook::add raise_chat_tab_hook ::wmdock::msg_read 15 tkabber-0.11.1/plugins/si/0000755000175000017500000000000011076120366014620 5ustar sergeisergeitkabber-0.11.1/plugins/si/socks5.tcl0000644000175000017500000003517210726056150016543 0ustar sergeisergei# $Id: socks5.tcl 1325 2007-12-06 20:32:40Z sergei $ # # SOCKS5 Bytestreams (XEP-0065) transport for SI # ############################################################################### namespace eval socks5 {} namespace eval socks5::target {} namespace eval socks5::initiator { custom::defvar options(enable_mediated_connection) 1 \ [::msgcat::mc "Use mediated SOCKS5 connection if proxy is available."] \ -group {Stream Initiation} -type boolean custom::defvar options(proxy_servers) "proxy.netlab.cz proxy.jabber.cd.chalmers.se" \ [::msgcat::mc "List of proxy servers for SOCKS5 bytestreams (all\ available servers will be tried for mediated connection)."] \ -group {Stream Initiation} -type string } set ::NS(bytestreams) http://jabber.org/protocol/bytestreams ############################################################################### proc socks5::target::sock_connect {stream hosts lang} { upvar #0 $stream state foreach host $hosts { lassign $host addr port streamhost debugmsg si "CONNECTING TO $addr:$port..." if {[catch {set sock [socket -async $addr $port]}]} continue fconfigure $sock -translation binary -blocking no puts -nonewline $sock "\x05\x01\x00" if {[catch {flush $sock}]} continue set state(sock) $sock fileevent $sock readable \ [list [namespace current]::wait_for_method $sock $stream] # Can't avoid vwait, because this procedure must return result or error vwait ${stream}(status) if {$state(status) == 0} continue set res [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(bytestreams)] \ -subtags [list \ [jlib::wrapper:createtag streamhost-used \ -vars [list jid $streamhost]]]] return [list result $res] } debugmsg si "FAILED" return [list error cancel item-not-found \ -text [::trans::trans \ $lang \ "Cannot connect to any of the streamhosts"]] } ############################################################################### proc socks5::target::wait_for_method {sock stream} { upvar #0 $stream state if {[catch {set data [read $sock]}]} { ::close $sock set state(status) 0 return } if {[eof $sock]} { ::close $sock set state(status) 0 return } binary scan $data cc ver method if {$ver != 5 || $method != 0} { ::close $sock set state(status) 0 return } set myjid [encoding convertto utf-8 \ [tolower_node_and_domain [my_jid $state(connid) $state(jid)]]] set hisjid [encoding convertto utf-8 [tolower_node_and_domain $state(jid)]] set hash [::sha1::sha1 $state(id)$hisjid$myjid] set len [binary format c [string length $hash]] puts -nonewline $sock "\x05\x01\x00\x03$len$hash\x00\x00" flush $sock fileevent $sock readable \ [list [namespace current]::wait_for_reply $sock $stream] } proc socks5::target::wait_for_reply {sock stream} { upvar #0 $stream state if {[catch {set data [read $sock]}]} { ::close $sock set state(status) 0 return } if {[eof $sock]} { set state(status) 0 return } binary scan $data cc ver rep if {$ver != 5 || $rep != 0} { ::close $sock set state(status) 0 return } set state(status) 1 fileevent $sock readable \ [list [namespace parent]::readable $stream $sock] } ############################################################################### proc socks5::target::send_data {stream data} { upvar #0 $stream state puts -nonewline $state(sock) $data flush $state(sock) return 1 } ############################################################################### proc socks5::target::close {stream} { upvar #0 $stream state ::close $state(sock) } ############################################################################### ############################################################################### proc socks5::initiator::connect {stream chunk_size command} { variable options variable hash_sid upvar #0 $stream state set_status [::msgcat::mc "Opening SOCKS5 listening socket"] set servsock [socket -server [list [namespace current]::accept $stream] 0] set state(servsock) $servsock lassign [fconfigure $servsock -sockname] addr hostname port set ip [jlib::socket_ip $state(connid)] set myjid [encoding convertto utf-8 \ [tolower_node_and_domain [my_jid $state(connid) $state(jid)]]] set hisjid [encoding convertto utf-8 [tolower_node_and_domain $state(jid)]] set hash [::sha1::sha1 $state(id)$myjid$hisjid] set hash_sid($hash) $state(id) set streamhosts [list [jlib::wrapper:createtag streamhost \ -vars [list jid [my_jid $state(connid) $state(jid)] \ host $ip \ port $port]]] if {!$options(enable_mediated_connection)} { request $stream $streamhosts $command } else { set proxies [split $options(proxy_servers) " "] set proxies1 {} foreach p $proxies { if {$p != ""} { lappend proxies1 $p } } request_proxy $stream $streamhosts $proxies1 $command } } ############################################################################### proc socks5::initiator::request_proxy {stream streamhosts proxies command} { upvar #0 $stream state if {[lempty $proxies]} { request $stream $streamhosts $command } else { jlib::send_iq get \ [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(bytestreams)]] \ -to [lindex $proxies 0] \ -command [list [namespace current]::recv_request_proxy_response \ $stream $streamhosts [lrange $proxies 1 end] \ $command] \ -connection $state(connid) } } proc socks5::initiator::recv_request_proxy_response \ {stream streamhosts proxies command res child} { if {$res == "DISCONNECT"} { uplevel #0 $command [list [list 0 [::msgcat::mc "Disconnected"]]] return } if {$res != "OK"} { request_proxy $stream $streamhosts $proxies $command return } jlib::wrapper:splitxml $child tag vars isempty chdata children foreach ch $children { jlib::wrapper:splitxml $ch tag1 vars1 isempty1 chdata1 children1 if {$tag1 == "streamhost"} { lappend streamhosts $ch } } request_proxy $stream $streamhosts $proxies $command } ############################################################################### proc socks5::initiator::request {stream streamhosts command} { upvar #0 $stream state jlib::send_iq set \ [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(bytestreams) \ sid $state(id)] \ -subtags $streamhosts] \ -to $state(jid) \ -command [list [namespace current]::recv_request_response \ $stream $streamhosts $command] \ -connection $state(connid) } proc socks5::initiator::recv_request_response \ {stream streamhosts command res child} { upvar #0 $stream state if {$res != "OK"} { uplevel #0 $command [list [list 0 [error_to_string $child]]] return } jlib::wrapper:splitxml $child tag vars isempty chdata children jlib::wrapper:splitxml [lindex $children 0] \ tag1 vars1 isempty1 chdata1 children1 if {$tag1 != "streamhost-used"} { uplevel #0 $command [list [list 0 [::msgcat::mc "Illegal result"]]] return } set jid [jlib::wrapper:getattr $vars1 jid] set idx 0 foreach streamhost $streamhosts { jlib::wrapper:splitxml $streamhost tag2 vars2 isempty2 chdata2 children2 if {[jlib::wrapper:getattr $vars2 jid] == $jid} { break } incr idx } if {$idx == 0} { # Target uses nonmediated connection uplevel #0 $command 1 } elseif {$idx == [llength $streamhosts]} { # Target has reported missing JID uplevel #0 $command [list [list 0 [::msgcat::mc "Illegal result"]]] } else { # TODO: zeroconf support set jid [jlib::wrapper:getattr $vars2 jid] set host [jlib::wrapper:getattr $vars2 host] set port [jlib::wrapper:getattr $vars2 port] # Target uses proxy, so closing server socket ::close $state(servsock) proxy_connect $stream $jid $host $port $command } } ############################################################################### proc socks5::initiator::proxy_connect {stream jid host port command} { upvar #0 $stream state debugmsg si "CONNECTING TO PROXY $host:$port..." if {[catch {socket -async $host $port} sock]} { debugmsg si "CONNECTION FAILED" uplevel #0 $command [list [list 0 [::msgcat::mc \ "Cannot connect to proxy"]]] return } debugmsg si "CONNECTED" fconfigure $sock -translation binary -blocking no set state(sock) $sock puts -nonewline $sock "\x05\x01\x00" flush $sock fileevent $sock readable \ [list [namespace current]::proxy_wait_for_method $sock $stream] vwait ${stream}(status) if {$state(status) == 0} { debugmsg si "SOCKS5 NEGOTIATION FAILED" uplevel #0 $command \ [list [list 0 [::msgcat::mc \ "Cannot negotiate proxy connection"]]] return } # Activate mediated connection jlib::send_iq set \ [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(bytestreams) \ sid $state(id)] \ -subtags [list [jlib::wrapper:createtag activate \ -chdata $state(jid)]]] \ -to $jid \ -command [list [namespace current]::proxy_activate_response \ $stream $command] \ -connection $state(connid) } ############################################################################### proc socks5::initiator::proxy_activate_response {stream command res child} { upvar #0 $stream state if {$res != "OK"} { uplevel #0 $command [list [list 0 [error_to_string $child]]] return } uplevel #0 $command 1 } ############################################################################### proc socks5::initiator::proxy_wait_for_method {sock stream} { upvar #0 $stream state if {[catch {set data [read $sock]}]} { ::close $sock set state(status) 0 return } if {[eof $sock]} { ::close $sock set state(status) 0 return } binary scan $data cc ver method if {$ver != 5 || $method != 0} { ::close $sock set state(status) 0 return } set myjid [encoding convertto utf-8 \ [tolower_node_and_domain [my_jid $state(connid) $state(jid)]]] set hisjid [encoding convertto utf-8 [tolower_node_and_domain $state(jid)]] set hash [::sha1::sha1 $state(id)$myjid$hisjid] set len [binary format c [string length $hash]] puts -nonewline $sock "\x05\x01\x00\x03$len$hash\x00\x00" flush $sock fileevent $sock readable \ [list [namespace current]::proxy_wait_for_reply $sock $stream] } proc socks5::initiator::proxy_wait_for_reply {sock stream} { upvar #0 $stream state if {[catch {set data [read $sock]}]} { ::close $sock set state(status) 0 return } if {[eof $sock]} { set state(status) 0 return } binary scan $data cc ver rep if {$ver != 5 || $rep != 0} { ::close $sock set state(status) 0 return } set state(status) 1 } ############################################################################### proc socks5::initiator::send_data {stream data command} { upvar #0 $stream state puts -nonewline $state(sock) $data flush $state(sock) after idle [list uplevel #0 $command 1] } ############################################################################### proc socks5::initiator::close {stream} { upvar #0 $stream state ::close $state(sock) catch {::close $state(servsock)} } ############################################################################### proc socks5::initiator::accept {stream sock addr port} { upvar #0 $stream state debugmsg si "CONNECT FROM $addr:$port" set state(sock) $sock fconfigure $sock -translation binary -blocking no fileevent $sock readable \ [list [namespace current]::wait_for_methods $sock $stream] } proc socks5::initiator::wait_for_methods {sock stream} { upvar #0 $stream state if {[catch {set data [read $sock]}]} { ::close $sock set state(status) 0 return } if {[eof $sock]} { set state(status) 0 return } binary scan $data ccc* ver nmethods methods if {$ver != 5 || ![lcontain $methods 0]} { puts -nonewline $sock "\x05\xff" ::close $sock set state(status) 0 return } puts -nonewline $sock "\x05\x00" flush $sock fileevent $sock readable \ [list [namespace current]::wait_for_request $sock $stream] } proc socks5::initiator::wait_for_request {sock stream} { variable hash_sid upvar #0 $stream state if {[catch {set data [read $sock]}]} { ::close $sock set state(status) 0 return } if {[eof $sock]} { set state(status) 0 return } binary scan $data ccccc ver cmd rsv atyp len if {$ver != 5 || $cmd != 1 || $atyp != 3} { set reply [string replace $data 1 1 \x07] puts -nonewline $sock $reply ::close $sock set state(status) 0 return } binary scan $data @5a${len} hash debugmsg si "RECV HASH: $hash" if {[info exists hash_sid($hash)] && \ [string equal $hash_sid($hash) $state(id)]} { set reply [string replace $data 1 1 \x00] puts -nonewline $sock $reply flush $sock fileevent $sock readable {} } else { set reply [string replace $data 1 1 \x02] puts -nonewline $sock $reply ::close $sock set state(status) 0 } } ############################################################################### proc socks5::readable {stream chan} { if {![eof $chan]} { set buf [read $chan 4096] si::recv_data $stream $buf } else { fileevent $chan readable {} si::closed $stream } } ############################################################################### proc socks5::iq_set_handler {connid from lang child} { jlib::wrapper:splitxml $child tag vars isempty chdata children if {$tag != "query"} { return [list error modify bad-request] } set id [jlib::wrapper:getattr $vars sid] if {[catch {si::in $connid $from $id} stream]} { return [list error modify bad-request \ -text [::trans::trans $lang \ "Stream ID has not been negotiated"]] } set hosts {} foreach item $children { jlib::wrapper:splitxml $item tag1 vars1 isempty1 chdata1 children1 switch -- $tag1 { streamhost { lappend hosts [list [jlib::wrapper:getattr $vars1 host] \ [jlib::wrapper:getattr $vars1 port] \ [jlib::wrapper:getattr $vars1 jid]] } } } debugmsg si [list $hosts] [namespace current]::target::sock_connect $stream $hosts $lang } iq::register_handler set "" $::NS(bytestreams) \ [namespace current]::socks5::iq_set_handler ############################################################################### si::register_transport $::NS(bytestreams) $::NS(bytestreams) 50 \ [namespace current]::socks5::initiator::connect \ [namespace current]::socks5::initiator::send_data \ [namespace current]::socks5::initiator::close ############################################################################### tkabber-0.11.1/plugins/si/iqibb.tcl0000644000175000017500000000772410574536044016432 0ustar sergeisergei# $Id: iqibb.tcl 1038 2007-03-10 14:09:40Z sergei $ # # IQ-based In-Band Bytestreams (XEP is to be submitted) transport for SI # ############################################################################### namespace eval iqibb {} set ::NS(iqibb) http://jabber.org/protocol/iqibb ############################################################################### proc iqibb::connect {stream chunk_size command} { upvar #0 $stream state set_status [::msgcat::mc "Opening IQ-IBB connection"] jlib::send_iq set \ [jlib::wrapper:createtag open \ -vars [list xmlns $::NS(iqibb) \ sid $state(id) \ block-size $chunk_size]] \ -to $state(jid) \ -connection $state(connid) \ -command [list [namespace current]::recv_connect_response \ $stream $command] } proc iqibb::recv_connect_response {stream command res child} { upvar #0 $stream state if {$res != "OK"} { uplevel #0 $command [list [list 0 [error_to_string $child]]] return } jlib::wrapper:splitxml $child tag vars isempty chdata children set state(seq) 0 uplevel #0 $command 1 } ############################################################################### package require base64 proc iqibb::send_data {stream data command} { upvar #0 $stream state jlib::send_iq set \ [jlib::wrapper:createtag data \ -vars [list xmlns $::NS(iqibb) \ sid $state(id) \ seq $state(seq)] \ -chdata [base64::encode $data]] \ -to $state(jid) \ -command [list [namespace current]::send_data_ack $stream $command] \ -connection $state(connid) set state(seq) [expr {($state(seq) + 1) % 65536}] } proc iqibb::send_data_ack {stream command res child} { if {$res != "OK"} { uplevel #0 $command [list [list 0 [error_to_string $child]]] } else { uplevel #0 $command 1 } } ############################################################################### proc iqibb::close {stream} { upvar #0 $stream state jlib::send_iq set \ [jlib::wrapper:createtag close \ -vars [list xmlns $::NS(iqibb) \ sid $state(id)]] \ -to $state(jid) \ -connection $state(connid) } ############################################################################### proc iqibb::iq_set_handler {connid from lang child} { jlib::wrapper:splitxml $child tag vars isempty chdata children set id [jlib::wrapper:getattr $vars sid] if {[catch {si::in $connid $from $id} stream]} { return [list error modify bad-request \ -text [::trans::trans $lang \ "Stream ID has not been negotiated"]] } upvar #0 $stream state switch -- $tag { open { set state(block-size) [jlib::wrapper:getattr $vars block-size] set state(seq) 0 } close { si::closed $stream } data { set seq [jlib::wrapper:getattr $vars seq] if {$seq != $state(seq)} { si::closed $stream return [list error modify bad-request \ -text [::trans::trans $lang \ "Unexpected packet sequence number"]] } else { set state(seq) [expr {($state(seq) + 1) % 65536}] } set data $chdata if {[catch {set decoded [base64::decode $data]}]} { debugmsg si "IQIBB: WRONG DATA" si::closed $stream return [list error modify bad-request \ -text [::trans::trans $lang \ "Cannot decode recieved data"]] } else { debugmsg si "IQIBB: RECV DATA [list $data]" if {![si::recv_data $stream $decoded]} { si::closed $stream return [list error cancel not-allowed \ -text [::trans::trans $lang \ "File transfer is aborted"]] } } } } return [list result ""] } iq::register_handler set "" $::NS(iqibb) \ [namespace current]::iqibb::iq_set_handler ############################################################################### si::register_transport $::NS(iqibb) $::NS(iqibb) 70 \ [namespace current]::iqibb::connect \ [namespace current]::iqibb::send_data \ [namespace current]::iqibb::close ############################################################################### tkabber-0.11.1/plugins/si/ibb.tcl0000644000175000017500000001331410715344161016062 0ustar sergeisergei# $Id: ibb.tcl 1307 2007-11-10 15:04:17Z sergei $ # # In-Band Bytestreams (XEP-0047) transport for SI # ############################################################################### namespace eval ibb {} set ::NS(ibb) http://jabber.org/protocol/ibb ############################################################################### proc ibb::connect {stream chunk_size command} { upvar #0 $stream state set_status [::msgcat::mc "Opening IBB connection"] jlib::send_iq set \ [jlib::wrapper:createtag open \ -vars [list xmlns $::NS(ibb) \ sid $state(id) \ block-size $chunk_size]] \ -to $state(jid) \ -connection $state(connid) \ -command [list [namespace current]::recv_connect_response \ $stream $command] } proc ibb::recv_connect_response {stream command res child} { upvar #0 $stream state if {$res != "OK"} { uplevel #0 $command [list [list 0 [error_to_string $child]]] return } jlib::wrapper:splitxml $child tag vars isempty chdata children set state(seq) 0 uplevel #0 $command 1 } ############################################################################### package require base64 proc ibb::send_data {stream data command} { upvar #0 $stream state jlib::send_msg $state(jid) \ -xlist [list [jlib::wrapper:createtag data \ -vars [list xmlns $::NS(ibb) \ sid $state(id) \ seq $state(seq)] \ -chdata [base64::encode $data]]] \ -connection $state(connid) set state(seq) [expr {($state(seq) + 1) % 65536}] after 2000 [list uplevel #0 $command 1] } ############################################################################### proc ibb::close {stream} { upvar #0 $stream state jlib::send_iq set \ [jlib::wrapper:createtag close \ -vars [list xmlns $::NS(ibb) \ sid $state(id)]] \ -to $state(jid) \ -connection $state(connid) } ############################################################################### proc ibb::iq_set_handler {connid from lang child} { jlib::wrapper:splitxml $child tag vars isempty chdata children set id [jlib::wrapper:getattr $vars sid] if {[catch {si::in $connid $from $id} stream]} { return [list error modify bad-request \ -text [::trans::trans $lang \ "Stream ID has not been negotiated"]] } upvar #0 $stream state switch -- $tag { open { set state(block-size) [jlib::wrapper:getattr $vars block-size] set state(seq) 0 } close { si::closed $stream } data { set seq [jlib::wrapper:getattr $vars seq] if {$seq != $state(seq)} { si::closed $stream return [list error modify bad-request \ -text [::trans::trans $lang \ "Unexpected packet sequence number"]] } else { set state(seq) [expr {($state(seq) + 1) % 65536}] } set data $chdata if {[catch {set decoded [base64::decode $data]}]} { debugmsg si "IBB: WRONG DATA" si::closed $stream return [list error modify bad-request \ -text [::trans::trans $lang \ "Cannot decode recieved data"]] } else { debugmsg si "IBB: RECV DATA [list $data]" if {![si::recv_data $stream $decoded]} { si::closed $stream return [list error cancel not-allowed \ -text [::trans::trans $lang \ "File transfer is aborted"]] } } } default { return [list error modify bad-request] } } return [list result ""] } iq::register_handler set "" $::NS(ibb) [namespace current]::ibb::iq_set_handler ############################################################################### proc ibb::return_error {connid jid id error} { if {$id == ""} return jlib::send_msg $jid \ -type error \ -id $id \ -xlist [eval stanzaerror::error $error] \ -connection $connid } ############################################################################### proc ibb::message_handler {connid from mid type is_subject subject body \ err thread priority x} { if {$type == "error"} return foreach item $x { jlib::wrapper:splitxml $item tag vars isempty chdata children set xmlns [jlib::wrapper:getattr $vars xmlns] if {[string equal $xmlns $::NS(ibb)]} { set id [jlib::wrapper:getattr $vars sid] if {[catch {si::in $connid $from $id} stream]} { # Unknown Stream ID return_error $connid $from $mid \ [list modify bad-request \ -text [::trans::trans \ "Stream ID has not been negotiated"]] return stop } upvar #0 $stream state set seq [jlib::wrapper:getattr $vars seq] if {$seq != $state(seq)} { # Incorrect sequence number si::closed $stream return_error $connid $from $mid \ [list modify bad-request \ -text [::trans::trans \ "Unexpected packet sequence number"]] return stop } set state(seq) [expr {($state(seq) + 1) % 65536}] set data $chdata if {[catch {set decoded [base64::decode $data]}]} { debugmsg si "IBB: WRONG DATA" si::closed $stream return_error $connid $from $mid \ [list modify bad-request \ -text [::trans::trans \ "Cannot decode recieved data"]] } else { debugmsg si "IBB: RECV DATA [list $data]" if {![si::recv_data $stream $decoded]} { si::closed $stream return_error $connid $from $mid \ [list cancel not-allowed \ -text [::trans::trans \ "File transfer is aborted"]] } } return stop } } } hook::add process_message_hook [namespace current]::ibb::message_handler 50 ############################################################################### si::register_transport $::NS(ibb) $::NS(ibb) 75 \ [namespace current]::ibb::connect \ [namespace current]::ibb::send_data \ [namespace current]::ibb::close ############################################################################### tkabber-0.11.1/plugins/search/0000755000175000017500000000000011076120366015452 5ustar sergeisergeitkabber-0.11.1/plugins/search/headlines.tcl0000644000175000017500000001521710572524206020121 0ustar sergeisergei# $Id: headlines.tcl 1002 2007-03-04 11:07:50Z sergei $ ############################################################################# namespace eval headlines::search {} proc headlines::search::open_panel {w dw sf} { pack $sf -side bottom -anchor w -fill x -before $dw.sw update idletasks $w.body see end } ############################################################################# proc headlines::search::close_panel {w tw sf} { $w.body tag remove search_highlight 0.0 end pack forget $sf focus $tw } ############################################################################# proc headlines::search::setup_panel {w tw uw dw} { set body $w.body $body mark set sel_start end $body mark set sel_end 0.0 set sf [plugins::search::spanel $w.search \ -searchcommand [list [namespace current]::do_search $w $tw $uw $dw] \ -closecommand [list [namespace current]::close_panel $w $tw]] foreach ww [list $tw.c $w.body $dw.date.ts $dw.from.jid $dw.subject.subj] { bind $ww <> \ [double% [list [namespace current]::open_panel $w $dw $sf]] } } hook::add open_headlines_post_hook \ [namespace current]::headlines::search::setup_panel ############################################################################# proc headlines::search::do_search {hw tw uw dw pattern dir} { if {![string length $pattern]} { return 0 } if {$dir == "up"} { set start_node [lindex [$tw selection get] 0] if {$start_node == ""} { set start_node root } set node [search_up $hw $tw $uw $dw $start_node $pattern] } else { set start_node [lindex [$tw selection get] end] if {$start_node == ""} { set start_node root } set node [search_down $hw $tw $uw $dw $start_node $pattern] } if {$node != ""} { return 1 } else { return 0 } } ########################################################################## proc headlines::search::search_up {hw tw uw dw node pattern} { set body $hw.body set subj $dw.subject.subj # Try to search in current article if {[search_in_article_up $body $subj $pattern]} { return $node } set n [plugins::search::bwtree::prev_node $tw $node] while {1} { if {($n != "root") && \ ![catch { array set props [$tw itemcget $n -data] }] && \ [info exists props(type)] && \ $props(type) == "article"} { set subjtext [string map [list "\n" " "] $props(text)] set bodytext "$props(body)\n\n[::msgcat::mc {Read on...}]" if {[plugins::search::match $pattern $subjtext] || \ [plugins::search::match $pattern $bodytext]} { plugins::search::bwtree::search_hilite $tw $n if {[search_in_article_up $body $subj $pattern]} { return $n } } } if {$n == $node} break set n [plugins::search::bwtree::prev_node $tw $n] } return "" } ############################################################################# proc headlines::search::search_in_article_up {body subj pattern} { catch { set bfirst [$body index search_highlight.first] set blast [$body index search_highlight.last] } catch { set sfirst [$subj index search_highlight.first] set slast [$subj index search_highlight.last] } if {![info exists sfirst]} { # Try to find pattern in article body plugins::search::do_text_search $body $pattern up if {![catch { set bfirst1 [$body index search_highlight.first] set blast1 [$body index search_highlight.last] }]} { if {![info exists bfirst]} { return 1 } if {[$body compare $bfirst1 < $bfirst] || \ ([$body compare $bfirst1 == $bfirst] && [$body compare $blast1 < $blast])} { return 1 } $body tag remove search_highlight 0.0 end } $subj mark set sel_start end $subj mark set sel_end 0.0 } # Then try to find pattern in the subject plugins::search::do_text_search $subj $pattern up if {![catch { set sfirst1 [$subj index search_highlight.first] set slast1 [$subj index search_highlight.last] }]} { if {![info exists sfirst]} { return 1 } if {[$subj compare $sfirst1 < $sfirst] || \ ([$subj compare $sfirst1 == $sfirst] && [$subj compare $slast1 < $slast])} { return 1 } $subj tag remove search_highlight 0.0 end } return 0 } ############################################################################# proc headlines::search::search_down {hw tw uw dw node pattern} { set body $hw.body set subj $dw.subject.subj # Try to search in current article if {[search_in_article_down $body $subj $pattern]} { return $node } set n [plugins::search::bwtree::next_node $tw $node] while {1} { if {($n != "root") && \ ![catch { array set props [$tw itemcget $n -data] }] && \ [info exists props(type)] && \ $props(type) == "article"} { set subjtext [string map [list "\n" " "] $props(text)] set bodytext "$props(body)\n\n[::msgcat::mc {Read on...}]" if {[plugins::search::match $pattern $subjtext] || \ [plugins::search::match $pattern $bodytext]} { plugins::search::bwtree::search_hilite $tw $n if {[search_in_article_down $body $subj $pattern]} { return $n } } } if {$n == $node} break set n [plugins::search::bwtree::next_node $tw $n] } return "" } ############################################################################# proc headlines::search::search_in_article_down {body subj pattern} { catch { set bfirst [$body index search_highlight.first] set blast [$body index search_highlight.last] } catch { set sfirst [$subj index search_highlight.first] set slast [$subj index search_highlight.last] } if {![info exists bfirst]} { # Try to find pattern in article subject plugins::search::do_text_search $subj $pattern down if {![catch { set sfirst1 [$subj index search_highlight.first] set slast1 [$subj index search_highlight.last] }]} { if {![info exists sfirst]} { return 1 } if {[$subj compare $sfirst1 > $sfirst] || \ ([$subj compare $sfirst1 == $sfirst] && [$subj compare $slast1 > $slast])} { return 1 } $subj tag remove search_highlight 0.0 end } $body mark set sel_start end $body mark set sel_end 0.0 } # Then try to find pattern in the body plugins::search::do_text_search $body $pattern down if {![catch { set bfirst1 [$body index search_highlight.first] set blast1 [$body index search_highlight.last] }]} { if {![info exists bfirst]} { return 1 } if {[$body compare $bfirst1 > $bfirst] || \ ([$body compare $bfirst1 == $bfirst] && [$body compare $blast1 > $blast])} { return 1 } $body tag remove search_highlight 0.0 end } return 0 } ########################################################################## tkabber-0.11.1/plugins/search/browser.tcl0000644000175000017500000000137010572524206017643 0ustar sergeisergei# $Id: browser.tcl 1002 2007-03-04 11:07:50Z sergei $ namespace eval search {} namespace eval search::browser { hook::add open_browser_post_hook [namespace current]::setup_panel hook::add open_disco_post_hook [namespace current]::setup_panel } proc search::browser::open_panel {sw sf} { pack $sf -side bottom -anchor w -fill x -before $sw } proc search::browser::close_panel {tw sf} { pack forget $sf focus $tw } proc search::browser::setup_panel {w sw tw} { set sf [plugins::search::spanel $w.search \ -searchcommand [list [namespace parent]::bwtree::do_search $tw] \ -closecommand [list [namespace current]::close_panel $tw]] bind $tw.c <> \ [double% [list [namespace current]::open_panel $sw $sf]] } tkabber-0.11.1/plugins/search/logger.tcl0000644000175000017500000000150410574616566017453 0ustar sergeisergei# $Id: logger.tcl 1044 2007-03-10 21:04:54Z sergei $ namespace eval search {} namespace eval search::logger { hook::add open_log_post_hook [namespace current]::setup_panel } proc search::logger::open_panel {w tw sf} { pack $sf -side bottom -anchor w -fill x -before $w.sw update idletasks $tw see end } proc search::logger::close_panel {tw sf} { $tw tag remove search_highlight 0.0 end pack forget $sf } proc search::logger::setup_panel {connid jid w} { set tw $w.log $tw mark set sel_start end $tw mark set sel_end 0.0 set sf [plugins::search::spanel $w.search \ -searchcommand [list [namespace parent]::do_text_search $tw] \ -closecommand [list [namespace current]::close_panel $tw]] bind $w <> \ [double% [list [namespace current]::open_panel $w $tw $sf]] } tkabber-0.11.1/plugins/search/spanel.tcl0000644000175000017500000001160010655575013017443 0ustar sergeisergei# $Id: spanel.tcl 1174 2007-08-06 10:38:03Z sergei $ # Generic horizontal search panel. ########################################################################## option add *noMatchesBackground pink widgetDefaul ########################################################################## namespace eval search {} # TODO (?) require searchcmd to return a list: # [search_result wrapped_around] # and signalize wrap-around condition to the user # # Recognized options: # -searchcommand # -opencommand # -closecommand # -allowclose # -twoway # -defaultdirection # proc search::spanel {w args} { set opencmd "" set closecmd "" set stopcmd "" set canclose 1 set twoway 1 set defbutton 0 set async 0 foreach {key val} $args { switch -- $key { -searchcommand { set searchcmd $val } -opencommand { set opencmd $val } -closecommand { set closecmd $val } -allowclose { set canclose $val } -twoway { set twoway $val } -defaultdirection { switch -- $val { up { set defbutton 0 } down { set defbutton 1 } default { error "Invaild default search direcrion: $val" } } } -stopcommand { set async 1 set stopcmd $val } default { error "invalid option: $key" } } } if {![info exists searchcmd]} { error "missing mandatory option: -searchcommand" } frame $w set sentry [entry $w.sentry \ -validate all \ -validatecommand [namespace code {validate_entry %W %P}]] pack $sentry -padx 1m -side left set bg [lindex [$sentry configure -background] 4] bind $w [namespace code [list spanel_open [double% $w] \ [double% $opencmd]]] set sbox [ButtonBox $w.sbox -spacing 0] if {$twoway} { set lbl [::msgcat::mc "Search up"] } else { set lbl [::msgcat::mc "Search"] } $sbox add -text $lbl \ -command [namespace code [list spanel_search $w $async \ $searchcmd up $bg]] if {$twoway} { $sbox add -text [::msgcat::mc "Search down"] \ -command [namespace code [list spanel_search $w $async \ $searchcmd down $bg]] } pack $sbox -side left -padx 1m set xbox [ButtonBox $w.xbox -spacing 0] $xbox add -text [::msgcat::mc "Cancel"] \ -command [namespace code [list spanel_cancel $w $stopcmd]] if {$async} { bind $sentry [namespace code [list spanel_cancel \ [double% $w] \ [double% $stopcmd]]] pack $xbox -side left -padx 1m } set cbox [ButtonBox $w.cbox -spacing 0] $cbox add -text [::msgcat::mc "Close"] \ -command [namespace code [list spanel_close $w $closecmd]] if {$canclose} { pack $cbox -side right -padx 1m } bind $sentry [double% [list $sbox invoke $defbutton]] bind $sentry [double% [list $sbox invoke [expr {!$defbutton}]]] if {$canclose} { bind $sentry [double% [list $cbox invoke 0]] bind $sentry +break ;# prevent forwarding upstream } spanel_state $w inactive set w } # In async mode, the result of eval'ing of $searchcmd # is treated specially: # * true ("found") means the client code has started the search process; # * false ("not found") means it refused to search for some reason. proc search::spanel_search {w async searchcmd dir dbg} { set sentry $w.sentry spanel_state $w active set cmd $searchcmd lappend cmd [$sentry get] $dir if {$async} { lappend cmd -completioncommand [list \ [namespace current]::spanel_on_completed $w $dbg] } set failed [catch { eval $cmd } found] if {$failed} { spanel_state $w inactive return -code error $found } if {$async && $found} return spanel_state $w inactive spanel_signalize_result $w $dbg $found } proc search::spanel_state {w state} { set sentry $w.sentry set sbox $w.sbox set xbox $w.xbox set cbox $w.cbox if {[string equal $state active]} { set a disabled set b normal } else { set a normal set b disabled } $sentry configure -state $a $sbox configure -state $a $xbox configure -state $b $cbox configure -state $a } proc search::spanel_signalize_result {w dbg found} { set sentry $w.sentry if {$found} { set bg $dbg } else { set bg [option get $sentry noMatchesBackground ""] if {$bg == ""} { set bg $dbg } } $sentry configure -background $bg } proc search::spanel_open {w opencmd} { if {$opencmd != ""} { eval $opencmd [list $w] } focus $w.sentry } proc search::spanel_close {w closecmd} { if {$closecmd != ""} { eval $closecmd [list $w] } } proc search::spanel_cancel {w stopcmd} { if {$stopcmd != ""} { eval $stopcmd [list $w] } } proc search::spanel_on_completed {w dbg found} { spanel_state $w inactive spanel_signalize_result $w $dbg $found } # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/plugins/search/rawxml.tcl0000644000175000017500000000155710572524206017501 0ustar sergeisergei# $Id: rawxml.tcl 1002 2007-03-04 11:07:50Z sergei $ namespace eval search {} namespace eval search::rawxml { hook::add open_rawxml_post_hook [namespace current]::setup_panel } proc search::rawxml::open_panel {w sf} { pack $sf -side bottom -anchor w -fill x -before $w.sw update idletasks $w.dump see end } proc search::rawxml::close_panel {w sf} { $w.dump tag remove search_highlight 0.0 end pack forget $sf focus $w.input } proc search::rawxml::setup_panel {w} { set dump $w.dump $dump mark set sel_start end $dump mark set sel_end 0.0 set sf [plugins::search::spanel [winfo parent $dump].search \ -searchcommand [list [namespace parent]::do_text_search $dump] \ -closecommand [list [namespace current]::close_panel $w]] bind $w.input <> \ [double% [list [namespace current]::open_panel $w $sf]] } tkabber-0.11.1/plugins/search/custom.tcl0000644000175000017500000000155310572524206017475 0ustar sergeisergei# $Id: custom.tcl 1002 2007-03-04 11:07:50Z sergei $ namespace eval search {} namespace eval search::custom { hook::add open_custom_post_hook [namespace current]::setup_panel } proc search::custom::open_panel {w sf} { pack $sf -side bottom -anchor w -fill x -before $w.sw update idletasks $w.fields see end } proc search::custom::close_panel {w sf} { $w.fields tag remove search_highlight 0.0 end pack forget $sf focus $w.fields } proc search::custom::setup_panel {w} { set fields $w.fields $fields mark set sel_start end $fields mark set sel_end 0.0 set sf [plugins::search::spanel $w.search \ -searchcommand [list [namespace parent]::do_text_search $fields] \ -closecommand [list [namespace current]::close_panel $w]] bind $fields <> \ [double% [list [namespace current]::open_panel $w $sf]] } tkabber-0.11.1/plugins/search/chat.tcl0000644000175000017500000000202310572524206017073 0ustar sergeisergei# $Id: chat.tcl 1002 2007-03-04 11:07:50Z sergei $ namespace eval search {} namespace eval search::chat { hook::add open_chat_post_hook [namespace current]::setup_panel } proc search::chat::open_panel {chatw sf} { pack $sf -side bottom -anchor w -fill x -before [winfo parent $chatw].csw update idletasks $chatw see end } proc search::chat::close_panel {chatid sf} { set cw [chat::winid $chatid] set chatw [chat::chat_win $chatid] $chatw tag remove search_highlight 0.0 end pack forget $sf focus $cw.input } proc search::chat::setup_panel {chatid type} { set cw [chat::winid $chatid] set chatw [chat::chat_win $chatid] $chatw mark set sel_start end $chatw mark set sel_end 0.0 set sf [plugins::search::spanel [winfo parent $chatw].search \ -searchcommand [list [namespace parent]::do_text_search $chatw] \ -closecommand [list [namespace current]::close_panel $chatid]] bind $cw.input <> \ [double% [list [namespace current]::open_panel $chatw $sf]] } tkabber-0.11.1/plugins/search/search.tcl0000644000175000017500000002113610607205346017427 0ustar sergeisergei# $Id: search.tcl 1096 2007-04-11 16:20:54Z sergei $ ########################################################################## option add *highlightSearchBackground PaleGreen1 widgetDefaul ########################################################################## namespace eval search { custom::defgroup Plugins [::msgcat::mc "Plugins options."] \ -group Tkabber custom::defgroup Search \ [::msgcat::mc "Search in Tkabber windows options."] \ -group Plugins custom::defvar options(case) 0 \ [::msgcat::mc "Match case while searching in chat, log or disco windows."] \ -type boolean -group Search custom::defvar options(mode) substring \ [::msgcat::mc "Specifies search mode while searching in chat, log or\ disco windows. \"substring\" searches exact substring,\ \"glob\" uses glob style matching, \"regexp\" allows\ to match regular expression."] \ -type options \ -values [list substring substring glob glob regexp regexp] \ -group Search event add <> } ########################################################################## proc search::validate_entry {w val} { variable options if {$options(mode) == "regexp" && [catch { regexp -- $val {} }]} { $w configure -fg [option get $w errorForeground Entry] } else { $w configure -fg [option get $w foreground Entry] } return 1 } ########################################################################## # Search in text widget proc search::glob2regexp {pattern} { string map {\\* \\* \\? \\? \\[ \\[ * .* ? . [^] \\^ [^ [\\^ [! [^ | \\| + \\+ ( \\( ) \\) $ \\$ . \\. \" \\"} $pattern } proc search::do_text_search {txt pattern dir} { variable options if {![string length $pattern]} { return 0 } if {$dir == "up"} { set search_from sel_start set search_to 0.0 set search_dir -backwards } else { set search_from "sel_start +1char" set search_to end set search_dir -forwards } if {$options(case)} { set case "" } else { set case -nocase } switch -- $options(mode) { regexp { set exact -regexp } glob { set exact -regexp set pattern [glob2regexp $pattern] } default { set exact -exact } } if {[catch { eval [list $txt] search $search_dir $case $exact -- \ [list $pattern $search_from] } index]} { set index {} } if {![string length $index]} { return 0 } else { $txt tag remove search_highlight 0.0 end if {$exact == "-regexp"} { set line [$txt get $index "$index lineend"] eval regexp $case -- [list $pattern $line] match $txt tag add search_highlight $index "$index + [string length $match] chars" if {[string length $match] == 0} { set nohighlight 1 } else { set nohighlight 0 } } else { $txt tag add search_highlight $index "$index + [string length $pattern] chars" if {[string length $pattern] == 0} { set nohighlight 1 } else { set nohighlight 0 } } if {!$nohighlight} { $txt tag configure search_highlight -background \ [option get $txt highlightSearchBackground Text] $txt mark set sel_start search_highlight.first $txt mark set sel_end search_highlight.last $txt see $index return 1 } } } ########################################################################## # Search in BWidget Tree widget # Searches $where for $what using global searching options. # Returns: 1 if found, 0 otherwise. proc search::match {what where} { variable options if {$options(mode) == "substring"} { regsub -all {([*?\[\]\\])} $what {\\\1} what } if {$options(case)} { set case "" } else { set case -nocase } switch -- $options(mode) { substring - glob { return [eval string match $case [list *$what* $where]] } regexp { if {[catch {eval regexp $case -- [list $what $where]} res]} { return 0 } else { return $res } } exact { return [eval string equal $case [list $what $where]] } } return 0 } ########################################################################## ########################################################################## namespace eval search::bwtree {} ########################################################################## # Find "next" tree node # proc search::bwtree::next_node {t node} { if {[set child [$t nodes $node 0]] != ""} { return $child } else { while {[set parent [$t parent $node]] != ""} { set siblings [$t nodes $parent] set idx [lsearch -exact $siblings $node] if {$idx < 0} { # This should not happen return $parent } set next_sibling [lindex $siblings [expr {$idx + 1}]] if {$next_sibling != ""} { return $next_sibling } set node $parent } return root } } ########################################################################## # Find "previous" tree node # proc search::bwtree::prev_node {t node} { if {[set parent [$t parent $node]] != ""} { set siblings [$t nodes $parent] set idx [lsearch -exact $siblings $node] if {$idx < 0} { # This should not happen return $parent } set prev_sibling [lindex $siblings [expr {$idx - 1}]] if {$prev_sibling == ""} { return $parent } else { return [go_down $t $prev_sibling] } } else { return [go_down $t $node] } } proc search::bwtree::go_down {t node} { while {[set child [$t nodes $node end]] != ""} { set node $child } return $node } ########################################################################## proc search::bwtree::search_node {t next_node node what} { set n $node while {[set n [$next_node $t $n]] != $node} { if {$n != "root" && \ [[namespace parent]::match $what [$t itemcget $n -text]]} { return $n } } if {$n != "root" && \ [[namespace parent]::match $what [$t itemcget $n -text]]} { return $n } return "" } ########################################################################## proc search::bwtree::do_search {tw pattern dir} { if {![string length $pattern]} { return 0 } if {$dir == "up"} { set start_node [lindex [$tw selection get] 0] if {$start_node == ""} { set start_node root } set node [search_node $tw \ [namespace current]::prev_node \ $start_node \ $pattern] } else { set start_node [lindex [$tw selection get] end] if {$start_node == ""} { set start_node root } set node [search_node $tw \ [namespace current]::next_node \ $start_node \ $pattern] } if {$node != ""} { search_hilite $tw $node return 1 } else { return 0 } } ########################################################################## proc search::bwtree::search_hilite {t node} { tree_openpath $t $node $t selection set $node $t see $node } proc search::bwtree::tree_openpath {t node} { variable state set node [$t parent $node] while {$node != "root"} { $t opentree $node set node [$t parent $node] } } ########################################################################## ########################################################################## # Support for searching in listbox widgets for Tkabber. namespace eval search::listbox {} ########################################################################## proc search::listbox::do_search {w pattern dir} { set selection_first 0 set selection_last [$w index end] for {set i 0} {$i < [$w index end]} {incr i} { if {[$w selection includes $i]} { if {$selection_first == 0} { set selection_first $i } set selection_last $i } } if {[string equal $dir down]} { set step 1 set start1 [incr selection_last] set end1 [$w index end] set cond1 {$i <= $end1} set start2 0 set end2 $selection_last set cond2 {$i < $end2} } else { set step -1 set start1 [incr selection_first -1] set end1 0 set cond1 {$i >= $end1} set start2 [$w index end] set end2 $selection_first set cond2 {$i > $end2} } set found 0 for {set i $start1} $cond1 {incr i $step} { if {[[namespace parent]::match $pattern [$w get $i]]} { set found 1 break } } if {!$found} { for {set i $start2} $cond2 {incr i $step} { if {[[namespace parent]::match $pattern [$w get $i]]} { set found 1 break } } } if {$found} { hilite $w $i } return $found } ########################################################################## proc search::listbox::hilite {w index} { $w selection clear 0 end $w selection set $index $w see $index } ########################################################################## tkabber-0.11.1/plugins/chat/0000755000175000017500000000000011076120366015124 5ustar sergeisergeitkabber-0.11.1/plugins/chat/empty_body.tcl0000644000175000017500000000064410071632317020005 0ustar sergeisergei# $Id: empty_body.tcl 567 2004-07-03 22:35:59Z aleksey $ proc check_send_empty_body {chatid user body type} { if {[cequal $body ""]} { return stop } } hook::add chat_send_message_hook [namespace current]::check_send_empty_body 10 proc check_draw_empty_body {chatid from type body x} { if {[cequal $body ""]} { return stop } } hook::add draw_message_hook [namespace current]::check_draw_empty_body 4 tkabber-0.11.1/plugins/chat/me_command.tcl0000644000175000017500000000255310556440255017740 0ustar sergeisergei# $Id: me_command.tcl 882 2007-01-26 17:55:57Z sergei $ proc handle_me {chatid from type body x} { if {[cequal [crange $body 0 3] "/me "] || [cequal $body "/me"]} { set body [crange $body 4 end] if {[chat::is_our_jid $chatid $from]} { set tag me } else { set tag they } set connid [chat::get_connid $chatid] set chatw [chat::chat_win $chatid] set nick [chat::get_nick $connid $from $type] set cw [chat::winid $chatid] $chatw insert end "* $nick" [list $tag NICK-$nick] " " $chatw mark set MSGLEFT "end - 1 char" $chatw mark gravity MSGLEFT left if {[cequal $type groupchat]} { set myjid [chat::our_jid $chatid] set mynick [chat::get_nick $connid $myjid $type] ::richtext::property_add mynick $mynick ::richtext::render_message $chatw $body $tag } else { ::richtext::render_message $chatw $body $tag } $chatw tag add NICKMSG-$nick MSGLEFT "end - 1 char" if {![catch {::plugins::mucignore::is_ignored $connid $from $type} ignore] && \ $ignore != ""} { $chatw tag add $ignore {MSGLEFT linestart} {end - 1 char} } return stop } } hook::add draw_message_hook [namespace current]::handle_me 83 proc me_command_comp {chatid compsvar wordstart line} { upvar 0 $compsvar comps if {!$wordstart} { lappend comps {/me } } } hook::add generate_completions_hook [namespace current]::me_command_comp tkabber-0.11.1/plugins/chat/draw_message.tcl0000644000175000017500000000062310005304550020260 0ustar sergeisergei# $Id: draw_message.tcl 522 2004-01-26 21:40:56Z aleksey $ proc draw_message {chatid user body type} { variable F if {![cequal $type groupchat] && \ [hook::is_flag chat_send_message_hook draw]} { chat::add_message $chatid [chat::our_jid $chatid] $type $body {} } hook::unset_flag chat_send_message_hook draw } hook::add chat_send_message_hook [namespace current]::draw_message 91 tkabber-0.11.1/plugins/chat/logger.tcl0000644000175000017500000006245610752133252017122 0ustar sergeisergei# $Id: logger.tcl 1373 2008-02-05 19:19:06Z sergei $ ############################################################################# namespace eval ::logger { custom::defgroup Logging [::msgcat::mc "Logging options."] -group Chat custom::defvar options(logdir) [file join $::configdir logs] \ [::msgcat::mc "Directory to store logs."] \ -type string -group Logging custom::defvar options(log_chat) 1 \ [::msgcat::mc "Store private chats logs."] \ -type boolean -group Logging custom::defvar options(log_groupchat) 1 \ [::msgcat::mc "Store group chats logs."] \ -type boolean -group Logging variable version 1.0 if {![file exists $options(logdir)]} { file mkdir $options(logdir) # Storing version for possible future conversions set fd [open [file join $options(logdir) version] w] puts $fd $version close $fd } array set m2d [list [::msgcat::mc "January"] 01 \ [::msgcat::mc "February"] 02 \ [::msgcat::mc "March"] 03 \ [::msgcat::mc "April"] 04 \ [::msgcat::mc "May"] 05 \ [::msgcat::mc "June"] 06 \ [::msgcat::mc "July"] 07 \ [::msgcat::mc "August"] 08 \ [::msgcat::mc "September"] 09 \ [::msgcat::mc "October"] 10 \ [::msgcat::mc "November"] 11 \ [::msgcat::mc "December"] 12] array set d2m [list 01 [::msgcat::mc "January"] \ 02 [::msgcat::mc "February"] \ 03 [::msgcat::mc "March"] \ 04 [::msgcat::mc "April"] \ 05 [::msgcat::mc "May"] \ 06 [::msgcat::mc "June"] \ 07 [::msgcat::mc "July"] \ 08 [::msgcat::mc "August"] \ 09 [::msgcat::mc "September"] \ 10 [::msgcat::mc "October"] \ 11 [::msgcat::mc "November"] \ 12 [::msgcat::mc "December"]] } ############################################################################# proc ::logger::add_menu_item {state category m connid jid} { switch -- $category { roster { set rjid [roster::find_jid $connid $jid] if {$rjid != ""} { set jid $rjid } } chat { set nas [node_and_server_from_jid $jid] if {![chat::is_groupchat [chat::chatid $connid $nas]]} { set jid $nas } } } $m add command -label [::msgcat::mc "Show history"] \ -state $state \ -command [list logger::show_log $jid -connection $connid] } ############################################################################# hook::add chat_create_user_menu_hook \ [list ::logger::add_menu_item normal chat] 65 hook::add chat_create_conference_menu_hook \ [list ::logger::add_menu_item normal group] 65 hook::add roster_create_groupchat_user_menu_hook \ [list ::logger::add_menu_item normal grouproster] 65 hook::add roster_conference_popup_menu_hook \ [list ::logger::add_menu_item normal roster] 65 hook::add roster_service_popup_menu_hook \ [list ::logger::add_menu_item disabled roster] 65 hook::add roster_jid_popup_menu_hook \ [list ::logger::add_menu_item normal roster] 65 hook::add message_dialog_menu_hook \ [list ::logger::add_menu_item disabled message] 65 hook::add search_popup_menu_hook \ [list ::logger::add_menu_item disabled search] 65 ############################################################################# proc ::logger::str_to_log {str} { return [string map {\\ \\\\ \r \\r \n \\n} $str] } ############################################################################# proc ::logger::log_to_str {str} { return [string map {\\\\ \\ \\r \r \\n \n} $str] } ############################################################################# proc ::logger::jid_to_filename {jid} { set utf8_jid [encoding convertto utf-8 $jid] set len [string length $utf8_jid] set filename "" for {set i 0} {$i < $len} {incr i} { binary scan $utf8_jid @${i}c sym set sym [expr {$sym & 0xFF}] switch -- $sym { 34 - 37 - 39 - 42 - 43 - 47 - 58 - 59 - 60 - 62 - 63 - 92 - 124 - 126 { # 34 " 37 % 39 ' 42 * 43 + 47 / 58 : 59 ; 60 < 62 > 63 ? 92 \ 124 | 126 ~ append filename [format "%%%02X" $sym] } 46 { # 46 . if {$i + 1 == $len} { append filename [format "%%%02X" $sym] } else { append filename [binary format c $sym] } } default { if {$sym >= 128 || $sym <= 32} { append filename [format "%%%02X" $sym] } else { append filename [binary format c $sym] } } } } if {[string index $filename 253] == "%"} { return [string range $filename 0 252] } if {[string index $filename 252] == "%"} { return [string range $filename 0 251] } return [string range $filename 0 253] } ############################################################################# proc ::logger::filename_to_jid {filename} { set len [string length $filename] set utf8_jid "" for {set i 0} {$i < $len} {incr i} { catch { binary scan $filename @${i}a sym switch -- $sym { "%" { incr i binary scan $filename @${i}a2 num append utf8_jid [binary format c 0x$num] incr i } default { append utf8_jid $sym } } } } return [encoding convertfrom utf-8 $utf8_jid] } ############################################################################# proc ::logger::cdopen {filepath {mode r}} { set dir [file dirname $filepath] set file [file tail $filepath] set current_dir [pwd] cd $dir if {[catch {open $file $mode} fd]} { cd $current_dir return -code error $fd } else { cd $current_dir return $fd } } ############################################################################# proc ::logger::log_message {chatid from type body x} { variable options if {$type == "chat" && !$options(log_chat)} return if {$type == "groupchat" && !$options(log_groupchat)} return set connid [chat::get_connid $chatid] set jid [chat::get_jid $chatid] set nas [node_and_server_from_jid $jid] if {$type == "chat" && ![chat::is_groupchat [chat::chatid $connid $nas]]} { set jid $nas } set nick [chat::get_nick $connid $from $type] set seconds [jlib::x_delay $x] foreach xelem $x { jlib::wrapper:splitxml $xelem tag vars isempty chdata children # Don't log message if this 'empty' tag is present. It indicates # messages history in chat window. if {[cequal $tag ""] && \ [cequal [jlib::wrapper:getattr $vars xmlns] tkabber:x:nolog]} { return } } set ts [clock format $seconds -format "%Y%m%dT%H%M%S" -gmt 1] set year [clock format $seconds -format %Y] set month [clock format $seconds -format %m] file mkdir [file join $options(logdir) $year $month] set fd [cdopen [file join $options(logdir) $year $month [jid_to_filename $jid]] a] fconfigure $fd -encoding utf-8 puts $fd [str_to_log [list timestamp $ts jid $from nick $nick body $body]] close $fd } hook::add draw_message_hook ::logger::log_message 15 ############################################################################# proc ::logger::winid {name} { set allowed_name [jid_to_tag $name] return .log_$allowed_name } ############################################################################# proc ::logger::describe_month {year-month} { variable d2m lassign [split ${year-month} -] year month return "$d2m($month) $year" } ############################################################################# proc ::logger::create_log_viewer {lw jid args} { global tcl_platform global defaultnick foreach {key val} $args { switch -- $key { -connection { set connid $val } -subdirs { set subdirs $val } } } if {![info exists connid]} { set connid [lindex [jlib::connections] 0] } set logfile [jid_to_filename $jid] set mynick [get_group_nick $jid ""] toplevel $lw -relief $::tk_relief -borderwidth $::tk_borderwidth -class Chat wm group $lw . wm withdraw $lw set title [format [::msgcat::mc "History for %s"] $jid] wm title $lw $title wm iconname $lw $title set lf [ScrolledWindow $lw.sw] set l [text $lw.log -wrap word -takefocus 0] set mf [frame $lw.mf] pack $mf -side top -fill x -expand no -padx 1m -pady 1m set mlabel [label $mf.mlabel -text [::msgcat::mc "Select month:"]] pack $mlabel -side left set ebutton [button $mf.ebutton -text [::msgcat::mc "Export to XHTML"] \ -command [list [namespace current]::export \ $l $lw.mf.mcombo $logfile $mynick]] pack $ebutton -side right pack $lf -padx 1m -pady 1m -fill both -expand yes $lf setwidget $l regsub -all %W [bind Text ] $l prior_binding regsub -all %W [bind Text ] $l next_binding bind $lw $prior_binding bind $lw $next_binding $l tag configure they -foreground [option get $lw theyforeground Chat] $l tag configure me -foreground [option get $lw meforeground Chat] $l tag configure server_lab \ -foreground [option get $lw serverlabelforeground Chat] $l tag configure server \ -foreground [option get $lw serverforeground Chat] $l configure -state disabled if {![info exists subdirs]} { set subdirs [get_subdirs $logfile] } set ympairs {} foreach sd [lsort -decreasing $subdirs] { lappend ympairs [describe_month $sd] } lappend ympairs [::msgcat::mc "All"] set mcombo [ComboBox $mf.mcombo \ -editable no \ -exportselection no \ -values $ympairs \ -text [lindex $ympairs 0] \ -modifycmd [list \ [namespace current]::change_month \ $mf.mcombo $logfile $l $mynick]] pack $mcombo -side left hook::run open_log_post_hook $connid $jid $lw wm deiconify $lw } ############################################################################# proc ::logger::show_log {jid args} { set lw [winid $jid] debugmsg plugins "LOGGER: $lw" variable $lw upvar 1 $lw state if {![winfo exists $lw]} { eval [list create_log_viewer $lw $jid] $args } else { focus -force $lw } foreach {key val} $args { switch -- $key { -when { set when $val } -timestamp { set timestamp $val } } } set logfile [jid_to_filename $jid] set mynick [get_group_nick $jid ""] set log $lw.log set cbox $lw.mf.mcombo set ympairs [$cbox cget -values] if {[info exists when]} { set text [describe_month $when] if {[lsearch -exact $ympairs $text] < 0} { error "no log entries for: $when" } } else { set text [lindex $ympairs 0] } $cbox configure -text $text change_month $cbox $logfile $log $mynick if {[info exists timestamp]} { set pos [lindex [$log tag ranges TS-$timestamp] 0] if {$pos == ""} { set pos end } } else { set pos end } $log see $pos } ############################################################################# proc ::logger::get_subdirs {logfile} { variable options set subdirs {} foreach yeard [glob -nocomplain -type d -directory $options(logdir) *] { foreach monthd [glob -nocomplain -type d -directory $yeard *] { if {[file exists [file join $monthd $logfile]]} { lappend subdirs [file tail $yeard]-[file tail $monthd] } } } return $subdirs } ############################################################################# proc ::logger::draw_messages {l hist mynick} { $l configure -state normal $l delete 1.0 end add_messages $l $hist $mynick } ############################################################################# proc ::logger::formatxmppts {xmppts} { set seconds [clock scan $xmppts -gmt 1] clock format $seconds -format {%Y-%m-%d %X} } ############################################################################# proc ::logger::exists_and_empty {what} { upvar 1 $what var expr {[info exists var] && $var == ""} } proc ::logger::exists_and_nonempty {what} { upvar 1 $what var expr {[info exists var] && $var != ""} } proc ::logger::add_messages {l hist mynick} { $l configure -state normal foreach vars $hist { array unset tmp if {[catch {array set tmp $vars}]} continue if {[info exists tmp(timestamp)]} { $l insert end \[[formatxmppts $tmp(timestamp)]\] \ [list TS-$tmp(timestamp)] } if {[exists_and_empty tmp(jid)]} { # synthesized message $l insert end "---" server_lab set servertag server } else { if {[exists_and_empty tmp(nick)]} { # message from the server: $l insert end "---" server_lab set servertag server } else { set nick $tmp(nick) if {[string equal $nick $mynick]} { set tag me } else { set tag they } if {[info exists tmp(body)] && [regsub {^/me } $tmp(body) {} body]} { $l insert end "*$nick $body" $tag unset tmp(body) } else { $l insert end "<$nick>" $tag } set servertag "" } } if {[info exists tmp(body)]} { $l insert end " $tmp(body)" $servertag } if {![$l compare "end -1 chars linestart" == "end -1 chars"]} { $l insert end "\n" } } $l configure -state disabled } ############################################################################# proc ::logger::change_month {mcombo logfile l mynick} { variable m2d set month [$mcombo cget -text] if {$month == [::msgcat::mc "All"]} { draw_messages $l {} $mynick foreach m [lsort -increasing [get_subdirs $logfile]] { add_messages $l [read_hist_from_file $logfile $m] $mynick update } } else { set my_list [split $month " "] set month [lindex $my_list end]-$m2d([join [lrange $my_list 0 end-1] " "]) draw_messages $l [read_hist_from_file $logfile $month] $mynick } $l see end } ############################################################################# proc ::logger::read_hist_from_file {logfile month} { variable options lassign [split $month -] year month1 set filename [file join $options(logdir) $year $month1 $logfile] set hist {} if {[file exists $filename]} { set fd [cdopen $filename r] fconfigure $fd -encoding utf-8 while {[gets $fd line] > 0} { lappend hist [log_to_str $line] } close $fd } return $hist } ############################################################################# proc ::logger::get_last_messages {jid max interval} { if {$max == 0 || $interval == 0} { return {} } set logfile [jid_to_filename $jid] set months [lsort -decreasing [get_subdirs $logfile]] set messages {} set curseconds [clock seconds] set max1 [expr {$max - 1}] foreach m $months { catch { set messages [lsort -increasing -index 1 \ [concat [read_hist_from_file $logfile $m] \ $messages]] } if {$interval > 0} { set idx 0 foreach msg $messages { set timestamp [lindex $msg 1] set seconds [clock scan $timestamp -gmt 1] if {$seconds + $interval * 3600 < $curseconds} { incr idx } else { break } } if {$idx > 0} { set messages [lrange $messages $idx end] if {$max > 0 && [llength $messages] >= $max} { return [lrange $messages end-$max1 end] } else { return $messages } } } if {$max > 0 && [llength $messages] >= $max} { return [lrange $messages end-$max1 end] } } return $messages } ############################################################################# proc ::logger::export {lw mcombo logfile mynick} { variable m2d set month [$mcombo cget -text] if {$month == [::msgcat::mc "All"]} { set hist {} foreach m [lsort -increasing [get_subdirs $logfile]] { set hist [concat $hist [read_hist_from_file $logfile $m]] } } else { set my_list [split $month " "] set month [lindex $my_list end]-$m2d([join [lrange $my_list 0 end-1] " "]) set hist [read_hist_from_file $logfile $month] } set filename [tk_getSaveFile -defaultextension .html] if {$filename == ""} return set fd [open $filename w] fconfigure $fd -encoding utf-8 puts $fd {} puts $fd {} puts $fd {} set head [jlib::wrapper:createtag head \ -subtags [list [jlib::wrapper:createtag link \ -vars { rel stylesheet type text/css href tkabber-logs.css }]]] puts $fd [jlib::wrapper:createxml $head] foreach vars $hist { array unset tmp if {[catch {array set tmp $vars}]} continue set subtags {} if {[info exists tmp(timestamp)]} { set seconds [clock scan $tmp(timestamp) -gmt 1] set timestamp [clock format $seconds -format {[%Y-%m-%d %X]}] lappend subtags [jlib::wrapper:createtag span \ -vars {class timestamp} \ -chdata $timestamp] } if {[info exists tmp(nick)] && $tmp(nick) != ""} { if {$tmp(nick) == $mynick} { set tag me } else { set tag they } if {[info exists tmp(body)] && [regsub {^/me } $tmp(body) {} body]} { set nick "*$tmp(nick) $body" unset tmp(body) } else { set nick "<$tmp(nick)> " } lappend subtags [jlib::wrapper:createtag span \ -vars [list class $tag] \ -chdata $nick] if {[info exists tmp(body)]} { lappend subtags [jlib::wrapper:createtag span \ -vars [list class body] \ -chdata "$tmp(body)"] } } else { if {[info exists tmp(body)]} { lappend subtags [jlib::wrapper:createtag span \ -vars [list class server] \ -chdata "--- $tmp(body)"] } } #if {![$l compare "end -1 chars linestart" == "end -1 chars"]} { # puts "\n" #} set msg [jlib::wrapper:createtag div \ -vars [list class message] \ -subtags $subtags] puts $fd [jlib::wrapper:createxml $msg] } puts $fd {} close $fd write_css $lw [file join [file dirname $filename] tkabber-logs.css] } ############################################################################# proc ::logger::write_css {lw filename} { set fd [open $filename w] puts $fd " html body { background-color: white; color: black; } .me { color: blue; } .they { color: red; } .server { color: green; } " close $fd } ############################################################################# proc ::logger::convert_subdir_log {t logfrom logto jid dir} { if {[catch { set fd [cdopen $logfrom r] } err]} { $t configure -state normal $t insert end [::msgcat::mc "File %s cannot be opened: %s.\ History for %s (%s) is NOT converted\n" \ $err $logfrom $jid $dir] error $t configure -state disabled $t see end update return } fconfigure $fd -encoding utf-8 set hist [read $fd] close $fd set fd [cdopen $logto a] fconfigure $fd -encoding utf-8 if {[catch { foreach vars $hist { puts $fd [str_to_log $vars] } }]} { $t configure -state normal $t insert end [::msgcat::mc "File %s is corrupt.\ History for %s (%s) is NOT converted\n" \ $logfrom $jid $dir] error $t configure -state disabled $t see end } else { $t configure -state normal $t insert end "($dir) $jid\n" $t configure -state disabled $t see end } close $fd update } proc ::logger::convert_root_log {t dirfrom dirto filename jid} { set logfile [file join $dirfrom $filename] if {[catch { set fd [cdopen $logfile r] } err]} { $t configure -state normal $t insert end [::msgcat::mc "File %s cannot be opened: %s.\ History for %s is NOT converted\n" \ $err $logfile $jid] error $t configure -state disabled $t see end update return } fconfigure $fd -encoding utf-8 set hist [read $fd] close $fd if {[catch { foreach vars $hist { array unset tmp if {[catch {array set tmp $vars}]} continue if {[info exists tmp(timestamp)]} { set seconds [clock scan $tmp(timestamp) -gmt 1] set ym [clock format $seconds -format %Y-%m] lappend newhist($ym) $vars } } }]} { $t configure -state normal $t insert end [::msgcat::mc "File %s is corrupt.\ History for %s is NOT converted\n" \ $logfile $jid] error $t configure -state disabled $t see end update return } foreach ym [lsort [array names newhist]] { $t configure -state normal $t insert end "($ym) $jid\n" $t configure -state disabled $t see end update lassign [split $ym -] year month set dir [file join $dirto $year $month] set newlog [file join $dir [jid_to_filename $jid]] file mkdir $dir set fd [cdopen $newlog a] fconfigure $fd -encoding utf-8 catch { foreach vars $newhist($ym) { puts $fd [str_to_log $vars] } } close $fd } } proc ::logger::convert_logs {t dirfrom dirto} { variable version # Heuristically reconstruct JIDs set fnlist {} foreach subdir [glob -nocomplain -type d -directory $dirfrom *] { set dir [file tail $subdir] if {![regexp {^(\d\d\d\d)-(\d\d)$} $dir -> year month]} continue foreach filepath [glob -nocomplain -type f -directory $subdir *] { lappend fnlist [file tail $filepath] } } foreach filepath [glob -nocomplain -type f -directory $dirfrom *] { lappend fnlist [file tail $filepath] } # Sort the list. It's important not only because it removes duplicates set fnlist [lsort -unique $fnlist] foreach fn $fnlist { # Set prefix (for processing groupchats) if {![info exists prefix] || ([string first $prefix $fn] != 0)} { set prefix $fn } # Simple case: no or one underscore in the filename set idx [string first _ $fn] if {($idx < 0) || ([string first _ $fn [expr {$idx + 1}]] < 0)} { set JID($fn) [string map {_ @} $fn] continue } # JID without a resource (very likely) # Since underscore is not allowed in domain names, just replace # the last one by @. It's the best guess we can do if {$prefix == $fn} { set idx [string last _ $fn] set pr [string range $fn 0 [expr {$idx - 1}]] set sf [string range $fn [expr {$idx + 1}] end] set JID($fn) $pr@$sf continue } # JID with a resource is a private chat with someone in the # conference room. Take room JID from the $prefix and add # resource (don't replace _ in the resource) set idx [expr {[string length $prefix] + 1}] set sf [string range $fn $idx end] set JID($fn) $JID($prefix)/$sf } # Create dir for new logs if {![file exists $dirto]} { file mkdir $dirto } # Process all subdirs YYYY-MM foreach subdir [glob -nocomplain -type d -directory $dirfrom *] { set dir [file tail $subdir] if {![regexp {^(\d\d\d\d)-(\d\d)$} $dir -> year month]} continue foreach filepath [glob -nocomplain -type f -directory $subdir *] { set jid $JID([file tail $filepath]) set filename [jid_to_filename $jid] set fdir [file join $dirto $year $month] file mkdir $fdir convert_subdir_log $t $filepath [file join $fdir $filename] $jid $dir } } # Process all files in log dir itself foreach filepath [glob -nocomplain -type f -directory $dirfrom *] { if {[file tail $filepath] == "message_archive"} { convert_subdir_log $t $filepath \ [file join $dirto [file tail $filepath]] \ message_archive "" } else { convert_root_log $t $dirfrom $dirto \ [file tail $filepath] $JID([file tail $filepath]) } } # Storing version for possible future conversions set fd [open [file join $dirto version] w] puts $fd $version close $fd } ############################################################################# proc ::logger::convert_on_start {} { variable version variable options set version_file [file join $options(logdir) version] if {[file exists $version_file]} { set fd [open $version_file r] set v [string trim [read $fd]] close $fd if {$v >= $version} return } set parent_dir [file dirname $options(logdir)] set log_dir [file tail $options(logdir)] if {$log_dir == ""} { return -code error \ [::msgcat::mc "You're using root directory %s for storing Tkabber\ logs!\n\nI refuse to convert logs database." \ $options(logdir)] } # Create temporary directory for converted logs set dir $log_dir.new while {[file exists [file join $parent_dir $dir]]} { set dir $dir~ } set w .log_convert Dialog $w -title [::msgcat::mc "Converting Log Files"] \ -separator 1 -anchor e -default 0 -cancel 0 -modal none bind $w [list set convert_result 1] $w add -text [::msgcat::mc "Close"] \ -state disabled \ -command [list destroy $w] set f [$w getframe] set msg [message $f.msg -aspect 50000 \ -text [::msgcat::mc "Please, be patient while chats\ history is being converted to new format"]] pack $msg set sw [ScrolledWindow $f.sw] pack $sw -expand yes -fill both set t [text $sw.t -state disabled -wrap word] $t tag configure error -foreground [option get $t errorForeground Text] $sw setwidget $t $w draw grab $w convert_logs $t $options(logdir) [file join $parent_dir $dir] set bdir $log_dir~ while {[file exists [file join $parent_dir $bdir]]} { set bdir $bdir~ } file rename -- $options(logdir) [file join $parent_dir $bdir] file rename -- [file join $parent_dir $dir] $options(logdir) if {[winfo exists $w]} { $w itemconfigure 0 -state normal $msg configure -text [::msgcat::mc "Chats history is converted.\nBackup\ of the old history\ is stored in %s" \ [file join $parent_dir $bdir]] $t configure -state normal $t insert end "[::msgcat::mc {Conversion is finished}]\n" $t configure -state disabled $t see end vwait convert_result } catch {unset ::convert_result} } hook::add finload_hook ::logger::convert_on_start 1000 ############################################################################# # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/plugins/chat/irc_commands.tcl0000644000175000017500000001215210563607265020277 0ustar sergeisergei# $Id: irc_commands.tcl 924 2007-02-11 12:40:21Z sergei $ namespace eval irc {} proc irc::handle_irc_commands {chatid user body type} { set body [string trim $body] if {[cequal [crange $body 0 6] "/topic "]} { set command subject set subject [string trim [crange $body 7 end]] } elseif {[cequal [crange $body 0 8] "/subject "]} { set command subject set subject [string trim [crange $body 9 end]] } elseif {[cequal $body "/topic"] || \ [cequal $body "/subject"]} { set command show_subject } elseif {[cequal [crange $body 0 5] "/nick "]} { set command nick set nick [string trim [crange $body 6 end]] } elseif {[cequal [crange $body 0 7] "/invite "]} { set command invite set arg [crange $body 8 end] lassign [parse_body $arg "\n"] to reason } elseif {[cequal [crange $body 0 5] "/join "]} { set command join set arg [crange $body 6 end] lassign [parse_body $arg " "] room password } elseif {[cequal $body "/join"]} { set command join set room "" set password "" } elseif {[cequal [crange $body 0 4] "/msg "]} { set command msg set arg [crange $body 5 end] lassign [parse_body $arg "\n"] nick body } elseif {[cequal $body "/nick"] || \ [cequal $body "/msg"] || \ [cequal $body "/invite"]} { return stop } elseif {[cequal [crange $body 0 5] "/part "]} { set command leave set status [string trim [crange $body 6 end]] } elseif {[cequal [crange $body 0 6] "/leave "]} { set command leave set status [string trim [crange $body 7 end]] } elseif {[cequal $body "/part"] || \ [cequal $body "/leave"]} { set command leave set status "" } else { return } set connid [chat::get_connid $chatid] set jid [chat::get_jid $chatid] switch -- $command { nick { if {![cequal $type groupchat]} return if {$chat::chats(status,$chatid) == "disconnected"} { if {[info exists ::muc::muc_password($chatid)]} { set password $::muc::muc_password($chatid) } else { set password "" } muc::join_group $connid $jid $nick $password debugmsg plugins "NICK -> JOIN: $nick" } else { muc::change_nick $chatid $nick debugmsg plugins "NICK: $nick" } } subject { if {![cequal $type groupchat]} return message::send_msg $jid -connection $connid \ -type groupchat -subject $subject debugmsg plugins "SUBJECT: $subject" } show_subject { chat::add_message $chatid $jid info \ "[::msgcat::mc Subject:] $chat::chats(subject,$chatid)" {} } invite { if {[cequal $type groupchat]} { muc::invite_muc $connid $jid $to $reason } else { muc::invite_muc $connid $to $jid $reason } debugmsg plugins "INVITE: $to $reason" } join { if {[cequal $type groupchat]} { if {[cequal $room ""]} { set room $jid } elseif {[string first @ $room] < 0} { set room $room@[server_from_jid $jid] } } if {[catch { get_our_groupchat_nick [chat::chatid $connid $room] } nick]} { set nick [get_group_nick $room $::gr_nick] } muc::join_group $connid \ $room \ $nick \ $password debugmsg plugins "JOIN: $room" } msg { if {[cequal $type groupchat] && \ $nick != "" && $body != ""} { chat::open_to_user $connid $jid/$nick -message $body debugmsg plugins "MSG: $jid/$nick: $body" } else { chat::add_message $chatid $jid error \ "/msg to $nick failed" {} } } leave { set chat::chats(exit_status,$chatid) $status after idle [list ifacetk::destroy_win [chat::winid $chatid]] debugmsg plugins "LEAVE: $jid $status" } } return stop } hook::add chat_send_message_hook [namespace current]::irc::handle_irc_commands 50 proc irc::parse_body {line separator} { set ne [string first $separator $line] if {$ne < 0} { set nick $line set body "" } else { set nick [string range $line 0 [expr {$ne - 1}]] set body [string range $line [expr {$ne + [string length $separator]}] end] } return [list $nick [string trim $body]] } proc irc::irc_commands_comp {chatid compsvar wordstart line} { upvar 0 $compsvar comps if {!$wordstart} { lappend comps {/invite } lappend comps {/join } lappend comps {/leave } lappend comps {/msg } lappend comps {/nick } lappend comps {/part } lappend comps {/subject } lappend comps {/topic } } if {$wordstart && [cequal [crange $line 0 7] "/invite "] && \ [string first "\n" $line] < 0} { set prefix $plugins::completion::options(prefix) set suffix $plugins::completion::options(suffix) set jidcomps {} set connid [chat::get_connid $chatid] if {[chat::is_groupchat $chatid]} { foreach jid [roster::get_jids $connid] { if {[roster::itemconfig $connid $jid -isuser]} { lappend jidcomps $prefix$jid$suffix } } } else { foreach chatid1 [lfilter chat::is_groupchat [chat::opened $connid]] { set jid [chat::get_jid $chatid1] lappend jidcomps $prefix$jid$suffix } } set jidcomps [lsort -dictionary -unique $jidcomps] set comps $jidcomps debugmsg plugins "COMPLETION from roster: $comps" return stop } } hook::add generate_completions_hook [namespace current]::irc::irc_commands_comp tkabber-0.11.1/plugins/chat/nick_colors.tcl0000644000175000017500000002350310752133252020136 0ustar sergeisergei# nick_colors.tcl - Copyright (C) 2004 Pat Thoyts # # Do full text coloring based upon nicks. Includes a color editor and # persistence for modified color selection. # # $Id: nick_colors.tcl 1373 2008-02-05 19:19:06Z sergei $ package require sum namespace eval nickcolors { custom::defvar options(use_colored_nicks) 0 \ [::msgcat::mc "Use colored nicks in chat windows."] \ -group Chat -type boolean \ -command [namespace current]::change_options custom::defvar options(use_colored_roster_nicks) 0 \ [::msgcat::mc "Use colored nicks in groupchat rosters."] \ -group Chat -type boolean \ -command [namespace current]::change_options custom::defvar options(use_colored_messages) 0 \ [::msgcat::mc "Color message bodies in chat windows."] \ -group Chat -type boolean \ -command [namespace current]::change_options hook::add open_chat_post_hook [namespace current]::chat_add_nick_colors hook::add close_chat_post_hook [namespace current]::chat_delete_nick_colors hook::add quit_hook [namespace current]::save_nick_colors hook::add draw_message_hook [namespace current]::check_nick 60 hook::add finload_hook [namespace current]::init_nick_colors hook::add chat_win_popup_menu_hook [namespace current]::add_chat_win_popup_menu 10 hook::add roster_create_groupchat_user_menu_hook \ [namespace current]::add_groupchat_user_menu_items variable NickColorPool if {![info exists NickColorPool]} { set NickColorPool [list blue4 green4 red brown4 orange3 purple3 \ tomato chocolate pink3] } variable NickColors if {![info exists NickColors]} { array set NickColors {} } } proc nickcolors::init_nick_colors {} { load_nick_colors add_nick_colors_menu } proc nickcolors::add_nick_colors_menu {} { set m [.mainframe getmenu chats] $m insert end checkbutton \ -label [::msgcat::mc "Use colored nicks"] \ -variable [namespace current]::options(use_colored_nicks) \ -command [namespace current]::change_options $m insert end checkbutton \ -label [::msgcat::mc "Use colored roster nicks"] \ -variable [namespace current]::options(use_colored_roster_nicks) \ -command [namespace current]::change_options $m insert end checkbutton \ -label [::msgcat::mc "Use colored messages"] \ -variable [namespace current]::options(use_colored_messages) \ -command [namespace current]::change_options $m insert end command \ -label [::msgcat::mc "Edit nick colors..."] \ -command [namespace current]::edit_nick_colors } # Called upon startup, this will merge the user's stored set of nick-colors # into the current array. New chat windows will pick these up. # proc nickcolors::load_nick_colors {} { variable NickColors set filename [file join $::configdir nickcolors.tcl] if {[file exists $filename]} { set f [open $filename r] fconfigure $f -encoding utf-8 while {![eof $f]} { set line [string trim [gets $f]] if {[string length $line] > 0 && ![string match \#* $line]} { catch { set NickColors([lindex $line 0]) [lindex $line 1] } } } close $f } } # Called at shutdown to save the current set of nick-colors to file. proc nickcolors::save_nick_colors {} { variable NickColors set filename [file join $::configdir nickcolors.tcl] set f [open $filename w] fconfigure $f -encoding utf-8 puts $f "# This is an automatically generated file. Do not edit." foreach {nick clr} [array get NickColors] { puts $f [list $nick $clr] } close $f } proc nickcolors::get_color {nick} { variable NickColors variable NickColorPool if {[info exists NickColors($nick)]} { return $NickColors($nick) } else { set index [expr {[crc::sum -- $nick] % [llength $NickColorPool]}] return [lindex $NickColorPool $index] } } proc nickcolors::set_color {chatid nick color} { variable options if {[catch {set w [chat::chat_win $chatid]}] || \ ![winfo exists $w]} { return } if {$options(use_colored_nicks)} { $w tag configure NICK-$nick -foreground $color $w tag configure NICKMSG-$nick -foreground $color } if {$options(use_colored_messages)} { $w tag configure MSG-$nick -foreground $color $w tag lower MSG-$nick } } # Called upon opening a new chat window. This added all the currently defined # nick-colors as tags into the text widget. # proc nickcolors::chat_add_nick_colors {chatid type} { variable NicksInChat debugmsg chat "on_open_chat $chatid $type" set NicksInChat($chatid) {} } proc nickcolors::chat_delete_nick_colors {chatid} { variable NicksInChat debugmsg chat "on_close_chat $chatid" catch {unset NicksInChat($chatid)} } # draw_message hook used to check that the nick exists as a color and tag. proc nickcolors::check_nick {chatid from type body x} { variable NicksInChat set connid [chat::get_connid $chatid] set nick [chat::get_nick $connid $from $type] if {[lsearch -exact $NicksInChat($chatid) $nick] < 0} { lappend NicksInChat($chatid) $nick set_color $chatid $nick [get_color $nick] } } proc nickcolors::edit_nick_colors {} { variable NickColors variable NickColorEdits array set NickColorEdits [array get NickColors] set w .edit_nicks Dialog $w -title [::msgcat::mc "Edit chat user colors"] \ -modal none -separator 1 -anchor e \ -default 0 -cancel 1 $w add -text [::msgcat::mc "OK"] \ -command [list [namespace current]::end_dialog $w ok] $w add -text [::msgcat::mc "Cancel"] \ -command [list [namespace current]::end_dialog $w cancel] bind $w [list [namespace current]::end_dialog $w cancel] set f [$w getframe] set tools [frame $f.tools] pack $tools -side bottom -fill x set sw [ScrolledWindow $w.sw] set lf [text $w.nicks -width 32 -height 14 -cursor left_ptr] pack $sw -side top -expand yes -fill both -in $f -pady 1m -padx 1m $sw setwidget $lf foreach nick [lsort -dictionary [array names NickColors]] { set clr $NickColors($nick) $lf tag configure NICK-$nick -foreground $clr $lf tag bind NICK-$nick \ [list [namespace current]::on_nick_hover $lf $nick Enter] $lf tag bind NICK-$nick \ [list [namespace current]::on_nick_hover $lf $nick Leave] $lf tag bind NICK-$nick \ [list [namespace current]::on_nick_click $lf $nick] $lf insert end $nick [list NICK-$nick] $lf insert end "\n" } $lf configure -state disabled $w draw } proc nickcolors::end_dialog {w res} { variable options variable NickColors variable NickColorEdits bind $w { } destroy $w if {$res == "ok"} { array set NickColors [array get NickColorEdits] change_options } catch {unset NickColorEdits} } proc nickcolors::on_nick_hover {w nick event} { if {$event == "Enter"} { $w tag configure NICK-$nick -underline 1 $w configure -cursor hand2 } else { $w tag configure NICK-$nick -underline 0 $w configure -cursor left_ptr } } proc nickcolors::on_nick_click {w nick} { variable NickColorEdits if {[info exists NickColorEdits($nick)]} { set clr $NickColorEdits($nick) } else { set clr black } set new [tk_chooseColor -initialcolor $clr -parent $w \ -title [format [::msgcat::mc "Edit %s color"] $nick]] if {$new != ""} { $w tag configure NICK-$nick -foreground $new set NickColorEdits($nick) $new } } proc nickcolors::change_options {args} { variable options variable NicksInChat foreach chatid [chat::opened] { set wn [chat::chat_win $chatid] if {[winfo exists $wn]} { if {[chat::is_groupchat $chatid]} { chat::redraw_roster_after_idle $chatid } foreach nick $NicksInChat($chatid) { set clr [get_color $nick] $wn tag configure NICK-$nick \ -foreground [expr {$options(use_colored_nicks) ? $clr : ""}] $wn tag configure NICKMSG-$nick \ -foreground [expr {$options(use_colored_nicks) ? $clr : ""}] $wn tag configure MSG-$nick \ -foreground [expr {$options(use_colored_messages) ? $clr : ""}] } } } } proc nickcolors::add_chat_win_popup_menu {m chatwin X Y x y} { variable options set tags [$chatwin tag names "@$x,$y"] set nick "" if {$options(use_colored_messages)} { if {[set idx [lsearch -glob $tags MSG-*]] >= 0} { set nick [string range [lindex $tags $idx] 4 end] } } if {$options(use_colored_nicks)} { if {[set idx [lsearch -glob $tags NICK-*]] >= 0} { set nick [string range [lindex $tags $idx] 5 end] } if {[set idx [lsearch -glob $tags NICKMSG-*]] >= 0} { set nick [string range [lindex $tags $idx] 5 end] } } if {$nick == ""} return $m add command -label [::msgcat::mc "Edit nick color..."] \ -command [list [namespace current]::edit_nick_color $chatwin $nick] } proc nickcolors::add_groupchat_user_menu_items {m connid jid} { variable options if {$options(use_colored_roster_nicks)} { set chatid [chat::chatid $connid [node_and_server_from_jid $jid]] set chatwin [chat::chat_win $chatid] set nick [chat::get_nick $connid $jid groupchat] $m add command -label [::msgcat::mc "Edit nick color..."] \ -command [list [namespace current]::edit_nick_color $chatwin $nick] } } proc nickcolors::edit_nick_color {chatwin nick} { variable NickColors set new [tk_chooseColor -initialcolor [get_color $nick] -parent $chatwin \ -title [format [::msgcat::mc "Edit %s color"] $nick]] if {$new == ""} return if {$new != [get_color $nick]} { set NickColors($nick) $new change_options } } tkabber-0.11.1/plugins/chat/postpone.tcl0000644000175000017500000000353610566127440017511 0ustar sergeisergei# The "Postpone text" plugin for Tkabber. # # Provides a private hidden text buffer for each chat input window # and a binding to operate with it. # The idea is to provide for quick moving of the text typed into the chat # input window to that buffer, and then moving it back to the input window # with and . # This is helpful when the user types in some elaborate text and realizes she # wants to quickly post another text to the same chat and then continue with # editing. # # Written by Konstantin Khomoutov # Modified by Sergei Golovan # # $Id: postpone.tcl 953 2007-02-18 19:55:12Z sergei $ namespace eval postpone { variable state event add <> event add <> ::hook::add open_chat_post_hook [namespace current]::setup_bindings } proc postpone::setup_bindings {chatid type} { variable state set w [::chat::input_win $chatid] set state($w,buffer) [list] bind $w +[list [namespace current]::cleanup_text_widget $w %W] bind $w <> [list [namespace current]::buffer_push $w] bind $w <> +break bind $w <> [list [namespace current]::buffer_pop $w] bind $w <> +break } proc postpone::cleanup_text_widget {w1 w2} { variable state if {$w1 != $w2} return array unset state $w1,* } proc postpone::buffer_push {w} { variable state if {[$w compare 1.0 == {end - 1 char}]} return ;# empty lappend state($w,buffer) [$w get 1.0 {end - 1 char}] ;# don't get last newline $w delete 1.0 end } proc postpone::buffer_pop {w} { variable state if {[llength $state($w,buffer)] == 0} return set text [lindex $state($w,buffer) end] set state($w,buffer) [lrange $state($w,buffer) 0 end-1] $w insert insert $text } tkabber-0.11.1/plugins/chat/log_on_open.tcl0000644000175000017500000000421010562424423020123 0ustar sergeisergei# $Id: log_on_open.tcl 903 2007-02-07 19:31:31Z sergei $ namespace eval log_on_open { custom::defvar options(max_messages) 20 \ [::msgcat::mc "Maximum number of log messages to show in newly\ opened chat window (if set to negative then the\ number is unlimited)."] \ -type integer -group Chat custom::defvar options(max_interval) 24 \ [::msgcat::mc "Maximum interval length in hours for which log\ messages should be shown in newly opened chat\ window (if set to negative then the interval is\ unlimited)."] \ -type integer -group Chat } proc log_on_open::show {chatid type} { variable options if {$type != "chat"} return set connid [chat::get_connid $chatid] set jid [chat::get_jid $chatid] set bare_jid [node_and_server_from_jid $jid] set gc [chat::is_groupchat [chat::chatid $connid $bare_jid]] if {!$gc} { set log_jid $bare_jid } else { set log_jid $jid } set messages [::logger::get_last_messages $log_jid $options(max_messages) \ $options(max_interval)] foreach msg $messages { array unset tmp if {[catch {array set tmp $msg}]} continue set x {} if {[info exists tmp(timestamp)]} { set seconds [clock scan $tmp(timestamp) -gmt 1] set date [clock format $seconds -format "%Y%m%dT%H:%M:%S" -gmt 1] lappend x [jlib::wrapper:createtag x \ -vars [list xmlns "jabber:x:delay" \ stamp $date]] } if {[info exists tmp(jid)]} { if {$tmp(jid) == ""} { # Synthesized message set from "" } elseif {(!$gc && [node_and_server_from_jid $tmp(jid)] != $bare_jid) || \ $gc && $tmp(jid) != $jid} { set from [jlib::connection_jid $connid] } else { set from $jid } } else { set from "" } # Don't log this message. Request this by creating very special 'empty' # tag which can't be received from the peer. # TODO: Create more elegant mechanism lappend x [jlib::wrapper:createtag "" \ -vars [list xmlns "tkabber:x:nolog"]] chat::add_message $chatid $from $type $tmp(body) $x } } hook::add open_chat_post_hook [namespace current]::log_on_open::show 100 # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/plugins/chat/draw_error.tcl0000644000175000017500000000047710556440255020012 0ustar sergeisergei# $Id: draw_error.tcl 882 2007-01-26 17:55:57Z sergei $ proc handle_error {chatid from type body x} { if {[cequal $type error]} { set chatw [chat::chat_win $chatid] $chatw insert end $body err set cw [chat::winid $chatid] return stop } } hook::add draw_message_hook [namespace current]::handle_error 10 tkabber-0.11.1/plugins/chat/bookmark_highlighted.tcl0000644000175000017500000001235010525164146022000 0ustar sergeisergei# $Id: bookmark_highlighted.tcl 789 2006-11-10 21:00:22Z sergei $ namespace eval bookmark { hook::add postload_hook [namespace current]::init hook::add open_chat_post_hook [namespace current]::on_open_chat hook::add close_chat_post_hook [namespace current]::on_close_chat hook::add chat_win_popup_menu_hook [namespace current]::popup_menu hook::add draw_message_hook [namespace current]::add_bookmark 80 } proc bookmark::init {} { global usetabbar if {$usetabbar} { bind . [list [namespace current]::next_bookmark .] bind . [list [namespace current]::prev_bookmark .] } } proc bookmark::on_open_chat {chatid type} { global usetabbar if {!$usetabbar} { set cw [chat::chat_win $chatid] set top [winfo toplevel $cw] bind $top [list [namespace current]::next_bookmark $cw] bind $top [list [namespace current]::prev_bookmark $cw] } } proc bookmark::on_close_chat {chatid} { variable bookmark set cw [chat::chat_win $chatid] catch { array unset bookmark $cw,* } } proc bookmark::popup_menu {m W X Y x y} { set groupchat 0 foreach chatid [chat::opened] { if {[chat::chat_win $chatid] == $W} { set groupchat [expr {[chat::is_groupchat $chatid]}] break } } if {!$groupchat} return $m add command -label [::msgcat::mc "Prev highlighted"] -accelerator F3 \ -command [list [namespace current]::prev_bookmark $W] $m add command -label [::msgcat::mc "Next highlighted"] -accelerator Shift-F3 \ -command [list [namespace current]::next_bookmark $W] } proc bookmark::get_chatwin {} { global usetabbar if {!$usetabbar} { return "" } set cw "" foreach chatid [chat::opened] { if {[.nb raise] == [ifacetk::nbpage [chat::winid $chatid]]} { set cw [chat::chat_win $chatid] break } } return $cw } proc bookmark::add_bookmark {chatid from type body x} { variable bookmark if {$type != "groupchat"} return set cw [chat::chat_win $chatid] set connid [chat::get_connid $chatid] set jid [chat::get_jid $chatid] set myjid [chat::our_jid $chatid] set mynick [chat::get_nick $connid $myjid $type] if {[cequal $jid $from] || [cequal $myjid $from] || \ ![check_message $mynick $body]} { return } if {![info exists bookmark($cw,id)]} { set bookmark($cw,id) 0 } set b [incr bookmark($cw,id)] $cw mark set hbookmark$b "end - 1 char" $cw mark gravity hbookmark$b left } proc bookmark::next_bookmark {cw} { variable bookmark if {$cw == "."} { set cw [get_chatwin] if {$cw == ""} return } set groupchat 0 foreach chatid [chat::opened] { if {[chat::chat_win $chatid] == $cw} { set groupchat [expr {[chat::is_groupchat $chatid]}] break } } if {!$groupchat} return if {![info exists bookmark($cw,last)] || \ [catch {$cw index $bookmark($cw,last)}]} { set bookmark($cw,last) 0.0 } set idx [$cw index $bookmark($cw,last)] if {$bookmark($cw,last) == "end" || \ (([lindex [$cw yview] 0] == 0 || [lindex [$cw yview] 1] == 1) && \ ([$cw dlineinfo $idx] == {} || \ [lsearch -exact [$cw tag names $idx] sel] < 0))} { set bookmark($cw,last) 0.0 } if {$bookmark($cw,last) == "0.0"} { set first_round 0 } else { set first_round 1 } while {($bookmark($cw,last) != {}) || $first_round} { if {$bookmark($cw,last) == {}} { set bookmark($cw,last) 0.0 set first_round 0 } set bookmark($cw,last) [$cw mark next $bookmark($cw,last)] if {[string match "hbookmark*" $bookmark($cw,last)]} { break } } if {$bookmark($cw,last) == {}} { set bookmark($cw,last) 0.0 } else { $cw tag remove sel 0.0 end $cw tag add sel \ "$bookmark($cw,last) linestart" \ "$bookmark($cw,last) lineend" $cw see $bookmark($cw,last) } return $bookmark($cw,last) } proc bookmark::prev_bookmark {cw} { variable bookmark if {$cw == "."} { set cw [get_chatwin] if {$cw == ""} return } set groupchat 0 foreach chatid [chat::opened] { if {[chat::chat_win $chatid] == $cw} { set groupchat [expr {[chat::is_groupchat $chatid]}] break } } if {!$groupchat} return if {![info exists bookmark($cw,last)] || \ [catch {$cw index $bookmark($cw,last)}]} { set bookmark($cw,last) end } set idx [$cw index $bookmark($cw,last)] if {$bookmark($cw,last) == "0.0" || \ ([lindex [$cw yview] 1] == 1 && \ ([$cw dlineinfo $idx] == {} || \ [lsearch -exact [$cw tag names $idx] sel] < 0))} { set bookmark($cw,last) end } if {$bookmark($cw,last) == "end"} { set first_round 0 } else { set first_round 1 } while {($bookmark($cw,last) != {}) || $first_round} { if {$bookmark($cw,last) == {}} { set bookmark($cw,last) end set first_round 0 } set bookmark($cw,last) [$cw mark previous $bookmark($cw,last)] if {[string match "hbookmark*" $bookmark($cw,last)]} { break } } if {($bookmark($cw,last) == {})} { set bookmark($cw,last) end } else { $cw tag remove sel 0.0 end $cw tag add sel \ "$bookmark($cw,last) linestart" \ "$bookmark($cw,last) lineend" $cw see $bookmark($cw,last) } return $bookmark($cw,last) } tkabber-0.11.1/plugins/chat/info_commands.tcl0000644000175000017500000002524110566637612020462 0ustar sergeisergei# $Id: info_commands.tcl 954 2007-02-20 18:35:54Z sergei $ # # Plugin implements commands /time, /last, /vcard, /version in chat # and groupchat windows. # ############################################################################## namespace eval chatinfo { custom::defgroup VCard \ [::msgcat::mc "vCard display options in chat windows."] \ -group Chat set vcard_defs [list fn [::msgcat::mc "Full Name"] 1 \ family [::msgcat::mc "Family Name"] 1 \ name [::msgcat::mc "Name"] 1 \ middle [::msgcat::mc "Middle Name"] 0 \ prefix [::msgcat::mc "Prefix"] 0 \ suffix [::msgcat::mc "Suffix"] 0 \ nickname [::msgcat::mc "Nickname"] 1 \ email [::msgcat::mc "E-mail"] 1 \ url [::msgcat::mc "Web Site"] 1 \ jabberid [::msgcat::mc "JID"] 1 \ uid [::msgcat::mc "UID"] 1 \ tel_home [::msgcat::mc "Phone Home"] 1 \ tel_work [::msgcat::mc "Phone Work"] 1 \ tel_voice [::msgcat::mc "Phone Voice"] 1 \ tel_fax [::msgcat::mc "Phone Fax"] 0 \ tel_pager [::msgcat::mc "Phone Pager"] 0 \ tel_msg [::msgcat::mc "Phone Message Recorder"] 0 \ tel_cell [::msgcat::mc "Phone Cell"] 1 \ tel_video [::msgcat::mc "Phone Video"] 0 \ tel_bbs [::msgcat::mc "Phone BBS"] 0 \ tel_modem [::msgcat::mc "Phone Modem"] 0 \ tel_isdn [::msgcat::mc "Phone ISDN"] 0 \ tel_pcs [::msgcat::mc "Phone PCS"] 0 \ tel_pref [::msgcat::mc "Phone Preferred"] 1 \ address [::msgcat::mc "Address"] 1 \ address2 [::msgcat::mc "Address 2"] 0 \ city [::msgcat::mc "City"] 1 \ state [string trim [::msgcat::mc "State "]] 1 \ pcode [::msgcat::mc "Postal Code"] 0 \ country [::msgcat::mc "Country"] 1 \ geo_lat [::msgcat::mc "Latitude"] 0 \ geo_lon [::msgcat::mc "Longitude"] 0 \ orgname [::msgcat::mc "Organization Name"] 1 \ orgunit [::msgcat::mc "Organization Unit"] 1 \ title [::msgcat::mc "Title"] 1 \ role [::msgcat::mc "Role"] 1 \ bday [::msgcat::mc "Birthday"] 1 \ desc [string trim [::msgcat::mc "About "]] 0] foreach {opt name default} $vcard_defs { custom::defvar options($opt) $default \ [::msgcat::mc "Display %s in chat window when using /vcard command." \ $name] \ -type boolean -group VCard } } ############################################################################## proc chatinfo::handle_info_commands {chatid user body type} { if {[string equal -length 6 $body "/time "] || [cequal $body "/time"]} { set name [crange $body 6 end] set command time } elseif {[string equal -length 6 $body "/last "] || [cequal $body "/last"]} { set name [crange $body 6 end] set command last } elseif {[string equal -length 7 $body "/vcard "] || [cequal $body "/vcard"]} { set name [crange $body 7 end] set command vcard } elseif {[string equal -length 9 $body "/version "] || [cequal $body "/version"]} { set name [crange $body 9 end] set command version } else { return } set connid [chat::get_connid $chatid] set jid [chat::get_jid $chatid] set jids {} set vcard_jids {} if {[cequal $type groupchat]} { if {[cequal $name ""]} { set jids [list $jid] } else { set jids [list "$jid/$name"] } set vcard_jids $jids } else { if {[cequal $name ""]} { set bare_jid [node_and_server_from_jid $jid] set full_jids [::get_jids_of_user $connid $bare_jid] if {[lsearch $full_jids $jid] >= 0} { set jids [list $jid] } elseif {[lempty $full_jids]} { set jids [list $jid] } else { set jids $full_jids } set vcard_jids [list $bare_jid] } } if {[cequal $jids {}]} { lassign [roster_lookup $connid $name] jids vcard_jids if {[cequal $jids {}]} { set jids [list $name] } } if {[cequal $vcard_jids {}]} { set vcard_jids $jids } if {[cequal $command vcard]} { foreach jid $vcard_jids { request_vcard $connid $chatid $jid } } else { foreach jid $jids { request_iq $command $connid $chatid $jid } } return stop } hook::add chat_send_message_hook \ [namespace current]::chatinfo::handle_info_commands 15 ############################################################################## proc chatinfo::roster_lookup {connid name} { set ret {} set ret1 {} foreach jid [roster::get_jids $connid] { set rname [roster::get_label $connid $jid] if {[cequal $rname $name]} { set bare_jid [node_and_server_from_jid $jid] set full_jids [::get_jids_of_user $connid $bare_jid] if {![cequal $full_jids {}]} { set ret [concat $ret $full_jids] } else { lappend ret $bare_jid } lappend ret1 $bare_jid } } return [list [lsort -unique $ret] [lsort -unique $ret1]] } ############################################################################## proc chatinfo::info_commands_comps {chatid compsvar wordstart line} { upvar 0 $compsvar comps set commands [list "/time " "/last " "/vcard " "/version "] if {!$wordstart} { set comps [concat $comps $commands] } elseif {![chat::is_groupchat $chatid]} { set q 0 foreach cmd $commands { if {[string equal -length [string length $cmd] $cmd $line]} { set q 1 break } } if {!$q} return set connid [chat::get_connid $chatid] set names {} foreach jid [roster::get_jids $connid] { lappend names "[roster::get_label $connid $jid] " } set comps [concat $comps [lsort -unique $names]] } } hook::add generate_completions_hook \ [namespace current]::chatinfo::info_commands_comps ############################################################################## proc chatinfo::request_iq {type connid chatid jid} { jlib::send_iq get \ [jlib::wrapper:createtag query \ -vars [list xmlns jabber:iq:$type]] \ -to $jid \ -connection $connid \ -command [list [namespace current]::parse_info_iq$type $chatid $jid] } ############################################################################## proc chatinfo::request_vcard {connid chatid jid} { jlib::send_iq get \ [jlib::wrapper:createtag vCard \ -vars [list xmlns vcard-temp]] \ -to $jid \ -connection $connid \ -command [list [namespace current]::parse_info_vcard $chatid $jid] } ############################################################################## proc chatinfo::whois {chatid jid} { set connid [chat::get_connid $chatid] set real_jid [muc::get_real_jid $connid $jid] if {$real_jid != ""} { return " ($real_jid)" } else { return "" } } ############################################################################## proc chatinfo::parse_info_iqtime {chatid jid res child} { if {![winfo exists [chat::chat_win $chatid]]} { return } set rjid [whois $chatid $jid] if {![cequal $res OK]} { chat::add_message $chatid $jid error \ [::msgcat::mc "time %s%s: %s" $jid $rjid [error_to_string $child]] {} return } jlib::wrapper:splitxml $child tag vars isempty chdata children if {[cequal [jlib::wrapper:getattr $vars xmlns] jabber:iq:time]} { userinfo::parse_iqtime_item $jid $children } set message [::msgcat::mc "time %s%s:" $jid $rjid] foreach {i j} [list time [::msgcat::mc "Time:"] \ tz [::msgcat::mc "Time Zone:"] \ utc [::msgcat::mc "UTC:"]] { if {[info exists userinfo::userinfo($i,$jid)] && \ ![cequal $userinfo::userinfo($i,$jid) ""] } { append message "\n $j $userinfo::userinfo($i,$jid)" } } chat::add_message $chatid $jid info $message {} } ############################################################################## proc chatinfo::parse_info_iqlast {chatid jid res child} { if {![winfo exists [chat::chat_win $chatid]]} { return } set rjid [whois $chatid $jid] if {![cequal $res OK]} { chat::add_message $chatid $jid error \ [::msgcat::mc "last %s%s: %s" $jid $rjid [error_to_string $child]] {} return } jlib::wrapper:splitxml $child tag vars isempty chdata children if {[cequal [jlib::wrapper:getattr $vars xmlns] jabber:iq:last]} { set ::userinfo::userinfo(lastseconds,$jid) \ [format_time [jlib::wrapper:getattr $vars seconds]] set ::userinfo::userinfo(lastdesc,$jid) $chdata } set message [::msgcat::mc "last %s%s:" $jid $rjid] foreach {i j} [list lastseconds [::msgcat::mc "Interval:"] \ lastdesc [::msgcat::mc "Description:"]] { if {[info exists userinfo::userinfo($i,$jid)] && \ ![cequal $userinfo::userinfo($i,$jid) ""]} { append message "\n $j $userinfo::userinfo($i,$jid)" } } chat::add_message $chatid $jid info $message {} } ############################################################################## proc chatinfo::parse_info_iqversion {chatid jid res child} { if {![winfo exists [chat::chat_win $chatid]]} { return } set rjid [whois $chatid $jid] if {![cequal $res OK]} { chat::add_message $chatid $jid error \ [::msgcat::mc "version %s%s: %s" $jid $rjid [error_to_string $child]] {} return } jlib::wrapper:splitxml $child tag vars isempty chdata children if {[cequal [jlib::wrapper:getattr $vars xmlns] jabber:iq:version]} { userinfo::parse_iqversion_item $jid $children } set message [::msgcat::mc "version %s%s:" $jid $rjid] foreach {i j} [list clientname [::msgcat::mc "Client:"] \ clientversion [::msgcat::mc "Version:"] \ os [::msgcat::mc "OS:"]] { if {[info exists userinfo::userinfo($i,$jid)] && \ ![cequal $userinfo::userinfo($i,$jid) ""]} { append message "\n $j $userinfo::userinfo($i,$jid)" } } chat::add_message $chatid $jid info $message {} } ############################################################################## proc chatinfo::parse_info_vcard {chatid jid res child} { variable options variable vcard_defs if {![winfo exists [chat::chat_win $chatid]]} { return } set rjid [whois $chatid $jid] if {![cequal $res OK]} { chat::add_message $chatid $jid error \ [::msgcat::mc "vcard %s%s: %s" $jid $rjid [error_to_string $child]] {} return } jlib::wrapper:splitxml $child tag vars isempty chdata children foreach item $children { userinfo::parse_vcard_item $jid $item } set message [::msgcat::mc "vcard %s%s:" $jid $rjid] foreach {def name ignore} $vcard_defs) { if {$options($def) && \ [info exists userinfo::userinfo($def,$jid)] && \ ![cequal $userinfo::userinfo($def,$jid) ""]} { append message "\n $name: $userinfo::userinfo($def,$jid)" } } chat::add_message $chatid $jid info $message {} } ############################################################################## tkabber-0.11.1/plugins/chat/exec_command.tcl0000644000175000017500000000134110011503704020236 0ustar sergeisergei# $Id: exec_command.tcl 525 2004-02-08 19:02:28Z aleksey $ proc handle_exec_command {chatid user body type} { if {[string equal -length 6 $body "/exec "]} { set iw [chat::input_win $chatid] set command [crange $body 6 end] set res [catch {set output [eval exec $command]} errMsg] if {$res} { set msg $errMsg } else { set msg $output } after idle [list $iw insert end "\$ $command\n" {} $msg] return stop } } hook::add chat_send_message_hook [namespace current]::handle_exec_command 15 proc exec_command_comps {chatid compsvar wordstart line} { upvar 0 $compsvar comps if {!$wordstart} { lappend comps {/exec } } } hook::add generate_completions_hook [namespace current]::exec_command_comps tkabber-0.11.1/plugins/chat/clear.tcl0000644000175000017500000000224610364052020016710 0ustar sergeisergei# $Id: clear.tcl 663 2006-01-20 03:08:00Z aleksey $ namespace eval clear {} proc clear::clear_chat_win {chatid} { set chatw [chat::chat_win $chatid] $chatw configure -state normal $chatw delete 0.0 end $chatw configure -state disabled } proc clear::handle_clear_command {chatid user body type} { set body [string trim $body] if {![cequal $body "/clear"]} { return } clear_chat_win $chatid return stop } hook::add chat_send_message_hook \ [namespace current]::clear::handle_clear_command 50 proc clear::clear_command_comp {chatid compsvar wordstart line} { upvar 0 $compsvar comps if {!$wordstart} { lappend comps {/clear } } } hook::add generate_completions_hook \ [namespace current]::clear::clear_command_comp proc clear::add_chat_menu_item {m connid jid} { set chatid [chat::chatid $connid $jid] $m add command -label [::msgcat::mc "Clear chat window"] \ -command [list [namespace current]::clear_chat_win $chatid] } hook::add chat_create_conference_menu_hook \ [namespace current]::clear::add_chat_menu_item 41 hook::add chat_create_user_menu_hook \ [namespace current]::clear::add_chat_menu_item 41 tkabber-0.11.1/plugins/chat/unisymbols.tcl0000644000175000017500000000115307603657460020047 0ustar sergeisergei# $Id: unisymbols.tcl 261 2002-12-29 20:46:40Z alexey $ namespace eval unisymbols {} proc unisymbols::expand_entity {iw} { set s [$iw get "insert linestart" insert] if {[regexp {.*&(.*)} $s temp e]} { if {$e != "" && [string is xdigit $e]} { $iw delete "insert -[string length $e] char -1c" insert $iw insert insert [format %c 0x$e] } } } proc unisymbols::setup_bindings {chatid type} { set iw [chat::input_win $chatid] bind $iw \ [list [namespace current]::expand_entity $iw] } hook::add open_chat_post_hook [namespace current]::unisymbols::setup_bindings tkabber-0.11.1/plugins/chat/history.tcl0000644000175000017500000000317307770377274017357 0ustar sergeisergei# $Id: history.tcl 494 2003-12-18 19:23:40Z aleksey $ proc history_move {chatid shift} { variable history set newpos [expr $history(pos,$chatid) + $shift] if {$newpos < 0} { set newpos 0 } set len [expr [llength $history(stack,$chatid)] - 1] if {$newpos > $len} { set newpos $len } set iw [chat::winid $chatid].input set body [$iw get 1.0 "end -1 chars"] if {$history(pos,$chatid) == 0} { set history(stack,$chatid) \ [lreplace $history(stack,$chatid) 0 0 $body] } set history(pos,$chatid) $newpos set newbody [lindex $history(stack,$chatid) $newpos] $iw delete 1.0 end after idle [list $iw insert end $newbody] } #debugmsg plugins "HISTORY: [namespace which history_move]" #namespace export history_move proc add_body_to_history {chatid user body type} { variable history lvarpush history(stack,$chatid) $body 1 set history(pos,$chatid) 0 } hook::add chat_send_message_hook [namespace current]::add_body_to_history 12 proc setup_history_bindings {chatid type} { variable history set cw [chat::winid $chatid] bind $cw.input \ [list [namespace current]::history_move [double% $chatid] 1] bind $cw.input \ [list [namespace current]::history_move [double% $chatid] 1] bind $cw.input \ [list [namespace current]::history_move [double% $chatid] -1] bind $cw.input \ [list [namespace current]::history_move [double% $chatid] -1] set history(stack,$chatid) [list {}] set history(pos,$chatid) 0 } hook::add open_chat_post_hook [namespace current]::setup_history_bindings tkabber-0.11.1/plugins/chat/open_window.tcl0000644000175000017500000000046110316351101020146 0ustar sergeisergei# $Id: open_window.tcl 652 2005-09-27 23:14:09Z aleksey $ proc chat_open_window {chatid from type body x} { chat::open_window $chatid $type -cleanroster 0 set chatw [chat::chat_win $chatid] $chatw configure -state normal } hook::add draw_message_hook [namespace current]::chat_open_window 5 tkabber-0.11.1/plugins/chat/chatstate.tcl0000644000175000017500000001356511011777242017622 0ustar sergeisergei# $Id: chatstate.tcl 1416 2008-05-12 08:24:02Z sergei $ # # Chat State Notifications (XEP-0085) (only and ) support. # namespace eval chatstate { custom::defgroup Chatstate \ [::msgcat::mc "Chat message window state plugin options."] \ -group Chat custom::defvar options(enable) 0 \ [::msgcat::mc "Enable sending chat state notifications."] \ -type boolean -group Chatstate disco::register_feature $::NS(chatstate) } # Workaround a bug in JIT, which responds with error to chatstate # events without a body proc chatstate::ignore_error \ {connid from id type is_subject subject body err thread priority x} { switch -- $type/$id { error/chatstate { return stop } } } hook::add process_message_hook [namespace current]::chatstate::ignore_error 20 proc chatstate::flush_composing {chatid user body type} { variable chatstate set chatstate(composing,$chatid) 1 } hook::add chat_send_message_hook \ [list [namespace current]::chatstate::flush_composing] 91 proc chatstate::process_x {chatid from type body xs} { if {$type == "chat"} { foreach x $xs { jlib::wrapper:splitxml $x tag vars isempty chdata children set xmlns [jlib::wrapper:getattr $vars xmlns] switch -- $xmlns \ $::NS(chatstate) { return [process_x_chatstate \ $chatid $from $type $body $x] } } } } hook::add draw_message_hook \ [list [namespace current]::chatstate::process_x] 1 proc chatstate::process_x_chatstate {chatid from type body x} { variable options variable chatstate jlib::wrapper:splitxml $x tag vars isempty chdata children switch -- $tag { active { if {![info exists chatstate(active,$chatid)] || \ !$chatstate(active,$chatid)} { set chatstate(active,$chatid) 1 change_status $chatid active } } inactive { if {[info exists chatstate(active,$chatid)] && \ $chatstate(active,$chatid)} { set chatstate(active,$chatid) 0 change_status $chatid inactive } } gone { set chatstate(active,$chatid) 0 change_status $chatid gone } composing - paused { change_status $chatid $tag } } return } proc chatstate::change_status {chatid status} { variable event_afterid if {[info exists event_afterid($chatid)]} { after cancel $event_afterid($chatid) } set cw [chat::winid $chatid] set jid [chat::get_jid $chatid] set text "" set stext "" switch -- $status { active { set text [::msgcat::mc "Chat window is active"] set stext [format [::msgcat::mc "%s has activated chat window"] $jid] } composing { set text [::msgcat::mc "Composing a reply"] set stext [format [::msgcat::mc "%s is composing a reply"] $jid] } paused { set text [::msgcat::mc "Paused a reply"] set stext [format [::msgcat::mc "%s is paused a reply"] $jid] } inactive { set text [::msgcat::mc "Chat window is inactive"] set stext [format [::msgcat::mc "%s has inactivated chat window"] $jid] } gone { set text [::msgcat::mc "Chat window is gone"] set stext [format [::msgcat::mc "%s has gone chat window"] $jid] } } if {$stext != "" && $::usetabbar} {set_status $stext} if {![winfo exists $cw]} return $cw.status.event configure -text $text set event_afterid($chatid) \ [after 10000 [list [namespace current]::clear_status $chatid]] } proc chatstate::clear_status {chatid} { set cw [chat::winid $chatid] if {![winfo exists $cw]} return $cw.status.event configure -text "" } proc chatstate::event_composing {chatid sym} { variable options variable chatstate if {![chat::is_chat $chatid]} return if {$sym == ""} return if {[info exists chatstate(composing,$chatid)] && \ !$chatstate(composing,$chatid)} return if {!$options(enable)} return set connid [chat::get_connid $chatid] set jid [chat::get_jid $chatid] set chatstate(composing,$chatid) 0 if {[get_jid_status $connid $jid] == "unavailable"} return lappend xlist [jlib::wrapper:createtag composing \ -vars [list xmlns $::NS(chatstate)]] jlib::send_msg $jid -id chatstate -xlist $xlist -connection $connid } proc chatstate::setup_ui {chatid type} { variable chatstate if {![chat::is_chat $chatid]} return set cw [chat::winid $chatid] set l $cw.status.event if {![winfo exists $l]} { label $l pack $l -side left } set iw [chat::input_win $chatid] bind $iw +[list [namespace current]::event_composing \ [double% $chatid] %A] } hook::add open_chat_post_hook [namespace current]::chatstate::setup_ui proc chatstate::clear_status_on_send {chatid user body type} { if {![chat::is_chat $chatid]} return clear_status $chatid } hook::add chat_send_message_hook \ [namespace current]::chatstate::clear_status_on_send proc chatstate::make_xlist {varname chatid user body type} { variable options variable chatstate upvar 2 $varname var if {!$options(enable) || $type != "chat"} { return } set chatstate(windowactive,$chatid) 1 lappend var [jlib::wrapper:createtag active \ -vars [list xmlns $::NS(chatstate)]] return } hook::add chat_send_message_xlist_hook \ [namespace current]::chatstate::make_xlist proc chatstate::send_gone {chatid} { variable options variable chatstate if {![info exists chatstate(windowactive,$chatid)] || \ ($chatstate(windowactive,$chatid) == 0)} return if {![chat::is_chat $chatid]} return if {!$options(enable)} return set connid [chat::get_connid $chatid] set jid [chat::get_jid $chatid] unset chatstate(windowactive,$chatid) if {[get_jid_status $connid $jid] == "unavailable"} return lappend xlist [jlib::wrapper:createtag gone \ -vars [list xmlns $::NS(chatstate)]] jlib::send_msg $jid -id chatstate -xlist $xlist -connection $connid } hook::add close_chat_post_hook \ [namespace current]::chatstate::send_gone 10 tkabber-0.11.1/plugins/chat/insert_nick.tcl0000644000175000017500000000171010366753724020152 0ustar sergeisergei# $Id: insert_nick.tcl 666 2006-01-28 20:45:08Z aleksey $ namespace eval insert_nick {} proc insert_nick::insert {chatid nick} { set ci [chat::input_win $chatid] if {[$ci compare insert == "1.0"]} { $ci insert insert \ $plugins::completion::options(nlprefix)$nick$plugins::completion::options(nlsuffix) } else { $ci insert insert \ $plugins::completion::options(prefix)$nick$plugins::completion::options(suffix) } } hook::add groupchat_roster_user_singleclick_hook \ [namespace current]::insert_nick::insert proc insert_nick::insert_from_window {chatid w x y} { set nick "" set cw [chat::chat_win $chatid] set tags [$cw tag names "@$x,$y"] if {[set idx [lsearch -glob $tags NICK-*]] >= 0} { set nick [string range [lindex $tags $idx] 5 end] } if {$nick == ""} return insert $chatid $nick return stop } hook::add chat_window_click_hook \ [namespace current]::insert_nick::insert_from_window tkabber-0.11.1/plugins/chat/complete_last_nick.tcl0000644000175000017500000000372310525164146021476 0ustar sergeisergei# $Id: complete_last_nick.tcl 789 2006-11-10 21:00:22Z sergei $ namespace eval completion { custom::defvar options(completion_expire) 10 \ [::msgcat::mc "Number of groupchat messages to expire nick completion according to the last personally addressed message."] \ -type integer -group Chat } proc handle_last_nick {chatid from type body x} { global last_nick my_last_nick my_last_nick_counter if {$type != "groupchat"} return set connid [chat::get_connid $chatid] set nick [chat::get_nick $connid $from $type] set myjid [chat::our_jid $chatid] set mynick [chat::get_nick $connid $myjid $type] if {$nick != $mynick} { if {[check_message $mynick $body]} { set my_last_nick($chatid) $nick set my_last_nick_counter($chatid) 0 } else { set last_nick($chatid) $nick if {[info exists my_last_nick_counter($chatid)]} { incr my_last_nick_counter($chatid) } } } return } hook::add draw_message_hook [namespace current]::handle_last_nick 79 proc last_nick_comp {chatid compsvar wordstart line} { global last_nick my_last_nick my_last_nick_counter upvar 0 $compsvar comps if {$wordstart} return set prefix $plugins::completion::options(nlprefix) set suffix $plugins::completion::options(nlsuffix) if {[info exists last_nick($chatid)]} { set ln ${prefix}$last_nick($chatid)${suffix} set idx [lsearch -exact $comps $ln] #set comps [lreplace $comps $idx $idx] if {$idx > 0} { set comps [concat [list $ln] $comps] } } if {[info exists my_last_nick($chatid)] && \ (![info exists my_last_nick_counter($chatid)] || \ $my_last_nick_counter($chatid) < $::plugins::completion::options(completion_expire))} { set ln ${prefix}$my_last_nick($chatid)${suffix} set idx [lsearch -exact $comps $ln] #set comps [lreplace $comps $idx $idx] if {$idx > 0} { set comps [concat [list $ln] $comps] } } } hook::add generate_completions_hook \ [namespace current]::last_nick_comp 92 tkabber-0.11.1/plugins/chat/completion.tcl0000644000175000017500000002141110512772222017776 0ustar sergeisergei# $Id: completion.tcl 756 2006-10-10 19:29:22Z sergei $ namespace eval completion { set options(prefix) "" set options(suffix) " " set options(nlprefix) "" set options(nlsuffix) ": " } # Run all generate_completions hooks and return only those completion # that could be used to complete given word, provided that it was typed in given window # from the given position proc completion::get_matching_completions {chatid input_window word_pos word} { variable comps {} hook::run generate_completions_hook \ $chatid [namespace current]::comps \ [clength [$input_window get 1.0 $word_pos]] \ [$input_window get 1.0 "end -1c"] set len [clength $word] set matches {} foreach comp $comps { if {[string equal -nocase -length $len $word $comp]} { lappend matches $comp } } return $matches } proc completion::complete {chatid} { variable completion # completion(state,$chatid) holds state of completion for each chatid. # Possible states are: # normal -- we are not currently completing anything # menu_start -- # menu_next -- # completed -- # # completion(word,$chatid) holds current word being completed # (for the "menu-style" completion) # # completion(idx, variable options variable comps {} global grouproster # TODO: find out what is this state transition for ... if {![info exists completion(state,$chatid)] || \ [cequal $completion(state,$chatid) normal]} { set completion(state,$chatid) completed } set iw [chat::input_win $chatid] if {$completion(state,$chatid) == "menu_next" && \ [$iw compare insert == compins]} { set word $completion(word,$chatid) set matches [get_matching_completions $chatid $iw compstart $word] set n [llength $matches] if {!$n} {return} # TODO: what is this for? set completion(idx,$chatid) [expr ($completion(idx,$chatid)+1) % $n] set comp [lindex $matches $completion(idx,$chatid)] debugmsg plugins "COMPLETION deleting compstart compent for $comp" $iw delete compstart compend $iw insert compstart $comp return } elseif {$completion(state,$chatid) == "menu_next"} { set completion(state,$chatid) completed } set ins [lindex [split [$iw index insert] .] 1] set line [$iw get "insert linestart" "insert lineend"] set lbefore [crange $line 0 [expr $ins - 1]] #set lafter [crange $line $ins end] # Try to find out what part of the input we are going to complete. # If line is empty or consists of a single word, then complete that, # if there are several words, try to complete all of them, except for the case when first # word starts with a '/' - then it is a command name and must be excluded from completion if {[string first " " $lbefore] == -1} { # Trying to complete a single word set word $lbefore debugmsg plugins "COMPLETION SINGLEWORD: $word" } else { # Trying to complete multy-word phrase. # If there is no completion for current line, drop the first word # Repeat until there would be some completions or all words would be dropped if {[string equal -nocase -length 1 $lbefore "/"]} { # First word is a command and will be ignored by regexp later in the code set words $lbefore } else { # First word is not a command, we should add a bogus word to be ignored # by the regexp later in the code set words "foo $lbefore" } debugmsg plugins "COMPLETION MULTIWORD: $words" while {$words != ""} { if {[regexp {^\S+\s+(.*)$} $words temp word] == 0} { set word $words debugmsg plugins "MULTIWORD COMPLETION fallback to single word $word" break } set phrasestart [expr $ins - [clength $word]] set matches [get_matching_completions $chatid $iw "insert linestart +$phrasestart chars" $word] debugmsg plugins "COMPLETION for $word: $matches" if {[llength $matches] == 0} { # Drop first word. Since "$word" has all words from "$words" minus first, it is easy. set words $word } else { # we got some completions, lets apply them break } } } #set wordstart [expr $ins - [clength $word]] #set word [$iw get "insert -1 chars wordstart" insert] debugmsg plugins "COMPLETION: completing $word" set len [clength $word] if {1 || $word != ""} { set wordstart [expr $ins - [clength $word]] set matches [get_matching_completions $chatid $iw "insert linestart +$wordstart chars" $word] debugmsg plugins "COMPLETION: $matches" if {[llength [lrmdups $matches]] == 1 || \ $completion(state,$chatid) == "menu_start"} { set comp [lindex $matches 0] debugmsg plugins "COMPLETION deleting from $wordstart for $comp" $iw delete "insert linestart +$wordstart chars" insert $iw insert insert $comp if {$completion(state,$chatid) == "menu_start"} { set compstart $wordstart set compend [expr $compstart + [clength $comp]] $iw mark set compstart "insert linestart +$compstart chars" $iw mark gravity compstart left $iw mark set compend "insert linestart +$compend chars" $iw mark gravity compend right $iw mark set compins insert set completion(state,$chatid) menu_next set completion(word,$chatid) $word set completion(idx,$chatid) 0 } } elseif {[llength [lrmdups $matches]] > 1} { set app "" while {[set ch [same_char $matches $len]] != ""} { debugmsg plugins "COMPLETION APP: $len; $ch" append app $ch incr len } $iw insert insert $app set completion(state,$chatid) menu_start } } } proc completion::same_char {strings pos} { if {![llength $strings]} { return "" } set strs [lassign $strings str1] set ch [string index $str1 $pos] foreach str $strs { if {![string equal -nocase $ch [string index $str $pos]]} { return "" } } return $ch } proc completion::nick_comps {chatid compsvar wordstart line} { if {![chat::is_groupchat $chatid]} return set connid [chat::get_connid $chatid] variable options global grouproster upvar 0 $compsvar comps debugmsg plugins "COMPLETION N: $comps" if {!$wordstart} { set prefix $options(nlprefix) set suffix $options(nlsuffix) } else { set prefix $options(prefix) set suffix $options(suffix) } set nickcomps {} foreach jid $grouproster(users,$chatid) { lappend nickcomps $prefix[chat::get_nick $connid $jid groupchat]$suffix } set nickcomps [lsort -dictionary -unique $nickcomps] set comps [concat $nickcomps $comps] debugmsg plugins "COMPLETION N: $comps" } hook::add generate_completions_hook \ [namespace current]::completion::nick_comps 90 proc completion::sort_comps {chatid compsvar wordstart line} { upvar 0 $compsvar comps set comps [lsort -dictionary -unique $comps] debugmsg plugins "COMPLETION S: $comps" } hook::add generate_completions_hook \ [namespace current]::completion::sort_comps 75 proc completion::delete_suffix {chatid} { variable completion variable options set iw [chat::input_win $chatid] if {![info exists completion(state,$chatid)]} return if {([cequal $completion(state,$chatid) menu_next] || \ [cequal $completion(state,$chatid) completed]) && \ [$iw compare insert == {end - 1 chars}]} { set ind [list insert - [string length $options(suffix)] chars] if {[cequal [$iw get $ind insert] $options(suffix)]} { debugmsg plugins "COMPLETION deleting suffix" $iw delete $ind insert } } set completion(state,$chatid) normal } proc completion::on_keypress {chatid} { set iw [chat::input_win $chatid] after idle \ [list [namespace current]::on_keypress1 $chatid [$iw index insert]] } proc completion::on_keypress1 {chatid idx} { variable completion set iw [chat::input_win $chatid] if {![winfo exists $iw]} return if {[$iw index insert] != $idx} { set completion(state,$chatid) normal } } proc completion::setup_bindings {chatid type} { variable history set iw [chat::input_win $chatid] set cc CompCtl$iw set bt [bindtags $iw] set bt [lreplace $bt -1 -1 $cc] bindtags $iw $bt debugmsg plugins "COMPLETION TAGS: $bt" bind $cc \ [list [namespace current]::complete [double% $chatid]] bind $cc +break bind $cc \ [list [namespace current]::delete_suffix [double% $chatid]] bind $cc \ [list [namespace current]::on_keypress [double% $chatid]] } hook::add open_chat_post_hook [namespace current]::completion::setup_bindings tkabber-0.11.1/plugins/chat/send_message.tcl0000644000175000017500000000266110503044060020260 0ustar sergeisergei# $Id: send_message.tcl 718 2006-09-16 18:53:36Z sergei $ proc send_message {chatid user body type} { global chat_msg_id if {![info exists chat_msg_id]} { set chat_msg_id 1 } else { incr chat_msg_id } set connid [chat::get_connid $chatid] set jid [chat::get_jid $chatid] set chatw [chat::chat_win $chatid] if {[hook::is_flag chat_send_message_hook send]} { set command [list message::send_msg $jid \ -id $chat_msg_id \ -connection $connid \ -type $type \ -body $body] if {[info exists ::chat::chats(thread,$chatid)]} { lappend command -thread $::chat::chats(thread,$chatid) } set xlist {} hook::run chat_send_message_xlist_hook xlist $chatid $user $body $type if {![lempty $xlist]} { lappend command -xlist $xlist } lassign [eval $command] status x if {$status == "error"} { return stop } set signP 0 set encryptP 0 foreach xe $x { jlib::wrapper:splitxml $xe tag vars isempty chdata children switch -- [jlib::wrapper:getattr $vars xmlns] \ $::NS(signed) { set signP 1 } \ $::NS(encrypted) { set encryptP 1 } } if {![cequal $type groupchat]} { if {$encryptP} { $chatw image create start_message -image gpg/encrypted } if {$signP} { $chatw image create start_message -image gpg/signed } } } hook::unset_flag chat_send_message_hook send } hook::add chat_send_message_hook [namespace current]::send_message 90 tkabber-0.11.1/plugins/chat/draw_normal_message.tcl0000644000175000017500000000215110556440255021644 0ustar sergeisergei# $Id: draw_normal_message.tcl 882 2007-01-26 17:55:57Z sergei $ proc draw_normal_message {chatid from type body x} { if {[chat::is_our_jid $chatid $from]} { set tag me } else { set tag they } set connid [chat::get_connid $chatid] set chatw [chat::chat_win $chatid] set nick [chat::get_nick $connid $from $type] set cw [chat::winid $chatid] $chatw insert end "<$nick>" [list $tag NICK-$nick] " " $chatw mark set MSGLEFT "end - 1 char" $chatw mark gravity MSGLEFT left if {[cequal $type groupchat]} { set myjid [chat::our_jid $chatid] set mynick [chat::get_nick $connid $myjid $type] ::richtext::property_add mynick $mynick ::richtext::render_message $chatw $body "" } else { ::richtext::render_message $chatw $body "" } $chatw tag add MSG-$nick MSGLEFT "end - 1 char" if {![catch {::plugins::mucignore::is_ignored $connid $from $type} ignore] && \ $ignore != ""} { $chatw tag add $ignore {MSGLEFT linestart} {end - 1 char} } return stop } hook::add draw_message_hook [namespace current]::draw_normal_message 87 # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/plugins/chat/draw_server_message.tcl0000644000175000017500000000100210756616160021656 0ustar sergeisergei# $Id: draw_server_message.tcl 1375 2008-02-19 18:14:08Z sergei $ proc handle_server_message {chatid from type body x} { set jid [chat::get_jid $chatid] if {([cequal $type groupchat] && [string equal $jid $from]) \ || ([cequal $type chat] && $from == "")} { set chatw [chat::chat_win $chatid] $chatw insert end --- server_lab " " ::richtext::render_message $chatw $body server return stop } } hook::add draw_message_hook [namespace current]::handle_server_message 20 # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/plugins/chat/draw_xhtml_message.tcl0000644000175000017500000002137310764241406021515 0ustar sergeisergei# $Id: draw_xhtml_message.tcl 1390 2008-03-07 13:28:38Z sergei $ namespace eval xhtml { set statevars { color lmargin1 lmargin2 weight slant size list_style list_counter } set urlid 0 custom::defvar options(enable) 0 \ [::msgcat::mc "Enable rendering of XHTML messages."] \ -type boolean -group Chat } proc xhtml::draw_xhtml_message {chatid from type plainbody x} { variable options if {!$options(enable)} return foreach xelem $x { jlib::wrapper:splitxml $xelem tag vars isempty chdata children if {[cequal [jlib::wrapper:getattr $vars xmlns] \ http://jabber.org/protocol/xhtml-im]} { set xhtml $children } } if {![info exists xhtml]} return foreach el $xhtml { jlib::wrapper:splitxml $el tag vars isempty chdata children if {$tag == "body"} { set body $el } } if {![info exists body]} return if {[chat::is_our_jid $chatid $from]} { set tag me } else { set tag they } set connid [chat::get_connid $chatid] set chatw [chat::chat_win $chatid] set nick [chat::get_nick $connid $from $type] set cw [chat::winid $chatid] if {[cequal $type groupchat]} { return # TODO $chatw insert end "<$nick>" $tag " " set myjid [chat::our_jid $chatid] set mynick [chat::get_nick $connid $myjid $type] if {[crange $body 0 [expr [clength $mynick] + 1]] == "${mynick}: "} { $chatw insert end $mynick me ::richtext::render_message [::chat::chat_win $chatid] \ [crange $body [clength $mynick] end] "" } else { ::richtext::render_message [::chat::chat_win $chatid] $body "" } } else { $chatw insert end "<$nick>" $tag " " init [::chat::chat_win $chatid] add_xhtml [::chat::chat_win $chatid] $body } return stop } hook::add draw_message_hook [namespace current]::xhtml::draw_xhtml_message 85 proc xhtml::init {cw} { variable state variable stack array unset stack array unset state set state(color) [$cw cget -foreground] set stack(color) {} set state(lmargin1) 0 set stack(lmargin1) {} set state(lmargin2) 0 set stack(lmargin2) {} set state(weight) 0 set stack(weight) {} set state(slant) 0 set stack(slant) {} # TODO: use default font size set state(size) 12 set stack(size) {} set state(list_style) ul set stack(list_style) {} set state(list_counter) 0 set stack(list_counter) {} set state(afterspace) 1 set state(lastnl) 2 } proc xhtml::add_xhtml {cw xhtml} { variable state jlib::wrapper:splitxml $xhtml name vars isempty chdata childrens set nextchdata [jlib::wrapper:get_subchdata $xhtml] push set tag "" set prefix "" set suffix "" set pre 0 parse_style [jlib::wrapper:getattr $vars style] switch -- $name { h1 - h2 - h3 - blockquote - p { set prefix [string repeat "\n" [expr {2 - $state(lastnl)}]] set suffix "\n\n" set state(afterspace) 1 } pre - li { set prefix [string repeat "\n" [expr {1 - $state(lastnl)}]] set suffix "\n" set state(afterspace) 1 } } switch -- $name { h1 { incr state(size) 6 set state(weight) 1 } h2 { incr state(size) 4 set state(weight) 1 } h3 { incr state(size) 2 set state(weight) 1 } p { } br { set prefix "\n" set state(afterspace) 1 } strong { set state(weight) 1 } em { set state(slant) [expr {!$state(slant)}] } a { set url [jlib::wrapper:getattr $vars href] lappend tag [get_url_tag $cw $url] } img { set imgsrc [jlib::wrapper:getattr $vars src] set imgalt [jlib::wrapper:getattr $vars alt] set nextchdata "\[$imgalt\]" lappend tag [get_url_tag $cw $imgsrc] } span {} blockquote { incr state(lmargin1) 32 incr state(lmargin2) 32 } q { #set nextchdata "\"[string trim $chdata]\"" #set childrens {} set prefix \" set suffix \" } pre { set nextchdata $chdata set childrens {} set pre 1 } li { ::richtext::render_message $cw $prefix "" -nonewline set prefix "" switch -- $state(list_style) { ul { set item_prefix "\u2022 " } ol { variable stack set item_prefix "[incr state(list_counter)]. " set stack(list_counter) \ [lreplace $stack(list_counter) 0 0 \ $state(list_counter)] } } ::richtext::render_message $cw $item_prefix \ [concat xhtml_symb [get_tags $cw]] -nonewline } ul { incr state(lmargin1) 32 incr state(lmargin2) 32 set state(list_style) ul } ol { incr state(lmargin1) 32 incr state(lmargin2) 32 set state(list_style) ol set state(list_counter) 0 } } # TODO set tag [concat $tag [get_tags $cw]] if {!$pre} { regsub -all {[[:space:]]+} $nextchdata " " formated } else { set formated [string trim $nextchdata "\n"] } if {$state(afterspace) && [string index $formated 0] == " "} { set formated [crange $formated 1 end] } if {$formated != ""} { set state(afterspace) [expr {[string index $formated end] == " "}] } ::richtext::render_message $cw $prefix $tag -nonewline ::richtext::render_message $cw $formated $tag -nonewline if {$formated != ""} { set state(lastnl) 0 } foreach xelem $childrens { add_xhtml $cw $xelem set nextchdata [jlib::wrapper:get_fchdata $xelem] regsub -all {[[:space:]]+} $nextchdata " " formated if {$state(afterspace) && [string index $formated 0] == " "} { set formated [crange $formated 1 end] } if {$formated != ""} { set state(afterspace) [expr {[string index $formated end] == " "}] } ::richtext::render_message $cw $formated $tag -nonewline if {$formated != ""} { set state(lastnl) 0 } } # messy set state(lastnl) 0 if {[$cw get "end - 2c"] == "\n"} { incr state(lastnl) set state(afterspace) 1 if {[$cw get "end - 3c"] == "\n"} { incr state(lastnl) } } if {$suffix == "\n\n"} { ::richtext::render_message $cw \ [string repeat "\n" [expr {2 - $state(lastnl)}]] "" -nonewline } elseif {$suffix == "\n"} { ::richtext::render_message $cw \ [string repeat "\n" [expr {1 - $state(lastnl)}]] "" -nonewline } else { ::richtext::render_message $cw $suffix $tag -nonewline } set state(lastnl) 0 if {[$cw get "end - 2c"] == "\n"} { incr state(lastnl) set state(afterspace) 1 if {[$cw get "end - 3c"] == "\n"} { incr state(lastnl) } } pop } proc xhtml::push {} { variable state variable stack variable statevars foreach name $statevars { set stack($name) [linsert $stack($name) 0 $state($name)] } } proc xhtml::pop {} { variable state variable stack variable statevars foreach name $statevars { if {[info exists stack($name)]} { set stack($name) [lassign $stack($name) state($name)] } } } proc xhtml::parse_style {style} { variable state set optlist [split $style ";"] foreach opt $optlist { lassign [split $opt ":"] arg val set val [string trim $val] switch -- $arg { color { set state(color) $val } } } } proc xhtml::get_tags {chatw} { variable state set tags {} set color_tag tag_color_$state(color) $chatw tag configure $color_tag -foreground $state(color) lappend tags $color_tag set indent_tag tag_indent_$state(lmargin1)_$state(lmargin2) $chatw tag configure $indent_tag \ -lmargin1 $state(lmargin1) -lmargin2 $state(lmargin2) lappend tags $indent_tag if {$state(weight)} { set fweight bold if {$state(slant)} { set fslant i set fnt $::ChatBoldItalicFont } else { set fslant r set fnt $::ChatBoldFont } } else { set fweight normal if {$state(slant)} { set fslant i set fnt $::ChatItalicFont } else { set fslant r set fnt $::ChatFont } } # TODO: use different sizes set fsize $state(size) set font_tag tag_font_${fsize}_${fslant}_${fweight} $chatw tag configure $font_tag -font $fnt lappend tags $font_tag $chatw tag lower $font_tag xhtml_symb return $tags } proc xhtml::get_url_tag {chatw url} { variable urlid set tag xhtmlurl[incr urlid] set urlfg [option get $chatw urlforeground Text] set urlactfg [option get $chatw urlactiveforeground Text] $chatw tag configure $tag -foreground $urlfg -underline 1 $chatw tag bind $tag <1> [list browseurl [double% $url]] $chatw tag bind $tag \ [list ::richtext::highlighttext $chatw $tag $urlactfg hand2] $chatw tag bind $tag \ [list ::richtext::highlighttext $chatw $tag $urlfg xterm] $chatw tag raise $tag return $tag } proc xhtml::setup_xhtml_tags {chatid type} { set cw [::chat::chat_win $chatid] $cw tag configure xhtml_symb -font $::ChatFont $cw tag raise xhtml_symb } hook::add open_chat_post_hook [namespace current]::xhtml::setup_xhtml_tags tkabber-0.11.1/plugins/chat/muc_ignore.tcl0000644000175000017500000004346310736174616020002 0ustar sergeisergei# $Id: muc_ignore.tcl 1342 2007-12-31 14:15:42Z sergei $ # Support for ignoring occupant activity in MUC rooms. # # A note on runtime ruleset format: # * A hash is used to hold ignore rules at runtime; each key # uniquely refers to its related "connid, room, occupant, # message type" tuple; the existence of a key is used to # determine the fact of some type of a room occupant messages # being ignored. # * The format of the ruleset keys is as follows: # SESSION_JID NUL ROOM_JID/OCCUPANT NUL TYPE # where: # * NUL means character with code 0 (\u0000 in Tcl lingo). # It is used since ASCII NUL is prohibited in JIDs; # * SESSION_JID is the bare JID of a particular connection of # the Tkabber user (support for multiaccounting); # * ROOM_JID is the room bare JID; # * OCCUPANT is either an occupant's room nick OR her full # bare JID, if it's available; # * TYPE is either "chat" or "groupchat", literally, which determines # the type of messages to ignore. namespace eval mucignore { variable options variable ignored variable tid 0 variable tags variable menustate # Cutsomize section: custom::defvar stored_rules {} \ "Stored MUC ignore rules" \ -group Hidden \ -type string hook::add post_custom_restore [namespace current]::restore_rules custom::defgroup {MUC Ignoring} \ [::msgcat::mc "Ignoring groupchat and chat messages\ from selected occupants of multi-user conference\ rooms."] \ -group Privacy \ -group Chat custom::defvar options(transient_rules) 0 \ [::msgcat::mc "When set, all changes to the ignore rules are\ applied only until Tkabber is closed\;\ they are not saved and thus will be not restored at\ the next run."] \ -group {MUC Ignoring} \ -type boolean # Event handlers: # Handlers for creating various menus: hook::add chat_create_conference_menu_hook \ [namespace current]::setup_muc_menu hook::add chat_create_user_menu_hook \ [namespace current]::setup_private_muc_chat_menu hook::add roster_create_groupchat_user_menu_hook \ [namespace current]::setup_occupant_menu hook::add finload_hook \ [namespace current]::on_init # Block private MUC messages: hook::add process_message_hook \ [namespace current]::process_message # Weed out MUC room messages upon entering a room: hook::add open_chat_post_hook \ [namespace current]::sanitize_muc_display # Catch presence of ignored users. # NOTE: the order of this handler must be higher than # that of ::muc::process_presence (which is the default of 50) # since that handler extracts and stores the room occupant's # real JID in the non-anonymous rooms. hook::add client_presence_hook \ [namespace current]::catch_junkie_presence 55 # Adjust ignore rules on nick renames. # NOTE: this hook must be run earlier than client_presence_hook. hook::add room_nickname_changed_hook \ [namespace current]::trace_room_nick_change } # "Ignore tags" are used to mark whole messages posted in the room # by an ignored occupant. Their names are autogenerated and unique # throughout one Tkabber run. Each tag is bound to one particular # "room JID" of the ignored occupant. Ignore tags may be rebound # to another room JID when these change (on nickname changes). # Creates the ignore tag for a particular "room JID". # If matching tag exists, this proc does nothing, silently. # This provides for ignore tag "persistence". proc mucignore::ignore_tag_create {roomjid} { variable tid variable tags if {[info exists tags($roomjid)]} return set tags($roomjid) IGNORED-$tid incr tid } proc mucignore::ignore_tag_get {roomjid} { variable tags set tags($roomjid) } proc mucignore::ignore_tag_rebind {from to} { variable tags set tags($to) $tags($from) unset tags($from) } proc mucignore::ignore_tag_forget {roomjid} { variable tags unset tags($roomjid) } # Returns bare JID of the session identified by $connid proc mucignore::session_bare_jid {connid} { ::node_and_server_from_jid [::jlib::connection_jid $connid] } # Tries to get the real bare JID of the room occupant identified # by the $room_occupant_jid; returns that JID if it's available, # empty string otherwise. proc mucignore::get_real_bare_jid {connid room_occupant_jid} { set real_jid [::muc::get_real_jid $connid $room_occupant_jid] if {$real_jid != {}} { return [::node_and_server_from_jid $real_jid] } else { return {} } } # Creates an ignore rule suitable for using as a key to a hash of rules. # Expects: # * entity -- session's bare JID; # * jid -- JID to ignore ("room/nick" or "room/real_bare_jid"); # * type -- type of chat to ignore ("groupchat" or "chat"). # These parts are joined using the NUL character (since its appearance # is prohibited in any part of a JID) and so the rule can be reliably # split back into parts. # See also: [split_rule]. proc mucignore::mkrulekey {entity jid type} { join [list $entity $jid $type] \u0000 } # Creates an ignore rule suitable for using as a key to a hash of rules. # The $connid parameter is converted to the session's bare JID first. # It's just a convenient wrapper around [mkrulekey]. proc mucignore::mkrule {connid jid type} { mkrulekey [session_bare_jid $connid] $jid $type } # Splits given rule into the list of [entity jid type], where: # * entity -- is a bare JID of the user's session; # * jid -- is a JID to be ignored (usually a full room JID); # * type -- one of: "groupchat" or "chat", designating the type of messages # originating from jid to be ignored. # This proc reverses what [mkrulekey] does. proc mucignore::split_rule {rule} { split $rule \u0000 } proc mucignore::setup_muc_menu {m connid jid} { # TODO return $m add command \ -label [::msgcat::mc "Edit MUC ignore rules"] \ -command [list [namespace current]::editor::open $connid $jid] } proc mucignore::on_init {} { # TODO return set menu [.mainframe getmenu plugins] $menu add command -label [::msgcat::mc "Edit MUC ignore rules"] \ -command [list [namespace current]::editor::open {} {}] } proc mucignore::setup_private_muc_chat_menu {m connid jid} { set room [::node_and_server_from_jid $jid] if {![::chat::is_groupchat [::chat::chatid $connid $room]]} return setup_occupant_menu $m $connid $jid } # Prepares two global variables mirroring the current state of # ignoring for the room occupant on which groupchat roster nick # the menu is being created. They are used to represent # ignore state checkbutton menu entries. proc mucignore::setup_occupant_menu {m connid jid} { variable ignored variable menustate set our_nick [::get_our_groupchat_nick [ ::chat::chatid $connid [ ::node_and_server_from_jid $jid]]] set nick [::chat::get_nick $connid $jid groupchat] if {$nick == $our_nick} { # don't allow to ignore ourselves set state disabled } else { set state normal } foreach type {groupchat chat} { set menustate($connid,$jid,$type) [ info exists ignored([mkrule $connid $jid $type])] } set sm [menu $m.mucignore -tearoff 0] $m add cascade -menu $sm \ -state $state \ -label [::msgcat::mc "Ignore"] $sm add checkbutton -label [::msgcat::mc "Ignore groupchat messages"] \ -variable [namespace current]::menustate($connid,$jid,groupchat) \ -command [list [namespace current]::menu_toggle_ignoring \ $connid $jid groupchat] $sm add checkbutton -label [::msgcat::mc "Ignore chat messages"] \ -variable [namespace current]::menustate($connid,$jid,chat) \ -command [list [namespace current]::menu_toggle_ignoring \ $connid $jid chat] bind $m +[list \ [namespace current]::menu_cleanup_state $connid $jid] } proc mucignore::menu_toggle_ignoring {connid jid type} { variable menustate if {$menustate($connid,$jid,$type)} { occupant_ignore $connid $jid $type } else { occupant_attend $connid $jid $type } } proc mucignore::menu_cleanup_state {connid jid} { variable menustate array unset menustate $connid,$jid,* } # Ignores specified room occupant: # * Creates an ignore rule for her; # * Creates an ignore tag, if needed; # * Hides messages tagged with that tag, if any; # * Builds and saves current ruleset to the Customize db. proc mucignore::occupant_ignore {connid jid args} { variable options variable ignored foreach type $args { set ignored([mkrule $connid $jid $type]) true if {$type == "groupchat"} { ignore_tag_create $jid room_weed_messages $connid $jid true } } if {!$options(transient_rules)} { store_rules $connid } } # Un-ignores specified room occupant: # * Removes her ignore rules; # * Shows any hidden messages from her; # * Ignore tag is NOT removed to provide for "quick picking" # into what the ignored occupant have had written so far -- # when she is ignored again, all her messages tagged with # the appropriate ignore tag are again hidden. # * Builds and saves current ruleset to the Customize db. proc mucignore::occupant_attend {connid jid args} { variable options variable ignored foreach type $args { set rule [mkrule $connid $jid $type] if {[info exists ignored($rule)]} { unset ignored($rule) if {$type == "groupchat"} { room_weed_messages $connid $jid false # we don't use [ignore_tag_forget] here # so when we switch ignoring back on, # all already marked messagess will be weed out } } } if {!$options(transient_rules)} { store_rules $connid } } # Hides or shows messages tagged as ignored for the $jid, if any. proc mucignore::room_weed_messages {connid jid hide} { set room [::node_and_server_from_jid $jid] set cw [::chat::chat_win [::chat::chatid $connid $room]] $cw tag configure [ignore_tag_get $jid] -elide $hide } # This handler blocks further processing of the private room message # if its sender is blacklisted. # If the message is groupchat and its sender is blacklisted, it sets # the appropriate message property so that other message handlers # could treat such message in some special way. proc mucignore::process_message {connid from id type args} { variable ignored if {$type == "chat" && \ [info exists ignored([mkrule $connid $from chat])]} { return stop } } proc mucignore::is_ignored {connid jid type} { variable ignored if {[info exists ignored([mkrule $connid $jid $type])]} { return [ignore_tag_get $jid] } else { return "" } } # This handler is being run after opening the chat window. # It searches the ignore rules for JIDs matching the JID of the room, # extracts them from the rules and weeds out their messages from # the room display (chatlog). # NOTE that it gets executed before any presences arrive from the room # occupants, so the whole idea is to weed out messages with known (ignored) # nicks. proc mucignore::sanitize_muc_display {chatid type} { variable ignored if {$type != "groupchat"} return set connid [::chat::get_connid $chatid] set jid [::chat::get_jid $chatid] foreach rule [array names ignored [mkrule $connid $jid/* groupchat]] { set junkie [lindex [split_rule $rule] 1] # TODO handle "real JIDs" case... ignore_tag_create $junkie room_weed_messages $connid $junkie true } } # This handler is being run after the room_nickname_changed_hook # (which takes care of renaming the ignore list entries). # This proc serves two purposes: # * It converts rules from real JIDs and room JIDs and back # so that room JIDs are used for rule matching and real JIDs # are stored, if they are available, between sessions. # * It arranges for chat log display to be prepared to weed out # messages from ignored JIDs. # TODO why does real JID is available when this handler is run with # $type == "unavailable". memory leak in chats.tcl? # TODO use chat_user_enter/chat_user_exit instead? proc mucignore::catch_junkie_presence {connid from pres args} { variable options variable ignored set room [::node_and_server_from_jid $from] set rjid [get_real_bare_jid $connid $from] if {$pres == "available"} { debugmsg mucignore "avail: $from; real jid: $rjid" foreach type {groupchat chat} { if {$rjid != {} && \ [info exists ignored([mkrule $connid $room/$rjid $type])]} { rename_rule_jid $connid $room/$rjid $from $type } } if {[info exists ignored([mkrule $connid $from groupchat])]} { ignore_tag_create $from room_weed_messages $connid $from true } } elseif {$pres == "unavailable"} { debugmsg mucignore "unavail: $from; real jid: $rjid" if {[info exists ignored([mkrule $connid $from groupchat])]} { ignore_tag_forget $from } foreach type {groupchat chat} { if {$rjid != {} && \ [info exists ignored([mkrule $connid $from $type])]} { rename_rule_jid $connid $from $room/$rjid $type } } } } proc mucignore::trace_room_nick_change {connid room oldnick newnick} { variable ignored foreach type {groupchat chat} { if {[info exists ignored([mkrule $connid $room/$oldnick $type])]} { rename_rule_jid $connid $room/$oldnick $room/$newnick $type if {$type == "groupchat"} { ignore_tag_rebind $room/$oldnick $room/$newnick } } } } proc mucignore::rename_rule_jid {connid from to type} { variable ignored set oldrule [mkrule $connid $from $type] set newrule [mkrule $connid $to $type] set ignored($newrule) [set ignored($oldrule)] unset ignored($oldrule) debugmsg mucignore "rule renamed:\ [string map {\u0000 |} $oldrule]\ [string map {\u0000 |} $newrule]" } proc mucignore::explode_room_jid {connid room_occupant_jid vroom voccupant} { upvar 1 $vroom room $voccupant occupant set room [::node_and_server_from_jid $room_occupant_jid] set occupant [get_real_bare_jid $connid $room_occupant_jid] if {$occupant == {}} { set occupant [::resource_from_jid $room_occupant_jid] } } # Parses the runtime hash of ignore rules, makes up the hierarchical list # (a tree) of ignore rules, resolving the room JIDs to real JIDs, # if possible, then saves the list to the corresponding Customize variable. # The list has the form: # * session_bare_jid_1 # * room_bare_jid_1 # * occupant_1 (nick or real_jid) # * "groupchat" or "chat" or both # ...and so on proc mucignore::store_rules {connid} { variable ignored variable stored_rules array set entities {} foreach rule [array names ignored] { lassign [split_rule $rule] entity jid type explode_room_jid $connid $jid room occupant set entities($entity) 1 set rooms rooms_$entity if {![info exists $rooms]} { array set $rooms {} } set [set rooms]($room) 1 set occupants occupants_$entity$room if {![info exists $occupants]} { array set $occupants {} } lappend [set occupants]($occupant) $type } set LE {} foreach entity [array names entities] { set LR {} foreach room [array names rooms_$entity] { set LO {} set occupants occupants_$entity$room foreach occupant [array names $occupants] { lappend LO $occupant [set [set occupants]($occupant)] } lappend LR $room $LO } lappend LE $entity $LR } set stored_rules [list 1.0 $LE] ;# also record "ruleset syntax" version debugmsg mucignore "STORED: $LE" } proc mucignore::restore_rules {args} { variable ignored variable stored_rules array set ignored {} set failed [catch { lassign $stored_rules version ruleset array set entities $ruleset foreach entity [array names entities] { array set rooms $entities($entity) foreach room [array names rooms] { array set occupants $rooms($room) foreach occupant [array names occupants] { foreach type $occupants($occupant) { set ignored([mkrulekey $entity $room/$occupant $type]) true } } array unset occupants } array unset rooms } } err] if {$failed} { global errorInfo set bt $errorInfo set stored_rules {} after idle [list error \ [::msgcat::mc "Error loading MUC ignore rules, purged."] $bt] } debugmsg mucignore "RESTORED: [string map {\u0000 |} [array names ignored]]" } ######################################################################## # MUC Ignore ruleset editor ######################################################################## namespace eval mucignore::editor {} # ... # NOTE that both $connid and $jid may be empty at the time of invocation. proc mucignore::editor::open {connid jid} { set w .mucignore_rules_editor if {[winfo exists $w]} { return } add_win $w -title [::msgcat::mc "MUC Ignore Rules"] \ -tabtitle [::msgcat::mc "MUC Ignore"] \ -class MUCIgnoreRulesetEditor \ -raise 1 #-raisecmd "focus [list $w.input]" bind $w [list [namespace current]::cleanup $w %W] set sw [ScrolledWindow $w.sw -auto both] set t [Tree $w.tree -background [$w cget -background]] $sw setwidget $t pack $sw -fill both -expand true # NOTE that BWidget Tree doesn't aceept keyboard bindings. $t bindText [list $t toggle] bind $w [list [namespace current]::tree_toggle $t] bind $w [list [namespace current]::tree_edit_item $t] bind $w [list [namespace current]::tree_insert_item $t] bind $w [list [namespace current]::tree_insert_item $t] } proc mucignore::editor::cleanup {w1 w2} { if {$w1 != $w2} return # TODO do appropriate cleanup... } proc mucignore::editor::tree_toggle {t} { set node [lindex [$t selection get] 0] if {$node != {}} { $t toggle $node } } proc mucignore::editor::tree_edit_item {t} { set node [lindex [$t selection get] 0] if {$node == {}} return set text [$t itemcget $node -text] $t edit $node $text } proc mucignore::editor::tree_insert_item {t} { set parent [lindex [$t selection get] 0] if {$parent == {}} { set parent root } # TODO implement #add_nodes $t $parent {New {}} } # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/plugins/chat/disco.tcl0000644000175000017500000000166711062002727016736 0ustar sergeisergei# $Id: disco.tcl 1499 2008-09-10 17:37:27Z sergei $ namespace eval cdisco {} proc cdisco::handle_disco_command {chatid user body type} { set connid [chat::get_connid $chatid] set jid [chat::get_jid $chatid] set bjid [node_and_server_from_jid $jid] if {![chat::is_groupchat [chat::chatid $connid $bjid]]} { set jid $bjid } set body [string trim $body] if {[string equal [string range $body 0 6] "/disco "]} { set jid [string range $body 7 end] } elseif {![string equal $body "/disco"]} { return } disco::browser::open_win $jid -connection $connid return stop } hook::add chat_send_message_hook \ [namespace current]::cdisco::handle_disco_command 50 proc cdisco::disco_command_comp {chatid compsvar wordstart line} { upvar 0 $compsvar comps if {!$wordstart} { lappend comps {/disco } } } hook::add generate_completions_hook \ [namespace current]::cdisco::disco_command_comp tkabber-0.11.1/plugins/chat/events.tcl0000644000175000017500000001600211011777242017133 0ustar sergeisergei# $Id: events.tcl 1416 2008-05-12 08:24:02Z sergei $ # # Message Events (XEP-0022) support. # namespace eval events { custom::defgroup Events \ [::msgcat::mc "Chat message events plugin options."] \ -group Chat custom::defvar options(enable) 1 \ [::msgcat::mc "Enable sending chat message events."] \ -type boolean -group Events disco::register_feature $::NS(event) } proc events::process_x {check_request chatid from type body xs} { variable chats variable options if {$type == "chat"} { foreach x $xs { jlib::wrapper:splitxml $x tag vars isempty chdata children set xmlns [jlib::wrapper:getattr $vars xmlns] switch -- $xmlns \ $::NS(event) { return [process_x_event \ $check_request $chatid $from $type $body $x] } } } } hook::add draw_message_hook \ [list [namespace current]::events::process_x 0] 0 hook::add draw_message_hook \ [list [namespace current]::events::process_x 1] 6 proc events::process_x_event {check_request chatid from type body x} { variable options variable events set connid [chat::get_connid $chatid] set jid [chat::get_jid $chatid] set cw [chat::winid $chatid] jlib::wrapper:splitxml $x tag vars isempty chdata children set offline 0 set delivered 0 set displayed 0 set composing 0 set id 0 foreach child $children { jlib::wrapper:splitxml $child \ tag1 vars1 isempty1 chdata1 children1 switch -- $tag1 { offline {set offline 1} delivered {set delivered 1} displayed {set displayed 1} composing {set composing 1} id {set id 1} } } if {$id && !$check_request} { set status "" if {$offline} {set status offline} if {$delivered} {set status delivered} if {$displayed} {set status displayed} if {$composing} {set status composing} change_status $chatid $status if {$body != ""} { # due to some buggy clients (e.g. Yahoo-t), which send # with real messages return } else { return stop } } elseif {!$id && $check_request} { clear_status $chatid set events(displayed,$chatid) $displayed set events(composing,$chatid) $composing if {!$options(enable)} return if {[get_jid_status $connid $jid] == "unavailable"} return lappend eventtags [jlib::wrapper:createtag id \ -chdata $::chat::chats(id,$chatid)] if {$delivered} { lappend eventtags [jlib::wrapper:createtag delivered] } if {$displayed} { if {$::usetabbar} { set page [crange [win_id tab $cw] 1 end] if {[.nb raise] == $page} { lappend eventtags [jlib::wrapper:createtag displayed] set events(displayed,$chatid) 0 } } else { lappend eventtags [jlib::wrapper:createtag displayed] set events(displayed,$chatid) 0 } } if {[llength $eventtags] > 1} { lappend xlist [jlib::wrapper:createtag x \ -vars [list xmlns $::NS(event)] \ -subtags $eventtags] jlib::send_msg $from -xlist $xlist -connection $connid } } return } proc events::change_status {chatid status} { variable event_afterid if {[info exists event_afterid($chatid)]} { after cancel $event_afterid($chatid) } set cw [chat::winid $chatid] set jid [chat::get_jid $chatid] set text "" set stext "" switch -- $status { offline { set text [::msgcat::mc "Message stored on the server"] set stext [format [::msgcat::mc "Message stored on %s's server"] \ $jid] } delivered { set text [::msgcat::mc "Message delivered"] set stext [format [::msgcat::mc "Message delivered to %s"] $jid] } displayed { set text [::msgcat::mc "Message displayed"] set stext [format [::msgcat::mc "Message displayed to %s"] $jid] } composing { set text [::msgcat::mc "Composing a reply"] set stext [format [::msgcat::mc "%s is composing a reply"] $jid] } } if {$stext != "" && $::usetabbar} {set_status $stext} if {![winfo exists $cw]} return $cw.status.event configure -text $text set event_afterid($chatid) \ [after 10000 [list [namespace current]::clear_status $chatid]] } proc events::clear_status {chatid} { set cw [chat::winid $chatid] if {![winfo exists $cw]} return $cw.status.event configure -text "" } proc events::send_event_on_raise {cw chatid} { variable options variable events if {![chat::is_chat $chatid]} return if {![info exists events(displayed,$chatid)] || \ !$events(displayed,$chatid)} return set connid [chat::get_connid $chatid] set jid [chat::get_jid $chatid] set events(displayed,$chatid) 0 if {!$options(enable)} return if {[get_jid_status $connid $jid] == "unavailable"} return lappend eventtags [jlib::wrapper:createtag id \ -chdata $::chat::chats(id,$chatid)] lappend eventtags [jlib::wrapper:createtag displayed] lappend xlist [jlib::wrapper:createtag x \ -vars [list xmlns $::NS(event)] \ -subtags $eventtags] jlib::send_msg $jid -xlist $xlist -connection $connid } hook::add raise_chat_tab_hook [namespace current]::events::send_event_on_raise proc events::event_composing {chatid sym} { variable options variable events if {![chat::is_chat $chatid]} return if {$sym == ""} return if {![info exists events(composing,$chatid)] || \ !$events(composing,$chatid)} return set connid [chat::get_connid $chatid] set jid [chat::get_jid $chatid] set events(composing,$chatid) 0 if {!$options(enable)} return if {[get_jid_status $connid $jid] == "unavailable"} return lappend eventtags [jlib::wrapper:createtag id \ -chdata $::chat::chats(id,$chatid)] lappend eventtags [jlib::wrapper:createtag composing] lappend xlist [jlib::wrapper:createtag x \ -vars [list xmlns $::NS(event)] \ -subtags $eventtags] jlib::send_msg $jid -xlist $xlist -connection $connid } proc events::setup_ui {chatid type} { variable events if {![chat::is_chat $chatid]} return set cw [chat::winid $chatid] set l $cw.status.event if {![winfo exists $l]} { label $l pack $l -side left } set iw [chat::input_win $chatid] bind $iw +[list [namespace current]::event_composing \ [double% $chatid] %A] } hook::add open_chat_post_hook [namespace current]::events::setup_ui proc events::clear_status_on_send {chatid user body type} { if {![chat::is_chat $chatid]} return clear_status $chatid } hook::add chat_send_message_hook \ [namespace current]::events::clear_status_on_send proc events::make_xlist {varname chatid user body type} { variable options upvar 2 $varname var if {!$options(enable) || $type != "chat"} { return } lappend events [jlib::wrapper:createtag offline] lappend events [jlib::wrapper:createtag delivered] lappend events [jlib::wrapper:createtag displayed] lappend events [jlib::wrapper:createtag composing] lappend var [jlib::wrapper:createtag x \ -vars [list xmlns $::NS(event)] \ -subtags $events] return } hook::add chat_send_message_xlist_hook \ [namespace current]::events::make_xlist tkabber-0.11.1/plugins/chat/popupmenu.tcl0000644000175000017500000001451510673556704017701 0ustar sergeisergei# $Id: popupmenu.tcl 1229 2007-09-17 20:04:20Z sergei $ package require http namespace eval popupmenu { hook::add postload_hook [namespace current]::init hook::add open_chat_post_hook [namespace current]::on_open_chat hook::add close_chat_post_hook [namespace current]::on_close_chat } proc popupmenu::init {} { global usetabbar if {$usetabbar} { bind . [list [namespace current]::BookmarkNext .] bind . [list [namespace current]::BookmarkPrev .] bind . [list [namespace current]::GoogleSelection .] bind . [list [namespace current]::GoogleSelection .] } } proc popupmenu::on_open_chat {chatid type} { global usetabbar set cw [chat::chat_win $chatid] bind $cw [list [namespace current]::popup_menu %W %X %Y %x %y] if {!$usetabbar} { set top [winfo toplevel $cw] bind $top [list [namespace current]::BookmarkNext $cw] bind $top [list [namespace current]::BookmarkPrev $cw] bind $top [list [namespace current]::GoogleSelection $cw] bind $top [list [namespace current]::GoogleSelection $cw] } } proc popupmenu::on_close_chat {chatid} { variable bookmark set cw [chat::chat_win $chatid] catch { array unset bookmark $cw,* } } proc popupmenu::popup_menu {W X Y x y} { set m .popup if {[winfo exists $m]} { destroy $m } menu $m -tearoff 0 hook::run chat_win_popup_menu_hook $m $W $X $Y $x $y tk_popup $m $X $Y } proc popupmenu::selection_popup {m W X Y x y} { if {[lempty [$W tag ranges sel]]} { set state disabled } else { set state normal } $m add command -label [::msgcat::mc "Copy selection to clipboard"] \ -command [list [namespace current]::CopySelection $W] \ -state $state $m add command -label [::msgcat::mc "Google selection"] -accelerator Ctrl-G \ -command [list [namespace current]::GoogleSelection $W]\ -state $state } hook::add chat_win_popup_menu_hook [namespace current]::popupmenu::selection_popup 20 proc popupmenu::bookmarks_popup {m W X Y x y} { $m add command -label [::msgcat::mc "Set bookmark"] \ -command [list [namespace current]::BookmarkAdd $W $x $y] $m add command -label [::msgcat::mc "Prev bookmark"] -accelerator F2 \ -command [list [namespace current]::BookmarkPrev $W] $m add command -label [::msgcat::mc "Next bookmark"] -accelerator Shift-F2 \ -command [list [namespace current]::BookmarkNext $W] $m add command -label [::msgcat::mc "Clear bookmarks"] \ -command [list [namespace current]::BookmarkClear $W] } hook::add chat_win_popup_menu_hook [namespace current]::popupmenu::bookmarks_popup 80 proc popupmenu::get_chatwin {} { global usetabbar if {!$usetabbar} { return "" } set cw "" foreach chatid [chat::opened] { if {[.nb raise] == [ifacetk::nbpage [chat::winid $chatid]]} { set cw [chat::chat_win $chatid] break } } return $cw } proc popupmenu::BookmarkAdd {cw x y} { variable bookmark $cw mark set AddBookmark "@$x,$y linestart" debugmsg popupmenu "BookmarkAdd at [$cw index AddBookmark]" if {![info exists bookmark($cw,id)]} { set bookmark($cw,id) 0 } $cw configure -state normal $cw image create AddBookmark -image chat/bookmark/red set b [incr bookmark($cw,id)] $cw mark set bookmark$b AddBookmark $cw mark gravity bookmark$b left $cw mark unset AddBookmark $cw configure -state disabled } proc popupmenu::BookmarkNext {cw} { variable bookmark if {$cw == "."} { set cw [get_chatwin] if {$cw == ""} return } if {![info exists bookmark($cw,last)] || \ [catch {$cw index $bookmark($cw,last)}]} { set bookmark($cw,last) 0.0 } if {$bookmark($cw,last) == "end" || \ ((([lindex [$cw yview] 0] == 0) || ([lindex [$cw yview] 1] == 1)) && \ ([$cw dlineinfo [$cw index $bookmark($cw,last)]] == {}))} { set bookmark($cw,last) 0.0 } while {$bookmark($cw,last) != {}} { set bookmark($cw,last) [$cw mark next $bookmark($cw,last)] if {[string match "bookmark*" $bookmark($cw,last)]} { break } } if {$bookmark($cw,last) == {}} { set bookmark($cw,last) end } $cw see $bookmark($cw,last) return $bookmark($cw,last) } proc popupmenu::BookmarkPrev {cw} { variable bookmark if {$cw == "."} { set cw [get_chatwin] if {$cw == ""} return } if {![info exists bookmark($cw,last)] || \ [catch {$cw index $bookmark($cw,last)}]} { set bookmark($cw,last) end } if {$bookmark($cw,last) == "0.0" || \ (([lindex [$cw yview] 1] == 1) && \ ([$cw dlineinfo [$cw index $bookmark($cw,last)]] == {}))} { set bookmark($cw,last) end } while {$bookmark($cw,last) != {}} { set bookmark($cw,last) [$cw mark previous $bookmark($cw,last)] if {[string match "bookmark*" $bookmark($cw,last)]} { break } } if {$bookmark($cw,last) == {}} { set bookmark($cw,last) 0.0 } $cw see $bookmark($cw,last) return $bookmark($cw,last) } proc popupmenu::BookmarkClear {cw} { debugmsg popupmenu "BookmarkClear" set mark 0.0 while {[set mark [$cw mark next $mark]] != {}} { if {[string match "bookmark*" $mark]} { set remove $mark set mark "[$cw index $mark]" BookmarkRemove $cw $remove } } } proc popupmenu::BookmarkRemove {cw mark} { if {[lsearch -exact [$cw mark names] $mark] >= 0} { debugmsg popupmenu "BookmarkRemove $mark" $cw configure -state normal $cw delete "$mark - 1 char" $cw mark unset $mark $cw configure -state disabled } } proc popupmenu::GoogleSelection {cw} { if {$cw == "."} { set cw [get_chatwin] if {$cw == ""} return } set sel [$cw tag ranges sel] if {$sel != ""} { set t [$cw get [lindex $sel 0] [lindex $sel 1]] debugmsg popupmenu "google for $t" browseurl \ http://www.google.com/search?[::http::formatQuery ie UTF-8 oe UTF-8 q $t] } } proc popupmenu::CopySelection {cw} { if {$cw == "."} { set cw [get_chatwin] if {$cw == ""} return } set sel [$cw tag ranges sel] if {$sel != ""} { set t [$cw get [lindex $sel 0] [lindex $sel 1]] debugmsg popupmenu "copy selection $t" clipboard clear -displayof $cw clipboard append -displayof $cw $t } } tkabber-0.11.1/plugins/chat/update_tab.tcl0000644000175000017500000000245310562424423017744 0ustar sergeisergei# $Id: update_tab.tcl 903 2007-02-07 19:31:31Z sergei $ namespace eval update_tab { hook::add draw_message_hook [namespace current]::update 8 } proc update_tab::update {chatid from type body x} { set connid [chat::get_connid $chatid] set jid [chat::get_jid $chatid] set cw [chat::winid $chatid] foreach xelem $x { jlib::wrapper:splitxml $xelem tag vars isempty chdata children # Don't update tab if this 'empty' tag is present. It indicates # messages history in chat window. if {[cequal $tag ""] && \ [cequal [jlib::wrapper:getattr $vars xmlns] tkabber:x:nolog]} { return } } if {![catch {::plugins::mucignore::is_ignored $connid $from $type} ignore] && \ $ignore != ""} { return } switch -- $type { error - info { tab_set_updated $cw 1 $type } groupchat { if {$from == $jid} { tab_set_updated $cw 1 server } else { set myjid [chat::our_jid $chatid] set mynick [chat::get_nick $connid $myjid $type] if {[check_message $mynick $body]} { tab_set_updated $cw 1 mesg_to_user } else { tab_set_updated $cw 1 message } } } chat - default { if {$from == ""} { # synthesized message tab_set_updated $cw 1 server } else { tab_set_updated $cw 1 mesg_to_user } } } } # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/plugins/chat/abbrev.tcl0000644000175000017500000000660510572466206017106 0ustar sergeisergei# $Id: abbrev.tcl 999 2007-03-04 06:51:50Z sergei $ # "abbrev" Tkabber plugin -- "Chat input abbreviations". # Written by Konstantin Khomoutov # TODO More comments # TODO extensive testing namespace eval abbrev { variable abbrevs array set abbrevs {} trace variable [namespace current]::abbrevs w \ [namespace current]::store_abbrevs custom::defvar stored_abbrevs {} \ "List of chat input abbreviations" \ -group Hidden \ -type string bind TextAbbrevs \ [list [namespace current]::expand_abbrevs %W] } proc abbrev::command_comps {chatid compsvar wordstart line} { upvar 0 $compsvar comps if {!$wordstart} { lappend comps {/abbrev } {/unabbrev } {/listabbrevs } } } hook::add generate_completions_hook \ [namespace current]::abbrev::command_comps proc abbrev::handle_command {chatid user body type} { variable abbrevs if {[string match "/abbrev*" $body]} { if {![regexp {^/abbrev\s+(\S+)\s+(.*)$} $body - what for]} { show error $chatid [::msgcat::mc "Usage: /abbrev WHAT FOR"] return stop } set abbrevs($what) $for show info $chatid [::msgcat::mc "Added abbreviation:\n%s: %s" \ $what $for] } elseif {[string match "/unabbrev*" $body]} { if {![regexp {^/unabbrev\s+(\S+)} $body - what]} { show error $chatid [::msgcat::mc "Usage: /unabbrev WHAT"] return stop } # Handle special case: * stands for "all abbreviations": if {[string equal $what *]} { array unset abbrevs * show info $chatid [::msgcat::mc "Purged all abbreviations" $what] return stop } if {[catch {unset abbrevs($what)}]} { show error $chatid [::msgcat::mc "No such abbreviation: %s" $what] return stop } else { show info $chatid [::msgcat::mc "Deleted abbreviation: %s" $what] } } elseif {[string match "/listabbrevs*" $body]} { set out [::msgcat::mc "Abbreviations:"] foreach ab [array names abbrevs] { append out "\n$ab: $abbrevs($ab)" } show info $chatid $out } else { return } return stop } hook::add chat_send_message_hook \ [namespace current]::abbrev::handle_command 15 proc abbrev::install_bindtag {chatid type} { set iw [chat::input_win $chatid] set bt [bindtags $iw] set ix [lsearch -exact $bt Text] if {$ix < 0} return ;# very, very strange... bindtags $iw [linsert $bt $ix TextAbbrevs] } hook::add open_chat_post_hook \ [namespace current]::abbrev::install_bindtag proc abbrev::expand_abbrevs {w} { variable abbrevs if {[catch {tk::TextPrevPos $w insert tcl_startOfPreviousWord} from]} { set from [tkTextPrevPos $w insert tcl_startOfPreviousWord] } set what [$w get $from insert] if {[info exists abbrevs($what)]} { set for $abbrevs($what) $w delete $from insert $w insert $from $for } } proc abbrev::store_abbrevs args { variable abbrevs variable stored_abbrevs set stored_abbrevs [array get abbrevs] } proc abbrev::restore_abbrevs args { variable abbrevs variable stored_abbrevs array set abbrevs $stored_abbrevs } # Prio of this handler must be > 60 since customize db is read at 60 hook::add postload_hook \ [namespace current]::abbrev::restore_abbrevs 70 # $type should be either "info" or "error" proc abbrev::show {type chatid msg} { set jid [chat::get_jid $chatid] set cw [chat::chat_win $chatid] chat::add_message $chatid $jid $type $msg {} } tkabber-0.11.1/plugins/chat/open_chat.tcl0000644000175000017500000000267110363037223017573 0ustar sergeisergei# Allows to open new chat window without using mouse and roster pane :) # Just type "/open jid" and press enter. # Command and JID could be completed in the usual way. # # $Id: open_chat.tcl 659 2006-01-17 00:47:15Z aleksey $ proc handle_open_chat {chatid user body type} { if {[string equal -length 6 $body "/open "]} { set user [crange $body 6 end] # What if conference nickname contains "@"? if {[string first "@" $user] >= 0} { chat::open_to_user [chat::get_connid $chatid] $user } else { chat::open_to_user [chat::get_connid $chatid] \ [chat::get_jid $chatid]/$user } return stop } } hook::add chat_send_message_hook [namespace current]::handle_open_chat 15 proc roster_completions {chatid compsvar wordstart line} { upvar 0 $compsvar comps if {!$wordstart} { lappend comps {/open } } if {$wordstart && [string equal -length 6 $line "/open "]} { set prefix $plugins::completion::options(prefix) set suffix $plugins::completion::options(suffix) set jidcomps {} set connid [chat::get_connid $chatid] foreach jid [roster::get_jids $connid] { if {[roster::itemconfig $connid $jid -isuser]} { lappend jidcomps $prefix$jid$suffix } } set jidcomps [lsort -dictionary -unique $jidcomps] set comps [concat $comps $jidcomps] debugmsg plugins "COMPLETION from roster: $comps" } } hook::add generate_completions_hook \ [namespace current]::roster_completions 93 tkabber-0.11.1/plugins/chat/draw_timestamp.tcl0000644000175000017500000000211111062120632020632 0ustar sergeisergei# $Id: draw_timestamp.tcl 1500 2008-09-11 04:42:02Z sergei $ custom::defvar options(timestamp_format) {[%R]} \ [::msgcat::mc "Format of timestamp in chat message.\ Refer to Tcl documentation of 'clock' command for\ description of format.\n\nExamples:\n \ \[%R\] - \[20:37\]\n \[%T\] - \[20:37:12\]\n \ \[%a %b %d %H:%M:%S %Z %Y\] -\ \[Thu Jan 01 03:00:00 MSK 1970\]"] \ -type string -group Chat custom::defvar options(delayed_timestamp_format) {[%m/%d %R]} \ [::msgcat::mc "Format of timestamp in delayed chat messages delayed\ for more than 24 hours."] \ -type string -group Chat proc draw_timestamp {chatid from type body x} { variable options set chatw [chat::chat_win $chatid] set seconds [jlib::x_delay $x] set seconds1 [expr {[clock seconds] - 24*60*60 + 60}] if {$seconds <= $seconds1} { set format $options(delayed_timestamp_format) } else { set format $options(timestamp_format) } $chatw insert end [clock format $seconds -format $format] } hook::add draw_message_hook [namespace current]::draw_timestamp 9 tkabber-0.11.1/plugins/chat/draw_info.tcl0000644000175000017500000000043310556440255017604 0ustar sergeisergei# $Id: draw_info.tcl 882 2007-01-26 17:55:57Z sergei $ proc handle_info {chatid from type body x} { if {[cequal $type info]} { ::richtext::render_message [chat::chat_win $chatid] $body info return stop } } hook::add draw_message_hook [namespace current]::handle_info 10 tkabber-0.11.1/plugins/chat/histool.tcl0000644000175000017500000004514710771407443017331 0ustar sergeisergei# $Id: histool.tcl 1397 2008-03-23 08:04:51Z sergei $ # History tool -- allows browsing and searching through Tkabber chat logs. option add *ChatHistory.geometry "640x480" widgetDefault option add *ChatHistory.oddBackground "" widgetDefault option add *ChatHistory.evenBackground "" widgetDefault option add *ChatHistory.headerForeground blue widgetDefault option add *ChatHistory.bodyForeground "" widgetDefault option add *ChatHistory.warningForeground red widgetDefault event add <> event add <> event add <> namespace eval histool { hook::add finload_hook [namespace current]::on_init } proc histool::on_init {} { set m [.mainframe getmenu services] set idx [$m index [::msgcat::mc "Service Discovery"]] $m insert [expr {$idx + 2}] command \ -label [::msgcat::mc "Chats history"] \ -command [namespace current]::browse } proc histool::browse args { if {[is_unsupported]} { NonmodalMessageDlg [epath] \ -aspect 50000 \ -icon error \ -title [::msgcat::mc "Error"] \ -message [::msgcat::mc "Unsupported log dir format"] return } set w .histool if {[winfo exists $w]} { focus -force $w return } browser_create $w } proc histool::browser_create {w} { variable loghier [get_log_hier] add_win $w \ -title [::msgcat::mc "Chats History"] \ -tabtitle [::msgcat::mc "Chats history"] \ -class ChatHistory \ -raise 1 bind $w +[list [namespace current]::browser_cleanup [double% $w] %W] set nb [NoteBook $w.nb] set p [$nb insert end jidlist \ -text [::msgcat::mc "JID list"] \ -raisecmd [list [namespace current]::jidlist_raise $nb]] jidlist_create $p set p [$nb insert end ltree \ -text [::msgcat::mc "Logs"] \ -raisecmd [list [namespace current]::ltree_raise $nb]] ltree_create $p set p [$nb insert end ftsearch \ -text [::msgcat::mc "Full-text search"] \ -raisecmd [list [namespace current]::ftsearch_raise $nb]] ftsearch_create $p -mainwindow $w pack $nb -fill both -expand true $nb raise jidlist } proc histool::browser_cleanup {w1 w2} { if {![string equal $w1 $w2]} return variable loghier unset loghier } ################################################################ proc histool::jidlist_create {w} { variable loghier grid columnconfigure $w 0 -weight 1 set sw [ScrolledWindow $w.sw] set lbox [listbox $w.lbox -takefocus 1 -exportselection 0] $lbox selection clear 0 end $lbox selection set 0 focus $lbox # Workaround for a bug in listbox (can't get focus on mouse clicks): bind Listbox {+ if {[winfo exists %W]} {focus %W}} bind $lbox [namespace code { jidlist_open_log %W [%W nearest %y] }] bind $lbox [namespace code { jidlist_open_log %W [%W index active] }] $sw setwidget $lbox grid $sw -sticky news grid rowconfigure $w 0 -weight 1 foreach jid [sort_jids [get_jids $loghier] -order {server node resource}] { $lbox insert end $jid } # Setup searching: set sp [::plugins::search::spanel $w.spanel \ -defaultdirection up \ -searchcommand [list ::plugins::search::listbox::do_search $lbox] \ -closecommand [list [namespace current]::jidlist_spanel_close $lbox]] bind $lbox <> \ [list [namespace current]::jidlist_spanel_open $w $sp] } proc histool::jidlist_open_log {w idx args} { variable loghier set jid [$w get $idx] set subdirs [get_subdirs of $loghier for $jid] ::logger::show_log $jid -subdirs $subdirs } proc histool::jidlist_spanel_open {w sp} { grid $sp -sticky we } proc histool::jidlist_spanel_close {lbox w} { grid forget $w focus $lbox } ################################################################ proc histool::ltree_create {w} { variable loghier variable ::logger::d2m set sw [ScrolledWindow $w.sw] set t [Tree $w.tree] $sw setwidget $t pack $sw -fill both -expand yes $t bindText \ [list [namespace current]::ltree_node_action [double% $t]] # Keyboard bindings don't work in BWidget Tree's bindText; # HACK: Tree.c widget is what receives keyboard events: bind $t.c <> \ [list [namespace current]::ltree_for_node [double% $t] ltree_node_action] bind $t.c <> \ [list [namespace current]::ltree_for_node [double% $t] ltree_step_up] # Install mouse wheel bindings: bindscroll $t.c [namespace parent]::search::browser::setup_panel $w $sw $t set counter 0 foreach LA [lsort -index 0 $loghier] { lassign $LA year months $t insert end root root.$year -text $year foreach LB [lsort -index 0 $months] { lassign $LB month jids $t insert end root.$year root.$year.$month -text $d2m($month) foreach jid [sort_jids $jids -order {server node resource}] { $t insert end root.$year.$month [incr counter] -text $jid } } } } proc histool::ltree_for_node {t script} { set node [lindex [$t selection get] 0] if {[string equal $node ""]} return eval $script $t $node } proc histool::ltree_node_action {t n} { variable loghier if {[tree_node_is_leaf $t $n]} { variable ::logger::m2d set mn [$t parent $n] set yn [$t parent $mn] set year [$t itemcget $yn -text] set month $m2d([$t itemcget $mn -text]) set jid [$t itemcget $n -text] ::logger::show_log $jid -when $year-$month \ -subdirs [get_subdirs of $loghier for $jid] } else { $t toggle $n } } proc histool::tree_node_is_leaf {t n} { string equal [$t nodes $n 0] "" } proc histool::ltree_step_up {t n} { set p [$t parent $n] if {[string equal $p root]} return $t toggle $p $t selection set $p } ################################################################ proc histool::ftsearch_create {w args} { variable loghier variable ftsearch grid columnconfigure $w 0 -weight 1 set sp $w.spanel ::plugins::search::spanel $sp \ -allowclose no \ -twoway no \ -searchcommand [namespace current]::ftsearch_do_search \ -stopcommand [namespace current]::ftsearch_cancel_search grid $sp -sticky we set sw [ScrolledWindow $w.sw] set r [text $w.results -cursor "" -state disabled] $sw setwidget $r grid $sw -sticky news grid rowconfigure $w 1 -weight 1 set f [frame $w.cf -class Chat] $r tag configure they -foreground [option get $f theyforeground Chat] $r tag configure me -foreground [option get $f meforeground Chat] $r tag configure server_lab \ -foreground [option get $f serverlabelforeground Chat] $r tag configure server \ -foreground [option get $f serverforeground Chat] destroy $f bind $r [namespace code { ftsearch_open_log %W %x %y break }] set ix [lsearch $args -mainwindow] if {$ix >= 0} { set mw [lindex $args [incr ix]] if {$mw != ""} { set val [option get $mw oddBackground ChatHistory] if {$val != ""} { $r tag configure ODD -background $val } set val [option get $mw evenBackground ChatHistory] if {$val != ""} { $r tag configure EVEN -background $val } set val [option get $mw headerForeground ChatHistory] if {$val != ""} { $r tag configure HEADER -foreground $val } set val [option get $mw bodyForeground ChatHistory] if {$val != ""} { $r tag configure BODY -background $val } set val [option get $mw warningForeground ChatHistory] if {$val != ""} { $r tag configure WARNING -foreground $val } } } set ftsearch(last) "" set ftsearch(results) $r set ftsearch(bg) EVEN bind $w +[list [namespace current]::ftsearch_cleanup [double% $w] %W] # Set search panel up: # TODO remove when fixed elsewhere. # See also [ftsearch_spanel_close] $r mark set sel_start end $r mark set sel_end 1.0 set asp [::plugins::search::spanel $w.auxspanel \ -defaultdirection up \ -searchcommand [list ::plugins::search::do_text_search $r] \ -closecommand [list [namespace current]::ftsearch_spanel_close $r $sp.sentry]] bind $sp.sentry <> \ [list [namespace current]::ftsearch_spanel_open [double% $w] [double% $asp]] } # Schedules an execution of a script produced by concatenating # the words of $args using the # [after idle [after 0 [list ...]]] # concept presented at http://mini.net/tcl/1526 # The idea is that some parts of Tk wait for all idle event # handlers to complete. So, when executes, our idle event handler # installed in [schedule] installs timed event handler that # will be executed ASAP, and since it's not an idle event, it # allows the event queue to be in a state free of scheduled # idle events (thus allowing Tk to do its job, keeping GUI alive). proc histool::schedule args { after idle [list after 0 $args] } # Must be used as the (almost) first command inside any procs # scheduled as [after ...] callbacks installed in the course # of performing full-text search. proc histool::ftsearch_can_proceed {} { variable ftsearch_terminate if {$ftsearch_terminate} { unset ftsearch_terminate return false } else { return true } } # This proc builds a list of log files to grep and then starts # an asynchronous searching through them proc histool::ftsearch_do_search {what dir args} { variable loghier variable ftsearch variable ftsearch_terminate false # Returning false means we refuse to start searching: if {$what == ""} { return 0 } if {[string equal $ftsearch(last) $what]} { return 0 } set ftsearch(now) $what set ftsearch(found) 0 set r $ftsearch(results) $r configure -state normal $r delete 1.0 end $r configure -state normal set slist {} foreach LA [lsort -index 0 $loghier] { lassign $LA year months foreach LB [lsort -index 0 $months] { lassign $LB month jids foreach jid $jids { lappend slist [list $year $month $jid] } } } set ix [lsearch $args -completioncommand] if {$ix >= 0} { set ftsearch(compcmd) [lindex $args [incr ix]] } else { set ftsearch(compcmd) "" } # will return almost immediately: ftsearch_grep_next of $slist for $what return 1 ;# signalize we've started the search process } # Tries to open the last file in the $slist and schedules # the execution of a handler that will read that file # looking for $what proc histool::ftsearch_grep_next {"of" slist "for" what args} { if {![ftsearch_can_proceed]} return variable ftsearch variable ::logger::options # Some files are unreadable due to some reason, so we loop # over the list of them until opening succeeds or the list # is exhausted: while true { lassign [lindex $slist end] year month jid set fname [file join $options(logdir) \ $year $month [::logger::jid_to_filename $jid]] if {[catch {open $fname} chan]} { set r $ftsearch(results) $r configure -state normal $r insert end [::msgcat::mc "WARNING: %s\n" $chan] WARNING $r configure -state disabled set slist [lrange $slist 0 end-1] if {[llength $slist] > 0} { continue } else { ftsearch_complete_search for $what return } } else break } fconfigure $chan -encoding utf-8 schedule \ [namespace current]::ftsearch_grep_msg of $slist for $what from $chan } # Reads one line from a log file opened as $chan, parses it, looks # for $what in the relevant parts of the aqcuired message, renders # it if it match. # Searching conditions are checked: this proc is either re-schedules # its execution (for the next line of the log file) or schedules the # reading of the next log file or completes the searching process. proc histool::ftsearch_grep_msg {"of" slist "for" what "from" chan} { if {![ftsearch_can_proceed]} return variable ftsearch set line [gets $chan] if {![eof $chan]} { set msg [::logger::log_to_str $line] if {![catch {array set mparts $msg}]} { foreach part {nick body} { if {[info exists mparts($part)] && \ [::plugins::search::match $what $mparts($part)]} { lassign [lindex $slist end] year month jid set r $ftsearch(results) $r configure -state normal ftsearch_render_msg $r $year $month $jid $msg $r configure -state disabled set ftsearch(found) 1 break } } } schedule \ [namespace current]::ftsearch_grep_msg of $slist for $what from $chan } else { close $chan set rem [lrange $slist 0 end-1] if {[llength $rem] > 0} { schedule \ [namespace current]::ftsearch_grep_next of $rem for $what } else { ftsearch_complete_search for $what } } } proc histool::ftsearch_render_msg {t year month jid msg} { variable ftsearch set tags [list $ftsearch(bg) YEAR-$year MONTH-$month JID-$jid] set mynick [get_group_nick $jid ""] if {[catch {array set mparts $msg}]} return set start [$t index {end - 1 char}] set header $jid if {[info exists mparts(timestamp)] && $mparts(timestamp) != ""} { set ts [::logger::formatxmppts $mparts(timestamp)] append header " \[$ts\]" lappend tags TS-$mparts(timestamp) } if {[info exists mparts(jid)] && $mparts(jid) == ""} { append header " " [::msgcat::mc "Client message"] } elseif {[info exists mparts(nick)]} { if {$mparts(nick) == ""} { append header " " [::msgcat::mc "Server message"] } else { append header " " [::msgcat::mc "From:"] " " $mparts(nick) } } $t insert end $header\n HEADER $t insert end $mparts(body)\n BODY set end [$t index {end - 1 char}] foreach tag $tags { $t tag add $tag $start $end } if {[string equal $ftsearch(bg) EVEN]} { set ftsearch(bg) ODD } else { set ftsearch(bg) EVEN } } proc histool::ftsearch_complete_search {"for" what} { variable ftsearch set ftsearch(now) "" set ftsearch(last) $what if {$ftsearch(compcmd) != ""} { eval $ftsearch(compcmd) $ftsearch(found) } } proc histool::ftsearch_cancel_search {args} { variable ftsearch variable ftsearch_terminate true set ftsearch(last) $ftsearch(now) set ftsearch(now) "" if {$ftsearch(compcmd) != ""} { eval $ftsearch(compcmd) $ftsearch(found) } } proc histool::ftsearch_open_log {t x y} { variable loghier set year "" set month "" set ts "" set jid "" foreach tag [$t tag names @$x,$y] { if {[string match YEAR-* $tag]} { set year [string range $tag 5 end] } if {[string match MONTH-* $tag]} { set month [string range $tag 6 end] } if {[string match TS-* $tag]} { set ts [string range $tag 3 end] } if {[string match JID-* $tag]} { set jid [string range $tag 4 end] } } if {$jid == ""} return set cmd [list ::logger::show_log $jid] if {$year != "" && $month != ""} { lappend cmd -when $year-$month if {$ts != ""} { lappend cmd -timestamp $ts } } lappend cmd -subdirs [get_subdirs of $loghier for $jid] eval $cmd } proc histool::ftsearch_spanel_open {w sp} { grid $sp -sticky we } proc histool::ftsearch_spanel_close {t sentry w} { # TODO remove when fixed elsewhere. # See also [ftsearch_create] $t tag remove search_highlight 0.0 end $t mark set sel_start end $t mark set sel_end 0.0 grid forget $w focus $sentry } # Cleans up relevant variables when the browser form # is destroyed. "ftsearch_terminate" variable is # unset in the [after ...] event handler, if such # handler is installed. proc histool::ftsearch_cleanup {w1 w2} { if {![string equal $w1 $w2]} return variable ftsearch array unset ftsearch variable ftsearch_terminate if {[info exists ftsearch_terminate]} { set ftsearch_terminate true } } ################################################################ proc histool::jidlist_raise {nb} { set lbox [$nb getframe jidlist].lbox if {[winfo exists $lbox]} { focus $lbox } } proc histool::ltree_raise {nb} { set tree [$nb getframe ltree].tree if {[winfo exists $tree]} { focus $tree } } proc histool::ftsearch_raise {nb} { } # Sorts a list of JIDs based on their parts: node, server and resource. # The default comparison order is: server, node, resource. # Optional argument/value pairs are accepted: # -order LIST -- override the default comparison order. proc histool::sort_jids {jids args} { set order {server node resource} foreach {opt val} $args { switch -- $opt { -order { set order $val } default { error "invalid option: $opt" } } } set norder {} foreach part {node server resource} { lappend norder [lsearch $order $part] } set items {} foreach jid $jids { set parts [list \ [node_from_jid $jid] \ [server_from_jid $jid] \ [resource_from_jid $jid] \ ] set ordered [list \ [lindex $parts [lindex $norder 0]] \ [lindex $parts [lindex $norder 1]] \ [lindex $parts [lindex $norder 2]] \ ] set pat [join $ordered \u0000] lappend items [list $pat $jid] } set sorted {} foreach item [lsort -index 0 -dictionary $items] { lappend sorted [lindex $item 1] } set sorted } proc histool::is_unsupported {} { variable ::logger::options catch { set fd [open [file join $options(logdir) version]] if {![package vsatisfies [gets $fd] 1.0]} { close $fd error "unsupported log dir structure format" } close $fd } } proc histool::get_log_hier {} { variable ::logger::options set LA {} foreach dyear [glob -nocomplain -type d -directory $options(logdir) *] { set LB {} foreach dmonth [glob -nocomplain -type d -directory $dyear *] { set LC {} foreach file [glob -nocomplain -type f -directory $dmonth *] { lappend LC [::logger::filename_to_jid [file tail $file]] } set month [lindex [file split $dmonth] end] lappend LB [list $month $LC] } set year [lindex [file split $dyear] end] lappend LA [list $year $LB] } set LA } proc histool::get_jids {loghier} { foreach LA $loghier { foreach LB [lindex $LA 1] { foreach jid [lindex $LB 1] { set jids($jid) "" } } } array names jids } # From the log hierarchy given by $loghier builds a list of # YEAR-MONTH entries producing the same structure that # is generated by [::logger::get_subdirs]. # See plugins/chat/logger.tcl proc histool::get_subdirs {"of" loghier "for" jid} { set subdirs {} foreach LA $loghier { lassign $LA year months foreach LB $months { lassign $LB month jids if {[lsearch -exact $jids $jid] >= 0} { lappend subdirs $year-$month } } } set subdirs } # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/plugins/iq/0000755000175000017500000000000011076120366014616 5ustar sergeisergeitkabber-0.11.1/plugins/iq/version.tcl0000644000175000017500000001367410764210647017027 0ustar sergeisergei# $Id: version.tcl 1388 2008-03-07 09:57:59Z sergei $ custom::defvar options(reply_iq_version) 1 \ [::msgcat::mc "Reply to version (jabber:iq:version) requests."] \ -group IQ -type boolean custom::defvar options(reply_iq_os_version) 1 \ [::msgcat::mc "Include operating system info into a reply to version\ (jabber:iq:version) requests."] \ -group IQ -type boolean proc try_linux_version {distr file flag} { global linux_distribution if {![file exists $file]} { return } if {![file readable $file]} { set linux_distribution $distr return } set fd [open $file r] set content [read $fd] close $fd set last [string first "\n" $content] if {$last < 0} { set last end } else { set last [expr {$last - 1}] } set line [string range $content 0 $last] switch -- $flag { file { set linux_distribution $line } append { set linux_distribution "$distr $line" } } } # NOTE: lsb_release on Debian Etch is known to dump some complaints to # stderr is some LSB modules are not available, so we rely only on the # existence of lsb_release and its the return code. proc get_lsb_info {} { if {[catch {exec lsb_release -a 2>/dev/null} info]} { return {} } foreach line [split $info \n] { foreach {key val} [split $line :] { set fields([string tolower $key]) [string trim $val] } } foreach key {description release codename} { if {[info exists fields($key)]} { append out "$fields($key) " } } return [string trim $out] } proc guess_linux_distribution {} { global linux_distribution if {[info exists linux_distribution] && $linux_distribution != {}} { return $linux_distribution } # First, let's see if we're on a LSB-compatible system: set linux_distribution [get_lsb_info] if {$linux_distribution != {}} { return $linux_distribution } foreach {distr file flag} { \ "SuSE Linux" /etc/SuSE-release file \ "Debian GNU/Linux" /etc/debian_version append \ "ASPLinux" /etc/asplinux-release file \ "Alt Linux" /etc/altlinux-release file \ "PLD Linux" /etc/pld-release file \ "Gentoo Linux" /etc/gentoo-release file \ "Mandrake Linux" /etc/mandrake-release file \ "RedHat Linux" /etc/redhat-release file \ "Conectiva Linux" /etc/conectiva-release file \ "Slackware Linux" /etc/slackware-version append \ "Arch Linux" /etc/arch-release file} { try_linux_version $distr $file $flag if {[info exists linux_distribution] && $linux_distribution != {}} { return $linux_distribution } } set linux_distribution Linux return $linux_distribution } proc guess_windows_version {} { global tcl_platform switch -- $tcl_platform(os) { "Win32s" { return {Windows 3.1} } "Windows 95" { switch -- $tcl_platform(osVersion) { 4.0 { return {Windows 95} } 4.10 { return {Windows 98} } 4.90 { return {Windows ME} } default { return [list $tcl_platform(os) $tcl_platform(osVersion)] } } } "Windows NT" { switch -- $tcl_platform(osVersion) { 5.0 { return {Windows 2000} } 5.1 { return {Windows XP} } 5.2 { return {Windows 2003} } 6.0 { return {Windows Vista} } default { return [list $tcl_platform(os) $tcl_platform(osVersion)] } } } default { return [list $tcl_platform(os) $tcl_platform(osVersion)] } } } proc iq_version {connid from lang child} { global tkabber_version toolkit_version tcl_platform variable options if {!$options(reply_iq_version)} { return {error cancel service-unavailable} } jlib::wrapper:splitxml $child tag vars isempty chdata children set restags [list \ [jlib::wrapper:createtag name -chdata Tkabber] \ [jlib::wrapper:createtag version -chdata \ "$tkabber_version ($toolkit_version)"]] if {$options(reply_iq_os_version)} { switch -glob -- $tcl_platform(os) { Linux { set os "[guess_linux_distribution] $tcl_platform(osVersion)" } Win* { set os [join [guess_windows_version]] } default { set os "$tcl_platform(os) $tcl_platform(osVersion)" } } lappend restags [jlib::wrapper:createtag os -chdata $os] } set res [jlib::wrapper:createtag query \ -vars {xmlns jabber:iq:version} \ -subtags $restags] return [list result $res] } iq::register_handler get query jabber:iq:version \ [namespace current]::iq_version proc disco_extra_version {connid from lang} { global tkabber_version toolkit_version tcl_platform variable options set fields \ [list [jlib::wrapper:createtag field \ -vars [list var FORM_TYPE \ type hidden] \ -subtags [list [jlib::wrapper:createtag value -chdata \ urn:xmpp:dataforms:softwareinfo]]] \ [jlib::wrapper:createtag field \ -vars [list var software] \ -subtags [list [jlib::wrapper:createtag value \ -chdata Tkabber]]] \ [jlib::wrapper:createtag field \ -vars [list var software_version] \ -subtags [list [jlib::wrapper:createtag value -chdata \ "$tkabber_version ($toolkit_version)"]]]] if {$options(reply_iq_os_version)} { switch -glob -- $tcl_platform(os) { Linux { set os [guess_linux_distribution] set os_version $tcl_platform(osVersion) } Win* { lassign [guess_windows_version] os os_version } default { set os $tcl_platform(os) set os_version $tcl_platform(osVersion) } } lappend fields \ [jlib::wrapper:createtag field \ -vars [list var os] \ -subtags [list [jlib::wrapper:createtag value \ -chdata $os]]] \ [jlib::wrapper:createtag field \ -vars [list var os_version] \ -subtags [list [jlib::wrapper:createtag value \ -chdata $os_version]]] } return [jlib::wrapper:createtag x \ -vars [list xmlns $::NS(data) \ type result] \ -subtags $fields] } hook::add postload_hook \ [list disco::register_extra [namespace current]::disco_extra_version] tkabber-0.11.1/plugins/iq/time2.tcl0000644000175000017500000000217011025270506016336 0ustar sergeisergei# $Id: time2.tcl 1461 2008-06-15 19:45:10Z sergei $ # Replies to XEP-0202 (Entity Time) queries custom::defvar options(reply_xmpp_time) 1 \ [::msgcat::mc "Reply to entity time (urn:xmpp:time) requests."] \ -group IQ -type boolean proc xmpp_time {connid from lang child} { variable options if {!$options(reply_xmpp_time)} { return {error cancel service-unavailable} } jlib::wrapper:splitxml $child tag vars isempty chdata children set curtime [clock seconds] set restags \ [list [jlib::wrapper:createtag utc \ -chdata [clock format $curtime \ -format "%Y-%m-%dT%TZ" -gmt true]] \ [jlib::wrapper:createtag tzo \ -chdata [timezone_offset]]] set res [jlib::wrapper:createtag time \ -vars {xmlns urn:xmpp:time} \ -subtags $restags] return [list result $res] } proc timezone_offset {} { set H [clock format 0 -format %H] set M [clock format 0 -format %M] set S + if {$H > 12} { set H [expr {24 - $H}] set M [expr {60 - $M}] set S - } return $S$H:$M } iq::register_handler get time urn:xmpp:time \ [namespace current]::xmpp_time tkabber-0.11.1/plugins/iq/browse.tcl0000644000175000017500000000103410665573256016636 0ustar sergeisergei# $Id: browse.tcl 1203 2007-08-30 16:56:14Z sergei $ proc iq_browse_reply {connid from lang child} { set restags {} foreach ns [lsort $::iq::supported_ns] { lappend restags [jlib::wrapper:createtag ns \ -chdata $ns] } set res [jlib::wrapper:createtag query \ -vars {xmlns jabber:iq:browse \ category user \ type client \ name Tkabber} \ -subtags $restags] return [list result $res] } iq::register_handler get {} jabber:iq:browse \ [namespace current]::iq_browse_reply tkabber-0.11.1/plugins/iq/last.tcl0000644000175000017500000000171010547441553016272 0ustar sergeisergei# $Id: last.tcl 859 2007-01-05 12:24:11Z sergei $ custom::defvar options(reply_iq_last) 1 \ [::msgcat::mc "Reply to idle time (jabber:iq:last) requests."] \ -group IQ -type boolean proc iq_last {connid from lang child} { global idle_command global userstatus statusdesc textstatus variable options jlib::wrapper:splitxml $child tag vars isempty chdata children if {$options(reply_iq_last) && [info exists idle_command]} { set seconds [expr {[eval $idle_command]/1000}] set status $statusdesc($userstatus) if {[cequal $textstatus ""]} { set status "$statusdesc($userstatus) ($userstatus)" } else { set status "$textstatus ($userstatus)" } return [list result [jlib::wrapper:createtag query \ -vars [list xmlns jabber:iq:last seconds $seconds] \ -chdata $status]] } else { return [list error cancel service-unavailable] } } iq::register_handler get query jabber:iq:last [namespace current]::iq_last tkabber-0.11.1/plugins/iq/ping.tcl0000644000175000017500000000510310702176511016254 0ustar sergeisergei# $Id: ping.tcl 1259 2007-10-07 15:37:45Z sergei $ # Reply to XMPP Ping (XEP-0199) support ############################################################################# namespace eval ping { custom::defvar options(ping) 0 \ [::msgcat::mc "Ping server using urn:xmpp:ping requests."] \ -group IQ \ -type boolean \ -command [namespace current]::start_all custom::defvar options(timeout) 30 \ [::msgcat::mc "Reconnect to server if it does not reply (with result\ or with error) to ping (urn:xmpp:ping) request in\ specified time interval (in seconds)."] \ -group IQ \ -type integer \ -command [namespace current]::start_all custom::defvar options(pong) 1 \ [::msgcat::mc "Reply to ping (urn:xmpp:ping) requests."] \ -group IQ \ -type boolean variable sequence iq::register_handler get query urn:xmpp:ping [namespace current]::reply hook::add connected_hook [namespace current]::start } ############################################################################# proc ping::reply {connid from lang child} { variable options if {$options(pong)} { return [list result {}] } else { return [list error cancel service-unavailable] } } ############################################################################# proc ping::start_all {args} { variable options if {!$options(ping) || ($options(timeout) <= 0)} return foreach connid [jlib::connections] { start $connid } } ############################################################################# proc ping::start {connid} { variable options variable sequence after cancel [list [namespace current]::start $connid] if {!$options(ping) || ($options(timeout) <= 0)} return if {![info exists sequence($connid)]} { set sequence($connid) 0 } else { incr sequence($connid) } jlib::send_iq get \ [jlib::wrapper:createtag ping \ -vars [list xmlns urn:xmpp:ping]] \ -timeout [expr {$options(timeout)*1000}] \ -connection $connid \ -command [list [namespace current]::result $connid $sequence($connid)] } proc ping::result {connid seq res child} { variable options variable sequence if {!$options(ping) || ($options(timeout) <= 0)} return if {![lcontain [jlib::connections] $connid]} return if {$res == "DISCONNECT"} return if {$seq < $sequence($connid)} return if {$res == "TIMEOUT"} { # TODO jlib::inmsg $connid "" 1 return } after [expr {$options(timeout)*1000}] \ [list [namespace current]::start $connid] } ############################################################################# tkabber-0.11.1/plugins/iq/oob.tcl0000644000175000017500000000000010070634007016062 0ustar sergeisergeitkabber-0.11.1/plugins/iq/time.tcl0000644000175000017500000000305410503604452016257 0ustar sergeisergei# $Id: time.tcl 722 2006-09-18 21:01:30Z sergei $ custom::defvar options(reply_iq_time) 1 \ [::msgcat::mc "Reply to current time (jabber:iq:time) requests."] \ -group IQ -type boolean proc iq_time {connid from lang child} { variable options if {!$options(reply_iq_time)} { return {error cancel service-unavailable} } jlib::wrapper:splitxml $child tag vars isempty chdata children set curtime [clock seconds] set restags \ [list [jlib::wrapper:createtag utc \ -chdata [clock format $curtime \ -format "%Y%m%dT%T" -gmt true]] \ [jlib::wrapper:createtag tz -chdata \ [timezone $curtime]] \ [jlib::wrapper:createtag display \ -chdata [displaytime $curtime]]] set res [jlib::wrapper:createtag query \ -vars {xmlns jabber:iq:time} \ -subtags $restags] return [list result $res] } proc timezone {time} { global tcl_platform if {[cequal $tcl_platform(platform) "windows"] && \ [package vcompare [info patchlevel] 8.4.12] < 0} { return [string trim [encoding convertfrom utf-8 \ [encoding convertto [clock format $time -format "%Z%t"]]]] } else { return [clock format $time -format %Z] } } proc displaytime {time} { global tcl_platform if {[cequal $tcl_platform(platform) "windows"] && \ [package vcompare [info patchlevel] 8.4.12] < 0} { return [encoding convertfrom utf-8 \ [encoding convertto [clock format $time]]] } else { return [clock format $time] } } iq::register_handler get query jabber:iq:time \ [namespace current]::iq_time tkabber-0.11.1/plugins/roster/0000755000175000017500000000000011076120366015523 5ustar sergeisergeitkabber-0.11.1/plugins/roster/fetch_nicknames.tcl0000644000175000017500000000534511014026560021350 0ustar sergeisergei# $Id: fetch_nicknames.tcl 1430 2008-05-18 13:21:52Z sergei $ # Fetch roster item nickname(s) from vCard and set roster label(s) namespace eval fetch_nickname {} proc fetch_nickname::service_request {connid service} { foreach jid [::roster::get_jids $connid] { if {[server_from_jid $jid] == [server_from_jid $service]} { user_request $connid $jid } } } proc fetch_nickname::request_group_nicks {connid group args} { foreach jid [eval [list ::roster::get_group_jids $connid $group] $args] { if {[string equal [::roster::itemconfig $connid $jid -category] user]} { user_request $connid $jid } } } proc fetch_nickname::user_request {connid jid} { jlib::send_iq get \ [jlib::wrapper:createtag vCard \ -vars [list xmlns vcard-temp]] \ -to $jid \ -connection $connid \ -command [list [namespace current]::parse_result $connid $jid] } proc fetch_nickname::parse_result {connid jid res child} { if {$res != "OK"} return jlib::wrapper:splitxml $child tag vars isempty chdata children foreach item $children { userinfo::parse_vcard_item $jid $item } if {[info exists ::userinfo::userinfo(nickname,$jid)] && \ ![cequal $::userinfo::userinfo(nickname,$jid) ""]} { roster::itemconfig $connid $jid \ -name $::userinfo::userinfo(nickname,$jid) roster::send_item $connid $jid } } proc fetch_nickname::extend_user_menu {m connid jid} { set rjid [roster::find_jid $connid $jid] if {$rjid == ""} { set state disabled } else { set state normal } $m add command -label [::msgcat::mc "Fetch nickname"] \ -command [list [namespace current]::user_request $connid $rjid] \ -state $state } hook::add chat_create_user_menu_hook \ [namespace current]::fetch_nickname::extend_user_menu 73 hook::add roster_jid_popup_menu_hook \ [namespace current]::fetch_nickname::extend_user_menu 73 proc fetch_nickname::extend_service_menu {m connid jid} { set rjid [roster::find_jid $connid $jid] if {$rjid == ""} { set state disabled } else { set state normal } $m add command -label [::msgcat::mc "Fetch user nicknames"] \ -command [list [namespace current]::service_request $connid $rjid] \ -state $state } hook::add roster_service_popup_menu_hook \ [namespace current]::fetch_nickname::extend_service_menu 73 proc fetch_nickname::extend_group_menu {m connid name} { variable ::ifacetk::roster::options $m add command \ -label [::msgcat::mc "Fetch nicknames of all users in group"] \ -command [list [namespace current]::request_group_nicks $connid $name \ -nested $options(nested) \ -delimiter $options(nested_delimiter)] } hook::add roster_group_popup_menu_hook \ [namespace current]::fetch_nickname::extend_group_menu # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/plugins/roster/conferenceinfo.tcl0000644000175000017500000001222710657625177021234 0ustar sergeisergei# $Id: conferenceinfo.tcl 1184 2007-08-12 15:42:55Z sergei $ namespace eval conferenceinfo { custom::defgroup ConferenceInfo \ [::msgcat::mc "Options for Conference Info module, that allows you to see list of\ participants in roster popup, regardless of whether you are currently joined\ with the conference."] \ -group Tkabber \ -tag "Conference Info" custom::defvar options(autoask) 0 \ [::msgcat::mc "Use this module"] -group ConferenceInfo -type boolean \ -command [namespace current]::ask custom::defvar options(interval) 2 \ [::msgcat::mc "Interval (in minutes) between requests of participants list."] \ -type integer -group ConferenceInfo custom::defvar options(err_interval) 60 \ [::msgcat::mc "Interval (in minutes) after error reply on request of participants list."] \ -type integer -group ConferenceInfo } # TODO: connid proc conferenceinfo::add_user_popup_info {infovar connid jid} { variable data variable options upvar 0 $infovar info if {!$options(autoask)} return if {[chat::is_opened [chat::chatid $connid $jid]]} return if {![info exists data(error_browse,$jid)] || \ ![info exists data(error_disco,$jid)]} return if {$data(error_disco,$jid) != "" && $data(error_browse,$jid) != ""} { if {$data(error_browse_code,$jid) != "feature-not-implemented" && \ $data(error_browse_code,$jid) != "service-unavailable"} { set errstr $data(error_browse,$jid) } else { set errstr $data(error_disco,$jid) } append info [format [::msgcat::mc "\n\tCan't browse: %s"] $errstr] } else { if {$data(error_browse,$jid) == ""} { set mech browse } else { set mech disco } if {$data(users_$mech,$jid) != {}} { append info \ [format [::msgcat::mc "\nRoom participants at %s:"] \ [clock format $data(time_$mech,$jid) -format %R]] foreach name $data(users_$mech,$jid) { append info "\n\t$name" } } else { append info \ [format [::msgcat::mc "\nRoom is empty at %s"] \ [clock format $data(time_$mech,$jid) -format %R]] } } } hook::add roster_user_popup_info_hook \ [namespace current]::conferenceinfo::add_user_popup_info proc conferenceinfo::ask {args} { variable options variable data if {!$options(autoask)} return foreach connid [jlib::connections] { if {[catch { set roster::roster(jids,$connid) } jids]} { continue } foreach jid $jids { lassign [roster::get_category_and_subtype $connid $jid] \ category type if {$category == "conference" && [node_from_jid $jid] != "" && \ ![chat::is_opened [chat::chatid $connid $jid]]} { set sec [clock seconds] if {![info exists data(error_browse,$jid)] || \ $data(error_browse,$jid) == "" || \ $sec - $data(time_browse,$jid) >= $options(err_interval) * 60} { jlib::send_iq get \ [jlib::wrapper:createtag query \ -vars {xmlns jabber:iq:browse}] \ -to $jid \ -connection $connid \ -command [list [namespace current]::receive $jid browse] } if {![info exists data(error_disco,$jid)] || \ $data(error_disco,$jid) == "" || \ $sec - $data(time_disco,$jid) >= $options(err_interval) * 60} { jlib::send_iq get \ [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(disco_items)]] \ -to $jid \ -connection $connid \ -command [list [namespace current]::receive $jid disco] } } } } after cancel [list [namespace current]::ask] after [expr {$options(interval) * 60 * 1000}] [list [namespace current]::ask] } proc conferenceinfo::receive {jid mech res child} { variable options variable data set data(error_$mech,$jid) "" set data(error_${mech}_code,$jid) "" set data(time_$mech,$jid) [clock seconds] set data(users_$mech,$jid) {} if {$res != "OK"} { set data(error_${mech}_code,$jid) [lindex [error_type_condition $child] 1] set data(error_$mech,$jid) [error_to_string $child] return } jlib::wrapper:splitxml $child tag vars isempty chdata children foreach item $children { jlib::wrapper:splitxml $item tag1 vars1 isempty1 chdata1 children1 switch -- $mech { browse { if {$tag1 == "user" || ($tag1 == "item" && \ [jlib::wrapper:getattr $vars1 category] == "user")} { set name [jlib::wrapper:getattr $vars1 name] if {$name != ""} { lappend data(users_browse,$jid) $name } } } disco { if {$tag1 == "item"} { set node [jlib::wrapper:getattr $vars1 node] set name [jlib::wrapper:getattr $vars1 name] if {$name != "" && $node == ""} { lappend data(users_disco,$jid) $name } } } } } set data(users_$mech,$jid) [lsort -dictionary $data(users_$mech,$jid)] } proc conferenceinfo::stop {args} { if {[jlib::connections] == {}} { after cancel [list [namespace current]::ask] } } hook::add roster_end_hook [namespace current]::conferenceinfo::ask hook::add disconnected_hook [namespace current]::conferenceinfo::stop proc conferenceinfo::setup_menu {} { set m [.mainframe getmenu roster] $m add checkbutton \ -label [::msgcat::mc "Periodically browse roster conferences"] \ -variable [namespace current]::options(autoask) } hook::add finload_hook [namespace current]::conferenceinfo::setup_menu tkabber-0.11.1/plugins/roster/bkup_conferences.tcl0000644000175000017500000000635611014607652021554 0ustar sergeisergei# $Id: bkup_conferences.tcl 1440 2008-05-20 17:51:38Z sergei $ # Support for backup/restore of "roster bookmarks" to MUC rooms (XEP-0048, v1.0) # Depends on: conferences.tcl, backup.tcl namespace eval mucbackup { # Should probably go after the roster contacts, so we set prio to 70: hook::add serialize_roster_hook \ [namespace current]::serialize_muc_bookmarks 70 hook::add deserialize_roster_hook \ [namespace current]::deserialize_muc_bookmarks 70 } ############################################################################### proc mucbackup::serialize_muc_bookmarks {connid level varName} { upvar $level $varName subtags global NS foreach xmldata [::plugins::conferences::serialize_bookmarks $connid] { lappend subtags [jlib::wrapper:createtag privstorage \ -vars [list xmlns $NS(private)] \ -subtags [list $xmldata]] } } ############################################################################### proc mucbackup::deserialize_muc_bookmarks {connid data level varName} { global NS upvar $level $varName handlers set bookmarks [list] set bmgroups [list] foreach item $data { jlib::wrapper:splitxml $item tag vars isempty cdata children if {![string equal $tag privstorage]} continue set xmlns [jlib::wrapper:getattr $vars xmlns] if {![string equal $xmlns $NS(private)]} { return -code error "Bad roster element namespace \"$xmlns\":\ must be \"$NS(private)\"" } foreach storage $children { jlib::wrapper:splitxml $storage ctag cvars cisempty ccdata cchildren if {![string equal $ctag storage]} continue set xmlns [jlib::wrapper:getattr $cvars xmlns] switch -- $xmlns \ $NS(bookmarks) { set bookmarks [concat $bookmarks $cchildren] } \ $NS(tkabber:groups) { set bmgroups [concat $bmgroups $cchildren] } } } if {[llength $bookmarks] > 0 && [llength $bmgroups] > 0} { lappend handlers [list 70 [namespace code [list \ merge_muc_bookmarks $connid $bookmarks $bmgroups]]] } } ############################################################################### proc mucbackup::merge_muc_bookmarks {connid bookmarks bmgroups continuation} { variable updated 0 foreach item $bookmarks { set added [::plugins::conferences::create_muc_bookmark \ $connid $item -merge yes] set updated [expr {$updated || $added}] } foreach item $bmgroups { set added [::plugins::conferences::create_muc_bmgroup \ $connid $item -merge yes] set updated [expr {$updated || $added}] } if {$updated} { ::plugins::conferences::store_bookmarks $connid \ -command [namespace code [list process_merging_result $continuation]] ::plugins::conferences::push_bookmarks_to_roster $connid } else { eval $continuation } } ############################################################################### proc mucbackup::process_merging_result {continuation result xmldata} { switch -- $result { OK { eval $continuation } default { # TODO check whether TIMEOUT should be processed separately NonmodalMessageDlg [epath] \ -aspect 50000 \ -icon error \ -title [::msgcat::mc "Error"] \ -message [::msgcat::mc "Error restoring conference bookmarks: %s" \ [error_to_string $xmldata]] } } } # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/plugins/roster/backup.tcl0000644000175000017500000002025111014607652017474 0ustar sergeisergei# $Id: backup.tcl 1440 2008-05-20 17:51:38Z sergei $ # Export/import of the roster items using an XML file. # This code provides basic framework for handling roster backup # files and it's able to serialize/deserialize regular roster contacts. # Hooks provided to facilitate implementations of storing/restoring # other kinds of data logically pertaining to the roster # such as conference bookmarks, annotations, etc. namespace eval rosterbackup { global NS set NS(rosterbackup) http://tkabber.jabber.ru/contactlist hook::add connected_hook \ [namespace current]::setup_import_export_menus hook::add disconnected_hook \ [namespace current]::setup_import_export_menus hook::add finload_hook \ [namespace current]::setup_import_export_menus hook::add serialize_roster_hook \ [namespace current]::serialize_roster_contacts hook::add deserialize_roster_hook \ [namespace current]::deserialize_roster_contacts } ############################################################################### proc rosterbackup::setup_import_export_menus {args} { set emenu [.mainframe getmenu export_roster] set imenu [.mainframe getmenu import_roster] if {[winfo exists $emenu]} { destroy $emenu } menu $emenu -tearoff 0 if {[winfo exists $imenu]} { destroy $imenu } menu $imenu -tearoff 0 if {[jlib::connections] == {}} { .mainframe setmenustate export_roster disabled .mainframe setmenustate import_roster disabled } else { .mainframe setmenustate export_roster normal .mainframe setmenustate import_roster normal } foreach c [jlib::connections] { set jid [jlib::connection_jid $c] set label [format [::msgcat::mc "Roster of %s"] $jid] set ecommand [list [namespace current]::export_to_file $c] set icommand [list [namespace current]::import_from_file $c] $emenu add command -label $label -command $ecommand $imenu add command -label $label -command $icommand } } ############################################################################### proc rosterbackup::export_to_file {connid} { set filename [tk_getSaveFile \ -initialdir $::configdir \ -initialfile [jlib::connection_user $connid]-roster.xml \ -filetypes [list \ [list [::msgcat::mc "Roster Files"] \ .xml] \ [list [::msgcat::mc "All Files"] *]]] if {$filename == ""} return set fd [open $filename w] fconfigure $fd -encoding utf-8 puts $fd {} puts $fd [serialize_roster $connid] close $fd } ############################################################################### proc rosterbackup::serialize_roster {connid} { global NS set subtags [list] hook::run serialize_roster_hook $connid #[info level] subtags jlib::wrapper:createxml [jlib::wrapper:createtag contactlist \ -vars [list xmlns $NS(rosterbackup)] -subtags $subtags] \ -prettyprint 1 } ############################################################################### proc rosterbackup::serialize_roster_contacts {connid level varName} { upvar $level $varName subtags set items [list] foreach jid [::roster::get_jids $connid] { set category [::roster::itemconfig $connid $jid -category] switch -- $category { user - gateway { lappend items [::roster::item_to_xml $connid $jid] } } } lappend subtags [jlib::wrapper:createtag roster \ -vars {xmlns jabber:iq:roster} \ -subtags $items] } ############################################################################### proc rosterbackup::import_from_file {connid} { set filename [tk_getOpenFile \ -initialdir $::configdir \ -initialfile [jlib::connection_user $connid]-roster.xml \ -filetypes [list \ [list [::msgcat::mc "Roster Files"] \ .xml] \ [list [::msgcat::mc "All Files"] *]]] if {$filename == ""} return set fd [open $filename r] fconfigure $fd -encoding utf-8 set xml [string trimleft [read $fd] [format %c 0xFEFF]] ;# strip BOM, if any close $fd deserialize_roster $connid $xml } ############################################################################### proc rosterbackup::deserialize_roster {connid data} { hook::run roster_deserializing_hook $connid set parser [jlib::wrapper:new "#" "#" \ [list [namespace current]::parse_roster_xml $connid]] jlib::wrapper:elementstart $parser stream:stream {} {} jlib::wrapper:parser $parser parse $data jlib::wrapper:parser $parser configure -final 0 jlib::wrapper:free $parser hook::run roster_deserialized_hook $connid } ############################################################################### proc rosterbackup::parse_roster_xml {connid data} { global NS jlib::wrapper:splitxml $data tag vars isempty cdata children if {![string equal $tag contactlist]} { return -code error "Bad root element \"$tag\":\ must be contactlist" } set xmlns [jlib::wrapper:getattr $vars xmlns] if {![string equal $xmlns $NS(rosterbackup)]} { return -code error "Bad root element namespace \"$xmlns\":\ must be \"$NS(rosterbackup)\"" } set tuples [list] hook::run deserialize_roster_hook $connid $children #[info level] tuples if {[llength $tuples] > 0} { set scripts [list] foreach tuple [lsort -integer -index 0 $tuples] { lappend scripts [lindex $tuple 1] } [namespace current]::run_deserialization_scripts $scripts } } ############################################################################### proc rosterbackup::run_deserialization_scripts {scripts} { if {[llength $scripts] == 0} return uplevel #0 [linsert [lindex $scripts 0] end \ [list [lindex [info level 0] 0] [lrange $scripts 1 end]]] } ############################################################################### proc rosterbackup::deserialize_roster_contacts {connid data level varName} { global NS upvar $level $varName handlers array set existing {} foreach jid [::roster::get_jids $connid] { set existing($jid) {} } upvar 0 sent($connid,jids) jids set jids [list] set subtags [list] foreach item $data { jlib::wrapper:splitxml $item tag vars isempty cdata children if {![string equal $tag roster]} continue set xmlns [jlib::wrapper:getattr $vars xmlns] if {![string equal $xmlns $NS(roster)]} { return -code error "Bad roster element namespace \"$xmlns\":\ must be \"$NS(roster)\"" } foreach child $children { set jid [get_item_jid $child] if {![info exists existing($jid)]} { lappend jids $jid lappend subtags $child } } } if {[llength $subtags] > 0} { lappend handlers [list 50 [namespace code [list \ send_contacts $connid $subtags]]] } lappend handlers [list 1000 [namespace code [list \ show_restore_completion_dialog $connid]]] } ############################################################################### proc rosterbackup::get_item_jid {data} { jlib::wrapper:splitxml $data ? vars ? ? ? jlib::wrapper:getattr $vars jid } ############################################################################### proc rosterbackup::send_contacts {connid contacts continuation} { global NS jlib::send_iq set \ [jlib::wrapper:createtag query \ -vars [list xmlns $NS(roster)] \ -subtags $contacts] \ -connection $connid \ -command [namespace code [list process_send_result $continuation]] } ############################################################################### proc rosterbackup::process_send_result {continuation result xmldata} { switch -- $result { OK { eval $continuation } default { # TODO check whether do we need to handle TIMEOUT specially NonmodalMessageDlg [epath] \ -aspect 50000 \ -icon error \ -title [::msgcat::mc "Error"] \ -message [::msgcat::mc "Error restoring roster contacts: %s" \ [error_to_string $xmldata]] } } } ############################################################################### proc rosterbackup::show_restore_completion_dialog {connid continuation} { NonmodalMessageDlg [epath] \ -aspect 50000 \ -icon info \ -title [::msgcat::mc "Information"] \ -message [::msgcat::mc "Roster restoration completed"] eval $continuation } # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/plugins/roster/conferences.tcl0000644000175000017500000006457011062001355020524 0ustar sergeisergei# $Id: conferences.tcl 1498 2008-09-10 17:25:01Z sergei $ # # 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: # # # # # Conferences # jabber.ru # # # # # # getting: # # # # # # 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 args} { set command [list [namespace current]::store_bookmarks_result $connid] foreach {opt val} $args { switch -- $opt { -command { set command $val } default { return -code error "Bad option \"$opt\":\ must be -command" } } } foreach item [serialize_bookmarks $connid] { private::store [list $item] \ -command $command \ -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] # TODO: Check for real MUC? Move to muc.tcl? muc::add_muc_menu_items $m [chat::chatid $connid $jid] end } 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 tkabber-0.11.1/plugins/roster/roster_delimiter.tcl0000644000175000017500000000400710674777354021626 0ustar sergeisergei# $Id: roster_delimiter.tcl 1237 2007-09-21 17:27:08Z sergei $ # # Nested roster groups server-side delimiter storing (XEP-0083). # ############################################################################### namespace eval delimiter {} ############################################################################### # # Retrieving nested groups delimiter # proc delimiter::request {connid fallback args} { debugmsg plugins "delimiter::request $connid $fallback $args" set command "" foreach {key val} $args { switch -- $key { -command { set command $val } } } private::retrieve [list [jlib::wrapper:createtag roster \ -vars [list xmlns $::NS(delimiter)]]] \ -command [list [namespace current]::request_result \ $connid $fallback $command] \ -connection $connid } proc delimiter::request_result {connid fallback command res child} { debugmsg plugins "delimiter::request_result $connid $res" set delimiter $fallback if {$res == "OK"} { foreach ch $child { jlib::wrapper:splitxml $ch tag1 vars1 isempty1 cdata1 children1 if {[jlib::wrapper:getattr $vars1 xmlns] == $NS(delimiter)} { set delimiter $cdata1 } } } if {$command != ""} { eval $command [list $connid $delimiter] } } ############################################################################### # # Storing nested groups delimiter # proc delimiter::store {connid delimiter args} { debugmsg plugins "delimiter::store $connid $delimiter $args" set command "" foreach {key val} $args { switch -- $key { -command { set command $val } } } private::store [list [jlib::wrapper:createtag roster \ -vars [list xmlns $::NS(delimiter)] \ -chdata $delimiter]] \ -command [list [namespace current]::store_result $connid $command] \ -connection $connid } proc delimiter::store_result {connid command res child} { debugmsg plugins "delimiter::store_result $connid $res" if {$command != ""} { eval $command [list $res $child] } } tkabber-0.11.1/plugins/roster/bkup_annotations.tcl0000644000175000017500000000546611014607652021620 0ustar sergeisergei# $Id: bkup_annotations.tcl 1440 2008-05-20 17:51:38Z sergei $ # Support for backup/restore of "annotations" (XEP-0145) # for roster items. # Depends on: annotations.tcl, backup.tcl namespace eval annobackup { # Should probably go after the roster contacts, so we set prio to 60: hook::add serialize_roster_hook \ [namespace current]::serialize_annotations 60 hook::add deserialize_roster_hook \ [namespace current]::deserialize_annotations 60 } ############################################################################### proc annobackup::serialize_annotations {connid level varName} { upvar $level $varName subtags global NS set xmldata [::plugins::annotations::serialize_notes $connid] lappend subtags [jlib::wrapper:createtag privstorage \ -vars {xmlns jabber:iq:private} \ -subtags [list $xmldata]] } ############################################################################### proc annobackup::deserialize_annotations {connid data level varName} { global NS upvar $level $varName handlers set notes [list] foreach item $data { jlib::wrapper:splitxml $item tag vars isempty cdata children if {![string equal $tag privstorage]} continue set xmlns [jlib::wrapper:getattr $vars xmlns] if {![string equal $xmlns $NS(private)]} { return -code error "Bad roster element namespace \"$xmlns\":\ must be \"$NS(private)\"" } foreach storage $children { jlib::wrapper:splitxml $storage ctag cvars cisempty ccdata cchildren if {![string equal $ctag storage]} continue set xmlns [jlib::wrapper:getattr $cvars xmlns] if {![string equal $xmlns $NS(rosternotes)]} continue set notes [concat $notes $cchildren] } } if {[llength $notes] > 0} { lappend handlers [list 60 [namespace code [list \ send_notes $connid $notes]]] } } ############################################################################### proc annobackup::send_notes {connid notes continuation} { set updated 0 foreach item $notes { set added [::plugins::annotations::create_note \ $connid $item -merge yes] set updated [expr {$updated || $added}] } if {$updated} { ::plugins::annotations::cleanup_and_store_notes $connid \ -command [namespace code [list process_sending_result $continuation]] } else { eval $continuation } } ############################################################################### proc annobackup::process_sending_result {continuation result xmldata} { switch -- $result { OK { eval $continuation } default { # TODO check whether do we need to handle TIMEOUT specially NonmodalMessageDlg [epath] \ -aspect 50000 \ -icon error \ -title [::msgcat::mc "Error"] \ -message [::msgcat::mc "Error restoring annotations: %s" \ [error_to_string $xmldata]] } } } # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/plugins/roster/cache_categories.tcl0000644000175000017500000000544610534271023021503 0ustar sergeisergei# $Id: cache_categories.tcl 816 2006-12-02 12:31:15Z sergei $ namespace eval cache_categories { # {server1 {category1 type1} server2 {category2 type2}} custom::defvar category_and_subtype_list {} \ [::msgcat::mc "Cached service categories and types (from disco#info)."] \ -type string -group Hidden variable requested_categories } ############################################################################## proc cache_categories::fill_cached_categories_and_subtypes {connid} { variable category_and_subtype_list variable requested_categories catch { array set tmp $category_and_subtype_list } set requested_categories($connid) [array names tmp] foreach jid [array names tmp] { lassign $tmp($jid) category subtype roster::override_category_and_subtype $connid $jid \ $category $subtype } } hook::add connected_hook \ [namespace current]::cache_categories::fill_cached_categories_and_subtypes 5 ############################################################################## proc cache_categories::free_cached_categories_and_subtypes {connid} { variable category_and_subtype_list variable requested_categories if {$connid == {}} { array unset requested_categories } else { catch { unset requested_categories($connid) } } } hook::add disconnected_hook \ [namespace current]::cache_categories::free_cached_categories_and_subtypes ############################################################################## proc cache_categories::request_category_and_subtype {connid jid} { variable category_and_subtype_list variable requested_categories set server [server_from_jid $jid] if {[lsearch -exact $requested_categories($connid) $server] >= 0} { return } lappend requested_categories($connid) $server jlib::send_iq get \ [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(disco_info)]] \ -to $server \ -connection $connid \ -command [list [namespace current]::parse_requested_categories $connid $server] } ############################################################################## proc cache_categories::parse_requested_categories {connid server res child} { variable category_and_subtype_list if {$res != "OK"} return jlib::wrapper:splitxml $child tag vars isempty chdata children foreach ch $children { jlib::wrapper:splitxml $ch tag1 vars1 isempty1 chdata1 children1 switch -- $tag1 { identity { set category [jlib::wrapper:getattr $vars1 category] set type [jlib::wrapper:getattr $vars1 type] roster::override_category_and_subtype $connid $server \ $category $type lappend category_and_subtype_list \ $server [list $category $type] ::redraw_roster break } } } } ############################################################################### tkabber-0.11.1/plugins/roster/rosterx.tcl0000644000175000017500000001373211011554251017734 0ustar sergeisergei# $Id: rosterx.tcl 1408 2008-05-11 11:29:45Z sergei $ # # Roster Item Exchange Support (XEP-0093 and XEP-0144) # namespace eval rosterx {} ############################################################################### proc rosterx::process_x {rowvar bodyvar f x connid from id type replyP} { upvar 2 $rowvar row upvar 2 $bodyvar body set rosterx 0 foreach xa $x { jlib::wrapper:splitxml $xa tag vars isempty chdata children set xmlns [jlib::wrapper:getattr $vars xmlns] switch -- $xmlns \ $::NS(rosterx) { set rosterx 1 foreach child $children { process_x_rosterx $f $child $row $connid $from incr row } } \ $::NS(xroster) { if {$rosterx} break foreach child $children { process_x_xroster $f $child $row $connid $from incr row } } } return } hook::add message_process_x_hook [namespace current]::rosterx::process_x 60 ############################################################################### proc rosterx::process_x_rosterx {f x row connid from} { jlib::wrapper:splitxml $x tag vars isempty chdata children set jid [jlib::wrapper:getattr $vars jid] set name [jlib::wrapper:getattr $vars name] set action [jlib::wrapper:getattr $vars action] if {$jid == ""} return if {$name != ""} { set desc "$name ($jid)" } else { set desc $jid } label $f.luser$row -text [::msgcat::mc "Attached user:"] set cb [button $f.user$row -text $desc \ -command [list [namespace current]::process_user $connid $jid \ $name "$from asked me to add you to my roster."]] grid $f.luser$row -row $row -column 0 -sticky e grid $f.user$row -row $row -column 1 -sticky ew } ############################################################################### proc rosterx::process_x_xroster {f x row connid from} { jlib::wrapper:splitxml $x tag vars isempty chdata children set jid [jlib::wrapper:getattr $vars jid] set name [jlib::wrapper:getattr $vars name] if {$jid == ""} return if {$name != ""} { set desc "$name ($jid)" } else { set desc $jid } label $f.luser$row -text [::msgcat::mc "Attached user:"] set cb [button $f.user$row -text $desc \ -command [list [namespace current]::process_user $connid $jid \ $name "$from asked me to add you to my roster."]] grid $f.luser$row -row $row -column 0 -sticky e grid $f.user$row -row $row -column 1 -sticky ew } ############################################################################### proc rosterx::process_user {connid jid name body} { jlib::send_presence -to $jid \ -type subscribe \ -stat $body \ -connection $connid set vars [list jid $jid] if {$name != ""} { lappend vars name $name } jlib::send_iq set \ [jlib::wrapper:createtag query \ -vars [list xmlns $::NS(roster)] \ -subtags [list [jlib::wrapper:createtag item \ -vars $vars]]] \ -connection $connid } ############################################################################### proc rosterx::send_users_dialog {connid user} { global send_uc set jid [get_jid_of_user $connid $user] if {[cequal $jid ""]} { set jid $user } set gw .contacts catch { destroy $gw } if {[catch { set nick [roster::get_label $connid $user] }]} { if {[catch { set nick [chat::get_nick $connid \ $user groupchat] }]} { set nick $user } } set choices {} set balloons {} foreach c [jlib::connections] { foreach choice [roster::get_jids $c] { if {[roster::itemconfig $c $choice -isuser]} { lappend choices [list $c $choice] [roster::get_label $c $choice] lappend balloons [list $c $choice] $choice } } } if {[llength $choices] == 0} { MessageDlg ${gw}_err -aspect 50000 -icon info \ -message [::msgcat::mc "No users in roster..."] -type user \ -buttons ok -default 0 -cancel 0 return } CbDialog $gw [format [::msgcat::mc "Send contacts to %s"] $nick] \ [list [::msgcat::mc "Send"] \ [list [namespace current]::send_users $gw $connid $jid] \ [::msgcat::mc "Cancel"] \ [list destroy $gw]] \ send_uc $choices $balloons } ############################################################################### proc rosterx::add_menu_item {m connid jid} { $m add command \ -label [::msgcat::mc "Send users..."] \ -command [list [namespace current]::send_users_dialog $connid $jid] } hook::add roster_create_groupchat_user_menu_hook \ [namespace current]::rosterx::add_menu_item 45 hook::add chat_create_user_menu_hook \ [namespace current]::rosterx::add_menu_item 45 hook::add roster_jid_popup_menu_hook \ [namespace current]::rosterx::add_menu_item 45 hook::add message_dialog_menu_hook \ [namespace current]::rosterx::add_menu_item 45 hook::add search_popup_menu_hook \ [namespace current]::rosterx::add_menu_item 45 ############################################################################### proc rosterx::send_users {gw connid jid} { global send_uc set sf [$gw getframe].sw.sf set choices {} foreach uc [array names send_uc] { if {$send_uc($uc)} { lappend choices $uc } } destroy $gw set subtags {} set body [::msgcat::mc "Contact Information"] foreach choice $choices { lassign $choice con uc lappend subtags [roster::item_to_xml $con $uc] set nick [roster::get_label $con $uc] append body "\n$nick - xmpp:$uc" } message::send_msg $jid -type normal -body $body \ -xlist [list \ [jlib::wrapper:createtag x \ -vars [list xmlns $::NS(rosterx)] \ -subtags $subtags] \ [jlib::wrapper:createtag x \ -vars [list xmlns $::NS(xroster)] \ -subtags $subtags]] \ -connection $connid } ############################################################################### disco::register_feature $::NS(rosterx) tkabber-0.11.1/plugins/roster/annotations.tcl0000644000175000017500000002303010764214265020567 0ustar sergeisergei# $Id: annotations.tcl 1389 2008-03-07 10:28:05Z sergei $ # # Annotations (XEP-0145) support # namespace eval annotations { # variable to store roster notes array set notes {} set ::NS(rosternotes) "storage:rosternotes" } proc annotations::free_notes {connid} { variable notes array unset notes $connid,* } hook::add disconnected_hook [namespace current]::annotations::free_notes proc annotations::request_notes {connid} { variable NS variable notes private::retrieve [list [jlib::wrapper:createtag storage \ -vars [list xmlns $::NS(rosternotes)]]] \ -command [list [namespace current]::process_notes $connid] \ -connection $connid } hook::add connected_hook [namespace current]::annotations::request_notes proc annotations::process_notes {connid res child} { variable notes if {$res != "OK"} return free_notes $connid foreach xmldata $child { jlib::wrapper:splitxml $xmldata tag vars isempty cdata children if {[jlib::wrapper:getattr $vars xmlns] == $::NS(rosternotes)} { foreach note $children { create_note $connid $note } } } } proc annotations::create_note {connid xmldata args} { variable notes 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 tag vars isempty cdata children set jid [jlib::wrapper:getattr $vars jid] set cdate [jlib::wrapper:getattr $vars cdate] set mdate [jlib::wrapper:getattr $vars mdate] if {![catch { scan_time $cdate } cdate]} { set cdate [clock seconds] } if {![catch { scan_time $mdate } mdate]} { set cdate [clock seconds] } if {!$merge || [more_recent $connid $jid $cdate $mdate]} { set notes($connid,jid,$jid) $jid set notes($connid,cdate,$jid) $cdate set notes($connid,mdate,$jid) $mdate set notes($connid,note,$jid) $cdata return 1 } else { return 0 } } proc annotations::scan_time {timestamp} { if {[regexp {(.*)T(.*)Z} $timestamp -> date time]} { return [clock scan "$date $time" -gmt true] } else { return [clock scan $timestamp -gmt true] } } proc annotations::more_recent {connid jid cdate mdate} { variable notes if {![info exists notes($connid,jid,$jid)]} { return 1 } elseif {[info exists notes($connid,mdate,$jid)]} { return [expr {$mdate > $notes($connid,mdate,$jid)}] } elseif {[info exists notes($connid,cdate,$jid)]} { return [expr {$cdate > $notes($connid,cdate,$jid)}] } else { return 1 } } proc annotations::cleanup_and_store_notes {connid args} { variable notes set roster_jids {} foreach rjid [roster::get_jids $connid] { lappend roster_jids [node_and_server_from_jid $rjid] } foreach idx [array names notes $connid,jid,*] { set jid $notes($idx) if {[lsearch -exact $roster_jids $jid] < 0 || \ ![info exists notes($connid,note,$jid)] || \ $notes($connid,note,$jid) == ""} { catch { unset notes($connid,jid,$jid) } catch { unset notes($connid,cdate,$jid) } catch { unset notes($connid,mdate,$jid) } catch { unset notes($connid,note,$jid) } } } eval [list store_notes $connid] $args } proc annotations::serialize_notes {connid} { variable notes set notelist {} foreach idx [array names notes $connid,jid,*] { set jid $notes($idx) set vars [list jid $jid] if {[info exists notes($connid,cdate,$jid)]} { set cdate [clock format $notes($connid,cdate,$jid) \ -format "%Y-%m-%dT%TZ" -gmt true] } lappend vars cdate $cdate if {[info exists notes($connid,mdate,$jid)]} { set mdate [clock format $notes($connid,mdate,$jid) \ -format "%Y-%m-%dT%TZ" -gmt true] } lappend vars mdate $mdate if {[info exists notes($connid,note,$jid)] && \ $notes($connid,note,$jid) != ""} { lappend notelist \ [jlib::wrapper:createtag note \ -vars $vars \ -chdata $notes($connid,note,$jid)] } } jlib::wrapper:createtag storage \ -vars [list xmlns $::NS(rosternotes)] \ -subtags $notelist } proc annotations::store_notes {connid args} { set command [list [namespace current]::store_notes_result $connid] foreach {opt val} $args { switch -- $opt { -command { set command $val } default { return -code error "Bad option \"$opt\":\ must be -command" } } } private::store [list [serialize_notes $connid]] \ -command $command \ -connection $connid } proc annotations::store_notes_result {connid res child} { if {$res == "OK"} return if {[winfo exists .store_notes_error]} { destroy .store_notes_error } MessageDlg .store_notes_error -aspect 50000 -icon error \ -message [format [::msgcat::mc "Storing roster notes failed: %s"] \ [error_to_string $child]] \ -type user -buttons ok -default 0 -cancel 0 } proc annotations::add_user_popup_info {infovar connid jid} { variable notes upvar 0 $infovar info set jid [node_and_server_from_jid $jid] if {[info exists notes($connid,note,$jid)] && \ $notes($connid,note,$jid) != ""} { append info "\n\tNote:\t" append info [string map [list "\n" "\n\t\t"] "$notes($connid,note,$jid)"] if {0} { if {[info exists notes($connid,cdate,$jid)]} { append info [format "\n\tNote created: %s" \ [clock format $notes($connid,cdate,$jid) \ -format "%Y-%m-%d %T" -gmt false]] } if {[info exists notes($connid,mdate,$jid)]} { append info [format "\n\tNote modified: %s" \ [clock format $notes($connid,mdate,$jid) \ -format "%Y-%m-%d %T" -gmt false]] } } } } hook::add roster_user_popup_info_hook \ [namespace current]::annotations::add_user_popup_info 80 proc annotations::show_dialog {connid jid} { variable notes set jid [node_and_server_from_jid $jid] set allowed_name [jid_to_tag $jid] set w .note_edit_${connid}_$allowed_name if {[winfo exists $w]} { destroy $w } Dialog $w -title [format [::msgcat::mc "Edit roster notes for %s"] $jid] \ -modal none -separator 1 -anchor e \ -default 0 -cancel 1 $w add -text [::msgcat::mc "Store"] \ -command [list [namespace current]::commit_changes $w $connid $jid] $w add -text [::msgcat::mc "Cancel"] -command [list destroy $w] set f [$w getframe] if {[info exists notes($connid,cdate,$jid)]} { label $f.cdate -text [format [::msgcat::mc "Created: %s"] \ [clock format $notes($connid,cdate,$jid) \ -format "%Y-%m-%d %T" -gmt false]] pack $f.cdate -side top -anchor w } if {[info exists notes($connid,mdate,$jid)]} { label $f.mdate -text [format [::msgcat::mc "Modified: %s"] \ [clock format $notes($connid,mdate,$jid) \ -format "%Y-%m-%d %T" -gmt false]] pack $f.mdate -side top -anchor w } ScrolledWindow $f.sw pack $f.sw -side top -expand yes -fill both textUndoable $f.note -width 50 -height 5 -wrap word if {[info exists notes($connid,note,$jid)]} { $f.note insert 0.0 $notes($connid,note,$jid) } $f.sw setwidget $f.note bind $f.note "$w invoke default break" bind $w { } bind $w "$w invoke default break" $w draw $f.note } proc annotations::commit_changes {w connid jid} { variable notes set text [$w getframe].note set date [clock seconds] set notes($connid,jid,$jid) $jid if {![info exists notes($connid,cdate,$jid)]} { set notes($connid,cdate,$jid) $date } set notes($connid,mdate,$jid) $date set notes($connid,note,$jid) [$text get 0.0 "end -1 char"] cleanup_and_store_notes $connid destroy $w } proc annotations::prefs_user_menu {m connid jid} { set rjid [roster::find_jid $connid $jid] if {$rjid == ""} { set state disabled } else { set state normal } $m add command -label [::msgcat::mc "Edit item notes..."] \ -command [list [namespace current]::show_dialog $connid $rjid] \ -state $state } hook::add chat_create_user_menu_hook \ [namespace current]::annotations::prefs_user_menu 76 hook::add roster_conference_popup_menu_hook \ [namespace current]::annotations::prefs_user_menu 76 hook::add roster_service_popup_menu_hook \ [namespace current]::annotations::prefs_user_menu 76 hook::add roster_jid_popup_menu_hook \ [namespace current]::annotations::prefs_user_menu 76 proc annotations::note_page {tab connid jid editable} { variable notes if {$editable} return set jid [node_and_server_from_jid $jid] if {![info exists notes($connid,note,$jid)] || \ $notes($connid,note,$jid) == ""} { return } set notestab [$tab insert end notes -text [::msgcat::mc "Notes"]] set n [userinfo::pack_frame $notestab.notes [::msgcat::mc "Roster Notes"]] if {[info exists notes($connid,cdate,$jid)]} { label $n.cdate -text [format [::msgcat::mc "Created: %s"] \ [clock format $notes($connid,cdate,$jid) \ -format "%Y-%m-%d %T" -gmt false]] pack $n.cdate -side top -anchor w } if {[info exists notes($connid,mdate,$jid)]} { label $n.mdate -text [format [::msgcat::mc "Modified: %s"] \ [clock format $notes($connid,mdate,$jid) \ -format "%Y-%m-%d %T" -gmt false]] pack $n.mdate -side top -anchor w } set sw [ScrolledWindow $n.sw -scrollbar vertical] text $n.text -height 12 -wrap word $sw setwidget $n.text $n.text insert 0.0 $notes($connid,note,$jid) $n.text configure -state disabled pack $sw -side top -fill both -expand yes pack $n -fill both -expand yes } hook::add userinfo_hook [namespace current]::annotations::note_page 40 # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/plugins/filetransfer/0000755000175000017500000000000011076120366016671 5ustar sergeisergeitkabber-0.11.1/plugins/filetransfer/si.tcl0000644000175000017500000002251610747131017020015 0ustar sergeisergei# $Id: si.tcl 1351 2008-01-27 16:32:15Z sergei $ # File transfer via Stream Initiation (XEP-0096) ############################################################################### namespace eval si { set winid 0 set chunk_size 1024 variable options custom::defgroup {Stream Initiation} \ [::msgcat::mc "Stream initiation options."] \ -group {File Transfer} set ::NS(file-transfer) http://jabber.org/protocol/si/profile/file-transfer disco::register_feature $::NS(file-transfer) } ############################################################################### proc si::send_file {token} { upvar #0 $token state variable chunk_size if {![info exists state(fd)]} return set state(stream) [si::newout $state(connid) $state(jid)] set profile [jlib::wrapper:createtag file \ -vars [list xmlns $::NS(file-transfer) \ name $state(name) \ size $state(size)] \ -subtags [list [jlib::wrapper:createtag desc \ -chdata $state(desc)]]] si::connect $state(stream) $chunk_size application/octet-stream \ $::NS(file-transfer) $profile \ [list [namespace current]::send_file_result $token] } ############################################################################### proc si::send_file_result {token res} { upvar #0 $token state if {![info exists state(fd)]} return if {![lindex $res 0]} { eval $state(command) ERR \ [list [::msgcat::mc "Request failed: %s" [lindex $res 1]]] return } set_status [::msgcat::mc "Transferring..."] after idle [list [namespace current]::send_chunk $token] } proc si::send_chunk {token} { upvar #0 $token state variable chunk_size if {![info exists state(fd)]} return set chunk [read $state(fd) $chunk_size] if {$chunk != ""} { si::send_data $state(stream) $chunk \ [list [namespace current]::send_chunk_response $token] } else { eval $state(command) OK } } proc si::send_chunk_response {token res} { upvar #0 $token state if {![info exists state(fd)]} return if {![lindex $res 0]} { eval $state(command) ERR \ [list [::msgcat::mc "Transfer failed: %s" [lindex $res 1]]] return } eval $state(command) [list PROGRESS [tell $state(fd)]] after idle [list [namespace current]::send_chunk $token] } ############################################################################### proc si::send_file_close {token} { upvar #0 $token state if {![info exists state(stream)]} return catch {si::close $state(stream)} catch {si::freeout $state(stream)} } ############################################################################### ############################################################################### proc si::recv_file_dialog {connid from lang id name size date hash desc} { variable winid set token [namespace current]::[incr winid] upvar #0 $token state set w .rfd$winid set state(w) $w set state(connid) $connid set state(jid) $from set state(lang) $lang set state(id) $id Dialog $w -title [format [::msgcat::mc "Receive file from %s"] $from] \ -separator 1 -anchor e \ -modal none -default 0 -cancel 1 set f [$w getframe] label $f.lname -text [::msgcat::mc "Name:"] label $f.name -text $name label $f.lsize -text [::msgcat::mc "Size:"] label $f.size -text $size label $f.ldesc -text [::msgcat::mc "Description:"] message $f.desc -width 10c -text $desc set dir $ft::options(download_dir) label $f.lsaveas -text [::msgcat::mc "Save as:"] entry $f.saveas -textvariable ${token}(filename) set state(f) $f set state(size) $size set state(dir) $dir set state(name) $name set state(filename) [file join $dir $name] button $f.browsefile -text [::msgcat::mc "Browse..."] \ -command [list [namespace current]::set_receive_file_name $token] set state(progress) 0 # Working around a bug in ProgressBar: # crash when setting PB variable while -maximum is 0: if {$size > 0} { ProgressBar $f.pb -variable ${token}(progress) $f.pb configure -maximum $size grid $f.pb -row 5 -column 0 -sticky ew -columnspan 3 -pady 2m } # grid row 0 is used for displaying error messages grid $f.lname -row 1 -column 0 -sticky e grid $f.name -row 1 -column 1 -sticky w grid $f.lsize -row 2 -column 0 -sticky e grid $f.size -row 2 -column 1 -sticky w grid $f.ldesc -row 3 -column 0 -sticky en grid $f.desc -row 3 -column 1 -sticky ewns -columnspan 2 -pady 1m grid $f.lsaveas -row 4 -column 0 -sticky e grid $f.saveas -row 4 -column 1 -sticky ew grid $f.browsefile -row 4 -column 2 -sticky ew grid columnconfigure $f 1 -weight 1 -minsize 8c grid rowconfigure $f 3 -weight 1 $w add -text [::msgcat::mc "Receive"] -command \ [list [namespace current]::recv_file_start $token] $w add -text [::msgcat::mc "Cancel"] -command \ [list [namespace current]::recv_file_cancel $token] bind $w [list [namespace current]::recv_file_close $token $w %W] $w draw # Can't avoid vwait, because this procedure must return result or error vwait ${token}(result) lassign $state(result) destroy result if {$destroy} { destroy $state(w) } return $result } proc si::set_receive_file_name {token} { upvar #0 $token state set file [tk_getSaveFile -initialdir $state(dir) \ -initialfile $state(name)] if {$file != ""} { set state(filename) $file } } ############################################################################### proc si::recv_file_cancel {token} { upvar #0 $token state if {![info exists state(result)]} { set state(result) [list 1 [list error cancel not-allowed \ -text [::trans::trans $state(lang) \ "File transfer is refused"]]] } elseif {[info exists state(w)] && [winfo exists $state(w)]} { destroy $state(w) } } ############################################################################### proc si::recv_file_start {token} { upvar #0 $token state ft::hide_error_msg $state(f) if {[catch {open $state(filename) w} fd]} { ft::report_cannot_open_file $state(f) $state(filename) \ [ft::get_POSIX_error_desc] return } fconfigure $fd -translation binary $state(w) itemconfigure 0 -state disabled if {[catch {si::newin $state(connid) $state(jid) $state(id)} stream]} { # Return error to the sender but leave transfer window with disabled # 'Receive' button and error message. set state(result) [list 0 [list error modify bad-request \ -text [::trans::trans $state(lang) \ "Stream ID is in use"]]] ft::report_error $state(f) \ [error_to_string [::msgcat::mc "Receive error: Stream ID is in use"]] return } set state(stream) $stream set state(fd) $fd si::set_readable_handler \ $stream [list [namespace current]::recv_file_chunk $token] si::set_closed_handler \ $stream [list [namespace current]::closed $token] set state(result) [list 0 {}] } ############################################################################### proc si::recv_file_chunk {token stream} { upvar #0 $token state if {![info exists state(w)] || ![winfo exists $state(w)]} {return 0} if {![info exists state(stream)] || !($state(stream) == $stream)} {return 0} set fd $state(fd) set filename $state(filename) set data [si::read_data $stream] debugmsg filetransfer "RECV into $filename data $data" puts -nonewline $fd $data set state(progress) [tell $fd] return 1 } ############################################################################### proc si::closed {token stream} { upvar #0 $token state if {![info exists state(w)] || ![winfo exists $state(w)]} {return 0} if {![info exists state(stream)] || !($state(stream) == $stream)} {return 0} debugmsg filetransfer "CLOSE" destroy $state(w) } ############################################################################### proc si::recv_file_close {token w1 w2} { upvar #0 $token state if {$w1 != $w2} return catch {close $state(fd)} catch {si::freein $state(stream)} catch {unset $token} } ############################################################################### ############################################################################### proc si::si_handler {connid from lang id mimetype child} { debugmsg filetransfer "SI set: [list $from $child]" jlib::wrapper:splitxml $child tag vars isempty chdata children if {$tag == "file"} { set desc "" foreach item $children { jlib::wrapper:splitxml $item tag1 vars1 isempty1 chdata1 children1 switch -- $tag1 { desc {set desc $chdata1} } } recv_file_dialog \ $connid \ $from \ $lang \ $id \ [jlib::wrapper:getattr $vars name] \ [jlib::wrapper:getattr $vars size] \ [jlib::wrapper:getattr $vars date] \ [jlib::wrapper:getattr $vars hash] \ $desc } else { return [list error modify bad-request] } } si::register_profile $::NS(file-transfer) [namespace current]::si::si_handler ############################################################################### ft::register_protocol si \ -priority 10 \ -label "Stream Initiation" \ -send [namespace current]::si::send_file \ -close [namespace current]::si::send_file_close ############################################################################### tkabber-0.11.1/plugins/filetransfer/http.tcl0000644000175000017500000002427610653600460020365 0ustar sergeisergei# $Id: http.tcl 1168 2007-07-31 09:30:24Z sergei $ # File transfer via Out of Band Data (XEP-0066) ############################################################################### namespace eval http { variable winid 0 variable chunk_size 4096 variable options custom::defgroup HTTP \ [::msgcat::mc "HTTP options."] \ -group {File Transfer} custom::defvar options(port) 0 \ [::msgcat::mc "Port for outgoing HTTP file transfers (0 for assigned\ automatically). This is useful when sending files from\ behind a NAT with a forwarded port."] \ -group HTTP -type integer custom::defvar options(host) "" \ [::msgcat::mc "Force advertising this hostname (or IP address) for\ outgoing HTTP file transfers."] \ -group HTTP -type string } ############################################################################### proc http::send_file {token} { upvar #0 $token state variable options if {![info exists state(fd)]} return #set ip [$f.ip get] #label $f.lip -text [::msgcat::mc "IP address:"] #entry $f.ip -textvariable [list [namespace current]::ip$winid] #variable ip$winid 127.0.0.1 set host 127.0.0.1 if {[string compare $options(host) ""] != 0} { set host $options(host) } else { catch { set host [info hostname] set host [lindex [host_info addresses $host] 0] } if {[jlib::socket_ip $state(connid)] != ""} { set host [jlib::socket_ip $state(connid)] } } set state(host) $host set state(servsock) \ [socket -server \ [list [namespace current]::send_file_accept $token] $options(port)] lassign [fconfigure $state(servsock) -sockname] addr hostname port set url [cconcat "http://$state(host):$port/" [file tail $state(filename)]] jlib::send_iq set [jlib::wrapper:createtag query \ -vars {xmlns jabber:iq:oob} \ -subtags [list [jlib::wrapper:createtag url \ -chdata $url] \ [jlib::wrapper:createtag desc \ -chdata $state(desc)]]] \ -to $state(jid) \ -command [list [namespace current]::send_file_error_handler $token] \ -connection $state(connid) } ############################################################################### proc http::send_file_error_handler {token res child} { upvar #0 $token state if {![info exists state(fd)]} return if {[cequal $res OK]} return eval $state(command) ERR \ [list [::msgcat::mc "Request failed: %s" [error_to_string $child]]] } ############################################################################### proc http::send_file_accept {token chan addr port} { upvar #0 $token state if {![info exists state(fd)]} return variable chanreadable$chan if {[info exists state(chan)]} { close $chan return } else { set state(chan) $chan } set size $state(size) fconfigure $chan -blocking 0 -encoding binary -buffering line fileevent $chan readable [list set [namespace current]::chanreadable$chan 1] set request " " while {$request != ""} { vwait [namespace current]::chanreadable$chan set request [gets $chan] debugmsg filetransfer $request } fileevent $chan readable {} unset chanreadable$chan fconfigure $chan -translation binary puts -nonewline $chan "HTTP/1.0 200 OK\n" puts -nonewline $chan "Content-Length: $size\n" puts -nonewline $chan "Content-Type: application/octet-stream\n\n" fileevent $chan writable \ [list [namespace current]::send_file_transfer_chunk $token $chan] } ############################################################################### proc http::send_file_transfer_chunk {token chan} { upvar #0 $token state variable chunk_size if {![info exists state(fd)]} return set chunk [read $state(fd) $chunk_size] if {$chunk != ""} { if {[catch {puts -nonewline $chan $chunk}]} { eval $state(command) [list ERR "File transfer failed"] } else { eval $state(command) [list PROGRESS [tell $state(fd)]] } } else { eval $state(command) OK } } ############################################################################### proc http::send_file_close {token} { upvar #0 $token state if {![info exists state(fd)]} return catch {close $state(chan)} catch {close $state(servsock)} catch { variable chanreadable$state(chan) unset chanreadable$state(chan) } } ############################################################################### ############################################################################### proc http::recv_file_dialog {from lang urls desc} { variable winid variable result set w .ftrfd$winid while {[winfo exists $w]} { incr winid set w .ftrfd$winid } set url [lindex $urls 0] Dialog $w -title [format [::msgcat::mc "Receive file from %s"] $from] \ -separator 1 -anchor e \ -modal none -default 0 -cancel 1 set f [$w getframe] label $f.lurl -text [::msgcat::mc "URL:"] label $f.url -text $url label $f.ldesc -text [::msgcat::mc "Description:"] message $f.desc -width 10c -text $desc set dir $ft::options(download_dir) set fname [file tail $url] label $f.lsaveas -text [::msgcat::mc "Save as:"] entry $f.saveas -textvariable [list [namespace current]::saveas$winid] variable saveas$winid [file join $dir $fname] button $f.browsefile -text [::msgcat::mc "Browse..."] \ -command [list [namespace current]::set_receive_file_name $winid $dir $fname] ProgressBar $f.pb -variable [list [namespace current]::progress$f.pb] variable progress$f.pb 0 grid $f.lurl -row 0 -column 0 -sticky e grid $f.url -row 0 -column 1 -sticky w -columnspan 2 grid $f.ldesc -row 1 -column 0 -sticky en grid $f.desc -row 1 -column 1 -sticky ewns -columnspan 2 -pady 1m grid $f.lsaveas -row 2 -column 0 -sticky e grid $f.saveas -row 2 -column 1 -sticky ew grid $f.browsefile -row 2 -column 2 -sticky ew grid $f.pb -row 3 -column 0 -sticky ew -columnspan 3 -pady 2m grid columnconfigure $f 1 -weight 1 -minsize 8c grid rowconfigure $f 1 -weight 1 $w add -text [::msgcat::mc "Receive"] \ -command [list [namespace current]::recv_file_start $winid $from $lang $url] $w add -text [::msgcat::mc "Cancel"] \ -command [list destroy $w] bind .ftrfd$winid \ [list [namespace current]::recv_file_cancel $winid $lang] $w draw vwait [namespace current]::result($winid) set res $result($winid) unset result($winid) incr winid return $res } proc http::set_receive_file_name {winid dir fname} { variable saveas$winid set file [tk_getSaveFile -initialdir $dir -initialfile $fname] if {$file != ""} { set saveas$winid $file } } package require http proc http::recv_file_start {winid from lang url} { variable saveas$winid variable chunk_size variable result variable fds set filename [set saveas$winid] .ftrfd$winid itemconfigure 0 -state disabled set f [.ftrfd$winid getframe] set fd [open $filename w] fconfigure $fd -translation binary set fds($winid) $fd set geturl \ [list ::http::geturl $url -channel $fd \ -blocksize $chunk_size \ -progress [list [namespace current]::recv_file_progress $f.pb] \ -command [list [namespace current]::recv_file_finish $winid $lang]] if {[package vcompare 2.3.3 [package require http]] <= 0} { lappend geturl -binary 1 } if {[catch $geturl token]} { bind .ftrfd$winid {} destroy .ftrfd$winid # TODO: More precise error messages? set result($winid) \ [list error cancel item-not-found \ -text [::trans::trans $lang "File not found"]] after idle [list MessageDlg .ftrecv_error$winid \ -aspect 50000 \ -icon error \ -message [::msgcat::mc \ "Can't receive file: %s" $token] \ -type user \ -buttons ok \ -default 0 \ -cancel 0] } else { bind .ftrfd$winid \ [list [namespace current]::recv_file_cancel $winid $lang $token] } } proc http::recv_file_progress {pb token total current} { variable progress$pb debugmsg filetransfer "$total $current" $pb configure -maximum $total set progress$pb $current } proc http::recv_file_finish {winid lang token} { variable result variable fds if {[info exists fds($winid)]} { close $fds($winid) unset fds($winid) } upvar #0 $token state debugmsg filetransfer "transfer $state(status) $state(http)" bind .ftrfd$winid {} destroy .ftrfd$winid if {[::http::ncode $token] == 200} { set result($winid) {result {}} } else { # TODO: More precise error messages? set result($winid) \ [list error cancel item-not-found \ -text [::trans::trans $lang "File not found"]] after idle [list MessageDlg .ftrecv_error$winid \ -aspect 50000 \ -icon error \ -message [::msgcat::mc \ "Can't receive file: %s" [::http::code $token]] \ -type user \ -buttons ok \ -default 0 \ -cancel 0] } } proc http::recv_file_cancel {winid lang {token ""}} { variable result variable fds if {[info exists fds($winid)]} { close $fds($winid) unset fds($winid) } bind .ftrfd$winid {} if {![cequal $token ""]} { ::http::reset $token cancelled } set result($winid) \ [list error cancel not-allowed \ -text [::trans::trans $lang "File transfer is refused"]] } ############################################################################### proc http::iq_handler {connid from lang child} { jlib::wrapper:splitxml $child tag vars isempty chdata children set urls "" set desc "" foreach child $children { jlib::wrapper:splitxml $child tag vars isempty chdata children1 switch -- $tag { url {lappend urls $chdata} desc {set desc $chdata} } } return [recv_file_dialog $from $lang $urls $desc] } iq::register_handler set query jabber:iq:oob \ [namespace current]::http::iq_handler ############################################################################### ft::register_protocol http \ -priority 30 \ -label "HTTP" \ -send [namespace current]::http::send_file \ -close [namespace current]::http::send_file_close ############################################################################### tkabber-0.11.1/configdir.tcl0000644000175000017500000000640710612602324015175 0ustar sergeisergei# $Id: configdir.tcl 1123 2007-04-22 06:46:44Z sergei $ # Provides for deducing the location of Tkabber config directory depending # on the current platform. namespace eval config {} # Deduces the location of the "Application Data" directory # (in its wide sense) on the current Windows platform. # See: http://ru.tkabber.jabe.ru/index.php/Config_dir proc config::appdata_windows {} { global env if {[info exists env(APPDATA)]} { return $env(APPDATA) } if {![catch {package require registry}]} { set key {HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders} if {![catch {registry get $key AppData} dir]} { return $dir } } return {} } # Copies the contents of dir $from under dir $to using bells'n'whistles. # NOTE that at the time of invocation: # * $from MUST exist # * $to MUST NOT exist. # Returns true if copying succeeded, false otherwise. proc config::transfer_dir {from to} { wm withdraw . wm title . [::msgcat::mc "Attention"] pack [message .msg -aspect 50000 \ -text [::msgcat::mc "Please, be patient while Tkabber\ configuration directory is being transferred\ to the new location"]] -fill both -expand yes #::tk::PlaceWindow . wm deiconify . set failed [catch {file copy $from $to} err] if {$failed} { tk_messageBox -icon error \ -title [::msgcat::mc "Attention"] \ -message [format [::msgcat::mc "Tkabber configuration directory\ transfer failed with:\n%s\n\ Tkabber will use the old directory:\n%s"] $err $from] } else { set to [file nativename $to] tk_messageBox \ -title [::msgcat::mc "Attention"] \ -message [format \ [::msgcat::mc "Your new Tkabber config\ directory is now:\n%s\nYou can delete the old one:\n%s"] \ $to $from] } destroy .msg expr {!$failed} } # Based on the current platform, chooses the location of the Tkabber's # config dir and sets the "configdir" global variable to its pathname. # "TKABBER_HOME" env var overrides any guessing. # NOTE that this proc now tries to copy contents of the "old-style" # ~/.tkabber config dir to the new location, if needed, to provide # smooth upgrade for Tkabber users on Windows. # This behaviour should be lifted eventually in the future. if {![info exists env(TKABBER_HOME)]} { switch -- $tcl_platform(platform) { unix { set configdir ~/.tkabber } windows { set dir [config::appdata_windows] if {$dir != {}} { set configdir [file join $dir Tkabber] } else { # Fallback default (depends on Tcl's idea about ~): set configdir [file join ~ .tkabber] } } macintosh { set configdir [file join ~ Library "Application Support" Tkabber] } } set env(TKABBER_HOME) $configdir } else { set configdir $env(TKABBER_HOME) } if {$tcl_version >= 8.4} { set configdir [file normalize $configdir] } # This should be lifted in the next release after introduction # of configdir. # TODO: what perms does the dest dir of [file copy] receive? # Since it's only needed for Windows, we don't really care now. if {![file exists $configdir] && [file isdir ~/.tkabber]} { if {![config::transfer_dir ~/.tkabber $configdir]} { # Transfer error-case fallback: set configdir ~/.tkabber } } file mkdir $configdir # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/iface.tcl0000644000175000017500000000614511014773723014310 0ustar sergeisergei# $Id: iface.tcl 1441 2008-05-21 10:22:11Z sergei $ set user_status_list [list \ available [::msgcat::mc "Available"] \ chat [::msgcat::mc "Free to chat"] \ away [::msgcat::mc "Away"] \ xa [::msgcat::mc "Extended away"] \ dnd [::msgcat::mc "Do not disturb"] \ invisible [::msgcat::mc "Invisible"] \ unavailable [::msgcat::mc "Not logged in"]] array set ssl_certificate_fields [list \ subject [::msgcat::mc "Subject"] \ issuer [::msgcat::mc "Issuer"] \ notBefore [::msgcat::mc "Begin date"] \ notAfter [::msgcat::mc "Expiry date"] \ serial [::msgcat::mc "Serial number"] \ cipher [::msgcat::mc "Cipher"] \ sbits [::msgcat::mc "Session key bits"] \ sha1_hash [::msgcat::mc "SHA1 hash"]] proc ssl_info {} { global ssl_certificate_fields if {![llength [set conns [jlib::connections]]]} { return {} } set server_list {} set msg_list {} foreach connid $conns { if {[info exists ::jlib::lib($connid,sck)]} { if {![catch { tls::status $::jlib::lib($connid,sck) } status]} { set server [server_from_jid [jlib::connection_jid $connid]] if {[lcontain $server_list $server]} { continue } else { lappend server_list $server lappend msg_list $server } set info {} foreach {k v} $status { switch -- $k { subject - issuer { set v [regsub -all {\s*[/,]\s*(\w+=)} $v \n\t\\1] } } if {![cequal $v ""]} { if {[info exists ssl_certificate_fields($k)]} { append info \ [format "%s: %s\n" \ $ssl_certificate_fields($k) $v] } else { append info [format "%s: %s\n" $k $v] } } } lappend msg_list [string trim $info] } } } return $msg_list } proc update_ssl_info {} { global tls_warning_info set state disabled set len [llength [set conns [jlib::connections]]] set fg normal if {$len} { set balloon "" foreach connid $conns { if {$len > 1} { append balloon "[jlib::connection_jid $connid]: " } if {[info exists ::jlib::lib($connid,sck)]} { if {![catch { tls::status $::jlib::lib($connid,sck) } status]} { if {![info exists tls_warning_info($connid)] || [cequal $tls_warning_info($connid) ""]} { append balloon [::msgcat::mc "Enabled\n"] } else { append balloon $tls_warning_info($connid) set fg warning } set state normal } else { append balloon [::msgcat::mc "Disabled\n"] } } else { append balloon [::msgcat::mc "Disconnected"] "\n" } } } else { set balloon [::msgcat::mc "Disconnected"] } return [list $state $fg [string trim $balloon]] } ############################################################################### set status_afterid "" proc client:status {text} { set_status $text } proc set_status {text} { global status global status_afterid after cancel $status_afterid set status $text hook::run set_status_hook $text set status_afterid [after 5000 clear_status] } proc clear_status {} { global status set status "" hook::run clear_status_hook } # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/Tclx.tcl0000644000175000017500000000710407526776750014167 0ustar sergeisergeiproc cconcat {args} { set result "" foreach arg $args { append result $arg } return $result } proc cequal {string1 string2} { if {[string compare $string1 $string2]} { return 0 } return 1 } proc cindex {string indexExpr} { return [string index $string \ [indexExpr $indexExpr [string length $string]]] } proc clength {string} { return [string length $string] } proc crange {string firstExpr lastExpr} { set len [string length $string] return [string range $string [indexExpr $firstExpr $len] \ [indexExpr $lastExpr $len]] } proc ctype {args} { switch -- [llength $args] { 4 { return [eval string is [list [lindex $args 2]] \ [linsert $args 2 2]] } default { return [eval string is $args] } } } proc indexExpr {indexExpr len} { switch -regexp -- $indexExpr { {^[Ee][Nn][Dd]*$} { incr len -1 return [expr $len[string range $indexExpr 3 end]] } {^[Ll][Ee][Nn]*$} { return [expr $len[string range $indexExpr 3 end]] } default { return $indexExpr } } } proc lassign {list args} { foreach name $args { upvar $name var set var [lindex $list 0] set list [lrange $list 1 end] } return $list } proc lcontain {list element} { if {[lsearch -exact $list $element] < 0} { return 0 } return 1 } proc lempty {list} { if {[llength $list] > 0} { return 0 } return 1 } proc lmatch {args} { switch -- [llength $args] { 3 { set mode [lindex $args 0] set list [lindex $args 1] set pattern [lindex $args 2] } default { set mode -glob set list [lindex $args 0] set pattern [lindex $args 1] } } set result {} foreach elem $list { switch -- $mode { -glob { if {[string match $pattern $elem]} { lappend result $elem } } -exact { if {![string compare $pattern $elem]} { lappend result $elem } } -regexp { if {[regexp -- $pattern $elem]} { lappend result $elem } } } } return $result } proc lvarpop {name {indexExpr 0} args} { upvar $name var set result [lindex $var \ [set indexExpr [indexExpr $indexExpr [llength $var]]]] switch -- [llength $args] { 0 { set var [lreplace $var $indexExpr $indexExpr] } default { set var [lreplace $var $indexExpr $indexExpr [lindex $args 0]] } } return $result } proc lvarpush {name string {indexExpr 0}} { upvar $name var if {![info exists var]} { set var {} } set var [linsert $var [indexExpr $indexExpr [llength $var]] $string] } proc lrmdups {list} { return [lsort -unique $list] } proc max {num1 args} { foreach num $args { if {$num1 < $num} { set num1 $num } } return $num1 } proc min {num1 args} { foreach num $args { if {$num1 > $num} { set num1 $num } } return $num1 } proc random {args} { switch -- [llength $args] { 1 { return [expr round(rand()*[lindex $args 0])] } default { return "" } } } tkabber-0.11.1/presence.tcl0000644000175000017500000004306310764310554015045 0ustar sergeisergei# $Id: presence.tcl 1391 2008-03-07 19:03:08Z sergei $ ############################################################################### array set long_statusdesc [list \ available [::msgcat::mc "is available"] \ chat [::msgcat::mc "is free to chat"] \ away [::msgcat::mc "is away"] \ xa [::msgcat::mc "is extended away"] \ dnd [::msgcat::mc "doesn't want to be disturbed"] \ invisible [::msgcat::mc "is invisible"] \ unavailable [::msgcat::mc "is unavailable"]] proc get_long_status_desc {status} { set ::long_statusdesc($status) } ############################################################################### proc client:presence {connid from type x args} { global presence global processed_presence debugmsg presence "PRESENCE: $from; $type; $x; $args" set from [tolower_node_and_domain $from] switch -- $type { error - unavailable { catch { unset presence(type,$connid,$from) } catch { unset presence(status,$connid,$from) } catch { unset presence(priority,$connid,$from) } catch { unset presence(meta,$connid,$from) } catch { unset presence(icon,$connid,$from) } catch { unset presence(show,$connid,$from) } catch { unset presence(loc,$connid,$from) } catch { unset presence(x,$connid,$from) } catch { unset presence(error,$connid,$from) } set user [node_and_server_from_jid $from] if {[info exists presence(user_jids,$connid,$user)]} { set idx [lsearch -exact $presence(user_jids,$connid,$user) $from] set presence(user_jids,$connid,$user) \ [lreplace $presence(user_jids,$connid,$user) $idx $idx] } cache_preferred_jid_on_unavailable $connid $from $user cache_user_status $connid $user foreach {attr val} $args { switch -- $attr { -status { set presence(status,$connid,$from) $val if {[get_user_status $connid $user] == "unavailable"} { set presence(status,$connid,$user) $val } } -error { set presence(error,$connid,$from) $val } } } debugmsg presence "$connid $from unavailable" } subscribe {} subscribed {} unsubscribe {} unsubscribed {} probe {} default { set type available set presence(type,$connid,$from) available set presence(status,$connid,$from) "" set presence(priority,$connid,$from) 0 set presence(meta,$connid,$from) "" set presence(icon,$connid,$from) "" set presence(show,$connid,$from) available set presence(loc,$connid,$from) "" set presence(x,$connid,$from) $x foreach {attr val} $args { switch -- $attr { -status {set presence(status,$connid,$from) $val} -priority {set presence(priority,$connid,$from) $val} -meta {set presence(meta,$connid,$from) $val} -icon {set presence(icon,$connid,$from) $val} -show {set presence(show,$connid,$from) $val} -loc {set presence(loc,$connid,$from) $val} } } set presence(show,$connid,$from) \ [normalize_show $presence(show,$connid,$from)] set user [node_and_server_from_jid $from] if {![info exists presence(user_jids,$connid,$user)] || \ ![lcontain $presence(user_jids,$connid,$user) $from]} { lappend presence(user_jids,$connid,$user) $from } cache_preferred_jid_on_available $connid $from $user cache_user_status $connid $user } } eval {hook::run client_presence_hook $connid $from $type $x} $args } ############################################################################### proc get_jids_of_user {connid user} { global presence if {[info exists presence(user_jids,$connid,$user)]} { return $presence(user_jids,$connid,$user) } elseif {![cequal [resource_from_jid $user] ""]} { if {[info exists presence(type,$connid,$user)]} { return [list $user] } } return {} } proc get_jid_of_user {connid user} { global presence if {[info exists presence(preferred_jid,$connid,$user)]} { return $presence(preferred_jid,$connid,$user) } else { return $user } } proc cache_preferred_jid_on_available {connid jid user} { global presence if {[info exists presence(maxpriority,$connid,$user)]} { set maxpri $presence(maxpriority,$connid,$user) } else { cache_preferred_jid $connid $user return } set pri $presence(priority,$connid,$jid) if {$pri > $maxpri} { set presence(maxpriority,$connid,$user) $pri set presence(preferred_jid,$connid,$user) $jid } } proc cache_preferred_jid_on_unavailable {connid jid user} { global presence if {![info exists presence(maxpriority,$connid,$user)]} { cache_preferred_jid $connid $user return } if {$presence(preferred_jid,$connid,$user) == $jid} { unset presence(preferred_jid,$connid,$user) unset presence(maxpriority,$connid,$user) cache_preferred_jid $connid $user } } proc cache_preferred_jid {connid user} { global presence set jids [get_jids_of_user $connid $user] if {$jids != {}} { set rjid [lindex $jids 0] set pri $presence(priority,$connid,$rjid) foreach jid $jids { if {$presence(priority,$connid,$jid) > $pri} { set pri $presence(priority,$connid,$jid) set rjid $jid } } set presence(maxpriority,$connid,$user) $pri set presence(preferred_jid,$connid,$user) $rjid } } proc get_jid_status {connid jid} { global presence set j $jid if {[info exists presence(show,$connid,$j)]} { return $presence(show,$connid,$j) } else { return unavailable } } proc get_jid_presence_info {param connid jid} { global presence if {[info exists presence($param,$connid,$jid)]} { return $presence($param,$connid,$jid) } else { return "" } } proc get_user_status {connid user} { global presence if {[info exists presence(cachedstatus,$connid,$user)]} { return $presence(cachedstatus,$connid,$user) } elseif {[info exists presence(show,$connid,$user)]} { return $presence(show,$connid,$user) } else { return unavailable } } proc cache_user_status {connid user} { global presence set jid [get_jid_of_user $connid $user] if {[info exists presence(show,$connid,$jid)]} { set presence(cachedstatus,$connid,$user) $presence(show,$connid,$jid) } else { set presence(cachedstatus,$connid,$user) unavailable } } proc get_user_status_desc {connid user} { global presence set jid [get_jid_of_user $connid $user] if {[info exists presence(status,$connid,$jid)]} { return $presence(status,$connid,$jid) } else { return "" } } array set status_priority { unavailable 1 xa 2 away 3 dnd 4 available 5 chat 6 } proc compare_status {s1 s2} { global status_priority set p1 $status_priority($s1) set p2 $status_priority($s2) if {$p1 > $p2} { return 1 } elseif {$p1 == $p2} { return 0 } else { return -1 } } proc max_status {s1 s2} { global status_priority set p1 $status_priority($s1) set p2 $status_priority($s2) if {$p1 >= $p2} { return $s1 } else { return $s2 } } ############################################################################### set curpriority 0 set curuserstatus unavailable set curtextstatus "" custom::defvar userpriority 0 [::msgcat::mc "Stored user priority."] \ -type integer -group Hidden custom::defvar userstatus available [::msgcat::mc "Stored user status."] \ -type string -group Hidden custom::defvar textstatus "" [::msgcat::mc "Stored user text status."] \ -type string -group Hidden set userstatusdesc [::msgcat::mc "Not logged in"] set statusdesc(available) [::msgcat::mc "Available"] set statusdesc(chat) [::msgcat::mc "Free to chat"] set statusdesc(away) [::msgcat::mc "Away"] set statusdesc(xa) [::msgcat::mc "Extended away"] set statusdesc(dnd) [::msgcat::mc "Do not disturb"] set statusdesc(invisible) [::msgcat::mc "Invisible"] set statusdesc(unavailable) [::msgcat::mc "Unavailable"] ############################################################################### proc change_priority_dialog {} { global tmppriority global userpriority set tmppriority $userpriority set w .change_priority if {[winfo exists $w]} { focus -force $w return } Dialog $w -title [::msgcat::mc "Change Presence Priority"] \ -modal none -separator 1 -anchor e -default 0 -cancel 1 \ -parent . $w add -text [::msgcat::mc "OK"] \ -command [list do_change_priority $w] $w add -text [::msgcat::mc "Cancel"] -command [list destroy $w] set f [$w getframe] label $f.lpriority -text [::msgcat::mc "Priority:"] Spinbox $f.priority -1000 1000 1 tmppriority grid $f.lpriority -row 0 -column 0 -sticky e grid $f.priority -row 0 -column 1 -sticky ew grid columnconfigure $f 0 -weight 1 grid columnconfigure $f 1 -weight 1 $w draw } ############################################################################### proc do_change_priority {w} { global userstatus global tmppriority global userpriority destroy $w if {![cequal $userpriority $tmppriority]} { set userpriority $tmppriority set userstatus $userstatus } } ############################################################################### trace variable userstatus w change_our_presence trace variable logoutuserstatus w change_our_presence ############################################################################### proc change_our_presence {name1 name2 op} { global userstatus logoutuserstatus curuserstatus global textstatus logouttextstatus curtextstatus global userpriority logoutpriority curpriority global statusdesc userstatusdesc switch -- $name1 { logoutuserstatus { set newstatus $logoutuserstatus set newtextstatus $logouttextstatus set newpriority $logoutpriority } default { if {[lempty [jlib::connections]]} return set newstatus $userstatus set newtextstatus $textstatus set newpriority $userpriority } } if {[cequal $newstatus $curuserstatus] \ && [cequal $newtextstatus $curtextstatus] \ && [cequal $newpriority $curpriority]} { return } if {[lsearch -exact [array names statusdesc] $newstatus] < 0} { error [cconcat [::msgcat::mc "invalid userstatus value "] $newstatus] } set userstatusdesc $statusdesc($newstatus) if {[cequal $newtextstatus ""]} { set status $userstatusdesc } else { set status $newtextstatus } foreach connid [jlib::connections] { send_presence $newstatus \ -stat $status \ -pri $userpriority \ -connection $connid } foreach chatid [lfilter chat::is_groupchat [chat::opened]] { set connid [chat::get_connid $chatid] set group [chat::get_jid $chatid] set nick [get_our_groupchat_nick $chatid] if {$newstatus == "invisible"} { set newst available } else { set newst $newstatus } send_presence $newst \ -to $group/$nick \ -stat $status \ -pri $userpriority \ -connection $connid } set curuserstatus $newstatus set curtextstatus $newtextstatus set curpriority $newpriority hook::run change_our_presence_post_hook $newstatus } ############################################################################### proc send_first_presence {connid} { global userstatus curuserstatus statusdesc userstatusdesc global textstatus curtextstatus global userpriority curpriority global loginconf if {[lsearch -exact [array names statusdesc] $userstatus] < 0} { error [cconcat [::msgcat::mc "invalid userstatus value "] $userstatus] } set userstatusdesc $statusdesc($userstatus) if {[cequal $textstatus ""]} { set status $userstatusdesc } else { set status $textstatus } set curuserstatus $userstatus set curtextstatus $textstatus set curpriority [set userpriority $loginconf(priority)] send_presence $userstatus \ -stat $status \ -pri $userpriority \ -connection $connid hook::run change_our_presence_post_hook $userstatus } hook::add connected_hook [namespace current]::send_first_presence 10 ############################################################################### proc send_custom_presence {jid status args} { global userpriority global statusdesc set type jid set stat "" foreach {key val} $args { switch -- $key { -type { set type $val } -stat { set stat $val } -connection { set connid $val } } } if {![info exists connid]} { return -code error "send_custom_presence: -connection required" } if {$stat == ""} { set stat $statusdesc($status) } switch -- $type { group { set to $jid/[get_our_groupchat_nick [chat::chatid $connid $jid]] } default { set to $jid } } eval {send_presence $status} $args {-to $to -stat $stat -pri $userpriority} } ############################################################################### proc send_presence {status args} { set xlist {} set newargs {} set stat "" foreach {opt val} $args { switch -- $opt { -to { lappend newargs -to $val } -pri { lappend newargs -pri $val } -command { lappend newargs -command $val } -xlist { set xlist $val } -stat { set stat $val } -connection { set connid $val lappend newargs -connection $val } } } if {![info exists connid]} { return -code error "send_presence: -connection required" } if {$stat != ""} { lappend newargs -stat $stat } hook::run presence_xlist_hook xlist $connid $stat lappend newargs -xlist $xlist switch -- $status { available { set command [list jlib::send_presence] } unavailable { set command [list jlib::send_presence -type $status] } default { set command [list jlib::send_presence -show $status] } } debugmsg presence "$command $newargs" eval $command $newargs } ############################################################################### proc normalize_show {show} { set res $show switch -- $show { away {} chat {} dnd {} xa {} unavailable {} default {set res available} } return $res } ############################################################################### proc add_presence_to_popup_info {infovar connid jid} { upvar 0 $infovar info set bjid [node_and_server_from_jid $jid] if {[chat::is_groupchat [chat::chatid $connid $bjid]]} return set priority [get_jid_presence_info priority $connid $jid] if {$priority != ""} { append info [format "\n\t[::msgcat::mc {Priority:}] %s" $priority] } } hook::add roster_user_popup_info_hook add_presence_to_popup_info 20 ############################################################################### proc clear_presence_info {connid} { global presence if {$connid == {}} { array unset presence } else { # TODO array unset presence type,$connid,* array unset presence status,$connid,* array unset presence priority,$connid,* array unset presence meta,$connid,* array unset presence icon,$connid,* array unset presence show,$connid,* array unset presence loc,$connid,* array unset presence error,$connid,* array unset presence x,$connid,* array unset presence user_jids,$connid,* array unset presence preferred_jid,$connid,* array unset presence cachedstatus,$connid,* array unset presence maxpriority,$connid,* } } hook::add disconnected_hook clear_presence_info ############################################################################### proc custom_presence_menu {m connid jid} { set mm [menu $m.custom_presence -tearoff 0] $mm add command -label [::msgcat::mc "Available"] \ -command [list send_custom_presence $jid available -connection $connid] $mm add command -label [::msgcat::mc "Free to chat"] \ -command [list send_custom_presence $jid chat -connection $connid] $mm add command -label [::msgcat::mc "Away"] \ -command [list send_custom_presence $jid away -connection $connid] $mm add command -label [::msgcat::mc "Extended away"] \ -command [list send_custom_presence $jid xa -connection $connid] $mm add command -label [::msgcat::mc "Do not disturb"] \ -command [list send_custom_presence $jid dnd -connection $connid] $mm add command -label [::msgcat::mc "Unavailable"] \ -command [list send_custom_presence $jid unavailable -connection $connid] $m add cascade -label [::msgcat::mc "Send custom presence"] -menu $mm } hook::add chat_create_user_menu_hook custom_presence_menu 43 hook::add roster_jid_popup_menu_hook custom_presence_menu 43 hook::add roster_service_popup_menu_hook custom_presence_menu 43 hook::add chat_create_conference_menu_hook custom_presence_menu 43 ############################################################################### proc service_login {connid jid} { global userstatus switch -- $userstatus { available { jlib::send_presence -to $jid -connection $connid } invisible { jlib::send_presence -to $jid -type $userstatus -connection $connid } default { jlib::send_presence -to $jid -show $userstatus -connection $connid } } } proc service_logout {connid jid} { jlib::send_presence -to $jid -type unavailable -connection $connid } proc service_login_logout_menu_item {m connid jid} { # TODO $m add command -label [::msgcat::mc "Log in"] \ -command [list service_login $connid $jid] $m add command -label [::msgcat::mc "Log out"] \ -command [list service_logout $connid $jid] } hook::add roster_service_popup_menu_hook service_login_logout_menu_item 20 ############################################################################### # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/Makefile0000644000175000017500000000163310701637340014166 0ustar sergeisergei# $Id: Makefile 1244 2007-10-06 07:53:04Z sergei $ PREFIX = /usr/local TKABBERDIR = $(PREFIX)/share/tkabber DOCDIR = $(PREFIX)/share/doc/tkabber BINDIR = $(PREFIX)/bin SUBDIRS = emoticons \ ifacetk \ jabberlib \ mclistbox \ msgs \ pixmaps \ plugins \ sounds \ tclxml \ trans install: install-bin install-doc install-examples install-bin: mkdir -p $(DESTDIR)/$(TKABBERDIR) cp -r *.tcl $(SUBDIRS) $(DESTDIR)/$(TKABBERDIR) mkdir -p $(DESTDIR)/$(BINDIR) echo -e "#!/bin/sh\nexec wish $(TKABBERDIR)/tkabber.tcl -name tkabber \"\$$@\"\n" \ >$(DESTDIR)/$(BINDIR)/tkabber chmod 755 $(DESTDIR)/$(BINDIR)/tkabber install-doc: mkdir -p $(DESTDIR)/$(DOCDIR) cp AUTHORS COPYING ChangeLog README doc/tkabber.html $(DESTDIR)/$(DOCDIR) install-examples: mkdir -p $(DESTDIR)/$(DOCDIR) cp -r examples $(DESTDIR)/$(DOCDIR) .PHONY: install install-bin install-doc install-examples tkabber-0.11.1/richtext.tcl0000644000175000017500000002460011014607652015064 0ustar sergeisergei# $Id: richtext.tcl 1440 2008-05-20 17:51:38Z sergei $ # "Rich text" facility for Tk Text widgets -- allows to: # * Register parsers and renderers for particular patterns in plain text messages -- "entities"; # * Parse plain text messages with registered parsers (in order of their priorities); # * Render the resulting chunks of text with the appropriate renderers; # * Get back the original text from PRIMARY and CLIPBOARD selections acquired from such Text widget. # This scheme supports URL highlighting, emoticons and such. namespace eval richtext { variable registered variable entities variable state variable texts {} # free-form properties for processing of current message variable msgprops ::custom::defgroup {Rich Text} \ [::msgcat::mc "Settings of rich text facility which is used\ to render chat messages and logs."] \ -group Plugins } proc richtext::register_entity {type args} { variable registered variable entities lappend registered $type set entities($type,priority) 80 foreach {opt val} $args { switch -glob -- $opt { -configurator { set entities($type,configurator) $val } -parser { set entities($type,parser) $val } -reconstructor { set entities($type,reconstructor) $val } -renderer { set entities($type,renderer) $val } -parser-priority { set entities($type,priority) $val } default { return -code error "[namespace current]::register_entity:\ Unknown option $opt" } } } } proc richtext::unregister_entity {type} { variable registered variable entities lexclude registered $type array unset entities $type,* } proc richtext::entity_state {type {val ""}} { variable entities if {$val == ""} { set entities($type,enabled) } else { set entities($type,enabled) $val } } # Configures a text widget so that the "::richtext::render_message" proc # can be used on it. # Accepts an optional parameter "-using ?list_of_entities?"; when specified, # the text widget is configured to support only the specified entities, # otherwise it's configured to support all registered entities. If the list # is empty, this is *almost* a no-op: render_message can be called on such # widget, but it won't trigger any special processing of the passed text. # NOTE that currently this proc can be safely called only once per widget # since it essentially has a "constructor" semantics (though it requires # an already created text widget). proc richtext::config {w args} { variable registered variable entities variable state variable texts lappend texts $w # By default, configure for all registered entities: set using $registered # Parse options: foreach {opt val} $args { switch -- $opt { -using { set using $val } default { return -code error "[namespace current]::config:\ Unknown option: $opt" } } } # Run configurators for requested entities: foreach type $using { if {[info exists entities($type,configurator)]} { $entities($type,configurator) $w } } # Save enabled entities in the widget state, sorted by the # parsing priority: set state($w,types) [lsort -command compare_entity_prios $using] # Register a kind of "destructor" to clean up state: bind $w +[list [namespace current]::richtext_on_destroy $w %W] } # Cleans up state of richtext widgets: proc richtext::richtext_on_destroy {w1 w2} { if {$w1 != $w2} return variable state variable texts lexclude texts $w1 array unset state $w1,* } proc richtext::textlist {} { variable texts return $texts } proc richtext::compare_entity_prios {a b} { variable entities expr {$entities($a,priority) - $entities($b,priority)} } # Configure a text widget to be ready for enriched text: proc richtext::richtext {args} { set w [eval text $args] config $w install_selection_handlers $w $w configure -state disabled -font $::ChatFont } # TODO get rid of "deftag" proc richtext::render_message {w body deftag {nonewline ""}} { variable entities variable state variable msgprops # Parse the message text with rich text entity parsers: set chunks [list $body text $deftag] foreach type $state($w,types) { if {$entities($type,enabled) && [info exists entities($type,parser)]} { $entities($type,parser) [info level] chunks } } # Render the parsed pieces with entity renderers: foreach {piece type tags} $chunks { #puts "(draw) piece: $piece; type: $type; tags: $tags" if {! [info exists entities($type,renderer)]} { # Fallback debugmsg richtext "Got piece with unknown type $type" set type text } $entities($type,renderer) $w $type $piece $tags } if {$nonewline != "-nonewline"} { $w insert end \n } # Get rid of the current message properties array unset msgprops * } proc richtext::fixup_tags {tags tgroups} { foreach t $tags { set thash($t) 0 } foreach tg $tgroups { glue_tags thash $tg } return [array names thash] } proc richtext::glue_tags {arrayName tags} { upvar 1 $arrayName thash foreach t $tags { if {![info exists thash($t)]} return } foreach t $tags { unset thash($t) } set t [join $tags _] set thash($t) 0 } # Selection handlers are "wrapped" by Tk so that they cannot fail # due to errors since they are silenced. # So this proc is kind of "error-enabled selection handler" -- it will # raise any error occured in the selection handler. proc richtext::chk_reconstruct_text {w first last} { if {[catch [list reconstruct_text $w $first $last] out]} { after idle [list error $out] return } else { return $out } } # Parses the contents of Text widget $w from $first to $last # and returns reconstructed "plain text". # It's main purpose is to return the "original" text that was # submitted to that Text widget and then undergone # "rich text" processing. proc richtext::reconstruct_text {w first last} { variable state #puts "in [info level 0]" if {[catch {$w dump -text -tag $first $last} dump]} { #puts "dump failed: $dump" return {} } set dump [concat {start {} {}} $dump {end {} {}}] #puts "ready to parse: $dump" foreach {what val where} $dump { #puts "what: $what; val: $val; where $where" switch -- $what { start { set out "" set in nowhere set chunk "" set tags {} set ignore false } tagon { if {[lsearch $state($w,types) $val] >= 0} { if {$in != "tag"} { write_chunk_out out chunk $tags } lappend tags $val set in tag } elseif {$val == "transient"} { set ignore true } } tagoff { if {[lsearch $state($w,types) $val] >= 0} { if {$in != "tag"} { write_chunk_out out chunk $tags } lexclude tags $val set in tag } elseif {$val == "transient"} { set ignore false } } text { if {$ignore} continue append chunk $val set in text } image { set chunk $val set in image } end { if {$ignore} continue if {$in != "tag"} { write_chunk_out out chunk $tags } } } } #puts "parsed sel: $out" return $out } proc richtext::write_chunk_out {outVar chunkVar t} { upvar 1 $outVar out $chunkVar chunk variable entities if {[string length $chunk] == 0} return if {[llength $t] > 1} { #puts stderr "chunk $chunk belongs to several rich text entities: $t" } if {[info exists entities($t,reconstructor)]} { append out [$entities($t,reconstructor) $t $chunk] } else { append out $chunk } set chunk "" } # Used to handle PRIMARY selection requests on "rich text" widgets proc richtext::get_selection {w off max} { return [string range \ [chk_reconstruct_text $w sel.first sel.last] \ $off [expr {$off + $max}]] } # Used to subvert tk_textCopy on "rich text" widgets proc richtext::text_copy {w} { set data [chk_reconstruct_text $w sel.first sel.last] clipboard clear -displayof $w clipboard append -displayof $w $data } # Used to subvert tk_textCut on "rich text" widgets proc richtext::text_cut {w} { set data [chk_reconstruct_text $w sel.first sel.last] clipboard clear -displayof $w clipboard append -displayof $w $data $w delete sel.first sel.last } # Installs selection handlers on a text widget. # 1) There's only need to support PRIMARY selection of type STRING # since all other types are only used in application-private protocols # (except UTF8_STRING, which is used by UTF-8-enabled software); # 2) Tk automagically handles UTF8_STRING if the handler for STRING is installed; # 3) (2) is not exactly true, see Tk bug #1571737, we work around it here. proc richtext::install_selection_handlers {w} { # Handlers for PRIMARY selection: selection handle -type UTF8_STRING $w {} selection handle -type STRING $w \ [list [namespace current]::get_selection $w] # Handlers of CLIPBOARD selections # (subvert tk_textCopy and tk_textCut) bind $w <> [list [namespace current]::text_copy $w] bind $w <> [list [namespace current]::text_cut $w] } proc richtext::render_text {w type piece tags} { $w insert end $piece [fixup_tags $tags {{bold italic}}] } proc richtext::highlighttext {w tag color cursor} { $w configure -cursor $cursor $w tag configure $tag -foreground $color } # Message properties may be added before [::richtext::render_message] # is called and are intended to be used by rich text plugins whatever # they wish to use them. # Message properties are automatically killed when message rendering # process is over. # Assotiates "message property" $name and assigns value $val to it: proc richtext::property_add {name value} { variable msgprops if {[info exists msgprops(name)]} { return -code error "[namespace current]::property_add:\ Attempted to overwrite message property: $name" } set msgprops($name) $value } # Unlike _add, allows stomping on existing property value: proc richtext::property_update {name value} { variable msgprops set msgprops($name) $value } proc richtext::property_get {name} { variable msgprops set msgprops($name) } proc richtext::property_exists {name} { variable msgprops info exists msgprops($name) } # Register the most basic renderer for type "text": richtext::register_entity text -renderer richtext::render_text richtext::entity_state text 1 # vim:ts=8:sw=4:sts=4:noet tkabber-0.11.1/ChangeLog0000644000175000017500000113240111076045704014302 0ustar sergeisergei2008-10-17 Sergei Golovan * plugins/general/sound.tcl: Cleared sound external program option making Snack package the default alternative. * doc/tkabber.html, doc/tkabber.xml, README: Added note about three new plugins. 2008-10-11 Sergei Golovan * AUTHORS: Fixed authors list. * msgs/pl.msg: Updated Polish translation (thanks to Irek Chmielowiec). * chats.tcl, ifacetk/iface.tcl: Added command which programmatically closes chat window (thanks to Konstantin Khomoutov). * muc.tcl: Request MUC info not only from server but also from the room itself when joining conference room. It allows to use redirectors like J2J transport. 2008-10-10 Sergei Golovan * doc/tkabber.html, doc/tkabber.xml, README: Added notes about new sound theme and about upcoming 0.11.1 release. Replaced tabs by whitespaces. * ifacetk/iroster.tcl: Show offline users if roster filter is enabled and isn't empty (thanks to Ruslan Rakhmanin). * msgs/ru.msg: Updated Russian translation. * msgs/es.msg: Updated Spanish translation (thanks to Badlop). 2008-09-27 Sergei Golovan * plugins/general/sound.tcl: Fixed bug with sound notification of disconnect event if its default value is used. 2008-09-26 Sergei Golovan * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2008-09-25 Sergei Golovan * ifacetk/iface.tcl: A bit optimized running of map_window_hook. * chats.tcl: Added new hook draw_message_post_hook. It is necessary because procedures in a usual draw_message_hook often return stop, so it's impossible to add a procedure to the very end of the hook and be sure it will be executed (thanks to Konstantin Khomoutov). * jabberlib/jabberlib.tcl, login.tcl: Reworked forced disconnecting from a server to make possible to use sound notification. * plugins/general/sound.tcl: Added sound notification for disconnect and changed default sounds for own chat and groupchat messages. * sounds/default/*.wav: Replaced default sound theme by a new original one (thanks to Serge Yudin). 2008-09-12 Sergei Golovan * gpgme.tcl: Ported key info processing to GPG package where its format slightly differs from TclGPGME. 2008-09-11 Sergei Golovan * plugins/chat/draw_timestamp.tcl: Raised priority to enable timestamps for error and info messages. * gpgme.tcl: Added GPG package (http://code.google.com/p/tclgpg) as an alternative package for encryption/signing messages. * msgs/de.msg, msgs/es.msg, msgs/it.msg, msgs/nl.msg, msgs/pl.msg, msgs/ru.msg, msgs/uk.msg: Replaced GPGME by more generic GPG. 2008-09-10 Sergei Golovan * disco.tcl: Added procedure which returns features list for a node. * plugins/chat/disco.tcl: Added a new plugin which implements /disco command in a chat window. The command opens disco window either for the curernt chat JID or for any specified JID. * muc.tcl, plugins/roster/conferences.tcl: Added MUC menu for room configuration etc. to conference JID nodes in disco and to conference bookmarks in a roster. 2008-09-09 Sergei Golovan * msgs/ru.msg: Fixed Russian translation. 2008-09-07 Sergei Golovan * ifacetk/buttonbar.tcl: Fixed keyboard traversing order for tabbar after its buttons are moved or a new tab is inserted in the middle. 2008-08-26 Sergei Golovan * msgs/ru.msg: Updated Russian translation. 2008-08-25 Sergei Golovan * ifacetk/systray.tcl, jabberlib/jlibauth.tcl, jabberlib/jlibcomponent.tcl, jabberlib/jlibcompress.tcl, jabberlib/jlibsasl.tcl, jabberlib/jlibtls.tcl, plugins/general/headlines.tcl, plugins/windows/taskbar.tcl: Fixed usage of [namespace code] in callbacks. The previous behavior doesn't reveal bug in Tcl/Tk 8.6a1 and older due to a hack maintained for Itcl and removed in 8.6a2. Also, TkCon may mask the bug because it includes a copy of the hack. 2008-08-24 Sergei Golovan * plugins/unix/menu8.4.tcl: Enabled plugin for Tcl/Tk 8.6. 2008-08-08 Sergei Golovan * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). * msgs/es.msg: Fixed typo in Spanish translation (thanks to Emiliano Gavilan). 2008-08-03 Sergei Golovan * plugins/general/copy_jid.tcl: Added a menu item for copying real JID (if available) in groupchats to clipboard (thanks to Konstantin Khomoutov). * msgs/ru.msg: Updated Russian translation (thanks to Konstantin Khomoutov). 2008-07-30 Sergei Golovan * login.tcl: Added -proxy option to jlib::connect call even if no proxy is used. This fixes bug when it's impossible to disable once used proxy. 2008-07-28 Sergei Golovan * jabberlib/https.tcl: Fixed typo in basic authentication (thanks to Konstantin Khomoutov). 2008-07-16 Sergei Golovan * utils.tcl, roster.tcl, ifacetk/iroster.tcl: Fixed bug in splitting roster group by a delimiter, now correctly treating delimiter as a string and not as a regexp (thanks to Konstantin Khomoutov). 2008-07-12 Sergei Golovan * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2008-07-11 Sergei Golovan * chats.tcl: Use left-justified text in chat window/tab JID menubutton. * ifacetk/iface.tcl: Added an option to show only personal messages (chat or highlighted) in windows titles (thanks to Antoni Grzymala). 2008-07-08 Sergei Golovan * jabberlib/wrapper.tcl, tclxml/sgmlparser.tcl: Bugfix in XMLNS prefix processing when tDOM parser is used. 2008-07-07 Sergei Golovan * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2008-07-05 Sergei Golovan * jabberlib/wrapper.tcl, tclxml/sgmlparser.tcl: Fixed parsing XMLNS prefixes for tag attributes. Now they are replaced by XMLNS URI both when tDOM or internal parser are used. 2008-07-03 Sergei Golovan * plugins/general/caps.tcl: Added forgotten node in disco#info reply (thanks to Konstantin Khomoutov). 2008-06-17 Sergei Golovan * jabberlib/https.tcl: Fixed typo in basic authentication. 2008-06-15 Sergei Golovan * chats.tcl: Lower node and server case for JID to which a new chat window is opened using open_to_user procedure. * plugins/iq/time2.tcl: Fixed urn:xmpp:time tag (thanks to Konstantin Khomoutov). 2008-06-08 Sergei Golovan * doc/tkabber.html, doc/tkabber.xml, README: Added a note about data form media element (XEP-0221) support and mentioned that Tkabber supports only version 0.2 of this and version 0.9 of XEP-0156. * *: 0.11.0 is released. * tkabber.tcl: Pushed version number to 0.11.0-svn. 2008-06-05 Sergei Golovan * doc/tkabber.html, doc/tkabber.xml, README: Added working links to Tclmore and ZTcl sources. Fixed unclear external links. Added Konstantin Khomoutov to the authors list, fixed authors email addresses. * ifaceck/iface.tcl, ifacetk/iface.tcl, splash.tcl: Added Konstantin Khomoutov to the authors list. 2008-06-04 Sergei Golovan * msgs/pl.msg: Updated Polish translation (thanks to Irek Chmielowiec). * msgs/es.msg: Updated Spanish translation (thanks to Badlop). * plugins/pep/user_tune.tcl: Show user tune info even if it doesn't contain author's name using ? marks (thanks to Konstantin Khomoutov). * plugins/pep/user_location.tcl, plugins/pep/user_tune.tcl, plugins/pep/user_activity.tcl, plugins/pep/user_mood.tcl, msgs/es.msg, msgs/pl.msg, msgs/ru.msg, msgs/de.msg: Corrected messages in user popup info (thanks to Konstantin Khomoutov). * doc/tkabber.html, doc/tkabber.xml, README: Added upgrade section which describes main changes between 0.10.0 and 0.11.0 versions (thanks to Konstantin Khomoutov). 2008-05-22 Sergei Golovan * doc/tkabber.xml, doc/tkabber.html, README: Bumped stable version to 0.11.0. * examples/tools/jsend.tcl, examples/tools/rssbot.tcl: Fixed required jabberlib version. * msgs/ru.msg: Updated Russian translation. 2008-05-21 Sergei Golovan * iface.tcl, login.tcl: Prettified SSL certificate info output (thanks to Konstantin Khomoutov). * msgs/ru.msg: Updated Russian translation. * contrib/extract-translations/extract.tcl: Read message file using UTF-8 encoding. * plugins/chat/draw_timestamp.tcl, plugins/general/ispell.tcl: Turned multiline translateable messages in one-line messages because message extraction tool doesn't process multiline messages correctly. * datagathering.tcl: Restored E-mail spelling. * jabberlib/stanzaerror.tcl, login.tcl: Fixed commented out translateable messages, so they can be processed by an extraction script. * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2008-05-20 Sergei Golovan * utils.tcl: Added forgotten helper procedure lpop which is used in user tune plugin (thanks to Konstantin Khomoutov). * plugins/pep/user_tune.tcl: Added implementation of rating field, which was added to XEP-0118 in version 1.2 (thanks to Konstantin Khomoutov). * msgs/ru.msg: Updated Russian translation (thanks to Konstantin Khomoutov). * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2008-05-19 Sergei Golovan * jabberlib/stanzaerror.tcl, login.tcl: Added a few commented out strings for translation (messages from jabberd 1.4 and SSL info). * plugins/general/clientinfo.tcl, msgs/ca.msg, msgs/de.msg, msgs/eo.msg, msgs/es.msg, msgs/eu.msg, msgs/fr.msg, msgs/nl.msg, msgs/pl.msg, msgs/pt.msg, msgs/ro.msg, msgs/ru.msg, msgs/uk.msg: Replaced Os by OS (as operating system abbreviation). * plugins/pep/user_location.tcl: Made several field labels more clear (thanks to Konstantin Khomoutov). * plugins/pep/user_tune.tcl: Implemented stopping player and did a few other improvements (thanks to Konstantin Khomoutov). * msgs/ru.msg: Updated Russian translation (thanks to Konstantin Khomoutov). * msgs/ru.msg: Sorted messages and fit them into 80 columns. * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2008-05-18 Sergei Golovan * privacy.tcl: Removed hook create_privacy_rules_menu_hook added for receipts plugin but no longer needed (thanks to Konstantin Khomoutov). * roster.tcl: Removed unneeded variable link (thanks to Konstantin Khomoutov). * ifacetk/iface.tcl: Replaced status message entry field with a compbobox with several recently used status messages (thanks to Konstantin Khomoutov). * plugins/unix/icon.tcl: Use "user available" icon for all toplevel windows. * userinfo.tcl: Removed "Close" button from info window because it isn't a dialog. * chats.tcl, ifacetk/bwidget_workarounds.tcl, ifacetk/iface.tcl, plugins/general/headlines.tcl, plugins/general/message_archive.tcl, plugins/general/rawxml.tcl: Made paned window separators flat and decreased their width. * plugins/roster/fetch_nicknames.tcl: Added a command to fetch nicknames for all users in a given group (thanks to Konstantin Khomoutov). * ifacetk/iroster.tcl: Moved "Rename group" menu item from the top of menu. * ifacetk/iface.tcl: Made popup menu on text status combobox non-torn-off. * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2008-05-15 Sergei Golovan * plugins/general/caps.tcl: Fixed bug with incorrectly calculated hash string if extra info have spaces in field values (closes: http://www.jabber.ru/bugzilla/show_bug.cgi?id=380). 2008-05-14 Sergei Golovan * roster.tcl: Added an own JID to trusted JIDs and check bare JIDs instead of full ones. 2008-05-13 Sergei Golovan * plugins/general/challenge.tcl: Don't mirror challenge id attribute when submitting a form because it isn't necessary according to version 0.9 of XEP-0158. * roster.tcl: Added a helper function roster::is_trusted which returns true iff a roster user is subscribed to out presence. 2008-05-12 Sergei Golovan * plugins/chat/chatstate.tcl: Switch internal chat states even if messages aren't sent because a recipient is unavalable. It prevents accidental sending of chat state events when a recipient becomes available * plugins/chat/events.tcl: Do not send events if a recipient is unavailable. It's useless and sometimes a remote server returns error messages which confuse users. * msgs/pl.msg: Updated Polish translation (thanks to Irek Chmielowiec). 2008-05-11 Sergei Golovan * utils.tcl: Added two procedures get_conf and render_url. The first one returns the value of a given widget option, the second creates a one-line text widget with a specified URL in it. * messages.tcl: Render OOB urls as links and not as buttons. * chats.tcl, gpgme.tcl, messages.tcl, muc.tcl, plugins/general/remote.tcl, plugins/general/xaddress.tcl, plugins/roster/rosterx.tcl: Added id argument to message_process_x_hook arguments list. * datagathering.tcl: Added processing of media elements (XEP-0221). Only in-band images and uris are supported currently. * plugins/richtext/urls.tcl: Fixed typo. * jabberlib/jabberlib.tcl: Allowed using id specified by send_iq call even for get and set queries. * plugins/general/challenge.tcl: Added processing of robot challenges forms in XMPP messages. * jabberlib/namespaces.tcl: Added two new namespaces (from XEP-0221 and XEP-0158). * datagathering.tcl: Return error if a media element cannot be processed this allows to fall back to a legacy challenge. * plugins/general/challenge.tcl: Don't show a message if a robot challenge form is attached and can be processed without errors. * ifacetk/iroster.tcl: Added an option which controls whether chat or normal message window is to be opened on roster item doubleclick (defaults to chat). * messages.tcl: Lowered priority of normal message processing because it returns stop and breaks other procedures in process_message_hook if default message type is normal (as it should be). * README, doc/tkabber.html, doc/tkabber.xml, ifaceck/iface.tcl, ifacetk/iface.tcl, splash.tcl: Fixed copyright messages and added a few new features to 0.10.1 features list. * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2008-05-05 Sergei Golovan * disco.tcl: Added more heuristics when guessing JID category and type while dragging it to roster. 2008-05-04 Sergei Golovan * roster.tcl: When overriding roster item category or subtype check if it was already overridden. 2008-04-22 Sergei Golovan * plugins/general/caps.tcl: Fixed bug with jabber:x:data processing in case if field values contain spaces. * muc.tcl: Added reasons to all MUC /commands. It isn't supported by MUC servers currently, but might be useful in the future (thanks to Konstantin Khomoutov). 2008-04-21 Sergei Golovan * datagathering.tcl: Added variable type to parsed jabber:x:data form output. * plugins/general/remote.tcl: Adjusted to account for variable types in jabber:x:data forms. * disco.tcl: Changed semantics of extras argument in disco_info_hook to a list of forms instead of a flat list of all variables. * plugins/general/caps.tcl: Fixed identity support (added name and xml:lang processing). Added extras (additional jabber:x:data forms) support. 2008-04-16 Sergei Golovan * privacy.tcl: Changed "no default list" and "no active list" radiobutton values from "" to "\u0000" to workaround a bug with radiobutton tristate mode in Tk 8.5. 2008-04-07 Sergei Golovan * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2008-03-23 Sergei Golovan * jabberlib/wrapper.tcl: Fixed xml:lang parsing when tDOM is used as an XML parser. * utils.tcl: Added a procedure to generate a sequence of paths for message dialogs. * plugins/chat/histool.tcl, plugins/pep/user_activity.tcl, plugins/pep/user_location.tcl, plugins/pep/user_mood.tcl, plugins/pep/user_tune.tcl, plugins/roster/backup.tcl, plugins/roster/bkup_annotations.tcl, plugins/roster/bkup_conferences.tcl: Switched from tk_messageBox to MessageDlg (tk_messageBox in Tk 8.5.1 and newer uses Ttk unconditionally, which is unacceptable). * plugins/pep/user_activity.tcl, plugins/pep/user_location.tcl, plugins/pep/user_mood.tcl, plugins/pep/user_tune.tcl: Enable/disable menu items on connect/disconnect to a server. * muc.tcl: Added a possibility to change affiliation/role for all MUC list at once. * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2008-03-07 Sergei Golovan * plugins/chat/draw_xhtml_message.tcl: Fixed a bug with xhtml_symb tag which was introduced when removing global font variable. * disco.tcl: Added registering extras to include XEP-0128 forms into disco#info replies. * plugins/iq/version.tcl: Implemented reporting Tkabber version in disco#info replies (XEP-0232). * ifacetk/iroster.tcl, jabberlib/wrapper.tcl, plugins/roster/annotations.tcl, plugins/roster/backup.tcl, plugins/roster/bkup_annotations.tcl, plugins/roster/bkup_conferences.tcl, plugins/roster/conferences.tcl, roster.tcl: Rewritten roster export. Now it is exported to XML, and export includes roster items, conferences and roster notes (thanks to Konstantin Khomoutov). * ifacetk/idefault.tcl, ifacetk/iface.tcl, ifacetk/iroster.tcl, plugins/chat/draw_xhtml_message.tcl, plugins/richtext/stylecodes.tcl, richtext.tcl: Added a different for rosters (before that rosters and chats used the same font). * README, doc/tkabber.html, doc/tkabber.xml: Fixed section about using fonts and added a few items into the list of new features in 0.10.1. * ifacetk/iroster.tcl, presence.tcl: Code cleanup. 2008-03-06 Sergei Golovan * disco.tcl: Added new hook disco_node_reply_hook to allow answering service discovery queries to unregistered temporary nodes (as in entity capabilities plugin). * plugins/general/caps.tcl: Implemented version 1.5 of XEP-0115 (only sending capabilities and replying to disco#info queries). * iq.tcl: Fixed call of IQ handler if it is a command with arguments. * datagathering.tcl: Removed [cequal] and [cindex] calls. * negotiate.tcl: Adapted to a current version of XEP-0020. * privacy.tcl: Fixed possible race conditions with receiving/updating privacy lists. * plugins/pep/user_location.tcl: Added user location support plugin (XEP-0080). * plugins/iq/time2.tcl: Added entity time support plugin (XEP-0202). * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2008-03-04 Sergei Golovan * msgs/ru.msg: Updated Russian translation. * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2008-03-03 Sergei Golovan * muc.tcl: Added a warning message to groupchat window if a room the user enters is newly created. 2008-03-02 Sergei Golovan * ifacetk/bwidget_workarounds.tcl: Changed look and feel of paned window separators. * chats.tcl, examples/xrdb/badlop-dark.xrdb, examples/xrdb/dark.xrdb, examples/xrdb/dark2.xrdb, examples/xrdb/ice.xrdb, examples/xrdb/light.xrdb, examples/xrdb/lighthouse.xrdb, examples/xrdb/ocean-deep.xrdb, examples/xrdb/teopetuk.xrdb, examples/xrdb/warm.xrdb, ifacetk/idefault.tcl, ifacetk/iface.tcl, ifacetk/iroster.tcl, mclistbox/mclistbox.tcl, plugins/chat/draw_xhtml_message.tcl, plugins/richtext/stylecodes.tcl, richtext.tcl, tkabber.tcl: Removed global font variable. Now one should either add option *font or use ifacetk::options(font) variable. * idefault.tcl, iface.tcl, ifacetk/iroster.tcl, plugins/richtext/stylecodes.tcl, richtext.tcl: Partially rolled back the change in font options for Tcl/Tk on UNIX with disabled Xft. Removed use of named fonts wherever possible. Also, ifacetk::options(font) variable can't be used for roster and chats font setup. Use *Chat*Text.font resource instead. 2008-02-21 Sergei Golovan * msgs/ru.msg: Updated Russian translation. * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2008-02-20 Sergei Golovan * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2008-02-19 Sergei Golovan * plugins/chat/draw_server_message.tcl: Removed unnecessary procedure call (thanks to Konstantin Khomoutov). * plugins/richtext/stylecodes.tcl: Added a customize option which allows to show stylecode markup symbols regardles of changing fonts in a chat window (thanks to Konstantin Khomoutov). * msgs/ru.msg: Updated (thanks to Konstantin Khomoutov). 2008-02-18 Sergei Golovan * iface.tcl: Show SHA1 hash of SSL certificate when asking for its approval and in a certificate info. 2008-02-05 Sergei Golovan * doc/tkabber.html, doc/tkabber.xml, README: Fixed notice about external XML parser (replaced TclXML which diesnt' work by tDOM which works). * jabberlib/jabberlib.tcl: Eliminate use_external_tclxml variable. Now, to use tDOM a user should 'require' it in a config file. * chats.tcl, custom.tcl, datagathering.tcl, disco.tcl, ifaceck/iroster.tcl, messages.tcl, muc.tcl, plugins/chat/chatstate.tcl, plugins/chat/events.tcl, plugins/chat/histool.tcl, plugins/chat/logger.tcl, plugins/chat/nick_colors.tcl, plugins/general/headlines.tcl, plugins/general/message_archive.tcl, plugins/general/offline.tcl, plugins/general/rawxml.tcl, plugins/general/xcommands.tcl, plugins/roster/annotations.tcl, pubsub.tcl, register.tcl, search.tcl, userinfo.tcl: Removed usage of global variable font. 2008-01-27 Sergei Golovan * plugins/filetransfer/si.tcl: Registered filetransfer feature to include it into disco#info replies. 2008-01-23 Sergei Golovan * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2008-01-15 Sergei Golovan * tkabber.tcl: Moved loading BWidget below sourcing config file to allow adding/removing directories to auto_path in config. * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2008-01-05 Sergei Golovan * ifacetk/iface.tcl, ifacetk/iroster.tcl: Added simple roster filter. * ifacetk/iroster.tcl: Made roster filter case insensitive, added Escape binding which clears filter string. * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2008-01-03 Sergei Golovan * chats.tcl: Fixed raising tab in case when a user clicks on "Open new conversation" link which appears in chat tab if the other party changes his/her nickname. 2007-12-31 Sergei Golovan * ifaceck/iface.tcl, ifacetk/iface.tcl: Added -raise option to add_win to make it possible to raise new tab even if raise_new_tab option is switched off. Also, added new raise_win function which raise a corresponding tab. * chats.tcl, custom.tcl, disco.tcl, doc/tkabber.xml, ifacetk/iface.tcl, joingrdialog.tcl, plugins/chat/histool.tcl, plugins/chat/muc_ignore.tcl, plugins/general/message_archive.tcl, plugins/general/rawxml.tcl, plugins/general/stats.tcl: Do not raise new tabs (when raise_new_tab is off) only if it isn't created by a Tkabber user himself, but by some external event (incoming message etc.). 2007-12-30 Sergei Golovan * tclxml/sgmlparser.tcl, tclxml/tclparser-8.1.tcl, tclxml/xml-8.1.tcl: Fixed bug with processing multiple XML attributes in case when one of them contains unescaped >. Also, made XML parser more reliable when parsing incomplete document (e.g. correctly process XML entities split into packets). * custom.tcl: Fixed back/forward moving in customize window history. 2007-12-28 Sergei Golovan * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2007-12-27 Sergei Golovan * mclistbox/mclistbox.tcl: Fixed error message when selecting a row (in Tcl/Tk 8.5.0). 2007-12-26 Sergei Golovan * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2007-12-24 Sergei Golovan * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2007-12-23 Sergei Golovan * disco.tcl: Added unregistering and re-registering disco features. * pep.tcl: Added PEP customization group. * plugins/pep/user_activity.tcl, plugins/pep/user_mood.tcl, plugins/pep/user_tune.tcl: Report corresponding features in disco, added auto-subscription to PEP notifications. 2007-12-19 Sergei Golovan * mclistbox/mclistbox.tcl, plugins/pep/user_activity.tcl, plugins/pep/user_mood.tcl, plugins/pep/user_tune.tcl, tclxml/sgmlparser.tcl, tclxml/tclparser-8.1.tcl: Added -- to all switch commands. 2007-12-16 Sergei Golovan * plugins/windows/taskbar.tcl: Fixed tray and window icons change during pixmaps theme switch (thanks to Konstantin Khomoutov). 2007-12-06 Sergei Golovan * plugins/si/socks5.tcl: Fixed procedure call (thanks to Konstantin Khomoutov). 2007-11-29 Sergei Golovan * doc/tkabber.html, doc/tkabber.xml, README: Added an item to the list of searchable windows (thanks to Konstantin Khomoutov). 2007-11-28 Sergei Golovan * plugins/chat/nick_colors.tcl: Replaced crc16 by sum for performance reason and because crc16 fails to load in older Tcllib versions (observed in Gentoo and Tcllib 1.6.1). 2007-11-25 Sergei Golovan * chats.tcl, plugins/chat/nick_colors.tcl: Implemented storing and using nick colors using more efficient algorithm. 2007-11-20 Sergei Golovan * plugins/chat/draw_timestamp.tcl: Replaced [clock scan] by [expr] in "23 hours 59 minutes ago" calculation. 2007-11-16 Sergei Golovan * ifacetk/bwidget_workarounds.tcl: Fixed dialog definition if -parent is explicitly empty. 2007-11-13 Sergei Golovan * ifacetk/bwidget_workarounds.tcl: Make dialogs non-transient to their parents if parents aren't viewable. Transient window in this case become unmapped too and grab to it leads to complete application hang. 2007-11-12 Sergei Golovan * plugins/chat/logger.tcl: Replace trailing dot by its hexadecimal code to make it possible to create log files for JIDs which end by a dot. * plugins/chat/histool.tcl: Fixed bug with showing history only for odd JIDS in JID list (thanks to Konstantin Khomoutov). 2007-11-11 Sergei Golovan * ifacetk/iface.tcl: Fixed unneeded tab headers highlighting when Tkabber window is not shown. 2007-11-10 Sergei Golovan * utils.tcl: A small addition to underscrolling fix. * plugins/si/ibb.tcl: Fixed incorrect error reporting. * plugins/si/ibb.tcl: Fixed processing of messages with type error (by do not replying to them). 2007-11-09 Sergei Golovan * chats.tcl, utils.tcl: Fixed chatlog window scrolling if a tabbar row is added/removed when a tab is opened/closed. 2007-11-08 Sergei Golovan * msgs/pl.msg: Updated Polish translation (thanks to Irek Chmielowiec). * chats.tcl: Added workaround for underscrolled chatlog windows which are opened at Tkabber startup and not mapped yet (so their height is one pixel and adding any text to it likely switches off smart scrolling). * plugins/general/caps.tcl: Made hash attribute required and added node attribute to make outgoing caps conforming to XEP-0115 (version 1.5). 2007-11-02 Sergei Golovan * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2007-10-31 Sergei Golovan * msgs/es.msg: Updated Spanish translation (thanks to Badlop). 2007-10-30 Sergei Golovan * plugins/general/rawxml.tcl: Fixed sending messages from raw XML console (thanks to Konstantin Khomoutov). 2007-10-28 Sergei Golovan * ifacetk/unix.xrdb: Fixed balloons resources. * messages.tcl: Made 'Add user' menu item inactive if the contact's real JID isn't available (thanks to Konstantin Khomoutov). * *: Tagged 0.10.1-beta2 for release. * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2007-10-27 Sergei Golovan * tkabber.tcl: Increased priority for options read from default XRDB files. 2007-10-26 Sergei Golovan * jabberlib/autoconnect.tcl, jabberlib/https.tcl, jabberlib/jabberlib.tcl, jabberlib/pkgIndex.tcl, jabberlib/socks4.tcl, jabberlib/socks5.tcl, jabberlib/transports.tcl: Renamed https, socks4 and socks5 modules to autoconnect::https, autoconnect::socks4 and autoconnect::socks5. Rewritten proxy modules loading scheme (now they are registered in autoconnect). * ifaceck/ilogin.tcl, ifacetk/systray.tcl, msgs/ru.msg, pep.tcl: Updated Russian translation. * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2007-10-24 Sergei Golovan * jabberlib/https.tcl, jabberlib/socks3.tcl, jabberlib/socks5.tcl, jabberlib/autoconnect.tcl: Fixed closing TCP socket to a proxy in case of network problems. 2007-10-21 Sergei Golovan * plugins/richtext/emoticons.tcl: Added support for JISP emoticon sets (requires vfs::zip and Memchan Tcl extensions). * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2007-10-18 Sergei Golovan * plugins/windows/taskbar.tcl: Added window icons to all Tkabber windows (thanks to Konstantin Khomoutov). 2007-10-15 Sergei Golovan * ifacetk/buttonbar.tcl: Replaced ... by \u2026 at the end of trimmed button labels. This helps to show extra two symbols if a monospaced font is used. 2007-10-14 Sergei Golovan * chats.tcl: Added a procedure which returns chat ID given its window name (thanks to Konstantin Khomoutov). 2007-10-11 Sergei Golovan * ifacetk/iface.tcl: Fixed binding of and to chat windows/tabs (thanks to Konstantin Khomoutov). Also, cleaned up corresponding hooks. 2007-10-10 Sergei Golovan * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). * jabberlib/transports.tcl: Fixed supported proxy types list. 2007-10-07 Sergei Golovan * examples/xrdb/*: Fixed *Balloon*foreground and *Balloon*background resources. * tkabber.tcl, ckabber.tcl: Fixed default resources priority. * jabberlib/jabberlib.tcl: Fixed small typo. * doc/tkabber.html, doc/tkabber.xml, README: Added info on ctcomp plugin. * plugins/iq/ping.tcl: Use jlib::emergency_disconnect (indirectly via jlib::inmsg) for disconnecting/reconnecting after ping timeout. This should fix race condition during reconnect. * *: Tagged 0.10.1-beta for release. 2007-10-06 Sergei Golovan * jabberlib-tclxml/: Renamed to jabberlib/ directory. * tclxml/*: Code cleanup, removed xmldep.tcl and xpath.tcl since they are not necessary for jabberlib. * Makefile: Adopted to recent changes in directories list. * disco.tcl, ifacetk/iface.tcl, ifacetk/iroster.tcl, plugins/general/avatars.tcl, plugins/general/subscribe_gateway.tcl, plugins/roster/conferences.tcl, plugins/general/xcommands.tcl, privacy.tcl, pubsub.tcl: Got rid of ::jlib::route. * tkabber.tcl: Require jabberlib 0.10.1 * splash.tcl: Fixed label flicker during loading package indices. * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). * doc/tkabber.html, doc/tkabber.xml, README: Added info on floatinglog plugin. * balloon.tcl: Cleaned up usage of foreground and background resources for balloon windows. Also, the meaning of padX and padY was changed. * examples/xrdb/*: Removed *Balloon*padX and *Balloon*padY resources. * msgs/ru.msg: Added translation of user mood, user tune, user activity (thanks to Serge Yudin ans Konstantin Khomoutov). 2007-10-05 Sergei Golovan * jabberlib-tclxml/jabberlib.tcl, doc/tkabber.xml: Removed keep-alive periodic sending of space character to a server. XMPP Ping support does this job much better (at cost of bigger traffic though). * jabberlib-tclxml/jabberlib.tcl, jabberlib-tclxml/transports.tcl, jabberlib-tclxml/jlibsasl.tcl, jabberlib-tclxml/jlibtls.tcl, jabberlib-tclxml/jlibcompress.tcl: Moved starting and finishing stream to transports. Eventually it will allow to impolement unusual stream start and finish (e.g. in BOSH, XEP-0124). * login.tcl: Increased default polling intervals. Moved to more neutral options -httpurl, -httpusekeys, -httpnumkeys (they will be used not only in HTTP polling). * jabberlib-tclxml/transports.tcl: Code cleanup, use separate variables for different connections instead of a single array. * jabberlib-tclxml/tclxml: Moved to tkabber root directory. * jabberlib-tclxml/jabberlib.tcl, jabberlib-tclxml/wrapper.tcl, tclxml/xml__tcl.tcl: Added -namespace option to xml::parser and made possible to use tDOM as an XML parser. (tDOM parser is sensitive to unbound XML namespaces though, so to enable it use variable use_external_tclxml and set it to 1.) * doc/tkabber.html, doc/tkabber.xml, README: Added main changes in 0.10.1. 2007-09-25 Sergei Golovan * plugins/richtext/emoticons.tcl: Ignore empty text as an emoticon label (thanks to Konstantin Khomoutov). 2007-09-21 Sergei Golovan * private.tcl, tkabber.tcl: Separated interface to private XML storage (XEP-0049). Eventually private information via pubsub (XEP-0223) backend will be added. * plugins/roster/annotations.tcl, plugins/roster/conferences.tcl, plugins/roster/roster_delimiter.tcl: Switched to a separated private XML storage interface. * ifacetk/systray.tcl: Added call to [wm withdraw .] to please some window managers when raising main window. 2007-09-20 Sergei Golovan * plugins/general/xaddress.tcl: Moved address rewriting to rewrite_message_hook, check for forged address changes. * ifacetk/systray.tcl, plugins/unix/dockingtray.tcl, plugins/unix/systray.tcl, plugins/unix/tktray.tcl, plugins/windows/taskbar.tcl: Split main window showing and hiding into two separate gestures: left mouse button shows main window, middle mouse button hides. * ifacetk/iface.tcl: Added a few words describing systray icon behavior. * ifacetk/systray.tcl: Raise main window to top when showing it. * plugins/chat/events.tcl, plugins/chat/chatstate.tcl: Registered jabber:x:event and http://jabber.org/protocol/chatstates as Disco features. * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2007-09-18 Sergei Golovan * ifacetk/iroster.tcl: Fixed showing own resources if username is not in lowercase. 2007-09-17 Sergei Golovan * plugins/chat/popupmenu.tcl: Fixed double encoding of Google query to UTF-8. 2007-09-16 Sergei Golovan * userinfo.tcl: Fixed bug with reconfiguring photo after it is destroyed. * plugins/pep/user_tune.tcl: Replaced positional arguments of publish procedure by optional ones. 2007-09-08 Sergei Golovan * msgs/de.msg, trans/de.msg: Updated German translation (thanks to Roger Sondermann). 2007-09-05 Sergei Golovan * msgs/pl.msg, trans/pl.msg: Updated Polish translation (thanks to Irek Chmielowiec). 2007-09-04 Sergei Golovan * ifacetk/ilogin.tcl, jabberlib-tclxml/jabberlib.tcl, jabberlib-tclxml/jlibsasl.tcl, login.tcl: Added new option to disable X-GOOGLE-TOKEN SASL mechanism. This helps if Tkabber cannot connect to Google via HTTPS. Also, made error message about SASL mechanisms more clear. * msgs/es.msg: Updated Spanish translation (thanks to Badlop). * plugins/chat/histool.tcl: Ignore damaged history messages during search in history. 2007-09-03 Sergei Golovan * plugins/iq/version.tcl: Made reporting OS version optional as required by XEP-0092. 2007-09-02 Sergei Golovan * login.tcl: Added $connid suffix to authentication error dialog path to avoid conflict if several connections are used simultaneously. 2007-08-31 Sergei Golovan * README, doc/tkabber.html, doc/tkabber.xml, jidlink.tcl, plugins/filetransfer/jidlink.tcl, plugins/jidlink/dtcp.tcl, plugins/jidlink/ibb.tcl, tkabber.tcl: Moved Jidlink (obsolete undocumented filetransfer protocol) support to an external plugin. * ifaceck/iroster.tcl, ckabber.tcl, splash.tcl: Removed references to Jidlink. * examples/xrgb/*.xrdb: Added inactiveSelectBackground definitions. * msgs/ru.msg: Updated Russian translation. 2007-08-30 Sergei Golovan * README, browser.tcl, datagathering.tcl, disco.tcl, doc/tkabber.html, doc/tkabber.xml, ifacetk/default.xrdb, ifacetk/iface.tcl, ifacetk/unix.xrdb, muc.tcl, plugins/general/headlines.tcl, plugins/general/offline.tcl, plugins/general/subscribe_gateway.tcl, plugins/general/xcommands.tcl, plugins/iq/browse.tcl, plugins/unix/icon.tcl, plugins/windows/taskbar.tcl, register.tcl, search.tcl, tkabber.tcl, userinfo.tcl: Moved Jabber Browser (XEP-0011) support to an external plugin since it is deprecated for a long time. Moved registering Disco features (and Browser namespaces) to a new hook. Replaced JBrowser window class by JDisco. * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2007-08-18 Sergei Golovan * plugins/general/xcommands.tcl: Fixed x:data cleanup on completing or cancelling ad-hoc command. * plugins/pep/user_mood.tcl: Fixed typo (thanks to Roger Sondermann). * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). * plugins/general/headlines.tcl: Ensure that color of read messages is not an empty string. Also, minor code cleanup. * plugins.tcl: Sort list of files to source to make order of loaded plugins always the same. * plugins/pep/user_mood.tcl: Fixed status line notifications. * plugins/pep/user_activity.tcl: Added preliminary user activity implementation (XEP-0108). * plugins/pep/user_mood.tcl, plugins/pep/user_activity.tcl: Fixed multiuser support. * plugins/pep/user_tune.tcl: Added preliminary user tune implementation (XEP-0118). * plugins/pep/user_activity.tcl: Fixed publishing an activity without a subactivity, and fixed showing user activity in userinfo window. * plugins/pep/user_tune.tcl: Fixed showing user tune in userinfo window. 2007-08-17 Sergei Golovan * pubsub.tcl: Added notification support when deleting published item. * pep.tcl: Added item ID support when publishing PEP item. Also, added a node deleting procedure. * plugins/pep/user_mood.tcl: Added support of deleting published user mood. Also, added publishing user mood for all connected resources simultaneously. 2007-08-16 Sergei Golovan * datagathering.tcl: Register jabber:x:data to show in disco#info responses (closes: http://www.jabber.ru/bugzilla/show_bug.cgi?id=365). * messages.tcl: Register jabber:x:oob to show in disco#info responses (closes: http://www.jabber.ru/bugzilla/show_bug.cgi?id=366). * disco.tcl: Sort features list on sending disco#info response. * tkabber.tcl: Reordered files sourcesd at Tkabber start to allow registering jabber:x:oob as a disco feature in messages.tcl. * plugins/general/tkcon.tcl: Fixed clearing checkmark in main menu on closing TkCon window. * plugins/windows/console.tcl: Fixed clearing checkmark in main menu on closing console window. 2007-08-15 Sergei Golovan * examples/tools/jsend.tcl, examples/tools/rssbot.tcl: Fixed sending available presence and removed loading unnecessary Tclx package. 2007-08-12 Sergei Golovan * iq.tcl: Switched to returning service-unavailable instead of feature-not-implemented as recommended by RFC-3291. * plugins/iq/ping.tcl: Return service-unavailable instead of swallowing ping request because it's mandatory to reply to every IQ request. * plugins/general/caps.tcl: Index array of features lists not only by hash values but also by hash methods. * plugins/roster/conferenceinfo.tcl: Added service-unavailable to caught jabber:iq:browse errors. * muc.tcl: Added a hack to change room nickname instead of joining if we are already in the room. 2007-08-11 Sergei Golovan * jabberlib-tclxml/tclxml/xml-8.1.tcl: Fixed parsing XML attributes which end by an equal sign. * jabberlib-tclxml/jabberlib.tcl: Add any tags (not only ) to a presence extensions list. * plugins/general/caps.tcl: Added entitiy capabilities support (XEP-0115, version 1.4). 2007-08-10 Sergei Golovan * plugins/general/rawxml.tcl: Fixed bug with pretty-printing tags with no attributes. * plugins/general/headlines.tcl: Ignore empty messages with also empty attached URL and description. 2007-08-08 Sergei Golovan * jabberlib-tclxml/socks4.tcl: Fixed checking SOCKS server response. * login.tcl: Added readable connect error messages. * jabberlib-tclxml/socks4.tcl: Changed error reporting. * jabberlib-tclxml/https.tcl: Report error if connection to a proxy server fails. * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2007-08-07 Sergei Golovan * plugins/general/rawxml.tcl: Removed redundant xmlns attributes from pretty-printed XML for better readability. * plugins/chat/histool.tcl: Fixed history tree if JID resources contain double colons. 2007-08-06 Sergei Golovan * ifacetk/iroster.tcl: Fixed roster item menu commands in case when multiple contact resources connected and the command contains menu path (as in plugins/general/copy_jid.tcl). * plugins/search/spanel.tcl: Removed update idletasks to make creating chat window an atomic operation (this helps if there are several offline messages incoming). 2007-08-05 Sergei Golovan * ifacetk/iroster.tcl: Fixed cascaded roster item submenus in case of multiple contact resources connected. * plugins/pep/user_mood.tcl: Use JIDs without resource for sending user mood subscription/unsubscription stanzas via roster item menu. 2007-08-03 Sergei Golovan * pep.tcl: Fixed customization of menu tearoffs. * plugins/pep/user_mood.tcl: Fixed publishing of translated mood. * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2007-08-01 Sergei Golovan * pep.tcl, pubsub.tcl, tkabber.tcl: Moved personal evening support to a separate file (thanks to Konstantin Khomoutov). * plugins/pep/user_mood.tcl: Added user mood (XEP-107) support as an exercise on personal eventing (thanks to Konstantin Khomoutov). 2007-07-31 Sergei Golovan * jabberlib-tclxml/tclxml/xml-8.1.tcl: Fixed tokenizing regexp to match CDATA XML declaration (this bug was introduced at 2005-04-07 when parsing unescaped > in tag attributes was fixed). * login.tcl: Fixed 'Logout with reason' dialog. It incorrectly reused existing .logout window. (Closes http://www.jabber.ru/bugzilla/show_bug.cgi?id=341) * plugins/unix/icon.tcl: Do not load static icon if WindowMaker dock is used. (Closes http://www.jabber.ru/bugzilla/show_bug.cgi?id=342) * si.tcl: Fixed an application error message in case of cancelled file transfer. (Closes http://www.jabber.ru/bugzilla/show_bug.cgi?id=358) * plugins/filetransfer/http.tcl: Report an error message in case of unsuccessful HTTP reply. (Closes http://www.jabber.ru/bugzilla/show_bug.cgi?id=361) * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2007-07-26 Sergei Golovan * plugins/chat/logger.tcl: Added ~ to symbols which are escaped during JID-to-filename conversion. 2007-07-23 Sergei Golovan * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2007-07-22 Sergei Golovan * msgs/de.msg, trans/de.msg: Updated German translation (thanks to Roger Sondermann). 2007-07-21 Sergei Golovan * datagathering.tcl: Show descriptions in a balloon over the form fields (closes: http://www.jabber.ru/bugzilla/show_bug.cgi?id=359). 2007-07-17 Sergei Golovan * plugins/richtext/urls.tcl: Added upcoming asia TLD and changed URL regexp to accept URLS like http://example.org?par=val (without a slash after a domain name). 2007-07-16 Sergei Golovan * jabberlib-tclxml/https.tcl: Fixed bug with authorization at HTTPS proxy server. 2007-07-15 Sergei Golovan * jabberlib-tclxml/ntlm.tcl: Wrapped md5::md5 procedure to make possible using md5 package earlier than 2.0. * jabberlib-tclxml/transports.tcl, jabberlib-tclxml/https.tcl: Moved HTTPS proxy support to a separate https package. * jabberlib-tclxml/socks4.tcl, jabberlib-tclxml/socks5.tcl: Added SOCKS4a and SOCKS5 proxy support (the code is mostly borrowed from Mats Bengtsson). * jabberlib-tclxml/autoconnect.tcl: Added a wrapper over the socket command, which allows to connect via proxy. * jabberlib-tclxml/jabberlib.tcl, jabberlib-tclxml/transports.tcl: Made use of socks4, socks5 and https packages. Unfinished yet, todo meaningful error messages. * login.tcl, ifacetk/ilogin.tcl: Added support for new proxy types. Changed binary loginconf(useproxy) to loginconf(proxy) with values none, socks4, socks5, https. Changed loginconf(httpproxy) to loginconf(proxyhost), loginconf(httpport) to loginconf(proxyport), loginconf(httplogin) to loginconf(proxyusername) and loginconf(httppassword) to loginconf(proxypassword) option names. * doc/tkabber.xml, doc/tkabber.html, README: Documented changes in options. 2007-07-12 Sergei Golovan * jabberlib-tclxml/wrapper.tcl: Do not add xmlns attribute to an XML element if it is the same as for its parent element. 2007-07-11 Sergei Golovan * jabberlib-tclxml/tclxml/sgmlparser.tcl, jabberlib-tclxml/namespaces.tcl, jabberlib-tclxml/jabberlib.tcl, jabberlib-tclxml/jlibcomponent.tcl: Made XML namespace prefixes converted to xmlns attributes. Still ignore invalid prefixes. * jabberlib-tclxml/tclxml/sgmlparser.tcl: Fixed default xmlns processing (popping from stack). Also made code more readable and removed some pre 8.1 code. 2007-07-09 Sergei Golovan * hooks.tcl: Allowed hook priority to take real value instead of integer. This helps inserting a procedure to a hook between two existing procedures easier. * msgs/it.msg: Updated Italian translation (thanks to Mikhail Zakharenko) * plugins/si/socks5.tcl: Replaced buggy 'proxy.jabber.org' by known to work 'proxy.netlab.cz' and 'proxy.jabber.cd.chalmers.se' in default proxy list. * muc.tcl: Added chat messages about changes in occupants' roles and affiliations (thanks to Konstantin Khomoutov). * msgs/ru.msg: Updated (thanks to Konstantin Khomoutov). * plugins/roster/rosterx.tcl, search.tcl: Turned optional connection ID arguments to obligatory ones. 2007-06-22 Sergei Golovan * plugins/filetransfer/si.tcl: Don't close SOCKS5 connection upon receiving announced number of bytes because it leads to problems when the other side closes the socket. 2007-06-15 Sergei Golovan * userinfo.tcl: Request vCard from recipient bare JID except if the user is a groupchat member. 2007-06-13 Sergei Golovan * messages.tcl: Added 'Subscription' submenu to service popup menu in main roster. 2007-06-09 Sergei Golovan * jabberlib-tclxml/jabberlib.tcl, messages.tcl, examples/tools/jsend.tcl, examples/tools/rssbot.tcl: Made -connection option mandatory for jlib::send_msg. This prevents sending messages to wrong connection. * jabberlib-tclxml/jabberlib.tcl: Made parsing options in jlib::send_msg and jlib::send_presence more efficient. * jabberlib-tclxml/jabberlib.tcl: Made -connection option mandatory for jlib::send_presence. This prevents sending presence to wrong connection. 2007-05-29 Sergei Golovan * ifacetk/buttonbar.tcl: Fixed setting active page when -raisecmd is not called on activation. 2007-05-28 Sergei Golovan * ifacetk/buttonbar.tcl: Don't call -raisecmd command on first page creation. 2007-05-27 Sergei Golovan * ifacetk/buttonbar.tcl: Fixed activation of the first added button and deactivation of the last removed button (thanks to Konstantin Khomoutov). 2007-05-25 Sergei Golovan * richtext.tcl: Added -nonewline option to ::richtext::render_message procedure. * plugins/chat/draw_xhtml_message.tcl: Bugfix. Use -nonewline option in ::richtext::render_message calls when rendering XHTML messages. 2007-05-21 Sergei Golovan * doc/tkabber.xml, doc/tkabber.html, README: Fixed grammar in several sentences (thanks to Peter Kudinov). * pixmaps.tcl: Added JISP support (XEP-0038) for pixmap set loader. It requires vfs::zip, Memchan and Trf packages. * jabberlib-tclxml/transports.tcl, jidlink.tcl, messages.tcl, plugins/filetransfer/jidlink.tcl, plugins/general/message_archive.tcl, plugins/general/remote.tcl, plugins/jidlink/dtcp.tcl, plugins/jidlink/ibb.tcl, si.tcl, tkabber.tcl, utils.tcl: Renamed [random] procedure to [rand] to prevent clash with one from Memchan package, which is loaded for JISP support. 2007-05-08 Sergei Golovan * ifacetk/iface.tcl: Fixed main window gometry in untabbed mode (thanks to Konstantin Khomoutov). * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2007-05-06 Sergei Golovan * ifacetk/iface.tcl: Moved tab buttons closer to tabs themselves. 2007-05-01 Sergei Golovan * emoticons/default/icondef.xml: Lowered case of emoticons filenames. * emoticons/default/faceyukky.gif, emoticons/default/facehappy.gif, emoticons/default/facestartled.gif, emoticons/default/faceironic.gif, emoticons/default/facestraight.gif, emoticons/default/facewinking.gif, emoticons/default/facesad.gif, emoticons/default/facegrinning.gif: Updated (thanks to Artem Bannikov). 2007-04-29 Sergei Golovan * plugins/chat/logger.tcl: Fixed displaying announcement log messages in groupchat logs (thanks to Konstantin Khomoutov). * plugins/general/autoaway.tcl: Added support for tkinactive package from TIP 245 (see http://wiki.tcl.tk/14765) in Windows (thanks to Konstantin Khomoutov). * ifacetk/buttonbar.tcl: Cleanup in redraw buttonbar code. 2007-04-24 Sergei Golovan * ifacetk/buttonbar.tcl: Fixed raising tab page if this page is already activated. 2007-04-22 Sergei Golovan * configdir.tcl, splash.tcl, tkabber.tcl: Fixed bug when Tkabber couldn't show message dialogs during config directory transfer because the main window was withdrawn (thanks to Konstantin Khomoutov). 2007-04-21 Sergei Golovan * ifacetk/iface.tcl: Quickfixed bug with "bad window path name ".pages.ftab_0"" on updating tab foregrounds. 2007-04-19 Sergei Golovan * ifacetk/buttonbar.tcl: Fixed displaying vertical tabbar. Before that it might be wider than required and under certain conditions there was an infinite event loop. * ifacetk/iface.tcl: Color active tab foreground to highlight received messages when Tkabber has lost focus. 2007-04-18 Sergei Golovan * ifacetk/buttonbar.tcl, ifacetk/iface.tcl, ifacetk/systray.tcl, examples/xrdb/badlop-dark.xrdb, examples/xrdb/black.xrdb, examples/xrdb/dark.xrdb, examples/xrdb/dark2.xrdb, examples/xrdb/green.xrdb, examples/xrdb/ice.xrdb, examples/xrdb/light.xrdb, examples/xrdb/lighthouse.xrdb, examples/xrdb/teopetuk.xrdb, examples/xrdb/warm.xrdb: Merged changes from tkabber-tabbar branch. Changes introduce new user interface in tabbed mode. * plugins/general/session.tcl: Lowered priority of state loading procedure to make it work with colors in chat windows. 2007-04-15 Sergei Golovan * plugins/chat/logger.tcl: Fixed bug with converting chatlogs directory if its definition contains trailing slash. * doc/tkabber.xml, doc/tkabber.html, README: Fixed URL of Img extension project. 2007-04-13 Sergei Golovan * pixmaps/default-blue/docking/tkabber.ico, pixmaps/default-blue/docking/available-dnd.gif, pixmaps/default-blue/roster/available-dnd.gif, pixmaps/default-blue/icondef.xml: Changed DND icons in Default-blue theme (thanks to Artem Bannikov). 2007-04-12 Sergei Golovan * jabberlib-tclxml/jabberlib.tcl: Fixed bug with delayed delivery timestamps. * messages.tcl: Fixed jabber:x:data form processing. Before this fix Tkabber displayed not the form itself. * datagathering.tcl, muc.tcl: Returned cancel_command ardument to data::draw_window routine. Use it while configuring MUC rooms. * register.tcl, search.tcl: Manage focus using return value from data::fill_fields procedure. * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). * msgs/ru.msg: Updated Russian translation. * pixmaps/default/tkabber/gpg-signed.gif, pixmaps/default/tkabber/gpg-badsigned.gif, pixmaps/default/tkabber/gpg-unsigned.gif, pixmaps/default/tkabber/gpg-vsigned.gif: Updated (thanks to Artem Bannikov) * pixmaps/default/services/server.gif, pixmaps/default/icondef.xml: Added icon for jabber servers in service discovery windows (thanks to Artem Bannikov). * doc/tkabber.xml, doc/tkabber.html, README: Added few more lines to the release highlights. * doc/tkabber.xml, doc/tkabber.html, README: Fixed download URLs. * plugins/richtext/emoticons.tcl: Restored procedure ::emoteicons::load_dir, which loads emoticons set for compatibility with older Tkabber versions. * contrib/starkit/main.tcl: Require Tk package at script upper level. * doc/tkabber.xml, doc/tkabber.html, README: Added upgrade notes and extended release notes. * doc/tkabber.xml, doc/tkabber.html, README: Bumped stable version to 0.10.0. * *: 0.10.0 is released. * tkabber.tcl: Pushed version number to 0.10.0-svn. 2007-04-11 Sergei Golovan * jabberlib-tclxml/jabberlib.tcl: Added partial support of XEP-0203 (delayed delivery). * plugins/search/search.tcl: Fixed searching substrings and glob patterns. * messages.tcl: Ignore empty jabber:x:data form in messages. 2007-04-10 Sergei Golovan * messages.tcl, presence.tcl: Moved showing unsubscribed message dialog to messages.tcl and made several dialogs possible. 2007-04-09 Sergei Golovan * pixmaps/default/services/jud.gif, pixmaps/default/services/sms.gif: Updated (thanks to Artem Bannikov). * pixmaps/default/docking/tkabber.ico, pixmaps/default/docking-blue/tkabber.ico: Changed 32x32 icon from a bulb to a feather (thanks to Artem Bannikov). * ifacetk/iface.tcl: Fixed chat window/tab title updates when rendering a presence message. 2007-04-08 Sergei Golovan * plugins/chat/logger.tcl: Accept subdirs list when creating chatlog window to prevent extra directory tree scanning (thanks to Konstantin Khomoutov). * plugins/search/spanel.tcl: Removed checking for existence of search form. It should be done in search routines. Also added 'Stop' button and stop search callback (thanks to Konstantin Khomoutov). * plugins/chat/histool.tcl: Redone full-text search to use stop search callback and to avoid [update] calls. * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). * ifacetk/iroster.tcl: Changed default roster icon from empty to ordinary user icon. * msgs/uk.msg: Updated Ukrainian translation (thanks to Artem Bondarenko). * datagathering.tcl, plugins/chat/logger.tcl: Fixed switch statements (added missing --). * plugins/search/search.tcl, roster.tcl: Fixed regexp statements (added missing --). * datagathering.tcl: Added support for several values in list-multi and fixed data fields (thanks to Artem Borodin). * remote.tcl: Added ad-hoc wizards support to remote command scheduler (thanks to Artem Borodin). * xcommands.tcl: Uncommented draw_window calls to partially support ad-hoc wizards (thanks to Artem Borodin). * msgs/ru.msg: Updated Russian translation. 2007-04-02 Sergei Golovan * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). * plugins/roster/conferences.tcl: Fixed bug with autojoin when this attribute is set to 'true'. 2007-04-01 Sergei Golovan * contrib/starkit/README: Fixed double README. * privacy.tcl: Ensure conference list loading before any join room attempt is made. Without that it would be possible for conference list to become empty if there are autojoined conferences in bookmarks or if a user loads Tkabber's state on start. 2007-03-31 Sergei Golovan * contrib/starkit/main.tcl: Fixed usage of starkit::topdir variable, requre Tk package because Linux tclkit doesn't require it by default and forget zlib package to make it possible to use compressed XMPP streams (thanks to Konstantin Khomoutov, Sergey Yudin and Ruslan Rakhmanin). * contrib/starkit/README: Added README for those, who want to create Tkabber starkits (thanks to Konstantin Khomoutov, Sergey Yudin and Ruslan Rakhmanin). 2007-03-30 Sergei Golovan * splash.tcl, tkabber.tcl: Override bgerror even if splash screen is not used. Also, don't show the second error message if the previous one is shown. * plugins/chat/histool.tcl: Display chat log on in JID list tab. Also, don't export listbox selection. * messages.tcl: Fixed race condition when receiving several subscription requests. * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2007-03-29 Sergei Golovan * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2007-03-28 Sergei Golovan * muc.tcl: Fixed grid options in MUC lists editing windows. Also, added the possibilty of changing reasons without changing affiliation. * plugins/chat/histool.tcl: Added scrolling in logs tree using mousewheel. 2007-03-27 Sergei Golovan * plugins/windows/mousewheel.tcl, ifacetk/idefault.tcl: Moved scroll bindings outside from windows plugin. 2007-03-25 Sergei Golovan * muc.tcl: Process all errors in MUC presence. * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2007-03-23 Sergei Golovan * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2007-03-22 Sergei Golovan * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2007-03-21 Sergei Golovan * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). * msgs/es.msg: Updated Spanish translation (thanks to Badlop). * plugins/general/avatars.tcl: Fixed avatars menu in case of non-tornoff menus (thanks to Roger Sondermann). 2007-03-18 Sergei Golovan * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). * msgs/ru.msg: Updated Russian translation. 2007-03-17 Sergei Golovan * tkabber.tcl: Fixed Tkabber rootdir definition for starkit. Added starkit initialization (thanks to Konstantin Khomoutov). * contrib/starkit/main.tcl: Added main.tcl starkit script (thanks to Konstantin Khomoutov). * jabberlib-tclxml/jlibdns.tcl: Fixed nameservers list if they are separated by commas in corresponding registry key in Windows (thanks to Irek Chmielowiec). * privacy.tcl, msgs/ru.msg, msgs/pl.msg, msgs/uk.msg, msgs/de.msg: Fixed typo. * msgs/es.msg: Updated Spanish translation (thanks to Badlop). 2007-03-14 Sergei Golovan * msgs/pl.msg: Updated Polish translation (thanks to Irek Chmielowiec). * plugins/search/spanel.tcl: Added checking for existence of search panel after the search is done. * plugins/chat/histool.tcl: Do not throw an error if the user breaks full-text search by closing chats history window. * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2007-03-11 Sergei Golovan * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). * plugins/chat/histool.tcl: Optimized JID list sorting (thanks to Konstantin Khomoutov). 2007-03-10 Sergei Golovan * jabberlib-tclxml/jabberlib.tcl: Made -connection argument mandatory for send_iq. Call user callback even in case of disconnect. * disco.tcl, examples/tools/rssbot.tcl, filters.tcl, login.tcl, plugins/general/stats.tcl, plugins/roster/rosterx.tcl, plugins/si/ibb.tcl, plugins/si/iqibb.tcl, pubsub.tcl, userinfo.tcl: Added -connection argument to all jlib::send_iq calls, where it was missing. Fixed several bugs with backslash at the end of line. * privacy.tcl: Made error messageboxes appear only in case of errors (ignore disconnects). * jabberlib-tclxml/jabberlib.tcl: Added few extra checks if connection exists. * plugins/general/headlines.tcl: After removing a from headlines tree select the closest node to make keyboard traversal easier (thanks to Konstantin Khomoutov). * msgs/uk.msg: Updated Ukrainian translation (thanks to Artem Bondarenko). * plugins/windows/taskbar.tcl, plugins/unix/dockingtray.tcl, plugins/unix/systray.tcl, plugins/unix/tktray.tcl: Added extra checks for icon existence. * plugins/search/spanel.tcl: Added few new options to search panel (-allowclose, -twoway, -defaultdirection, thanks to Konstantin Khomoutov). * plugins/chat/logger.tcl, plugins/search/logger.tcl: Added possibility to open log window at a specific message by timestamp (thanks to Konstantin Khomoutov). * plugins/chat/histool.tcl: Added full-text search in all stored chatlogs (thanks to Konstantin Khomoutov). 2007-03-09 Sergei Golovan * ifacetk/iface.tcl, splash.tcl, tkabber.tcl: Withdraw main window at the very beginning because otherwise it's visible (and pretty ugly) during confid directory transfer. * userinfo.tcl: Fixed typo (destroying userinfo window didn't delete correspondent variabla trace). * userinfo.tcl: Rearranged controls on photo page because otherwise it isn't possible to replace large photos. * ifacetk/iface.tcl: Fixed profiling option ::enable_profiling. 2007-03-08 Sergei Golovan * presence.tcl, ifacetk/iroster.tcl: Show presence priority in roster contact tooltips. * presence.tcl, plugins/chat/histool.tcl, messages.tcl, ifacetk/iroster.tcl: Made messages, which are shown to user, more clear. * msgs/ru.msg: Updated Russian translation. * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). * config.tcl: Renamed to configdir.tcl. Name config.tcl confuses people. * tkabber.tcl: Use configdir.tcl instead of config.tcl. 2007-03-07 Sergei Golovan * muc.tcl, chats.tcl: Added new option ::muc::options(gen_muc_status_change_msgs) which allows to enable groupchat status messages separately from chat status messages. * roster.tcl, ifacetk/iroster.tcl: Added "My Resources" roster group, which contains own JID. * gpgme.tcl, plugins/chat/logger.tcl, plugins/roster/fetch_nicknames.tcl, plugins/roster/annotations.tcl, itemedit.tcl, messages.tcl: Fixed roster menu items if the JID, where the menu is popped up, doesn't belong to the roster. The bug appeared in "My Resources" and "Active chats" roster groups, and in chat windows menus. * plugins/general/jitworkaround.tcl: Fixed bug which appeared if subscribed presence from JIT comes before the roster item. * roster.tcl, ifacetk/iface.tcl, ifacetk/iroster.tcl: Renamed option for showing own resources in roster. Added menu item for quick change in this option. * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). * presence.tcl: Added custom presence menu to service contacts in roster. * messages.tcl: Added menu item for granting subscription (this helps if for some reason mutual subscription of two users is in inconsistent state). 2007-03-06 Sergei Golovan * chats.tcl: Fixed moving interface tabs by keyboard shortcuts and . * msgs/de.msg, trans/de.msg: Updated German translation (thanks to Roger Sondermann). * ifacetk/iface.tcl: Moved "Activate privacy lists at startup" higher in the menu item list. * privacy.tcl: Fixed bug with adding items to conference list, made all privacy lists updated in one transaction without packets in between. This makes changes in privacy lists taking significantly more time. Fixed Tkabber behavior in case if server doesn't support privacy lists (closes http://yo.jabber.ru/bugzilla/show_bug.cgi?id=333). * privacy.tcl: Set priority of initial privacy list activation on connect to the higher value to ensure it starts first. * pixmaps/default/icondef.xml: Added weather icons in addition to x-weather (closes http://yo.jabber.ru/bugzilla/show_bug.cgi?id=327). 2007-03-04 Sergei Golovan * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). * msgs/ru.msg: Updated Russian translation (thanks to Konstantin Khomoutov). * plugins/chat/abbrev.tcl: Made translated messages extractable by the extraction script. * plugins/chat/logger.tcl: Fixed bug with showing empty history. * plugins/search/*: Added unified search panel interface (thanks to Konstantin Khomoutov). Use this interface for searching in all Tkabber windows. * plugins/general/headlines.tcl: Moved search functions to plugins/search/headlines.tcl. * plugins/search/spanel.tcl: Fixed error message. * plugins/search/search.tcl: Added functions to search in listboxes (thanks to Konstantin Khomoutov). * plugins/chat/histool.tcl: Added Chats history tool plugin (thanks to Konstantiin Khomoutov). * doc/tkabber.xml, doc/tkabber.html, README: Added info about chats history tool. * Makefile: Removed reference to aniemoteicons directory. * *: 0.10.0-beta2 is released. * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2007-03-03 Sergei Golovan * plugins/general/headlines.tcl: Bugfix. Removed trailing linefeed from subject to prevent its scrolling. * plugins/search/search.tcl: Bugfix. Fixed search panel entry background coloring after successful search. * pixmaps/default/icondef.xml, pixmaps/default/tkabber/*.gif: Replaced chat-bookmark and xaddress icons by new versions (thanks to Artem Bannikov). * pixmaps/stars/icondef.xml: Renamed chat-bookmark icons. * plugins/chat/popupmenu.tcl: Renamed chat-bookmark image name. * plugins/general/xaddress.tcl: Renamed xaddress/info image name. * plugins/general/remote.tcl: Allow action execute at the final ad-hoc command step. * plugins/chat/abbrev.tcl: Added new plugin, which allows to abbreviate words in chat input windows. expands abbreviations (thanks to Konstantin Khomoutov). * aniemoteicons/*, tkabber.tcl, plugins/richtext/emoticons.tcl: Converted aniemoticons to external plugin. 2007-03-02 Sergei Golovan * ifacetk/iface.tcl, privacy.tcl: Redone accepting messages from roster only to proagate to all connected resources. 2007-03-01 Sergei Golovan * doc/tkabber.xml: Added note about new privacy lists case. * gpgme.tcl: Fixed inconsistent behaviour when chat window icon indicated unencrypted state and in fact the messages were encrypted. 2007-02-28 Sergei Golovan * plugins/chat/logger.tcl: Don't strip resource from JID when showing chat log (if the user is in roster then resource is removed earlier, otherwise the resource is nesessary to get private chat log with conference users). Also, made possible showing a certain month log instead of the latest (thanks to Konstantin Khomoutov). * chats.tcl: Fixed Alt-Prior and Alt-Next binding in chat input windows. * ifacetk/iface.tcl: Don't count server messages in tab headers. * privacy.tcl, ifacetk/iface.tcl, muc.tcl: Added blocking all messages to/from users, which aren't in the roster. Also, added special privacy rule for conferences, to allow joining them even if they aren't in the roster. * privacy.tcl: Added own JID to privacy lists, making communication between own different resources possible even if messages from users, which aren't in the roster, are blocked. * msgs/ru.msg: Updated Russian translation. * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2007-02-27 Sergei Golovan * plugins/general/remote.tcl, trans/pl.msg, trans/uk.msg, trans/ru.msg, trans/es.msg, trans/de.msg, msgs/es.msg, msgs/pl.msg, msgs/uk.msg, msgs/ru.msg, msgs/de.msg: Fixed user messages (thanks to Roger Sondermann). * muc.tcl: Fixed reason processing during editing (ban/member/admin/etc.) lists. 2007-02-26 Sergei Golovan * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). * pixmaps/default/tkabber/tkabber-logo.gif: Fixed edges of Tkabber logo. * pixmaps/default/docking/tkabber.ico, pixmaps/default-blue/docking/tkabber.ico: Changed icon colors to make them look acceptable on Windows 2000 (where tray icons use fixed 16-color palette). * pixmaps/default/docking/message-personal.gif: Minor change. * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). * trans/de.msg: Added German translation of error messages and forms (thanks to Roger Sondermann). 2007-02-25 Sergei Golovan * plugins/richtext/urls.tcl: Fixed bug with cursor restoring on leaving URL. * ifacetk/iface.tcl, userinfo.tcl: Removed trailing newline from URL one-line texts. This makes unneeded unbinding scrolling events. * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). 2007-02-24 Sergei Golovan * msgs/de.msg: Updated German translation (thanks to Roger Sondermann). * doc/tkabber.xml, doc/tkabber.html, README: Added some info on Tkabber look and feel. Aknowledged Artem Bannikov contribution to Tkabber's new look (thanks to Konstantin Khomoutov). 2007-02-23 Sergei Golovan * pixmaps/default/tkabber/tkabber-logo.gif: New (preliminary) Tkabber logo. * pixmaps/default/docking/tkabber.ico, pixmaps/default-blue/docking/tkabber.ico: New (preliminary) windows icons. * pixmaps/default/docking/message-personal.gif: Minor change. * splash.tcl: Changed position of Tkabber logo. * doc/tkabber.xml: Added renju plugin to changes list. * README, doc/tkabber.html: Updated. * *: 0.10.0-beta is released. * ifacetk/systray.tcl: Fixed bug with forgotten window geometry when hiding main window to system tray. * msgs/uk.msg: Updated (thanks to Artem Bondarenko). * plugins/richtext/highlight.tcl: Fixed bug with highlighting one-letter words. 2007-02-20 Sergei Golovan * plugins/chat/info_commands.tcl: Bugfix: send last, time and vaersion queries to full user's JID if it was not found in the roster. * default.tcl, login.tcl, msgs/ca.msg, msgs/de.msg, msgs/es.msg, msgs/eu.msg, msgs/fr.msg, msgs/nl.msg, msgs/pl.msg, msgs/pt.msg, msgs/ru.msg, msgs/uk.msg, search.tcl: Fixed typos in translatable messages. * plugins/unix/icon.tcl: Removed version check, since colored icons are supported not only in Tcl/Tk 8.5. 2007-02-18 Sergei Golovan * plugins/chat/postpone.tcl: Added new plugin, which allows to save input window content to a special buffer and restore it. Inspired by push-line and get-line zsh commands (thanks to Konstantin Khomoutov). 2007-02-17 Sergei Golovan * plugins/roster/fetch_nicknames.tcl: Bugfix. Don't try to fetch nickname if there aren't such item in the roster. 2007-02-16 Sergei Golovan * utils.tcl: Recent changes trigger unknown bug in Tcl/Tk from Debian sarge, so reverted them. 2007-02-14 Sergei Golovan * ifacetk/iface.tcl, userinfo.tcl: Unbound mousewheel bindings from one-line URL text widgets. Also, unbound <> and <> virtual events. * utils.tcl: Optimized procedures, which extract JID parts. Also fixed a bug in procedure, which returns JID node (thanks to Konstantin Khomoutov). * msgs/pl.msg: Updated Polish translation (thanks to Irek Chmielowiec). 2007-02-13 Sergei Golovan * msgs/es.msg: Updated Spanish translation (thanks to Badlop). * chats.tcl: Small fix for tclshat plugin. 2007-02-12 Sergei Golovan * plugins/windows/taskbar.tcl: Reverted the previous change. It needs more work. * pixmaps/default/services/aim*: Updated (thanks to Artem Bannikov). 2007-02-11 Sergei Golovan * pixmaps/default/tkabber/new-msg.gif, pixmaps/default/tkabber/search_bk.gif, pixmaps/default/tkabber/search_exact.gif, pixmaps/default/tkabber/search_case.gif, pixmaps/default/tkabber/search_fw.gif: Removed, as they are no longer used. * custom.tcl: Added saving customize tab during state saving. * jabberlib-tclxml/jabberlib.tcl: Added procedures, which return requested username, server and resource (before resource binding). They are used in saving sessions. * chats.tcl: Bind chat tabs to requested JIDs, and not to real ones (this helps if resource binding changes JID, as at gmail.com). * plugins/richtext/emoticons.tcl: Fixed (mitigated) bug with crash during emoticons menu constructing. * jabberlib-tclxml/jabberlib.tcl: Added jlib::x_delay command to calculate message time (and to workaround a bug with timestamp format in some unknown Jabber client). * plugins/chat/logger.tcl, plugins/chat/draw_timestamp.tcl, plugins/general/message_archive.tcl, plugins/general/headlines.tcl: Use jlib::x_delay command. * muc.tcl, plugins/chat/irc_commands.tcl: Always include element when joining a conference. Otherwise it becomes impossible to join a password-protected room with empty password. * plugins/general/rawxml.tcl: Save tab on exit and restore it on start. * plugins/general/session.tcl: Fixed order of restored tabs. * doc/tkabber.xml: Listed main changes in upcoming 0.10.0. * mclistbox-1.02, ckabber.tcl, tkabber.tcl: Renamed mclistbox-1.02 directory to mclistbox. * Makefile: Adapted to the current version. Separated installation of scripts and docs. * ifacetk/systray.tcl, plugins/windows/taskbar.tcl: Code cleanup, changed systray icon behaviour in Windows (doubleclick deiconifies Tkabber window). * plugins/richtext/stylecodes.tcl: Removed unnecessary variable reference. * plugins/richtext/emoticons.tcl, ifacetk/iface.tcl: Added emoticons quick showing and hiding. 2007-02-10 Sergei Golovan * pixmaps/default/services/aim*, pixmaps/default/services/gg*, pixmaps/default/services/mrim*, pixmaps/default/services/msn*, pixmaps/default/services/weather*, pixmaps/default/services/yahoo*: Updated (thanks to Artem Bannikov). * msgs/es.msg, msgs/pl.msg, msgs/ru.msg, msgs/uk.msg, pixmaps.tcl, plugins/richtext/emoticons.tcl: Replaced ~/.tkabber by actual config directory name. * pixmaps/default/roster/invisible.gif, pixmaps/default/docking/invisible.gif: Fixed. * plugins/chat/chatstate.tcl: Made workaround of the bug in JIT, which raise an error if chat state notification message is sent without a body. 2007-02-09 Sergei Golovan * messages.tcl: Launch browser on jabber:x:oob attachments, and do not start file transfer. * pixmaps.tcl: Made possible to add pixmap directories during startup. * plugins/unix/icon.tcl: Fixed window icons changes when pixmaps theme is changed. * pixmaps/default/*, pixmaps/default-blue/*: Added new default Tkabber pixmaps theme (unfinished yet) - big thanks to Artem Bannikov. * pixmaps/feather16/*: Renamed old default pixmaps theme. * pixmaps/stars/*: Added new Stars pixmaps theme (thanks to Serge Yudin). * ifacetk/iface.tcl: Added clickable URL to 'About' window, removed Tkabber logo from 'Quick help' window. * splash.tcl: Moved Tcl/Tk version up. * tkabber.tcl: Replace 'alpha' by 'SVN' in version label. * chats.tcl, plugins/iq/ping.tcl, plugins/chat/muc_ignore.tcl: Slightly changed message strings. * msgs/ru.msg: Updated. * pixmaps/default/services/icq*: Updated (thanks to Artem Bannikov). 2007-02-08 Sergei Golovan * examples/tools/jsend.tcl: Adapted to new jabberlib version. * examples/tools/rssbot.tcl: Adapted to new jabberlib version. * plugins/general/headlines.tcl: Fixed 'Read on...' URL processing (thanks to Konstantin Khomoutov). * plugins/chat/logger.tcl: Wrapped opening log files into cd call (workaround of a bug with very long file names in Windows). Added extra open file checks during log conversion. * plugins/general/headlines.tcl: Don't ignore headline messages with empty URL or subject. 2007-02-07 Sergei Golovan * plugins/si/socks5.tcl: Fixed bug with lowering case of JID. Resource case does not need to be lowered. * plugins/si/socks5.tcl: Fixed bug with error on logout if there are pending IQ requests to SOCKS5 capable proxy. * chats.tcl: Add informational message to chat window if it is a chat with groupchat user and she changes nickname (thanks to Konstantin Khomoutov). * chats.tcl, plugins/chat/draw_server_message.tcl, plugins/chat/log_on_open.tcl, plugins/chat/logger.tcl, plugins/chat/update_tab.tcl, plugins/general/sound.tcl: Replaced 'synthetic' JID in genersted messages by empty JID to make sure it cannot be a real JID (thanks to Konstantin Khomoutov). * plugins/richtext/urls.tcl: Fixed duplicate URL processing in case of nonstandard URL's (thanks to Konstantin Khomoutov). * plugins/filetransfer/si.tcl: Close SOCKS5 connection upon receiving announced number of bytes (helps to avoid infinite waiting if the other side does not close the socket). Also, fixed cancelling of incoming file transfer. 2007-02-01 Sergei Golovan * utils.tcl: Optiimized jid_to_tag (thanks to Konstantin Khomoutov). * gpgme.tcl: Added submenu, which allows to toggle traffic signing and encryption, to main menu. 2007-01-31 Sergei Golovan * plugins/unix/wmdock.tcl: Fixed bug with processing messages from chat history. * plugins/chat/update_tab.tcl: Don't update tab label color on messages from chat history. * plugins/general/headlines.tcl: Fixed subject background definition. 2007-01-30 Sergei Golovan * ifacetk/iface.tcl: Fixed description. * messages.tcl: Enabled sending normal message to groupchat users. * muc.tcl: Fixed sometimes duplicated MUC menu entries. * plugins/general/headlines.tcl: Added search in headlines. * msgs/uk.msg: Updated (thanks to Artem Bondarenko). * plugins/search/custom.tcl, custom.tcl: Added search in customize window. 2007-01-27 Sergei Golovan * datagathering.tcl: Made data form windows transient and made default window height smaller. * examples/xrdb/badlop-dark.xrdb, examples/xrdb/black.xrdb, examples/xrdb/dark.xrdb, examples/xrdb/dark2.xrdb, examples/xrdb/green.xrdb, examples/xrdb/ice.xrdb, examples/xrdb/light.xrdb, examples/xrdb/lighthouse.xrdb, examples/xrdb/teopetuk.xrdb, examples/xrdb/warm.xrdb: Added *readonlyBackground resource definition (it is used in MUC management). * jabberlib-tclxml/jabberlib.tcl: Fixed unsetting variable, which stores received IQ's id. * muc.tcl: Moved MUC room menu items to a submenu. Also, increased width of input entries in configuration forms. * plugins/chat/muc_ignore.tcl, plugins/iq/ping.tcl: Fixed user messages. * register.tcl: Made register form scrollable (see http://www.jabber.ru/bugzilla/show_bug.cgi?id=313). 2007-01-26 Sergei Golovan * jabberlib-tclxml/jabberlib.tcl: Added -timeout option to send_iq. * login.tcl: Removed unnecessary check whether "replace connections" is set. Added extra call to jlib::disconnect to client:reconnect procedure. * plugins/iq/ping.tcl: Implemented aggressive server ping with reconnection on ping timeout. * utils.tcl: Added function caller, which returns the name of upper level procedure or empty string if it is called at levels 0 or 1 (thanks to Konstantin Khomoutov). * custom.tcl: Use caller procedure from utils.tcl (thanks to Konstantin Khomoutov). * examples/configs/mtr-config.tcl, ifacetk/iface.tcl, plugins/chat/draw_error.tcl, plugins/chat/draw_info.tcl, plugins/chat/draw_normal_message.tcl, plugins/chat/draw_server_message.tcl, plugins/chat/draw_xhtml_message.tcl, plugins/chat/me_command.tcl, plugins/general/headlines.tcl, plugins/general/message_archive.tcl, plugins/general/rawxml.tcl, plugins/chat/update_tab.tcl: Moved most instances of tab_set_updated calls to ifacetk/iface.tcl and plugins/chat/update_tab.tcl. * ifacetk/iface.tcl, plugins/chat/draw_normal_message.tcl, plugins/chat/me_command.tcl, plugins/chat/update_tab.tcl, plugins/chat/muc_ignore.tcl: Added new plugin, which allows to ignore messages from given conference occupants. It is not finished yet, but usable. (Thanks to Konstantin Khomoutov.) 2007-01-22 Sergei Golovan * plugins/iq/ping.tcl: Added reply to XMPP ping (XEP-0199) support. * iq.tcl: Explicitly allowed ignoring requests. 2007-01-19 Sergei Golovan * plugins/roster/conferences.tcl: Do not autojoin already joined conference room (this might change nickname, if it's unusual). * utils.tcl: Added two functions: lmap and lfilter to apply function to list elements and to filter list using specified function. * chats.tcl, ifacetk/iface.tcl, ifacetk/iroster.tcl, muc.tcl, plugins/chat/chatstate.tcl, plugins/chat/events.tcl, plugins/chat/irc_commands.tcl, plugins/general/remote.tcl, plugins/roster/conferenceinfo.tcl, plugins/roster/conferences.tcl, presence.tcl: Code cleanup, removed almost all external references to internal variables in ::chat namespace. 2007-01-18 Sergei Golovan * muc.tcl: Fixed reporting own presences in MUC rooms. * chats.tcl, ifacetk/bwidget_workarounds.tcl, ifacetk/iface.tcl, plugins/general/headlines.tcl, plugins/general/message_archive.tcl, plugins/general/rawxml.tcl: Made a step toward using panedwindow from Tk 8.5 and newer. It is still buggy yet, so this feature is disabled for now. PanedWindow from BWidget is still used. 2007-01-17 Sergei Golovan * plugins/unix/icon.tcl: Added plugin, which sets Tkabber titlebar icons. It uses [wm iconphoto], so, it works with Tk 8.5 or newer. 2007-01-16 Sergei Golovan * plugins/chat/me_command.tcl, plugins/chat/nick_colors.tcl: Fixed bug with inserting nicknames to chat input windows on /me messages. * plugins/general/ispell.tcl: Some code cleanup, replaced option options(dictionary) by more general options(command_line) to allow any ispell/aspell options. Moved plugin to general directory because it works not only in UNIX (the only requirement is working ispell). * README, doc/tkabber.html, doc/tkabber.xml: Documented changes in ispell module. * plugins/chat/nick_colors.tcl: Fixed colored nicknames processing. 2007-01-15 Sergei Golovan * plugins/general/autoaway.tcl: Fixed bug with restoring status and status message on disconnect in autoaway state. 2007-01-14 Sergei Golovan * plugins/unix/ispell.tcl: Changed option, which enables ispell to plugins::ispell::options(enable). Enabled changing ispell path, dictionary, its encoding on the fly. * README, doc/tkabber.html, doc/tkabber.xml: Documented changes in ispell module. 2007-01-13 Sergei Golovan * custom.tcl: Raise customize tab on Tkabber->Customize if it is already opened (thanks to Pavel Borzenkov). Save page offsets in the history (not very accurately because ScrolledWindow changes window width). * muc.tcl: Replaced labels by entries in owner/admin/moderator/etc. list editing form. * plugins/general/copy_jid.tcl: Added "Copy JID to clipboard" menu item to roster, chat, groupchat, message, search menus. * splash.tcl, plugins/iq/version.tcl, tkabber.tcl, ifaceck/iface.tcl, ckabber.tcl, ifacetk/iface.tcl: Changed version variable to tkabber_version. 2007-01-11 Sergei Golovan * plugins/richtext/urls.tcl: Fixed proc, which adds leading http:// and ftp:// prefix to URL. 2007-01-08 Sergei Golovan * plugins/general/tkcon.tcl: Adapted to use tkcon as a Tcl package. 2007-01-06 Sergei Golovan * README, doc/tkabber.xtml, doc/tkabber.xml: Documented changes in the config directory for different operating systems. Replaced ~/.tkabber by $::configdir in docs. Documented searching in Tkabber windows. Documented hook roster_group_popup_menu_hook (thanks to Konstantin Khomoutov). 2007-01-05 Sergei Golovan * plugins/general/autoaway.tcl, plugins/iq/last.tcl: Added support of [tk inactive], which works in Tk 8.5. * ifacetk/iface.tcl: Added window path to map_window_hook call. * ifacetk/iface.tcl, splash.tcl, tkabber.tcl: Added Tcl/Tk version to About and splash windows. Added description of a vew more commands to Quick help window (thanks to Konstantin Khomoutov). * config.tcl, tkabber.tcl: Changed config directory in Windows and MacOS. Also, Tkabber now honors TKABBER_HOME environment variable (thanks to Konstantin Khomoutov). * msgs/pl.msg: Updated (thanks to Irek Chmielowiec). * plugins/general/tkcon.tcl: Moved Tkcon menu item to Help submenu. * ifacetk/iface.tcl, gpgme.tcl: Removed path argument from ifacetk::set_toolbar_icon and ifacetk::set_toolbar_icon procedures. ifacetk::set_toolbar_icon now returns current icon index, which can be used in ifacetk::set_toolbar_icon. 2007-01-02 Sergei Golovan * userinfo.tcl, chats.tcl: Added empty item to comboboxes in show userinfo and open chat dialogs. * msgs/ru.msg: Added VIM modeline. 2007-01-01 Sergei Golovan * msgs/ru.msg: Updated. * README, doc/tkabber.html, doc/tkabber.xml, ifaceck/iface.tcl, ifacetk/iface.tcl, splash.tcl: Copyright updated. 2006-12-31 Sergei Golovan * jabberlib-tclxml/jabberlib.tcl, login.tcl: Fixed IDNA domains support. 2006-12-30 Sergei Golovan * msgs/es.msg: Updated (thanks to Badlop). * msgs/uk.msg: Updated (thanks to Artem Bondarenko). * trans/es.msg: Added Spanish translation of remote messages and errors (thanks to Badlop). * plugins/general/remote.tcl, trans/pl.msg, trans/ru.msg, trans/uk.msg: Fixed typo in text message (thanks to Badlop). 2006-12-29 Sergei Golovan * browser.tcl, disco.tcl: Bugfix in destroying state variables after browser/disco window is closed (thanks to Konstantin Khomoutov). * ifacetk/iroster.tcl: Added new hook roster_group_popup_menu_hook which is called on popping up group menu in main roster (thanks to Konstantin Khomoutov). * msgs/pl.msg: Updated (thanks to Irek Chmielowiec). * msgs/uk.msg: Updated (thanks to Artem Bondarenko). 2006-12-26 Sergei Golovan * plugins/chat/logger.tcl: Changed log directory structure and made log file format more rliable. Since that the first Tkabber run converts log files to new format. This conversion may take long time, so it shows a dialog window with the conversion progress during the conversion. * plugins/chat/logger.tcl: Shortened filenames of log files. * ckabber.tcl, custom.tcl, ifaceck/iroster.tcl, pixmaps.tcl, plugins/chat/logger.tcl, plugins/chat/nick_colors.tcl, plugins/general/headlines.tcl, plugins/general/message_archive.tcl, plugins/general/session.tcl, plugins/richtext/emoticons.tcl, roster.tcl splash.tcl tkabber.tcl: Introduced variable ::configdir, which is set to normalized name of ~/.tkabber. This should help with file operations in Windows. * plugins/chat/logger.tcl, plugins/general/message_archive.tcl: Specially process message_archive when converting logs. Changed message archive file format to make it more reliable. 2006-12-25 Sergei Golovan * plugins/general/session.tcl: Renamed session to state (only in user messages yet). Added menu for controlling save/load state options. * plugins/chat/logger.tcl: Added new conversion scheme between JIDs and log filenames. Added procedure, which converts old log directory structure to a new one. New log directory structure is not used yet, it's only for testing. 2006-12-24 Sergei Golovan * ifacetk/idefault.tcl, ifacetk/iface.tcl: Use named font instead of XLFD when XFT fonts rendering is used. * jabberlib-tclxml/jabberlib.tcl: Added connection_resource function. * joingrdialog.tcl: Removed two useless debug messages. * plugins/general/session.tcl: Added preliminary session support. Now it is possible to save some tabs at Tkabber exit and restore them on Tkabber start. * chats.tcl, plugins/general/headlines.tcl: Added functions which save chats and headlines during Tkabber exit. Separated opening headlines window from putting messages to it. * chats.tcl, ifacetk/iface.tcl, msgs/ru.msg, muc.tcl, plugins/chat/draw_server_message.tcl, presence.tcl, roster.tcl: Added chat messages on changing user status. These messages are off by default. Renamed option muc::options(gen_event) to more meaninful name muc::options(gen_enter_exit_msgs). 2006-12-22 Sergei Golovan * plugins/roster/fetch_nicknames.tcl: Added plugin, which automatically fetches user nickname from his/her vCard and makes it roster label. For services (e.g. ICQ-transport) it fetches nicknames for all service users. * plugins/roster/fetch_nicknames.tcl: Bugfix (thanks to Irek Chmielowiec). 2006-12-16 Sergei Golovan * msgs/ru.msg: Bugfix. 2006-12-15 Sergei Golovan * plugins.tcl: Worked around the bug in Tcl 8.3 when [glob -type d] doesn't return symbolic links to directories. 2006-12-10 Sergei Golovan * plugins/unix/menu8.4.tcl: Use this plugin with menu workaround in Tcl/Tk 8.5 also. * plugins/richtext/emoticons.tcl: Fixed tooltip behaviour over emoticons menu. 2006-12-06 Sergei Golovan * ifacetk/iface.tcl: Close tab with middle button click on the tab header. 2006-12-05 Sergei Golovan * gpgme.tcl: Fixed bug with incorrect call of signed:Label. * plugins/si/ibb.tcl: Return error message to file sender in case of error during file transaction. 2006-12-03 Sergei Golovan * plugins/si/socks5.tcl: Fixed SHA1 hash computing for SOCKS5 bytestreams support. * disco.tcl, utils.tcl, plugins/si/socks5.tcl: Introduced new function my_jid, which is suitable to get JID for including to requests and responses (for conference recipients it returns conference JID, for other recipients it returns real JID). Use this new function when replying disco queries and when sending files. 2006-12-02 Sergei Golovan * plugins/richtext/highlight.tcl: Enable highlighting by default. * browser.tcl, chats.tcl, disco.tcl, ifacetk/iface.tcl, ifacetk/iroster.tcl, joingrdialog.tcl, login.tcl, messages.tcl, plugins/general/headlines.tcl, plugins/roster/cache_categories.tcl, presence.tcl, userinfo.tcl: Removed explicit storing of customized variables because they are stored automatically. 2006-11-29 Sergei Golovan * plugins/richtext/highlight.tcl: Fixed initializing plugin state. * plugins/richtext/urls.tcl: Changed the way of storing URLs in text widget. Instead of hiding them in text, add them to tag list. * plugins/richtext/stylecodes.tcl, plugins/richtext/emoticons.tcl: Swapped priorities to make emoticons pluging move first (thanks to Konstantin Khomoutov). * plugins/richtext/chatlog.tcl, plugins/richtext/highlight.tcl: Replaced chatlog for highlight richtext entity in chatlog.tcl because two plugins defined highlight entity (thanks to Konstantin Khomoutov). 2006-11-27 Sergei Golovan * chats.tcl: Fixed error messages processing. * msgs/pl.msg, trans/pl.msg: Updated (thanks to Irek Chmielowiec). 2006-11-26 Sergei Golovan * contrib/extract-translations/extract.tcl: Fixed bug with multiline string processing. * filetransfer.tcl: Lessened file transfer dialog dimentions. * msgs/ru.msg, trans/ru.msg: Updated. 2006-11-25 Sergei Golovan * privacy.tcl: Disabled privasy rules menu item for chats with groupchats users. Privacy rules aren't intended to work with groupchats. * plugins/richtext/emoticons.tcl, pixmaps.tcl: Added dots at the end of sentences. * msgs/ru.msg: Added several translated messages (thanks to Pavel Borzenkov). 2006-11-24 Sergei Golovan * plugins/unix/ispell.tcl: Added processing of nonletter keys, which was broken after input methods were fixed 2006-10-11. * plugins/richtext/urls.tcl: Add URL prefixes ftp:// or http:// to URLs without them. * custom.tcl: Do not store loginconf automatically. * contrib/extract-translations/extract.tcl: Changed the only defined variable when checking for variables in strings to less common name. Added hidden key -showvars to show all strings with embedded variables. * jabberlib-tclxml/stanzaerror.tcl: Added extra braces to eval arguments to fix the hypothetical case of error type and condition with spaces. * plugins/filetransfer/http.tcl, plugins/filetransfer/jidlink.tcl, plugins/filetransfer/si.tcl, si.tcl: Added translations of error messages, sent to the peer. * plugins/richtext/emoticons.tcl: Removed list search options, which aren't in Tcl 8.3. 2006-11-23 Sergei Golovan * contrib/extract-translations/extract.tcl: Added search of ::trans messages. * trans.tcl: Added one-argument ::trans::trans (only to allow searching messages, which are not to be translated immediately). * muc.tcl, plugins/general/remote.tcl: Added ::trans::trans calls, which help to search translatable messages. * jabberlib-tclxml/jabberlib.tcl: Made get_lang routine working in Tcl/Tk 8.5 (thanks to Irek Chmielowiec). * msgs/uk.msg, trans/uk.msg: Updated Ukrainian translation (thanks to Artem Bondarenko). 2006-11-22 Sergei Golovan * plugins/iq/version.tcl: Fixed bug with reporting empty string for Linux distribution (thanks to Pavel Borzenkov). 2006-11-20 Sergei Golovan * plugins/chat/info_commands.tcl: Fixed bug with asking info in groupchats. When name was not specified, /version, /time, /last, /vcard sent IQ to an occupant with the highest priority and not to the room itself. 2006-11-19 Sergei Golovan * plugins/richtext/urls.tcl: Changed balloon behaviour to be consistent with other balloons. * plugins/roster/conferences.tcl: Made conference group name translateable (thanks to Irek Chmielowiec). * custom.tcl, plugins/general/rawxml.tcl: Removed menu tearoffs (thanks to Irek Chmielowiec). * plugins/richtext/emoticons.tcl: Removed txtlabels variable and made taking label names (ballon tips) from txtdefaults (thanks to Irek Chmielowiec). * gpgme.tcl: Added option to suppress warnings on signature verification failures (thanks to Antoni Grzymala). * plugins/iq/version.tcl: Use lsb_release to guess Linux distribution (this allows to distinguish Ubuntu from Debian, for example). (Thanks to Konstantin Khomoutov.) 2006-11-15 Sergei Golovan * userinfo.tcl: Bugfix. Add script to event, not override existing. * chats.tcl: Removed unused URL regexp (thanks to Konstantin Khomoutov). * richtext.tcl, plugins/richtext/urls.tcl: Added URLs with label, which differs from URL itself (thanks to Konstantin Khomoutov). * plugins/general/headlines.tcl: Replaced link text by a neutral message (the URL is showed in a tooltip) (thanks to Konstantin Khomoutov). * utils.tcl: Moved some useful functions from richtext.tcl (thanks to Konstantin Khomoutov). 2006-11-12 Sergei Golovan * INSTALL: Corrected link to README. * Makefile: Fixed installing docs, emoticons, and translations. * chats.tcl, messages.tcl, plugins/chat/draw_info.tcl, plugins/chat/draw_server_message.tcl, plugins/chat/draw_xhtml_message.tcl, plugins/chat/me_command.tcl, plugins/general/headlines.tcl, plugins/general/message_archive.tcl, richtext.tcl: Replaced chat::add_emoteiconed_text by richtext::render_message, removed highlightlist arg from richtext::render_message. * plugins/richtext/chatlog.tcl, plugins/richtext/emoticons.tcl, plugins/richtext/highlight.tcl, plugins/richtext/stylecodes.tcl, plugins/richtext/urls.tcl, richtext.tcl: Code cleanup. * chats.tcl, plugins/richtext/urls.tcl: Moved adding 'Copy URL' menu item to the appropriate plugin. 2006-11-10 Sergei Golovan * ifacetk/iroster.tcl: Bugfix (thanks to Irek Chmielowiec). * ifacetk/iface.tcl: Added two hooks: got_focus_hook and lost_focus_hook (thanks to Pavel Borzenkov). * plugins/richtext/emoticons.tcl: Added 'sweep' command, which removes all unused emoticons from the memory. Fixed loading emoticons at Tkabber start (thanks to Konstantin Khomoutov). * ifacetk/idefault.tcl: Moved workaround for calling emoticons menu using Alt-e in nonenglish keyboard layout to plugins/richtext/emoticons.tcl. * richtext.tcl, plugins/richtext/highlight.tcl, plugins/chat/draw_normal_message.tcl, plugins/richtext/urls.tcl: Moved highlight plugin to richtext plugins, changed priority of URL parsing plugin to higher value (thanks to Konstantin Khomoutov). * utils.tcl, plugins/richtext/highlight.tcl: Added new hook check_personal_message_hook and made using it in highlight plugin. Changed syntax of check_message. * ifacetk/iface.tcl, plugins/chat/bookmark_highlighted.tcl, plugins/chat/complete_last_nick.tcl, plugins/chat/draw_normal_message.tcl, plugins/chat/me_command.tcl, plugins/general/sound.tcl: Adapted calls of check_message to new syntax. 2006-11-06 Sergei Golovan * msgs/pl.msg, trans/pl.msg: Updated (thanks to Irek Chmielowiec). * plugins/richtext/emoticons.tcl: Renamed merge_dir command to load_dir (restored nondestructive behaviour of load_dir). Added clean command, which destroys all loaded emoticons. 2006-11-05 Sergei Golovan * README, doc/tkabber.html, doc/tkabber.xml: Fixed default emoticons directory name. 2006-11-04 Sergei Golovan * README, doc/tkabber.html, doc/tkabber.xml, richtext.tcl, examples/configs/badlop-config.tcl, examples/configs/config.tcl, examples/configs/mtr-config.tcl, examples/configs/teo-config.tcl: Changed emoticons interface in docs and examples. * filetransfer.tcl, plugins/filetransfer/http.tcl, plugins/filetransfer/jidlink.tcl, plugins/filetransfer/si.tcl: Moved send file user interface to filetransfer.tcl (unfinished yet). * plugins/richtext/emoticons.tcl, plugins/richtext/stylecodes.tcl, plugins/richtext/urls.tcl: Removed 'enable' options, added all customize groups to Chat group. Changed emoticons theme definition: now options(theme) should be set to the name of theme directory. Theme names are used only for labels in customize option menu. * plugins/richtext/emoticons.tcl: Fixed processing of 'None' emoticon theme (theme with no images at all). * plugins/richtext/urls.tcl, chats.tcl: Fixed URL highlighting when mouse pointer is over the URL (thanks to Konstantin Khomoutov). * filetransfer.tcl, plugins/filetransfer/si.tcl: Fixed bug with 'stream id is in use' after choosing a file, which cannot be written. Show error messages in the main file transfer windows, not in separate message boxes. Inserted several checks of transfer window existense (helps when the other side reply is received after closing the window). * plugins/richtext/emoticons.tcl: Fixed escaping regexp metacharacters. Also fixed emoticons::add procedure. 2006-11-03 Sergei Golovan * plugins/richtext/urls.tcl: Fixed URL regular expression. * richtext.tcl: Wrapper around text widget, which allows to use customizable message render plugins (thanks to Konstantin Khomoutov). * plugins/richtext/chatlog.tcl, plugins/richtext/emoticons.tcl, plugins/richtext/stylecodes.tcl, plugins/richtext/urls.tcl: Plugins with basic colored messages, emoticons (now configurable via GUI), stylecodes and URL handling support (thanks to Konstantin Khomoutov). * custom.tcl: Added new configvar function, which allowes changing config variable options on the fly (thanks to Konstantin Khomoutov). * aniemoteicons/aniemoteicons.tcl, chats.tcl, ifacetk/iface.tcl, messages.tcl, plugins/chat/draw_xhtml_message.tcl, plugins/general/headlines.tcl, plugins/general/message_archive.tcl, tkabber.tcl, userinfo.tcl: Use richtext for text widgets with highlighting support (thanks to Konstantin Khomoutov). * emoticons-tkabber/*: Moved to emoticons/default/ (thanks to Konstantin Khomoutov). * examples/configs/badlop-config.tcl, examples/configs/badlop-config-home.tcl: Fixed paths of sourced scripts. * ifacetk/iroster.tcl: Added support of checkbuttons in roster popup menu. 2006-10-27 Sergei Golovan * plugins/chat/irc_commands.tcl: Fixed bug with joining conference room from private chat window/tab. * plugins/chat/logger.tcl: Do not try to open log files when they do not exist. 2006-10-25 Sergei Golovan * jabberlib-tclxml/jlibsasl.tcl: Worked around bug 1545306 in tcllib SASL module. See http://sourceforge.net/tracker/index.php?func=detail&aid=1545306&group_id=12883&atid=112883 2006-10-24 Sergei Golovan * tkabber.tcl: Stepped required jabberlib version. * utils.tcl: Added extra rguments to Spinbox command. * plugins/general/stats.tcl: Use 'Set' button relief to show whether statistical parameter is requested periodically. 2006-10-22 Sergei Golovan * msgs/uk.msg, msgs/uk.rc: Updated Ukrainian translation (thanks to Artem Bondarenko). 2006-10-21 Sergei Golovan * pixmaps/default/icondef.xml, pixmaps/default/tkabber/gpg-vsigned.gif: Added image for signature which is not at least marginally trusted or which signer's JID does not belong to key UIDs. * gpgme.tcl: Added extra signature validity check and made drawing special icon when the signature seems to be suspicious. Don't check signature if message encryption fails. * msgs/ru.rc: Removed accelerators from labels in Font and Password dialogs. They cause runtime errors. 2006-10-20 Sergei Golovan * chats.tcl: Added new hook rewrite_message_hook. It is run before process_message_hook and allows to change message variables. Removed normalize_chatid_hook. * examples/configs/mtr-config.tcl: Use rewrite_message_hook instead of normalize_chatid_hook. * pixmaps/default/icondef.xml, pixmaps/default/tkabber/gpg-badencrypted.gif: Added image for message which cannot be deciphered. * gpgme.tcl: Use rewrite_message_hook to decrypt message bodies. Draw icon from gpg-badencrypted.gif when message cannot be deciphered. Draw it even if no GPG support at all to make messages more clear. Some code cleanup. 2006-10-15 Sergei Golovan * ifacetk/iface.tcl: Restored "Activate lists at startup" menu item for privacy lists. Since it is autosaved when switched it makes sense to use it again. * custom.tcl: Fixed sorting subgroups. 2006-10-14 Sergei Golovan * messages.tcl: Use threads for normal messages (they aren't stored in message archive yet). Also use different variables for choosing connection for different message windows. * muc.tcl: Added Node name for 'Current rooms' node. 2006-10-13 Sergei Golovan * ifacetk/iface.tcl: Bugfix. 2006-10-12 Sergei Golovan * plugins/chat/log_on_open.tcl: Changed default values for maximum message numbers to 20 and for time interval to 24 hours. 2006-10-11 Sergei Golovan * msgs/pl.msg: Updated (thanks to Irek Chmielowiec). * plugins/general/autoaway.tcl: Change text status when go to autoaway only if it's set to nonempty string (thanks to Irek Chmielowiec). * plugins/general/subscribe_gateway.tcl: Translated subscribe message similar to messages.tcl (thanks to Irek Chmielowiec). * plugins/general/xaddress.tcl: Set extended address label background in chat windows and in message windows to the background of parent element (thanks to Irek Chmielowiec). * jabberlib-tclxml/jlibsasl.tcl: Added support of X-GOOGLE-TOKEN authentication mechanism, which implemented in tcllib 1.9 SASL module. * utils.tcl: Added another workaround for XIM input. * plugins/unix/ispell.tcl: Use workaround from utils.tcl. Redesigned ispell plugin to work not only in chat windows. Reassigned two resources from Chat to Text class. * examples/xrdb/*: Reassigned two resources from Chat to Text class. * plugins/chat/completion.tcl: Bugfix, check if window with tab completion exists. * datagathering.tcl, messages.tcl, plugins/filetransfer/http.tcl, plugins/filetransfer/jidlink.tcl, plugins/filetransfer/si.tcl, plugins/general/message_archive.tcl, plugins/general/subscribe_gateway.tcl, userinfo.tcl: Use wrapper textUndoable which enables undo mechanism and initialises spellchecker for the text window. 2006-10-10 Sergei Golovan * plugins/chat/completion.tcl: Made workaround for XIM in chat input windows. Instead of binding %A to any key and query if the symbol is empty (which does not work if XIM is used because of known bug in Tk) Tkabber compares two indices, before and after keypress, and if they are the same then the symbol is thought as empty. 2006-10-09 Sergei Golovan * ifacetk/iface.tcl: Don't add message to tab or window title when it is from chat log and is shown by plugins/chat/log_on_open.tcl. * Makefile, chats.tcl, messages.tcl, splash.tcl, tkabber.tcl, textundo/dkflib.tcl, textundo/textundo.tcl, utils.tcl: Removed usage of textundo package. It leaves undeleted variables after destroying widget and text widget in Tcl/Tk 8.4 supports own undo mechanism. So, no undo when using Tcl/Tk 8.3 from now. * *: Replaced obsolete JEP (Jabber Enhancement Proposal) abbreviation by XEP (XMPP Extension Proposal) through all of the sources. 2006-10-08 Sergei Golovan * custom.tcl: Fixed duplicate parent groups (thanks to Pavel Borzenkov). * plugins/chat/log_on_open.tcl, plugins/chat/logger.tcl, plugins/general/sound.tcl: Added new plugin, which shows several last logged messages in newly opened chat (not groupchat) windows. Added jid attribute to log messages, changed timestamps to GMT (so, existing log messages show incorrect timestamps now). 2006-10-07 Sergei Golovan * custom.tcl: Autosave customized variable if it has been set from outside ::custom namespace. It should improve usability. * disco.tcl: Added connection ID to all disco operations. * disco.tcl, joingrdialog.tcl, messages.tcl, plugins/roster/conferences.tcl: Added new hook disco_node_menu_hook for popup menues in disco window. Moved join conference, add conference to roster, send message menu items to the hook. * plugins/chat/info_commands.tcl: Added roster item completion to /time, /last, /vcard, and /version commands. Made ::msgcat::mc handle substitutions in strings. 2006-10-05 Sergei Golovan * plugins/general/headlines.tcl, trans.tcl: Removed temporary changes of system encoding because it does not allow to install Tkabber to a directory, which name contains nonenglish characters. * ckabber.tcl, tkabber.tcl: Removed temporary changes of system encoding since [msgcat::mcload] and [option readfile] themselves use UTF-8. 2006-10-02 Sergei Golovan * plugins/general/headlines.tcl: Added option, which allows not to show balloons over hedlines tree. * chats.tcl, muc.tcl: Update chat window last message timestamp only in connected state. It fixes the situation when not all room history is requested when one client replaces another one with the same resource. 2006-10-01 Sergei Golovan * balloon.tcl: Made workaround for a bug when balloon shows up in wrong screen if multiple monitor configuration is used in Windows (thanks to Pat Thoyts). * pubsub.tcl: Made pubsub implementation closer to JEP-0060 v. 1.9. (It is still untested and unusable though.) * tkabber.tcl: Source pubsub.tcl. * browser.tcl, disco.tcl, ifacetk/iroster.tcl, ifacetk/iface.tcl, messages.tcl, privacy.tcl: Added connection ID to drag'n'drop JID data. * ifacetk/iroster.tcl: Added configurable drag'n'drop commands to roster::create. * chats.tcl: Added invitation to the conference when the user is dragged'n'dropped from the main roster to the room roster. 2006-09-30 Sergei Golovan * balloon.tcl: Added function balloon::setup, which is useful for registering common balloons with static or dynamic texts. Slightly changed syntax of balloon::default_balloon procedure. Destroy balloon when mouse moves over it (workaround for sometimes freezing balloons). * emoticons.tcl: Used new syntax of balloon::default_balloon. * browser.tcl, disco.tcl, ifacetk/systray.tcl, messages.tcl, plugins/general/headlines.tcl, plugins/unix/dockingtray.tcl, plugins/unix/systray.tcl, plugins/unix/tktray.tcl, plugins/unix/wmdock.tcl, utils.tcl, chats.tcl: Switched to balloon::setup when defining balloons. * roster.tcl: Strictened check whether removing JID is our server JID (to make sure that if it's in the roster then removing it doesn't unregister account). 2006-09-29 Sergei Golovan * custom.tcl: Added new variable type 'options'. GUI for this type is options menu. * utils.tcl: Workarounded fixed borderwidth of tk_optionMenu widget. * filters.tcl: Use workaround from utils.tcl. * ifacetk/iface.tcl, login.tcl, pixmaps.tcl, plugins/general/headlines.tcl, plugins/search/search.tcl: Replaced almost all customizeable radio variables by options variables. * chats.tcl: Small fix for URL regexp. * msgs/pl.msg: Updated (thanks to Irek Chmielowiec). 2006-09-26 Sergei Golovan * plugins/general/sound.tcl: Made sound::play loading sound file if it's not loaded yet if snack library is used (thanks to Pavel Borzenkov). 2006-09-25 Sergei Golovan * msgs/es.msg: Updated (thanks to Badlop). * disco.tcl, plugins/chat/logger.tcl: Fixed typo. * ifacetk/iface.tcl, userinfo.tcl: Replaced menu entry 'Show user info...' by 'Show user or service info...' which is more correct. * msgs/ru.msg: Updated. * emoticons.tcl: Added support of emoticons in formats other than GIF (thanks to Irek Chmielowiec). * messages.tcl: Made subscription request translateable (thanks to Irek Chmielowiec). * msgs/pl.msg, trans/msg.pl: Updated (thanks to Irek Chmielowiec). * messages.tcl: Remove item from the roster when user presses 'Unsubscribe' button in subscription window. Otherwise roster gradually becomes full of users with subscription 'none'. * roster.tcl: Fixed typo. * plugins/filetransfer/http.tcl: Added two options: advertised host and port for file transfer. They are useful for tranferring files through NAT via forwarded port (thanks to Antoni Grzymala). * plugins/iq/version.tcl: Guess Windows version. * plugins/general/remote.tcl: Moved remote control functions (leave groupchats, forward messages, change status) to separate namespaces. Moved session variables to a separate namespace, index sessions by connection ID, JID, node and session ID. Do not close session immediately if the error type is 'modify' (thanks to Artem Borodin). 2006-09-24 Sergei Golovan * filetransfer/si.tcl: Do not use progressbar if file size is zero (thanks to Konstantin Khomoutov). * si/socks5.tcl: Removed forgotten debug code. * msgs/en.msg: Removed English message file since all messages are in English by default. * msgs/ru.msg: Updated. * ifaceck/iface.tcl, ifacetk/iface.tcl, splash.tcl, doc/tkabber.xml, doc/tkabber.html: Changed Tkabber home page. * ifacetk/iface.tcl: In UNIX WM_SAVE_YOURSELF can be called several times. So, call quit only on windows, where WM_SAVE_YOURSELF means end of windows session. Also trap SIGTERM (call quit) when Tclx is available (thanks to Konstantin Khomoutov). * disco.tcl, plugins/general/xcommands.tcl: Show a special item for some (registered) features even if the remote service has not provided it. Especially, always show http://jabber.org/protocol/commands node if there is a corresponding feature. It helps for example to control Psi client remotely. 2006-09-23 Sergei Golovan * plugins/filetransfer/si.tcl, plugins/si/ibb.tcl, plugins/si/iqibb.tcl, plugins/si/socks5.tcl, si.tcl: Index bytestreams by direction (in, out), connection ID, JID, and SID instead of SID only. * plugins/si/socks5.tcl: Added mediated SOCKS5 connection support. 2006-09-21 Sergei Golovan * plugins/filetransfer/si.tcl, plugins/si/ibb.tcl, plugins/si/iqibb.tcl, plugins/si/socks5.tcl, si.tcl: Slightly redesigned filetransfer via SI (JEP-0095, JEP-0065, JEP-0047). Replaced all unnecessary vwaits by callbacks. Added new (undocumented yet) IQ-based IBB transport. Made IBB transport usable (now it does not throw all data immediately). * filetransfer.tcl, plugins/filetransfer/si.tcl: Use errors returned when file is being opened instead of simple file exisence check (thanks to Konstantin Khomoutov). * jabberlib-tclxml/jabberlib.tcl: Added jlib::socket_ip function. * userinfo.tcl: Made all userinfo fields flat. 2006-09-20 Sergei Golovan * datagathering.tcl, disco.tcl: Added processing and using of multiple values in jabber:x:data forms (thanks to Artem Borodin). * plugins/general/remote.tcl: A few bugfixes (thanks to Artem Borodin). * pubsub.tcl: Started implementing Publish-Subscribe (JEP-0060). 2006-09-18 Sergei Golovan * disco.tcl, examples/tools/jsend.tcl, examples/tools/rssbot.tcl, iq.tcl, jabberlib-tclxml/jabberlib.tcl, jidlink.tcl, muc.tcl, negotiate.tcl, plugins/filetransfer/http.tcl, plugins/filetransfer/jidlink.tcl, plugins/general/avatars.tcl, plugins/general/remote.tcl, plugins/iq/browse.tcl, plugins/iq/last.tcl, plugins/iq/time.tcl, plugins/iq/version.tcl, plugins/jidlink/dtcp.tcl, plugins/jidlink/ibb.tcl, plugins/si/ibb.tcl, plugins/si/socks5.tcl, privacy.tcl, si.tcl, tkabber.tcl, trans.tcl, trans/ru.msg: Added xml:lang support in incoming IQ queries. It allows to answer these queries using remote user's locale. Since msgcat is not designed to handle translation to many languages in parallel and it's not very wise to load all translations in msgs/ together new trans.tcl module and new translation files in trans/ subdirectory are added. They currently contain only translations for messages from remote control plugin, so they are relatively short. * plugins/general/remote.tcl: Corrected a few typos in the displayed messages. * jabberlib-tclxml/jabberlib.tcl: Removed useless -sendto option of jlib::create. 2006-09-17 Sergei Golovan * plugins/iq/version.tcl: Added code for reporting Arch Linux version (thanks to Pavel Borzenkov). * datagathering.tcl: Added server-side x:data processing routine which creates x:data field tag (thanks to Artem Borodin). * disco.tcl: Added subnodes registering (second level nodes only, thanks to Artem Borodin). * plugins/general/xaddress.tcl, pixmaps/default/icondef.xml, pixmaps/default/tkabber/xaddress.gif: Implemented Extended Stanza Addressing (JEP-0033, thanks to Artem Borodin). * plugins/general/remote.tcl: Implemented Remote Controlling Clients (JEP-0146) via Ad-hoc commands. Includes status change, messages forwarding, and leaving conference rooms (thanks to Artem Borodin). 2006-09-16 Sergei Golovan * jabberlib-tclxml/jabberlib.tcl, jabberlib-tclxml/pkgIndex.tcl, examples/tools/jsend.tcl, examples/tools/rssbot.tcl: Bumped jabberlib version to 0.10.0 (because of changes in client:roster arguments). * hooks.tcl: Use bgerror for displaying error messages in hooks. * splash.tcl: Wrapped bgerror to hide splash window when error occurs. Improved splash progress messages. * tkabber.tcl: Slightly changed order of loading modules making messages in splash window to flash less frequently. * ifacetk/idefault.tcl: Bugfix. Removed binding for <6> and <7> events, since they are ambiguous. Bind scrolling events only in x11 environment. * ifacetk/bwidget_workarounds.tcl: Made using auto_load to load BWidget scripts instead of creating and destroying widgets. * msgs/ru.msg: Updated. * examples/xrdb/lighthouse.tcl: New color theme (thanks to Max Loparyev). * examples/*.xrdb: Moved to examples/xrdb subdirectory. * examples/*.tcl: Moved to examples/configs subdirectory. * examples/tkabber_setstatus: Moved to examples/tools subdirectory. * gpgme.tcl, hooks.tcl, messages.tcl, muc.tcl, plugins/chat/chatstate.tcl, plugins/chat/events.tcl, plugins/chat/send_message.tcl, plugins/general/avatars.tcl, plugins/roster/rosterx.tcl, presence.tcl: Replaced hook::run with upvar for hook::foldl (it is more simple and looks more "ticklish"). * hooks.tcl: Removed hook::foldl procedure. 2006-09-15 Sergei Golovan * ifacetk/idefault.tcl: Bind mouse buttons to scroll events only on nonwindows systems. 2006-09-13 Sergei Golovan * msgs/pl.msg: Polish translation is updated (thanks to Irek Chmielowiec) * plugins/chat/draw_timestamp.tcl, msgs/*.msg: Corrected typo. * login.tcl: Run predisconnected_hook also before reconnect. 2006-09-12 Sergei Golovan * pixmaps/*: Fixed corrupt pixmaps. * ifacetk/idefault.tcl: Added virtual events for scrolling up, down, left, and right. * util.tcl: Increased horizontal mouswheel scroll increment. Use virtual events for scrolling. * plugins/windows/mouswheel.tcl: Added horizontal scrolling using mousewheel key. Use virtual events for scrolling. * ifacetk/iface.tcl: Use virtual scrolling events for tab switching using mousewheel. * plugins/windows/console.tcl: Added missing Id keyword. * jabberlib-tclxml/jabberlib.tcl: Added xml packet size logging possibility. It can be used for traffic accounting (thanks to Artem Borodin). 2006-09-10 Sergei Golovan * roster.tcl, pixmaps/*/icondef.xml: Replaced x-gadugadu gateway type by gadu-gadu as the latter is registed by Jabber Registrar. Added sms gateway icon to disco/browser. * muc.tcl: Bugfix. Convert MUC room JID to lowercase before joining it. * disco.tcl: Added displaying number of items in every node's title where this number is sufficiently large. * plugins/roster/conferences.tcl: Fixed race confition during autojoining conferences. * plugins/roster/cache_categories.tcl, roster.tcl: Fixed race condition when overriding servers categories and types. Made overriding scheme more robust. * chats.tcl: Fixed status icon behavior (transport icons are not replaced by ordinary icons anymore). * ifacetk/iroster.tcl: Added optional argument (status) to get_jid_icon. 2006-09-09 Sergei Golovan * browser.tcl, disco.tcl: Removed hardcoded icon names for disco/browser services. * pixmaps/*/icondef.xml: Changed browser/* icon names to match services categories and types. * pixmaps/default/services/mrim_*.gif, pixmaps/default/icondef.xml: Added Mail.ru Instant Messenger icons (thanks to Konstantin Khomoutov). * plugins/unix/wmdock.tcl, plugins/general/headlines.tcl: Changed displayed icon names. * plugins/chat/logger.tcl: Made Tkabber more responsible while converting or displaying chatlogs. * plugins/roster/, tkabber.tcl: Added new plugins directory. * plugins/general/annotations.tcl, plugins/general/conferenceinfo.tcl, plugins/general/conferences.tcl, plugins/general/rosterx.tcl, plugins/general/roster_delimiter.tcl: Moved to plugins/roster/ directory. * custom.tcl: Added store_vars procedure for convenience. * jabberlib-tclxml/jabberlib.tcl, roster.tcl, plugins/general/jitworkaround.tcl, plugins/roster/conferences.tcl, ifacetk/iroster.tcl: Don't use nonstandard way of getting item category in the roster. * roster.tcl, messages.tcl, ifacetk/iroster.tcl: Removed roster::is_user function. Forced usage of roster::configure instead. * itemedit.tcl, plugins/roster/conferences.tcl: Made sure that nickname or properties editing frame is the topmost frame of the item edit window. * plugins/roster/cache_categories.tcl: Added new plugin, which uses disco#info queries to retrieve services categories and types, caches them locally and makes roster using the cached information for displaying JIDs icons, menus etc. * gpgme.tcl, ifacetk/iroster.tcl, roster.tcl: Added checks for a few extra service categories. 2006-09-05 Sergei Golovan * ifacetk/iface.tcl: Added conventional quit on closing X session or Windows shutdown (thanks to Konstantin Khomoutov). * ifacetk/iroster.tcl: Quick bugfix. Roster redraw failed when active chats group was enabled. 2006-09-03 Serhei Golovan * jabberlib-tclxml/jabberlib.tcl: Fixed processing presence of type "error" 2006-08-18 Sergei Golovan * pixmaps/*/*.gif: svn:mime-type property is set to application/octet-stream to avoid corruption when downloading on nonunix systems (Closes: http://www.jabber.ru/bugzilla/show_bug.cgi?id=256) * plugins/general/rawxml.tcl, plugins/search/rawxml.tcl: Search in Raw XML window is added 2006-08-17 Sergei Golovan * plugins/search/chat.tcl, plugins/search/logger.tcl, plugins/search/browser.tcl, plugins/search/search.tcl: Searching in chat and chatlog windows moved to separate directory. New plugins which allow searching in browser and disco windows are added (thanks to Konstantin Khomoutov) * browser.tcl: New hook (open_browser_post_hook) is added. It is useful for new search feature * disco.tcl: New hook (open_disco_post_hook) is added. It is useful for new search feature * plugins/chat/logger.tcl: Search in chatlog window is moved to plugins/search directory * tkabber.tcl: Load plugins in plugins/search subdir * plugins/chat/info_commands.tcl: Bugfix. VCard is requested from bare JID (works when chat partner goes offline) 2006-08-16 Sergei Golovan * datagathering.tcl: Fixed empty form processing * jabberlib-tclxml/jlibtls.tcl, jabberlib-tclxml/jlibsasl.tcl, jabberlib-tclxml/jlibcompress.tcl: Fixed behavior when no callback is set * browser.tcl, disco.tcl: Unset all browser/disco window state variables on window destroy (thanks to Konstantin Khomoutov) * login.tcl: Replace .connect_err window if it exists instead of warning * doc/tkabber.xml, doc/tkabber.html, README: Changed Tkabber repository address 2006-07-08 Alexey Shchepin * jabberlib-tclxml/jlibdns.tcl: Fixed DNS reply processing (thanks to Sergei Golovan) * jabberlib-tclxml/jabberlib.tcl: Start IQ stanzas "id" from 1 instead of 0 (thanks to Sergei Golovan) * chats.tcl: Don't raise conference windows on reconnect (thanks to Sergei Golovan) * joingrdialog.tcl: Likewise * muc.tcl: Likewise * plugins/general/conferences.tcl: Likewise 2006-06-24 Alexey Shchepin * plugins/general/subscribe_gateway.tcl: Bugfix (thanks to Sergei Golovan) * jabberlib-tclxml/jlibsasl.tcl: Fixed a typo (thanks to Sergei Golovan) * ifacetk/iface.tcl: Bugfix (thanks to Sergei Golovan) * doc/tkabber.xml: Updated (thanks to Sergei Golovan) * aniemoteicons/anigif.tcl: Bugfix (thanks to Sergei Golovan) * muc.tcl: Raise conference window on join request if it is already opened (thanks to Sergei Golovan) * chats.tcl: Clear status in chat windows on disconnect (thanks to Sergei Golovan) 2006-06-12 Alexey Shchepin * jabberlib-tclxml/jabberlib.tcl: Bugfix (thanks to Sergei Golovan) * ifacetk/systray.tcl: Minor fix (thanks to Sergei Golovan) * ifacetk/iface.tcl: Disable presence menu in offline state, bugfix (thanks to Sergei Golovan) * presence.tcl: Don't change status in offline state (thanks to Sergei Golovan) * plugins/iq/time.tcl: Don't convert time under Windows and tcl newer than 8.4.12 (thanks to Sergei Golovan) 2006-06-01 Alexey Shchepin * doc/tkabber.xml: Updated (thanks to Sergei Golovan) 2006-05-28 Alexey Shchepin * chats.tcl: Don't use latest entered JID on dialog opening (thanks to Sergei Golovan) * userinfo.tcl: Likewise 2006-05-27 Alexey Shchepin * doc/tkabber.xml: Updated (thanks to Sergei Golovan) * README: Likewise * plugins/general/subscribe_gateway.tcl: Bugfix (thanks to Sergei Golovan) * plugins/unix/tktray.tcl: Yet another tray support (thanks to Sergei Golovan) * ifacetk/systray.tcl: Likewise * ifacetk/iface.tcl: Removed loginconf usage (thanks to Sergei Golovan) * doc/tkabber.xml: Updated (thanks to Sergei Golovan) * tkabber.tcl: Added ifacetk namespace definition (thanks to Sergei Golovan) * splash.tcl: Copyright update (thanks to Sergei Golovan) * ifacetk/iface.tcl: Likewise * Makefile: Updated (thanks to Sergei Golovan) 2006-05-21 Alexey Shchepin * messages.tcl: Bugfix (thanks to Sergei Golovan) 2006-05-13 Alexey Shchepin * plugins/general/conferences.tcl: Bugfix (thanks to Sergei Golovan) 2006-05-12 Alexey Shchepin * plugins/general/conferences.tcl: Bugfix (thanks to Sergei Golovan) * plugins/chat/logger.tcl: Avoid more special characters in file names (thanks to Sergei Golovan) * jabberlib-tclxml/namespaces.tcl: Added pubsub#owner namespace (thanks to Sergei Golovan) * jabberlib-tclxml/jlibdns.tcl: Added processing of "." target (thanks to Sergei Golovan) * userinfo.tcl: Added a check for invalid seconds values (thanks to Sergei Golovan) * register.tcl: Multilogin support (thanks to Sergei Golovan) * login.tcl: Don't resolve SRV records if alternative server is specified (thanks to Sergei Golovan) * datagathering.tcl: Added multilogin support (thanks to Sergei Golovan) * custom.tcl: Better mouse wheel support (thanks to Sergei Golovan) 2006-04-27 Alexey Shchepin * jabberlib-tclxml/jlibsasl.tcl: Added SASL::NTLM loading (thanks to Sergei Golovan) * ifacetk/bwidget_workarounds.tcl: Fixed mouse wheel behaviour on Windows (thanks to Sergei Golovan) * plugins/windows/mousewheel.tcl: Likewise * contrib/extract-translations/extract.tcl: Fixed case when extraction file doesn't exist (thanks to Sergei Golovan) * userinfo.tcl: "OS" entry moved to "Client Version" frame (thanks to Sergei Golovan) * privacy.tcl: Bugfix (thanks to Sergei Golovan) 2006-04-19 Alexey Shchepin * msgs/es.msg: Updated (thanks to Badlop) 2006-04-09 Alexey Shchepin * msgs/es.msg: Updated (thanks to Badlop) * plugins/general/roster_delimiter.tcl: Fixed typo (thanks to Sergei Golovan) * muc.tcl: Faster list edit dialog (thanks to Sergei Golovan) * itemedit.tcl: Adding conference to roster moved to plugin (thanks to Sergei Golovan) * roster.tcl: Likewise * ifacetk/iface.tcl: Likewise * ifacetk/iroster.tcl: Likewise * plugins/general/conferences.tcl: Likewise * chats.tcl: Bugfix (thanks to Sergei Golovan) 2006-03-28 Alexey Shchepin * gpgme.tcl: Updated translation strings (thanks to Sergei Golovan) * login.tcl: Likewise * muc.tcl: Likewise * utils.tcl: Likewise * ifacetk/iface.tcl: Likewise * ifacetk/ilogin.tcl: Likewise * msgs/ru.msg: Likewise 2006-03-26 Alexey Shchepin * jabberlib-tclxml/jlibtls.tcl: Bugfix (thanks to Sergei Golovan) 2006-03-25 Alexey Shchepin * plugins/general/xcommands.tcl: Bugfix (thanks to Sergei Golovan) * muc.tcl: Bugfix (thanks to Sergei Golovan) * login.tcl: Updated login interface (thanks to Sergei Golovan) * ifacetk/ilogin.tcl: Likewise * jabberlib-tclxml/jabberlib.tcl: Likewise 2006-03-23 Alexey Shchepin * plugins/chat/irc_commands.tcl: In disconnected chatroom /nick now works as /join (thanks to Sergei Golovan) * jabberlib-tclxml/jlibdns.tcl: Support for SRV and TXT DNS records (requires tcllib 1.8, or 1.7 for TXT only) (thanks to Sergei Golovan) * jabberlib-tclxml/jabberlib.tcl: Likewise * jabberlib-tclxml/pkgIndex.tcl: Likewise * login.tcl: Likewise * ifacetk/iroster.tcl: Add "Remove" menu item for all chat menus (thanks to Sergei Golovan) * userinfo.tcl: Bugfix (thanks to Sergei Golovan) * privacy.tcl: Updated (thanks to Sergei Golovan) * muc.tcl: Slightly changed argument parsing for IRC-like commands (thanks to Sergei Golovan) 2006-03-17 Alexey Shchepin * plugins/general/xcommands.tcl: Fixed typo (thanks to Sergei Golovan) * register.tcl: Fixed "Unregister" button state (thanks to Sergei Golovan) * privacy.tcl: Bugfix (thanks to Sergei Golovan) * plugins/filetransfer/http.tcl: Bugfix (thanks to Sergei Golovan) * msgs/uk.msg: Updated (thanks to Mykola Dzham) * msgs/ru.msg: Updated (thanks to Sergei Golovan) * jabberlib-tclxml/namespaces.tcl: Added jabber:iq:privacy namespace (thanks to Sergei Golovan) * ifacetk/iroster.tcl: Minor update (thanks to Sergei Golovan) * privacy.tcl: Updated (thanks to Sergei Golovan) * ifacetk/iface.tcl: Updated privacy rules menu * muc.tcl: Added missed -exact lsearch option (thanks to Sergei Golovan) * pixmaps.tcl: Likewise * roster.tcl: Likewise * splash.tcl: Likewise * examples/teo-config.tcl: Likewise * examples/tkabber_setstatus: Likewise * plugins/chat/popupmenu.tcl: Likewise * messages.tcl: Updated labels (thanks to Sergei Golovan) * muc.tcl: Likewise * plugins/general/subscribe_gateway.tcl: Likewise * iq.tcl: Don't show own requests in the status line (thanks to Sergei Golovan) * filters.tcl: Disabled by default (thanks to Sergei Golovan) * disco.tcl: Fixed extra info reordering and clearing (thanks to Sergei Golovan) * chats.tcl: Fixed copying of URL to clipboard (thanks to Sergei Golovan) 2006-02-25 Alexey Shchepin * plugins/unix/ispell.tcl: Bugfix (thanks to Sergei Golovan) * plugins/general/jitworkaround.tcl: Bugfix (thanks to Sergei Golovan) * plugins/chat/irc_commands.tcl: Bugfix (thanks to Sergei Golovan) * tkabber.tcl: Support for TKABBER_SITE_PLUGINS environment variable (thanks to Sergei Golovan) * plugins.tcl: Added check for file existence (thanks to Sergei Golovan) 2006-02-09 Alexey Shchepin * plugins/windows/taskbar.tcl: Fixed typo (thanks to Sergei Golovan) * plugins/unix/wmdock.tcl: Icon creation moved to postload_hook, added icon window existing check (thanks to Sergei Golovan) * plugins/general/headlines.tcl: Minor update (thanks to Sergei Golovan) * pixmaps/amibulb/roster/icondef.xml: Replaced \r\n with \n (thanks to Sergei Golovan) * utils.tcl: Performance improvement (thanks to Sergei Golovan) * pixmaps.tcl: Better file name handling (thanks to Sergei Golovan) * chats.tcl: Cleanup (thanks to Sergei Golovan) 2006-02-06 Alexey Shchepin * msgs/es.msg: Updated (thanks to Badlop) 2006-01-28 Alexey Shchepin * plugins/general/annotations.tcl: Bugfix (thanks to Sergei Golovan) * plugins/chat/logger.tcl: Cleanup (thanks to Sergei Golovan) * plugins/chat/irc_commands.tcl: Added error message on /msg command failure (thanks to Sergei Golovan) * plugins/chat/insert_nick.tcl: Minor fix (thanks to Sergei Golovan) * jabberlib-tclxml/jlib*.tcl: Replaced [$token action] to [action $token] calls (thanks to Sergei Golovan) * jabberlib-tclxml/jabberlib.tcl: "after idle" call moved back to jabberlib.tcl (thanks to Sergei Golovan) * jabberlib-tclxml/wrapper.tcl: Likewise * jabberlib-tclxml/jabberlib.tcl: Correctly handle resource change in resource binding (thanks to Sergei Golovan) * jabberlib-tclxml/jlibsasl.tcl: Likewise * jabberlib-tclxml/jabberlib.tcl: Bugfix (thanks to Sergei Golovan) * ifacetk/iroster.tcl: Show both subscribe and ask status in tooltip (thanks to Sergei Golovan) * ifacetk/ilogin.tcl: Fill both ltmp and loginconf variables on profile change (thanks to Sergei Golovan) * roster.tcl: Attribute "name" processing moved to plugin (thanks to Sergei Golovan) * plugins/general/jitworkaround.tcl: Likewise * pixmaps.tcl: Pixmaps now can be loaded on the fly (thanks to Sergei Golovan) * browser.tcl: Updated * chats.tcl: Likewise * disco.tcl: Likewise * gpgme.tcl: Likewise * splash.tcl: Likewise * tkabber.tcl: Likewise * ifacetk/idefault.tcl: Likewise * ifacetk/iface.tcl: Likewise * ifacetk/iroster.tcl: Likewise * plugins/chat/popupmenu.tcl: Likewise * plugins/chat/send_message.tcl: Likewise * plugins/general/headlines.tcl: Likewise * plugins/general/offline.tcl: Likewise * plugins/unix/dockingtray.tcl: Likewise * plugins/unix/systray.tcl: Likewise * plugins/unix/wmdock.tcl: Likewise * plugins/windows/taskbar.tcl: Likewise * muc.tcl: Added support for error codes 321 and 322 (thanks to Sergei Golovan) * custom.tcl: Minor change (thanks to Sergei Golovan) * chats.tcl: Bugfix (thanks to Sergei Golovan) * msgs/pl.msg: Updated (thanks to Irek Chmielowiec) 2006-01-25 Alexey Shchepin * plugins/chat/irc_commands.tcl: Bugfix (thanks to Sergei Golovan) * plugins/chat/insert_nick.tcl: Plugin for insert nick by clicking on conference roster or in chat or conference window (thanks to Sergei Golovan) * jabberlib-tclxml/transports.tcl: Added zlib over tls support (thanks to Sergei Golovan) * ifacetk/iroster.tcl: Added -singleclick and -doubleclick options to ifacetk::roster::create (thanks to Sergei Golovan) * ifacetk/iface.tcl: Likewise * chats.tcl: Likewise * roster.tcl: Minor change (thanks to Sergei Golovan) * presence.tcl: Bugfix (thanks to Sergei Golovan) * muc.tcl: Bugfix, added "/unban JID" command (thanks to Sergei Golovan) 2006-01-20 Alexey Shchepin * plugins/general/avatars.tcl: Bugfix (thanks to Irek Chmielowiec) * **/*.tcl: All menus now created using hooks (thanks to Sergei Golovan) * plugins/general/rosterx.tcl: Roster Item Exchange Support (JEP-0093) (thanks to Sergei Golovan) * messages.tcl: Rosterx-related stuff moved to rosterx plugin * roster.tcl: Likewise * plugins/general/clientinfo.tcl: Minor change (thanks to Sergei Golovan) * jabberlib-tclxml/namespaces.tcl: Added xroster and rosterx namespaces (thanks to Sergei Golovan) * jabberlib-tclxml/jlibcompress.tcl: Better error processing (thanks to Sergei Golovan) * ifacetk/iface.tcl: Removed invisible status (thanks to Sergei Golovan) * muc.tcl: Changed some menu labels, fixed presence sending upon room joining or nick changing (thanks to Sergei Golovan) * gpgme.tcl: Added "expires" field processing, fixed signature printing in user info (thanks to Sergei Golovan) * chats.tcl: Bugfixes (thanks to Sergei Golovan) * browser.tcl: The connid parameter is not optional now (thanks to Sergei Golovan) * disco.tcl: Likewise * filetransfer.tcl: Likewise * messages.tcl: Likewise 2006-01-17 Alexey Shchepin * ifacetk/iroster.tcl: Bugfix (thanks to Igor Goryachev) * plugins/general/xcommands.tcl: Updated (thanks to Sergei Golovan) * plugins/general/rawxml.tcl: Fixed "smart scroll" (thanks to Sergei Golovan) * chats.tcl: Likewise * plugins/general/headlines.tcl: Added "delete" button (thanks to Sergei Golovan) * plugins/general/conferenceinfo.tcl: Updated (thanks to Sergei Golovan) * plugins/general/avatars.tcl: Presence processing moved to another hook (thanks to Sergei Golovan) * plugins/general/annotations.tcl: Bugfix (thanks to Sergei Golovan) * plugins/chat/send_message.tcl: Add id to messages (thanks to Sergei Golovan) * plugins/chat/open_chat.tcl: Updated (thanks to Sergei Golovan) * plugins/chat/irc_commands.tcl: Added invitation support, reason now expected on second line (thanks to Sergei Golovan) * plugins/chat/completion.tcl: Remove additional suffix on Sh-RET (thanks to Sergei Golovan) * plugins/chat/clear.tcl: Support for /clear command (moved from irc_commands.tcl) (thanks to Sergei Golovan) * plugins/chat/irc_commands.tcl: Likewise * plugins/chat/chatstate.tcl: Bugfix (thanks to Sergei Golovan) * jabberlib-tclxml/ntlm.tcl: Bugfix (thanks to Pat Thoyts) * jabberlib-tclxml/namespaces.tcl: Updated (thanks to Sergei Golovan) * jabberlib-tclxml/jlibcompress.tcl: Support for stream compression (JEP-0138) (requires https://gna.org/projects/ztcl/) (thanks to Sergei Golovan) * login.tcl: Likewise * ifacetk/ilogin.tcl: Likewise * jabberlib-tclxml/jabberlib.tcl: Likewise * jabberlib-tclxml/pkgIndex.tcl: Likewise * jabberlib-tclxml/transports.tcl: Likewise * examples/mtr-config.tcl: Updated (thanks to Sergei Golovan) * userinfo.tcl: Bugfix (thanks to Sergei Golovan) * roster.tcl: Some procedures moved to hooks (thanks to Sergei Golovan) * register.tcl: Added "unregister" button (thanks to Sergei Golovan) * presence.tcl: Removed presence_process_x_hook, internal updates, save status on exit (thanks to Sergei Golovan) * muc.tcl: Cleanup, deny some affiliation changes, /kick and /ban now expect reason on second line, fixed invitations (thanks to Sergei Golovan) * messages.tcl: Destroy subscription window on roster push if subscription request is not required anymore (thanks to Sergei Golovan) * gpgme.tcl: All gpgme-related stuff moved here (thanks to Sergei Golovan) * messages.tcl: Likewise * userinfo.tcl: Likewise * ifacetk/iface.tcl: Likewise * plugins/chat/draw_encrypted.tcl: Likewise * plugins/chat/draw_signed.tcl: Likewise * plugins/general/presenceinfo.tcl: Likewise * disco.tcl: Added disco publish support (thanks to Sergei Golovan) * disco.tcl: Added disco tree clearing feature (thanks to Maxim Ryazanov) * datagathering.tcl: Changed focus behaviour (thanks to Sergei Golovan) * chats.tcl: Encode non-ASCII characters in URL, miscellaneous internal changes (thanks to Sergei Golovan) 2006-01-08 Alexey Shchepin * plugins/chat/bookmark_highlighted.tcl: Updated hook priority (thanks to Sergei Golovan) * plugins/chat/me_command.tcl: Likewise * ifacetk/systray.tcl: Changed menu title, don't set geometry if window state wasn't saved (thanks to Sergei Golovan) * doc/tkabber.xml: Fixed urls (thanks to Sergei Golovan) * utils.tcl: Bugfix (thanks to Sergei Golovan) * userinfo.tcl: Center photo in frame (thanks to Sergei Golovan) * userinfo.tcl: Set image MIME type according to image signature (thanks to Unatine) * splash.tcl: Set -topmost attribute to splash screen (thanks to Sergei Golovan) * messages.tcl: Bugfix (thanks to Sergei Golovan) * chats.tcl: Bugfix, added some items to chat menu (thanks to Sergei Golovan) 2005-11-30 Alexey Shchepin * plugins/general/headlines.tcl: Better keyboard management, highlight headers after clicking url in body (thanks to Sergei Golovan) * ifacetk/iroster.tcl: Bugfix (thanks to Sergei Golovan) * ifacetk/iface.tcl: Fixed focus behaviour in status line (thanks to Sergei Golovan) * roster.tcl: Fixed sending of custom presence and resubscription in undefined group (thanks to Sergei Golovan) * login.tcl: Option "sslcafile" replaced with "sslcacertstore", which accepts CA file or directory (thanks to Sergei Golovan) * jabberlib-tclxml/jabberlib.tcl: Likewise * jabberlib-tclxml/jlibtls.tcl: Likewise * jabberlib-tclxml/transports.tcl: Likewise 2005-11-20 Alexey Shchepin * plugins/general/headlines.tcl: Updated interface, added open_headlines_post_hook (thanks to Sergei Golovan) * plugins/chat/chatstate.tcl: Send "gone" event only after "active" event (thanks to Sergei Golovan) * jabberlib-tclxml/wrapper.tcl: Replace control characters to spaces (thanks to Sergei Golovan) * ifacetk/systray.tcl: Unification of tray support (thanks to Sergei Golovan) * ifacetk/iface.tcl: Likewise * plugins/unix/dockingtray.tcl: Likewise * plugins/unix/systray.tcl: Likewise * plugins/windows/taskbar.tcl: Likewise * presence.tcl: Likewise * search.tcl: Bugfix * roster.tcl: Support for sending custom presence to all group members (thanks to Sergei Golovan) * ifacetk/iroster.tcl: Likewise 2005-11-14 Alexey Shchepin * plugins/general/xcommands.tcl: Support for ad-hoc commands (JEP-0050) (thanks to Sergei Golovan) * plugins/general/roster_delimiter.tcl: Support for nested roster groups server-side delimiter storing (JEP-0083) (thanks to Sergei Golovan) * plugins/chat/logger.tcl: Removed dependency on loginconf variable (thanks to Sergei Golovan) * plugins/general/message_archive.tcl: Likewise * jabberlib-tclxml/namespaces.tcl: Updated (thanks to Sergei Golovan) * ifacetk/unix.xrdb: Updated (thanks to Sergei Golovan) * ifacetk/iface.tcl: Added separator in tab menu (thanks to Sergei Golovan) * ifacetk/bwidget_workarounds.tcl: Removed copying of selected nodes to primary X-selection (thanks to Sergei Golovan) * contrib/extract-translations/extract.tcl: Fixed processing of multiline strings (thanks to Sergei Golovan) * chats.tcl: Headlines stuff moved to plugin (thanks to Sergei Golovan) * messages.tcl: Likewise * plugins/general/headlines.tcl: Likewise * plugins/chat/chatstate.tcl: Disabled by default, don't send events to offline contacts (thanks to Sergei Golovan) * msgs/uk.msg: Updated Ukrainian translation (thanks to Mykola Dzham) * msgs/ua.msg: Removed * jabberlib-tclxml/namespaces.tcl: Updated (thanks to Sergei Golovan) * ifacetk/iroster.tcl: Fixed drag'n'drop of conferences from disco (thanks to Sergei Golovan) * plugins/general/conferences.tcl: Likewise * ifacetk/iroster.tcl: Removed items indenting when multilogin is used (thanks to Sergei Golovan) * ifacetk/iface.tcl: Added mouse wheel bindings for tab headers (thanks to Sergei Golovan) * messages.tcl: Removed "Cancel" button from subscribe dialog (thanks to Sergei Golovan) * disco.tcl: Added category and type attributes in drag'n'drop info (thanks to Sergei Golovan) * custom.tcl: Added status "set in config" (thanks to Sergei Golovan) * chats.tcl: Added nick highlighting in /me messages (thanks to Sergei Golovan) * plugins/chat/draw_normal_message.tcl: Likewise * plugins/chat/me_command.tcl: Likewise 2005-10-12 Alexey Shchepin * plugins/chat/events.tcl: Now message events can be switched off (thanks to Sergei Golovan) * plugins/chat/events.tcl: Generation of xlist is moved to hook (thanks to Sergei Golovan) * plugins/chat/send_message.tcl: Likewise * plugins/chat/chatstate.tcl: Support for Chat State Notifications (JEP-0085) (only and ) (thanks to Sergei Golovan) * jabberlib-tclxml/namespaces.tcl: Added 2 namespaces (thanks to Sergei Golovan) * login.tcl: Fixed error after unsuccessful registration (thanks to Sergei Golovan) * datagathering.tcl: Added support for "true" and "false" boolean values (thanks to Sergei Golovan) * chats.tcl: Now possible to read logs from conference private chats (thanks to Sergei Golovan) * ifacetk/iroster.tcl: Likewise * plugins/chat/logger.tcl: Likewise * chats.tcl: Changed message on topic change from room JID (thanks to Sergei Golovan) 2005-09-28 Alexey Shchepin * jabberlib-tclxml/jabberlib.tcl: Added a description for the DISCONNECT event (thanks to Sergei Golovan) * jabberlib-tclxml/stanzaerror.tcl: Likewise * register.tcl: Output a error message in the same registration window (thanks to Sergei Golovan) * muc.tcl: Show JID in kick and ban messages (thanks to Sergei Golovan) * datagathering.tcl: Now possible to clear fields and resend form (thanks to Sergei Golovan) * chats.tcl: Added a popup balloon for a topic label (thanks to Sergei Golovan) * chats.tcl: Bugfix (thanks to Sergei Golovan) * plugins/chat/open_window.tcl: Likewise * balloon.tcl: Don't show a empty balloon (thanks to Sergei Golovan) 2005-09-15 Alexey Shchepin * plugins/chat/highlight.tcl: Better highlighting (thanks to Sergei Golovan) * jabberlib-tclxml/*: Reorganized, a few fixes (thanks to Sergei Golovan) * iq.tcl: Updated * login.tcl: Likewise * utils.tcl: Likewise * plugins/general/conferenceinfo.tcl: Likewise 2005-09-02 Alexey Shchepin * plugins/general/conferences.tcl: Bugfix (thanks to Sergei Golovan) * jabberlib-tclxml/streamerror.tcl: Fixed CVS keyword (thanks to Sergei Golovan) * userinfo.tcl: Added connection choosing in user info dialog (thanks to Sergei Golovan) * plugins.tcl: Ignore non-directory files in plugins dir (thanks to Sergei Golovan) * messages.tcl: Added connection choosing in messages and subscription dialogs (thanks to Sergei Golovan) * presence.tcl: Likewise * chats.tcl: Added "open chat" dialog (thanks to Sergei Golovan) * ifacetk/iface.tcl: Likewise * chats.tcl: Updated URL regexp (thanks to Michail Litvak) 2005-08-28 Alexey Shchepin * msgs/pl.msg: Updated (thanks to Irek Chmielowiec) * plugins/chat/search.tcl: Fixed search panel displaying when the chat window have a small size (thanks to Sergei Golovan) 2005-08-19 Alexey Shchepin * login.tcl: Bugfix (thanks to Sergei Golovan) * ifacetk/iroster.tcl: Bugfix (thanks to Sergei Golovan) * doc/tkabber.xml: Updated 2005-08-14 Alexey Shchepin * msgs/nl.msg: Updated (thanks to Sander Devrieze) * chats.tcl: Bugfix (thanks to Michail Litvak) * plugins/general/conferences.tcl: Changed update_bookmark API (thanks to Sergei Golovan) * itemedit.tcl: Likewise * ifacetk/iroster.tcl: Fixed drug'n'drop of conference jids (thanks to Sergei Golovan) * roster.tcl: Removed setting of "conference" and "subtype" attributes (thanks to Sergei Golovan) 2005-08-11 Alexey Shchepin * joingrdialog.tcl: Minor fix (thanks to Sergei Golovan) 2005-08-10 Alexey Shchepin * msgs/es.msg: Updated (thanks to Badlop) * ifacetk/iroster.tcl: Bugfix (thanks to Sergei Golovan) 2005-08-09 Alexey Shchepin * plugins/general/annotations.tcl: Don't display note creation and modification dates in popup balloon (thanks to Sergei Golovan) * roster.tcl: Bugfix (thanks to Sergei Golovan) 2005-08-07 Alexey Shchepin * plugins/general/conferences.tcl: Bugfixes (thanks to Sergei Golovan) * plugins/chat/logger.tcl: Bugfix (thanks to Sergei Golovan) * msgs/ru.msg: Updated (thanks to Sergei Golovan) * itemedit.tcl: Minor translation string update (thanks to Sergei Golovan) * messages.tcl: Bugfix * plugins/general/conferences.tcl: Support for JEP-0048 (Bookmarks) (thanks to Sergei Golovan) * itemedit.tcl: Likewise * roster.tcl: Likewise * ifacetk/iroster.tcl: Likewise * muc.tcl: Added muc_password variable * login.tcl: Bugfix (thanks to Sergei Golovan) * joingrdialog.tcl: Updated join group dialog, removed add_group_dialog and add_conference procedures (bookmarks should be used) * browser.tcl: Updated * chats.tcl: Likewise * disco.tcl: Likewise * ifaceck/iroster.tcl: Likewise * ifacetk/iface.tcl: Likewise 2005-08-04 Alexey Shchepin * plugins/general/annotations.tcl: Added annotation page in user info window (thanks to Sergei Golovan) * msgs/ru.msg: Updated (thanks to Sergei Golovan) * jabberlib-tclxml/streamerror.tcl: Stream error processing (thanks to Sergei Golovan) * jabberlib-tclxml/jabberlib.tcl: Likewise * jabberlib-tclxml/pkgIndex.tcl: Updated * ifacetk/iface.tcl: Added procedure client:errormsg (thanks to Sergei Golovan) * jabberlib-tclxml/jabberlib.tcl: Likewise * login.tcl: Bugfix (thanks to Sergei Golovan) * disco.tcl: Support for JEP-0128, better usability (thanks to Sergei Golovan) * muc.tcl: Updated * datagathering.tcl: Added function data::parse_xdata_results (thanks to Sergei Golovan) * browser.tcl: Better usability, several variables made per-window (thanks to Sergei Golovan) 2005-08-01 Alexey Shchepin * plugins/general/annotations.tcl: Support for JEP-0145 (Annotations) (thanks to Sergei Golovan) * ifacetk/iroster.tcl: Added roster_create_user_menu_edit_hook, instead of roster_create_user_menu_gpg_hook (thanks to Sergei Golovan) * gpgme.tcl: Likewise * itemedit.tcl: Likewise * tkabber.tcl: Use Changelog file if available to generate version string (thanks to Sergei Golovan) 2005-07-31 Alexey Shchepin * msgs/ru.msg: Updated (thanks to Sergei Golovan) * jabberlib-tclxml/jabberlib.tcl: Better error handling (thanks to Sergei Golovan) * contrib/extract-translations/extract.tcl: Updated (thanks to Sergei Golovan) * gpgme.tcl: Fixed typo (thanks to Sergei Golovan) * login.tcl: Likewise * ifacetk/ilogin.tcl: Likewise 2005-07-30 Alexey Shchepin * jabberlib-tclxml/jlibsasl.tcl: SASL support moved here from jabberlib.tcl, and added support for SASL module from tcllib (thanks to Sergei Golovan) * jabberlib-tclxml/jabberlib.tcl: Likewise * jabberlib-tclxml/pkgIndex.tcl: Updated * jabberlib-tclxml/wrapper.tcl: Updated 2005-07-27 Alexey Shchepin * plugins/unix/ispell.tcl: Bugfix (thanks to Sergei Golovan) * jabberlib-tclxml/jabberlib.tcl: Workaround for jabberd2 bug (which is now fixed) (thanks to Sergei Golovan) 2005-07-15 Alexey Shchepin * jabberlib-tclxml/transports.tcl: Bugfix (thanks to Sergei Golovan) * ifacetk/iface.tcl: Added option for displaying notebook tabs at the bottom (thanks to Sergei Golovan) * gpgme.tcl: Fixed typo (thanks to Sergei Golovan) 2005-06-22 Alexey Shchepin * plugins/general/sound.tcl: Added option for muting sound when Tkabber window have no focus (thanks to Sergei Golovan) * jabberlib-tclxml/transports.tcl: Ignore "-certfile", "-cafile", "-keyfile" options if their argument is empty string (thanks to Sergei Golovan) * jabberlib-tclxml/jabberlib.tcl: Added errors returning on problems with authentication (thanks to Sergei Golovan) * jabberlib-tclxml/jabberlib.tcl: Separated SASL and STARTTLS options (thanks to Pat Thoyts) * ifacetk/ilogin.tcl: Added certificate file field (thanks to Sergei Golovan) * contrib/extract-translations/extract.tcl: Better output (thanks to Badlop) * privacy.tcl: Minor update to simplify extraction of translation strings (thanks to Sergei Golovan) * login.tcl: Added option for enabling PLAIN SASL mechanism (thanks to Sergei Golovan) * ifacetk/ilogin.tcl: Likewise * gpgme.tcl: Added customization options (thanks to Sergei Golovan) 2005-05-15 Alexey Shchepin * plugins/chat/nick_colors.tcl: Bugfix (thanks to Sergei Golovan) * msgs/ru.msg: Updated (thanks to Sergei Golovan) * ifacetk/iface.tcl: Replaced "Browser" with "Jabber Browser" (thanks to Sergei Golovan) * disco.tcl: Replaced "Jabber Discovery" with "Service Discovery" (thanks to Sergei Golovan) * ifacetk/iface.tcl: Likewise 2005-04-26 Alexey Shchepin * msgs/ru.msg: Updated (thanks to Sergei Golovan) * plugins/windows/taskbar.tcl: Now behaviour is the same as in unix taskbar plugin (thanks to Sergei Golovan) * pixmaps/*/doking/tkabber.ico: Updated * userinfo.tcl: Better displaying of big photos (thanks to Sergei Golovan) * chats.tcl: Better status displaying (thanks to Sergei Golovan) 2005-04-20 Alexey Shchepin * muc.tcl: Sort affiliation lists (thanks to Sergei Golovan) * gpgme.tcl: Added multilogin support for GPGME (thanks to Sergei Golovan) * chats.tcl: Likewise * messages.tcl: Likewise * presence.tcl: Likewise * ifacetk/iroster.tcl: Likewise * plugins/chat/draw_signed.tcl: Likewise 2005-04-13 Alexey Shchepin * messages.tcl: Bugfix 2005-04-07 Alexey Shchepin * jabberlib-tclxml/tclxml/: Removed unused code (thanks to Sergei Golovan) * jabberlib-tclxml/wrapper.tcl: Optimizations (thanks to Sergei Golovan) * ifacetk/default.xrdb: Non-geometry resources are moved to unix.xrdb (thanks to Sergei Golovan) * ifacetk/unix.xrdb: Likewise * tkabber.tcl: Updated loading of default XRDB resources (thanks to Sergei Golovan) * chats.tcl: Added processing of empty subject in messages (thanks to Sergei Golovan) * examples/mtr-config.tcl: Likewise * examples/tools/rssbot.tcl: Likewise * jabberlib-tclxml/jabberlib.tcl: Likewise * plugins/si/ibb.tcl: Likewise 2005-03-27 Alexey Shchepin * plugins/unix/systray.tcl: Added message tray icon blinking (thanks to Sergei Golovan) * plugins/unix/dockingtray.tcl: Now behaviour is almost the same as in systray.tcl (thanks to Sergei Golovan) * plugins/chat/draw_xhtml_message.tcl: Fixed groupchat messages displaying, updated hook priority (thanks to Sergei Golovan) * plugins/chat/draw_normal_message.tcl: Updated hook priority * msgs/ru.msg: Updated (thanks to Sergei Golovan) * ifacetk/iroster.tcl: Updated status description in roster balloon (thanks to Sergei Golovan) * ifacetk/iface.tcl: Added options to hide toolbar, status bar and presence bar (thanks to Sergei Golovan) * ifacetk/idefault.tcl: Workaround for shortcuts in russian keyboard layout in Windows (thanks to Sergei Golovan) * emoticons.tcl: Updated bindings * plugins/chat/search.tcl: Likewise * ifacetk/bwidget_workarounds.tcl: Updated to latest BWidget version (thanks to Sergei Golovan) * examples/*.xrdb: Updated (thanks to Sergei Golovan) * gpgme.tcl: Minor change (thanks to Sergei Golovan) * browser.tcl: Bugfix (thanks to Sergei Golovan) 2005-03-16 Alexey Shchepin * msgs/*.msg: Commented ::msgcat::mcset commands with empty second argument to be compatible with latest msgcat package * msgs/pl.msg: Updated (thanks to Irek Chmielowiec) 2005-03-15 Alexey Shchepin * plugins/chat/search.tcl: Removed "Search:" label and FocusOut binding, added "Close" button (thanks to Sergei Golovan) * plugins/chat/logger.tcl: Pack all buttons in one row, added check for regexp correctness (thanks to Sergei Golovan) * ifacetk/iface.tcl: Minor fix (thanks to Sergei Golovan) * plugins/chat/logger.tcl: Use tag instead of selection to highlight matched text (thanks to Michail Litvak) * chats.tcl: Minor change (thanks to Michail Litvak) * plugins/chat/search.tcl: Support for search in chat window (thanks to Michail Litvak) 2005-03-13 Alexey Shchepin * plugins/general/rawxml.tcl: Options moved to "Plugins" subgroup (thanks to Sergei Golovan) * plugins/unix/ispell.tcl: Likewise * plugins/general/autoaway.tcl: Removed sound muting in "away" and "xa" states (thanks to Sergei Golovan) * ifacetk/iroster.tcl: Fixed bug with "show offline contacts" nested group command (thanks to Sergei Golovan) * ifacetk/iface.tcl: Store window state on Windows, slightly reorganized menu, less roster width (thanks to Sergei Golovan) * ifacetk/default.xrdb: Removed unused resource "mainwindowstate" (thanks to Sergei Golovan) * splash.tcl: Splash window now transparent on win and mac platforms (thanks to Pat Thoyts) * sounds.tcl: Moved to plugins/general/sound.tcl (thanks to Sergei Golovan) * plugins/general/sound.tcl: Likewise * tkabber.tcl: Removed loading of sound.tcl * messages.tcl: Added "Message" class for message windows (thanks to Sergei Golovan) * login.tcl: Added loginconf(httpuseragent) variable (thanks to Sergei Golovan) * jabberlib-tclxml/transports.tcl: Added -proxyuseragent option * custom.tcl: Added "file" type of variable (thanks to Sergei Golovan) * login.tcl: Use "file" type for SSL certificates * balloon.tcl: Less balloon pads (thanks to Sergei Golovan) * jabberlib-tclxml/jabberlib.tcl: Bugfix (thanks to Sergei Golovan) * jabberlib-tclxml/transports.tcl: Likewise * roster.tcl: Bugfix (thanks to Sergei Golovan) 2005-03-12 Alexey Shchepin * plugins/chat/info_commands.tcl: Fixed typo (thanks to Sergei Golovan) * plugins/chat/events.tcl: Workaround for yahoo-t, which send inside jabber:x:event with real messages (thanks to Sergei Golovan) * msgs/ru.msg: Updated (thanks to Sergei Golovan) * jabberlib-tclxml/transports.tcl: Better SSL handling (thanks to Sergei Golovan) * ifacetk/iroster.tcl: Fixed roster aliases handling (thanks to Dmitry Astapov) * roster.tcl: Better handling of conference items (thanks to Pat Thoyts) * roster.tcl: Better status messages (thanks to Sergei Golovan) * muc.tcl: Added room destruction dialog (thanks to Sergei Golovan) * messages.tcl: Ignore messages with empty body and no (or unsupported, e.g. jabber:x:event) extras (thanks to Sergei Golovan) * chats.tcl: "Online" and "offline" strings replaced with "available" and "unavailable" (thanks to Sergei Golovan) * iface.tcl: Likewise * presence.tcl: Likewise * ifaceck/iroster.tcl: Likewise * ifacetk/iface.tcl: Likewise * ifacetk/iroster.tcl: Likewise * chats.tcl: Added /leave with reason command (thanks to Sergei Golovan) * plugins/chat/irc_commands.tcl: Likewise * chats.tcl: Added connid argument to get_nick function (thanks to Sergei Golovan) * muc.tcl: Likewise * sound.tcl: Likewise * examples/mtr-config.tcl: Likewise * ifaceck/iroster.tcl: Likewise * ifacetk/iface.tcl: Likewise * ifacetk/iroster.tcl: Likewise * plugins/chat/bookmark_highlighted.tcl: Likewise * plugins/chat/complete_last_nick.tcl:Likewise * plugins/chat/completion.tcl:Likewise * plugins/chat/draw_normal_message.tcl:Likewise * plugins/chat/draw_xhtml_message.tcl:Likewise * plugins/chat/logger.tcl:Likewise * plugins/chat/me_command.tcl:Likewise * plugins/chat/nick_colors.tcl:Likewise * plugins/chat/open_chat.tcl:Likewise 2005-03-08 Alexey Shchepin * custom.tcl: Remove duplicates in subgroup list (thanks to Sergei Golovan) 2005-03-03 Alexey Shchepin * plugins/unix/systray.tcl: Updated (thanks to Sergei Golovan) * plugins/general/conferenceinfo.tcl: All options now in minutes instead of seconds (thanks to Sergei Golovan) * plugins/chat/irc_commands.tcl: Command /subject without arguments doen't set empty subject and display current instead (thanks to Sergei Golovan) * plugins/chat/info_commands.tcl: Better customization (thanks to Sergei Golovan) * jabberlib-tclxml/transports.tcl: Fixed NTLM authentication (thanks to Sergei Golovan) * plugins.tcl: Remove definition of Plugins group (thanks to Sergei Golovan) * messages.tcl: Added news copying to clipboard (thanks to Sergei Golovan) * itemedit.tcl: User bare jid to retrieve user vCard (thanks to Sergei Golovan) * filetransfer.tcl: Insert tag in custom group definition (thanks to Sergei Golovan) * disco.tcl: Sort items by default (thanks to Sergei Golovan) * custom.tcl: Remove dups in group parent list, minor interface change (thanks to Sergei Golovan) * chats.tcl: Fixed bug with incorrect emphasizing initialization (thanks to Sergei Golovan) 2005-02-27 Alexey Shchepin * plugins/general/autoaway.tcl: Updated options(drop_priority) description (thanks to Sergei Golovan) * msgs/ru.msg: Updated (thanks to Sergei Golovan) * ifacetk/ilogin.tcl: Updated behaviour in SSL tab (thanks to Sergei Golovan) * login.tcl: Removed loginconf(usestarttls), updated usage of loginconf(usessl) variable (thanks to Sergei Golovan) 2005-02-22 Alexey Shchepin * plugins.tcl: Added "Plugins" customization group 2005-01-17 Alexey Shchepin * plugins/unix/menu.tcl: Fixed behaviour (thanks to Sergei Golovan) * plugins/unix/menu8.4.tcl: Likewise * plugins/unix/dockingtray.tcl: Replaced command renaming to hook calls (thanks to Sergei Golovan) * plugins/unix/systray.tcl: Likewise * plugins/windows/taskbar.tcl: Likewise * jabberlib-tclxml/pkgIndex.tcl: Added NTLM package, increased jabberlib version (thanks to Sergei Golovan) * jabberlib-tclxml/ntlm.tcl: Support for NTLM authentication (thanks to Sergei Golovan) * jabberlib-tclxml/jabberlib.tcl: All socket and HTTP stuff moved to transports.tcl (thanks to Sergei Golovan) * jabberlib-tclxml/transports.tcl: Likewise * ifacetk/ilogin.tcl: Updated SSL tab (thanks to Sergei Golovan) * ifacetk/iface.tcl: Removed unneeded separator in Help menu, added "update idletask" (thanks to Sergei Golovan) * ifacetk/default.xrdb: Added customize button label color and width of scrollbar resources (thanks to Sergei Golovan) * ifaceck/iroster.tcl: Better menu labels (thanks to Sergei Golovan) * ifacetk/iroster.tcl: Likewise * examples/tools/jsend.tcl: Updated to work with current jabberlib (thanks to Sergei Golovan) * examples/tools/rssbot.tcl: Likewise * roster.tcl: Don't send unregistration request if server's jid is deleted, added procedure roster::send_remove_users_group (thanks to Sergei Golovan) * ifacetk/iroster.tcl: Added "Remove all users in group..." command * login.tcl: Many internal changes (thanks to Sergei Golovan) * iface.tcl: Better TLS warnings, added hooks set_status_hook and clear_status_hook (thanks to Sergei Golovan) * datagathering.tcl: Added "wm group $w ." (thanks to Sergei Golovan) * messages.tcl: Likewise * register.tcl: Likewise * search.tcl: Likewise * userinfo.tcl: Likewise * ifacetk/iface.tcl: Likewise * plugins/chat/logger.tcl: Likewise * plugins/general/subscribe_gateway.tcl: Likewise * custom.tcl: Group names now drawed inside buttons (thanks to Sergei Golovan) 2005-01-04 Alexey Shchepin * ifacetk/iface.tcl: Copyright update * splash.tcl: Likewise 2004-12-22 Alexey Shchepin * plugins/unix/menu.tcl: Fixed menu closing behaviour (thanks to Sergei Golovan) * plugins/unix/menu8.4.tcl: Likewise * roster.tcl: Fixed nicknames importing from JIT (thanks to Sergei Golovan) * plugins/general/avatars.tcl: Allows translation of more strings (thanks to Badlop) * ifacetk/iface.tcl: Menu reorganization (thanks to Badlop and Sergei Golovan) * ifacetk/iroster.tcl: Likewise * examples/ocean-deep.xrdb: New color theme (thanks to Badlop) 2004-12-17 Alexey Shchepin * plugins/chat/logger.tcl: Avoid glob characters in filename to work properly in win32 2004-11-29 Alexey Shchepin * plugins/chat/logger.tcl: Updated search interface (thanks to Sergei Golovan) * msgs/*.msg: Updated (thanks to Sergei Golovan) * muc.tcl: Minor fix (thanks to Sergei Golovan) * login.tcl: Avoid vwait (thanks to Sergei Golovan) * chats.tcl: Removed "..." from "Show info" and "Show history" menu items (thanks to Sergei Golovan) * messages.tcl: Likewise * search.tcl: Likewise * ifaceck/iroster.tcl: Likewise * ifacetk/iroster.tcl: Likewise 2004-11-28 Alexey Shchepin * plugins/general/autoaway.tcl: Fixed priority storing, intervals now specified in minutes (thanks to Sergei Golovan) * presence.tcl: Send presence only when changed $userstatus, updated sending of first presence (thanks to Sergei Golovan) 2004-11-21 Alexey Shchepin * plugins/chat/open_chat.tcl: Support for /open command (thanks to Dmitry Astapov) * plugins/chat/completion.tcl: Support for completion of strings with spaces (thanks to Dmitry Astapov) * jabberlib-tclxml/jabberlib.tcl: Moved predisconnected_hook to login.tcl (thanks to Sergei Golovan) * login.tcl: Likewise * ifacetk/iroster.tcl: Updated set_group_lists (thanks to Sergei Golovan) * tkabber.tcl: Updated exiting (thanks to Sergei Golovan) * ifacetk/iface.tcl: Likewise * muc.tcl: Replaced "[namespace current]" with "muc" (thanks to Sergei Golovan) * messages.tcl: Replaced "gc_" with "muc#" (thanks to Sergei Golovan) * muc.tcl: Likewise * muc.tcl: Avoid vwait (thanks to Sergei Golovan) * chats.tcl: Removed "after idle" call, cleanup (thanks to Sergei Golovan) * ifacetk/ilogin.tcl: Better focus setting in login window (thanks to Sergei Golovan) 2004-09-30 Alexey Shchepin * msgs/ru.msg: Updated (thanks to Sergei Golovan) * jabberlib-tclxml/wrapper.tcl: Added wrapper::free procedure (thanks to Sergei Golovan) * jabberlib-tclxml/jabberlib.tcl: Better support for xml:lang (thanks to Sergei Golovan) * emoticons.tcl: Added freeing of xml parser (thanks to Sergei Golovan) * xmppmime.tcl: Likewise * jabberlib-tclxml/jabberlib.tcl: Likewise * jabberlib-tclxml/jabberlib.tcl (jlib::http_poll): Removed previous fix 2004-09-29 Alexey Shchepin * jabberlib-tclxml/jabberlib.tcl (jlib::http_poll): Bugfix (thanks to Sergei Golovan) 2004-09-28 Alexey Shchepin * tkabber.tcl: Added '-splash' option 2004-09-25 Alexey Shchepin * login.tcl: Display registration dialog only on authentication error (thanks to Sergei Golovan) * msgs/ru.msg: Updated (thanks to Sergei Golovan) * jabberlib-tclxml/jabberlib.tcl: Updated for better handling of translation strings (thanks to Sergei Golovan) * plugins/general/rawxml.tcl: Likewise * plugins/general/stats.tcl: Likewise * ifaceck/iface.tcl: Updated some translation strings (thanks to Sergei Golovan) * ifacetk/iface.tcl: Likewise * contrib/extract-translations/extract.tcl: Better search for translation stings (thanks to Sergei Golovan) * msgs/pl.msg: Updated (thanks to Irek Chmielowiec) 2004-09-21 Alexey Shchepin * joingrdialog.tcl (add_group_dialog): Bugfix * presence.tcl: Bugfix (thanks to Sergei Golovan) 2004-09-17 Alexey Shchepin * plugins/general/offline.tcl: Partial support for JEP-0013 (thanks to Sergei Golovan) * ifacetk/iface.tcl: Removed avatar menu, register name for services menu (thanks to Sergei Golovan) * userinfo.tcl: Added hook for inserting new pages in user info window (thanks to Sergei Golovan) * muc.tcl: Processing of conference presence packets moved here (thanks to Sergei Golovan) * messages.tcl: Support for password in conference room invitation (thanks to Sergei Golovan) * login.tcl: Fixed logout with reason (thanks to Sergei Golovan) * presence.tcl: Likewise * joingrdialog.tcl: Updated support for room password (thanks to Sergei Golovan) * hooks.tcl: Added procedure foldl (thanks to Sergei Golovan) * ckabber.tcl: Removed avatar namespace (thanks to Sergei Golovan) * chats.tcl: Fixed processing of disconnecting from conference room (thanks to Sergei Golovan) * avatars.tcl: Moved to plugins (thanks to Sergei Golovan) * plugins/general/avatars.tcl: Likewise, added connid support, avatar menu moved from ifacetk/iface.tcl (thanks to Sergei Golovan) * tkabber.tcl: Removed direct loading of avatars.tcl (thanks to Sergei Golovan) 2004-09-10 Alexey Shchepin * ifacetk/iroster.tcl: Bugfix (thanks to Sergei Golovan) * jabberlib-tclxml/jabberlib.tcl: Fixed TLS support (thanks to Sergei Golovan) * login.tcl: Likewise 2004-09-09 Alexey Shchepin * ifacetk/iface.tcl: Added "Iconize" option to options(closebuttonaction) (thanks to Badlop) 2004-09-05 Alexey Shchepin * chats.tcl: Better URL support, added "Add conference" in conference menu * plugins/chat/highlight.tcl: Removed highlighting inside URL * plugins/unix/systray.tcl: Fixed icon initialization * plugins/filetransfer/http.tcl: Bugfix * plugins/jidlink/dtcp.tcl: Likewise * jabberlib-tclxml/wrapper.tcl: Added stream_header and stream_trailer procedures * messages.tcl: Message body now displayed using $font * disco.tcl: Added sorting * browser.tcl: Added sorting by JID 2004-08-23 Alexey Shchepin * muc.tcl: Fixed invitation to conference (thanks to Sergei Golovan) * chats.tcl: Likewise 2004-08-16 Alexey Shchepin * plugins/unix/systray.tcl: New plugin for tray icon (thanks to Alexey Lyubimov) * plugins/unix/dockingtray.tcl: Now disabled by default (thanks to Sergei Golovan) * plugins/general/subscribe_gateway.tcl: New plugin for user adding using jabber:iq:gateway (thanks to Sergei Golovan) * msgs/ru.msg: Updated (thanks to Sergei Golovan) * ifacetk/iroster.tcl: Added service_popup_menu_hook (thanks to Sergei Golovan) * ifacetk/ilogin.tcl: Procedure logout_dialog moved to current namespace (thanks to Sergei Golovan) * ifacetk/iface.tcl: Added protocol_wm_delete_window_hook, bugfix (thanks to Sergei Golovan) * utils.tcl: Bugfix (thanks to Sergei Golovan) * userinfo.tcl: Bugfix (thanks to Sergei Golovan) * privacy.tcl: Updated messages (thanks to Sergei Golovan) * custom.tcl: Added interface to add options to radiobutton (thanks to Sergei Golovan) * pixmaps/: Renamed icons (thanks to Sergei Golovan) * browser.tcl: Likewise * disco.tcl: Likewise * splash.tcl: Likewise * ifacetk/iface.tcl: Likewise * ifacetk/iroster.tcl: Likewise * plugins/chat/popupmenu.tcl: Likewise * balloon.tcl: Better balloon placement in the bottom of screen (thanks to Sergei Golovan) * ifacetk/iroster.tcl: Move roster item on drag'n'drop instead of copying if it is dropped in the same roster (thanks to Sergei Golovan) * examples/tools/jsend.tcl: Updated (thanks to Marshall T. Rose) * jabberlib-tclxml/jabberlib.tcl: Added -from argument to jlib::send_msg (thanks to Marshall T. Rose) * jabberlib-tclxml/pkgIndex.tcl: Updated (thanks to Marshall T. Rose) 2004-08-08 Alexey Shchepin * jabberlib-tclxml/jabberlib.tcl: Don't send newline after stanza 2004-08-01 Alexey Shchepin * jabberlib-tclxml/jabberlib.tcl: Support for STARTTLS * login.tcl: Likewise * ifacetk/ilogin.tcl: Likewise 2004-07-23 Alexey Shchepin * doc/tkabber.xml: Updated 2004-07-20 Alexey Shchepin * roster.tcl (roster::get_label): Bugfix 2004-07-17 Alexey Shchepin * msgs/nl.msg: New Dutch translation (thanks to Sander Devrieze) 2004-07-16 Alexey Shchepin * plugins/filetransfer/si.tcl: Added missed function set_receive_file_name (thanks to Sergei Golovan) * jabberlib-tclxml/jabberlib.tcl: Minor fix (thanks to Sergei Golovan) * avatars.tcl: Removed loginconf usage (thanks to Sergei Golovan) * gpgme.tcl: Likewise * ifacetk/iface.tcl: Likewise in call to userinfo::open * privacy.tcl: Fixed some translatable messages * msgs/pl.msg: Updated (thanks to Irek Chmielowiec) 2004-07-10 Alexey Shchepin * plugins/general/tkcon.tcl: Updated label (thanks to Sergei Golovan) * plugins/filetransfer/*.tcl: Added transport enabling option, updated dialogs and menus (thanks to Sergei Golovan) * plugins/chat/popupmenu.tcl: Updated (thanks to Sergei Golovan) * plugins/chat/nick_colors.tcl: Added "Edit nick color" menu item to roster (thanks to Sergei Golovan) * msgs/ru.msg: Updated (thanks to Sergei Golovan) * ifacetk/iroster.tcl: Updated file transfer menu (thanks to Sergei Golovan) * tkabber.tcl: Returned loading of jidlink.tcl (thanks to Sergei Golovan) * si.tcl: Added customization options (thanks to Sergei Golovan) * jidlink.tcl: Removed "Jidlink" menu (thanks to Sergei Golovan) * ifacetk/iface.tcl: Likewise * hooks.tcl: Bugfix (thanks to Sergei Golovan) * filetransfer.tcl: Added "cascaded_menu" option (thanks to Sergei Golovan) * default.tcl: Minor fix (thanks to Sergei Golovan) * chats.tcl: Removed global variable "w" (thanks to Sergei Golovan) * iface.tcl: Likewise * messages.tcl: Likewise 2004-07-06 Alexey Shchepin * msgs/es.msg: Updated (thanks to Badlop) * msgs/ca.msg: Updated (thanks to Badlop) 2004-07-04 Alexey Shchepin * plugins/chat/events.tcl: Don't open window if event notification is received * chats.tcl: Opening of chat window is moved to plugin * plugins/chat/open_window.tcl: New plugin to open chat and groupchat windows * plugins/chat/empty_body.tcl: Changed priority for check_draw_empty_body 2004-07-02 Alexey Shchepin * plugins/filetransfer/si.tcl: Handle element properly * plugins/si/socks5.tcl: Bugfix 2004-07-01 Alexey Shchepin * plugins/si/socks5.tcl: JEP-0065 support * plugins/iq/oob.tcl: Moved to plugins/filetransfer/http.tcl * plugins/chat/irc_commands.tcl: Added /clear command, some commands now works in chat (non-conference) windows (thanks to Sergei Golovan) * msgs/ru.msg: Updated (thanks to Sergei Golovan) * ifacetk/default.xrdb: Updated (thanks to Sergei Golovan) * examples/teopetuk.xrdb: Updated (thanks to Sergei Golovan) * filetransfer.tcl: Moved HTTP, Jidlink and SI stuff to plugins/filetransfer (thanks to Sergei Golovan) * plugins/filetransfer/http.tcl: Likewise * plugins/filetransfer/jidlink.tcl: Likewise * plugins/filetransfer/si.tcl: Likewise * disco.tcl: Better multilogin support (thanks to Sergei Golovan) * jidlink.tcl: Likewise * negotiate.tcl: Likewise * plugins/jidlink/dtcp.tcl: Likewise * plugins/jidlink/ibb.tcl: Likewise * chats.tcl: Updated menu items related to sending files (thanks to Sergei Golovan) * messages.tcl: Likewise * search.tcl: Likewise * ifacetk/iroster.tcl: Likewise 2004-06-24 Alexey Shchepin * chats.tcl: Minor internal change * filetransfer.tcl: Added support for JEP-0096 (not completed: only IBB is supported) * si.tcl: Likewise * plugins/si/ibb.tcl: Likewise * ifacetk/iface.tcl: Fixed call to message::send_subsribe_dialog (thanks to Sergei Golovan) * ifacetk/iroster.tcl: Likewise * jabberlib-tclxml/jabberlib.tcl: Bugfix (thanks to Sergei Golovan) 2004-06-18 Alexey Shchepin * ifacetk/iface.tcl: Support for tabs drag'n'drop (thanks to Sergei Golovan) * (all): Better connid support (thanks to Sergei Golovan) 2004-06-14 Alexey Shchepin * plugins/unix/dockingtray.tcl: Replaced "dock_in_tray" with "dockingtray" (thanks to Sergei Golovan) * plugins/chat/info_commands.tcl: Bugfix (thanks to Sergei Golovan) * plugins/chat/bookmark_highlighted.tcl: Changed behaviour (thanks to Sergei Golovan) * plugins/chat/popupmenu.tcl: Likewise * msgs/ru.msg: Updated (thanks to Sergei Golovan) * ifacetk/iroster.tcl: Bugfix (thanks to Sergei Golovan) * ifacetk/iface.tcl: Second button in toolbar now opens "Discovery" window instead of "Browser" (thanks to Sergei Golovan) 2004-06-10 Alexey Shchepin * plugins/unix/dockingtray.tcl: Added option for plugin disabling (thanks to Sergei Golovan) * jabberlib-tclxml/jabberlib.tcl: Added registration for "https" protocol (thanks to Sergei Golovan) * ifacetk/iface.tcl: Don't count own messages in tab and main window titles (thanks to Sergei Golovan) * ifacetk/iface.tcl: Removed dots from "About" and "Quick help" menu items (thanks to Sergei Golovan) * plugins/unix/dockingtray.tcl: Likewise * plugins/windows/taskbar.tcl: Likewise * msgs/*.msg: Likewise * messages.tcl: Replace newlines to spaces in the headlines tree (thanks to Sergei Golovan) 2004-06-07 Alexey Shchepin * ifacetk/ilogin.tcl: Fixed bindings for C-Prior and C-Next (thanks to Sergei Golovan) 2004-05-11 Alexey Shchepin * msgs/fr.msg: Updated (thanks to Vincent Ricard) 2004-05-09 Alexey Shchepin * examples/tclCarbonNotification-1.0.0/: Package that adds support for "bouncing" the tkabber icon in the MacOS X (thanks to Marshall T. Rose) * examples/mtr-config.tcl: Updated (thanks to Marshall T. Rose) * balloon.tcl: Support for AquaBI (thanks to Marshall T. Rose) * register.tcl: Likewise * search.tcl: Likewise 2004-05-08 Alexey Shchepin * examples/mtr-config.tcl: Updated (thanks to Marshall T. Rose) * ifacetk/iface.tcl: Added "tab_set_updated" hook (thanks to Marshall T. Rose) * msgs/pl.msg: Removed trailing garbage 2004-04-27 Alexey Shchepin * plugins/general/autoaway.tcl: Support for AquaBI (thanks to Marshall T. Rose) * msgs/pl.msg: Updated (thanks to Irek Chmielowiec) 2004-04-23 Alexey Shchepin * (all): Updated to make tkabber run under AquaBI (thanks to Marshall T. Rose) 2004-04-17 Alexey Shchepin * plugins/chat/info_commands.tcl: Cleanup (thanks to Sergei Golovan) * muc.tcl: Display real jid in join message when available (thanks to Sergei Golovan) * jabberlib-tclxml/jabberlib.tcl: Support for "name" attribute in presence stanzas with type "subscribed" (thanks to Sergei Golovan) * messages.tcl: Likewise * roster.tcl: Likewise * messages.tcl: Bugfix with displaying of "Undefined" group in "Edit item" dialog (thanks to Sergei Golovan) * roster.tcl: Likewise * plugins/chat/popupmenu.tcl: Bugfixes (thanks to Sergei Golovan) 2004-04-12 Alexey Shchepin * pixmaps/kroc/: Pixmaps theme from tkabber-starkit * jabberlib-tclxml/jabberlib.tcl: Support for IDNA (RFC3490) * login.tcl: Likewise 2004-04-11 Alexey Shchepin * plugins/chat/bookmark_highlighted.tcl: Bugfix (thanks to Sergei Golovan) * roster.tcl (roster::get_groups): Bugfix (thanks to Sergei Golovan) * plugins/chat/popupmenu.tcl: Moved bookmark image to bookmark.xpm (thanks to Sergei Golovan) * pixmaps/default/tkabber/bookmark.xpm: Likewise * plugins/chat/bookmark_highlighted.tcl: Updated (thanks to Sergei Golovan) * ifacetk/iroster.tcl: Added "Send message to all users in group" menu item (thanks to Sergei Golovan) * roster.tcl: Changed get_groups (thanks to Sergei Golovan) * itemedit.tcl: Likewise * ifacetk/iroster.tcl: Likewise * roster.tcl: Added function get_group_jids (thanks to Sergei Golovan) * messages.tcl: Headlines now stored in utf-8 encoding (thanks to Sergei Golovan) * messages.tcl: Changed syntax of message::send and message::send_dialog (thanks to Sergei Golovan) * search.tcl: Likewise * xmppmime.tcl: Likewise * ifaceck/iroster.tcl: Likewise * ifacetk/iroster.tcl: Likewise * ifacetk/iface.tcl: Likewise * default.tcl: More i18n * chats.tcl: Removed chats(groupchats) variable, added function chat::opened (thanks to Sergei Golovan) * ifacetk/iface.tcl: Likewise * plugins/chat/popupmenu.tcl: Likewise * plugins/chat/nick_colors.tcl: Likewise 2004-04-07 Alexey Shchepin * plugins/chat/popupmenu.tcl: Fixes, added hook (thanks to Sergei Golovan) * plugins/chat/nick_colors.tcl: Added "Edit nick color" context menu to colored nicks, fixes (thanks to Sergei Golovan) * plugins/chat/me_command.tcl: Bugfix (thanks to Sergei Golovan) * plugins/chat/draw_normal_message.tcl: Optimization, changed load priority (thanks to Sergei Golovan) * plugins/chat/bookmark_highlighted.tcl: Support for scrolling to highlighted messages (thanks to Sergei Golovan) * chats.tcl: Support for colored nicks in conference roster (thanks to Sergei Golovan) * ifacetk/iroster.tcl: Likewise * plugins/chat/nick_colors.tcl: Likewise * chats.tcl: Added "Copy URL to clipboard" menu item (thanks to Sergei Golovan) 2004-04-04 Alexey Shchepin * pixmaps/gush/: New pixmaps theme (thanks to Badlop) * pixmaps/amibulb/: Updated (thanks to Badlop) * ifacetk/ilogin.tcl: Minor change (thanks to Badlop) * muc.tcl: More i18n support (thanks to Badlop) * ifacetk/iface.tcl: New option "closebuttonaction" (thanks to Badlop) * examples/badlop-*: Updated (thanks to Badlop) * default.tcl: Added customization option for web browser (thanks to Badlop) 2004-04-03 Alexey Shchepin * ifacetk/iroster.tcl: Customized tearoff displaying in roster menu (thanks to Sergei Golovan and Badlop) * ifacetk/iface.tcl: Bugfix in displaying of star in titlebar (thanks to Sergei Golovan) * ifacetk/idefault.tcl: Changed priority for define_fonts (thanks to Sergei Golovan) * privacy.tcl: Added debugmsgs (thanks to Sergei Golovan) * messages.tcl (message::str2node): Updated to work with latest tcllib (thanks to Sergei Golovan) * custom.tcl: Changed priority of custom::restore (thanks to Sergei Golovan) * chats.tcl: Added "highlight" tag (thanks to Sergei Golovan) * plugins/chat/draw_normal_message.tcl: Likewise * custom.tcl: Fixed custom.tcl path (this change and changes below are adaptations by Sergei Golovan of tkabber-starkit (authors: David Zolli, Steve Redler and Pat Thoyst)) * default.tcl: Updated browseurl * joingrdialog.tcl: Specified -parent and -modal options * muc.tcl: Likewise * presence.tcl: Likewise * tkabber.tcl: Debugging info is now off by default, fixed file paths * examples/gtklook.xrdb: New theme * ifacetk/idefault.tcl: Minor update * ifacetk/iface.tcl: Added option show_presencebar * plugins/chat/nick_colors.tcl: Support for colored messages * plugins/chat/draw_normal_message.tcl: Likewise * plugins/chat/me_command.tcl: Likewise * plugins/chat/logger.tcl: Fixed file path * plugins/chat/popupmenu.tcl: Popup menu for chat windows * plugins/windows/console.tcl: Display console window 2004-03-30 Alexey Shchepin * plugins/chat/logger.tcl (::logger::get_subdirs): Bugfix 2004-03-22 Alexey Shchepin * msgs/pl.msg: Updated (thanks to Irek Chmielowiec) * tkabber.tcl: Added setting of seed for tclx "random" command 2004-03-20 Alexey Shchepin * iface*/iroster.tcl: Added sorting in send users dialog (thanks to Marshall T. Rose) * roster.tcl (roster::get_jids): Likewise 2004-03-16 Alexey Shchepin * msgs/fr.msg: Updated (thanks to Vincent Ricard) * contrib/extract-translations/extract.tcl: Added '-v' option to display useless old keys from translation files (thanks to Vincent Ricard) * plugins/chat/logger.tcl: Don't show months with no history messages, now possible to view entire history, added explicit color definitions in CSS (thanks to Sergei Golovan) * ifacetk/iface.tcl: Added binding for <> (thanks to Sergei Golovan) * utils.tcl: Checkbuttons list now sorted, fixed some bindings (thanks to Sergei Golovan) * messages.tcl: Added "Copy URL to clipboard" command for headlines (thanks to Sergei Golovan) * chats.tcl: Minor change (thanks to Sergei Golovan) 2004-03-12 Alexey Shchepin * plugins/windows/taskbar.tcl: Bugfix (thanks to Roger Sondermann) * plugins/unix/dockingtray.tcl: Likewise 2004-03-11 Alexey Shchepin * ifacetk/iroster.tcl: Fixed group resubscribe (thanks to David Everly) 2004-03-10 Alexey Shchepin * jabberlib-tclxml/jabberlib.tcl: Added check for "http" package version (thanks to Sergei Golovan) * filetransfer.tcl: Fixed check for "http" package version (thanks to Sergei Golovan) * browser.tcl: Don't open window when tkabber is disconnected (thanks to Sergei Golovan) * disco.tcl: Likewise * joingrdialog.tcl: Likewise 2004-03-08 Alexey Shchepin * jabberlib-tclxml/jabberlib.tcl: Bugfix (thanks to Sergei Golovan) * examples/mtr-config.tcl: Updated (thanks to Marshall T. Rose) 2004-03-07 Alexey Shchepin * ifacetk/iface.tcl: Added option for showing/hiding tearoffs (thanks to Badlop) * ifacetk/iface.tcl: Updated toolbar icons changing (thanks to Sergei Golovan) * userinfo.tcl: More compatibility with old versions, fixed regsub usage (thanks to Sergei Golovan) * tkabber.tcl: Now possible to use site-wide config (thanks to Sergei Golovan) * messages.tcl: Updated few messages (thanks to Sergei Golovan) * chats.tcl: Fixed presence sending to conference (thanks to Sergei Golovan) * presence.tcl: Likewise * ifacetk/iroster.tcl: Likewise * roster.tcl: Recognize "weather" in addition to "pogoda" (thanks to Marshall T. Rose) * jabberlib-tclxml/jabberlib.tcl: Added option for passing "to" attribute (thanks to Marshall T. Rose) 2004-03-02 Alexey Shchepin * jabberlib-tclxml/jabberlib.tcl: Fixed handshake processing * plugins/chat/info_commands.tcl: Removed not-evident AI (thanks to Sergei Golovan) * msgs/ru.msg: Updated (thanks to Sergei Golovan) * userinfo.tcl: Text widgets now inside ScrolledWindow, added -page option to userinfo::open, EMAIL tag now processed according to JEP-0054 (thanks to Sergei Golovan) * datagathering.tcl: Slightly updated look of x:data forms (thanks to Sergei Golovan) * muc.tcl: Likewise for affiliation lists * custom.tcl: Added group sorting (thanks to Sergei Golovan) * chats.tcl: Fixed "smart scroll" (thanks to Sergei Golovan) 2004-02-27 Alexey Shchepin * msgs/pl.msg: Updated (thanks to Irek Chmielowiec) 2004-02-26 Alexey Shchepin * ifacetk/bwidget_workarounds.tcl: Disable previous workaround for unix platform 2004-02-25 Alexey Shchepin * msgs/ru.msg: Updated (thanks to Sergei Golovan) * ifacetk/idefault.tcl: Added changing of font "on the fly" for non-unix platforms (thanks to Sergei Golovan) * ifacetk/iface.tcl: Likewise * ifacetk/bwidget_workarounds.tcl: Fixed SelectFont widget (thanks to Sergei Golovan) * utils.tcl: Added "error_type_condition" function (thanks to Sergei Golovan) * privacy.tcl: Updated interface, also added interface to visible/invisible/ignore lists (thanks to Sergei Golovan) * ifacetk/iface.tcl: Updated menu for privacy rules (thanks to Sergei Golovan) * muc.tcl: Updated menu labels (thanks to Sergei Golovan) * login.tcl: Roster getting and first presence sending moved to hooks (thanks to Sergei Golovan) * presence.tcl: Likewise * roster.tcl: Likewise * datagathering.tcl: Removed "xml:lang" attribute (thanks to Sergei Golovan) * disco.tcl: Likewise * muc.tcl: Likewise * register.tcl: Likewise * search.tcl: Likewise * userinfo.tcl: Likewise * plugins/general/conferenceinfo.tcl: Likewise * datagathering.tcl: Better look (thanks to Sergei Golovan) * custom.tcl: Added "font" type for variables (thanks to Sergei Golovan) * chats.tcl: Fixed conference topic changing (thanks to Sergei Golovan) * chats.tcl: Minor update (thanks to Sergei Golovan) * ifaceck/widgets.tcl: Likewise * plugins/general/rawxml.tcl: Likewise * balloon.tcl: Minor change (thanks to Sergei Golovan) 2004-02-17 Alexey Shchepin * pixmaps/amibulb/: New pixmaps theme (thanks to Badlop) * datagathering.tcl: Minor fix * ifaceck/iroster.tcl: Likewise * login.tcl: Likewise * muc.tcl: Likewise * plugins/chat/logger.tcl: Likewise * roster.tcl: Likewise * jabberlib-tclxml/jabberlib.tcl: Fixed error message output (thanks to Sergei Golovan) * muc.tcl: Added history management (thanks to Sergei Golovan) * chats.tcl: "Extended Away" message is replaced with "Extended away" (thanks to Sergei Golovan) * iface.tcl: Likewise * presence.tcl: Likewise * ifaceck/iroster.tcl: Likewise * ifacetk/iroster.tcl: Likewise * chats.tcl: Don't scroll window if message have empty body (thanks to Sergei Golovan) 2004-02-10 Alexey Shchepin * msgs/ru.msg: Updated (thanks to Sergei Golovan) * iface.tcl: Fixed translatable string (thanks to Sergei Golovan) * search.tcl: Likewise * roster.tcl: Fixed get_category_and_subtype and heuristically_get_category_and_subtype (thanks to Sergei Golovan) * gpgme.tcl: Likewise * datagathering.tcl: Fixed sending of ejabberd:config element (thanks to Sergei Golovan) * chats.tcl: Nick change command moved to muc.tcl, fixed error with conference menu (thanks to Sergei Golovan) * muc.tcl: Likewise * plugins/chat/irc_commands.tcl: Likewise 2004-02-08 Alexey Shchepin * msgs/pl.msg: Updated (thanks to Irek Chmielowiec) * plugins/general/rawxml.tcl: Added mandatory "id" attribute to IQ templates * plugins/general/stats.tcl: Added disco feature description (thanks to Sergei Golovan) * plugins/chat/irc_commands.tcl: /part and /leave now close conference window (thanks to Sergei Golovan) * plugins/chat/exec_command.tcl: Cleanup (thanks to Sergei Golovan) * plugins/chat/info_commands.tcl: Likewise * ifacetk/iface.tcl: Added ifacetk::destroy_win function (thanks to Sergei Golovan) * tkabber.tcl: Restored previous loading order (thanks to Sergei Golovan) * datagathering.tcl: Support for ejabberd:config namespace (thanks to Sergei Golovan) * chats.tcl: Open conference window before MUC negotiation (thanks to Sergei Golovan) * joingrdialog.tcl: Likewise * muc.tcl: Likewise * ifacetk/iroster.tcl: Likewise * browser.tcl: Minor update in ns_handler and feature_handler processing (thanks to Sergei Golovan) * disco.tcl: Likewise * pixmaps/jajc/docking/*.gif: New JAJC-like docking icons (thanks to Oleksandr Yakovlyev) 2004-02-04 Alexey Shchepin * plugins/general/autoaway.tcl: Display autoaway options only if tkXwin is available (thanks to Sergei Golovan) * joingrdialog.tcl: Join conference with current presence status (thanks to Sergei Golovan) * muc.tcl: Likewise 2004-02-01 Alexey Shchepin * plugins/windows/taskbar.tcl: Added option for taskbar blinking (thanks to Badlop) * msgs/es.msg: Updated (thanks to Badlop) * msgs/ca.msg: Updated (thanks to Badlop) * examples/badlop-*: Updated (thanks to Badlop) * ifacetk/iface.tcl: Added options for switching of tabbed mode and toolbar displaying (thanks to Badlop) * tkabber.tcl: Slightly changed loading order * ifacetk/iface.tcl (ifacetk::update_chat_titles): Minor fix 2004-01-26 Alexey Shchepin * plugins/chat/irc_commands.tcl: Updated nick changing (thanks to Sergei Golovan) * plugins/chat/draw_message.tcl: Minor update (thanks to Sergei Golovan) * jabberlib-tclxml/jabberlib.tcl: Updated (thanks to Sergei Golovan) * presence.tcl: Removed "-id" processing (thanks to Sergei Golovan) * muc.tcl: Updated processing of nick changing (thanks to Sergei Golovan) * chats.tcl: Updated nick handling (thanks to Sergei Golovan) 2004-01-20 Alexey Shchepin * jabberlib-tclxml/jabberlib.tcl: Bugfix (thanks to Sergei Golovan) 2004-01-19 Alexey Shchepin * plugins/chat/irc_commands.tcl: Fixed nick changing (thanks to Sergei Golovan) * ifacetk/iroster.tcl: Bugfixes (thanks to Sergei Golovan) * jabberlib-tclxml/jabberlib.tcl: Added -command option to presence sending (thanks to Sergei Golovan) * presence.tcl: Likewise * jabberlib-tclxml/jabberlib.tcl: HTTP Polling update (thanks to Sergei Golovan) * chats.tcl: Bugfix (thanks to Sergei Golovan) 2004-01-18 Alexey Shchepin * jabberlib-tclxml/jabberlib.tcl: Function get_lang moved to jabberlib.tcl from utils.tcl, added sending of xml:lang attribute in stream header * utils.tcl: Likewise * plugins/chat/irc_commands.tcl: Minor update (thanks to Sergei Golovan) * login.tcl: Added 2 options for HTTP Polling, bugfix (thanks to Sergei Golovan) * jabberlib-tclxml/jabberlib.tcl: Cleanup, updated error codes, changed connid generation, added HTTP_LOG callback, more options for HTTP Polling (thanks to Sergei Golovan) * tkabber.tcl: Added HTTP_LOG callback * ckabber.tcl: Likewise * ifacetk/iroster.tcl: Bugfix (thanks to Sergei Golovan) * ifacetk/iface.tcl: Bugfix (thanks to Sergei Golovan) * chats.tcl: Added rejoining to conferences on login (thanks to Sergei Golovan) 2004-01-17 Alexey Shchepin * ifacetk/iface.tcl: Copyright update * splash.tcl: Likewise * ifacetk/iroster.tcl: Bugfix (thanks to Sergei Golovan) * ifacetk/ilogin.tcl: Bugfix (thanks to Sergei Golovan) 2004-01-14 Alexey Shchepin * plugins/chat/complete_last_nick.tcl: Minor fix (thanks to Sergei Golovan) * muc.tcl: Fixed /kick command (thanks to Sergei Golovan) * browser.tcl: Updated to latest JEP-0011 (thanks to Sergei Golovan) * plugins/iq/browse.tcl: Likewise * ifacetk/iroster.tcl: Bugfix (thanks to Sergei Golovan) 2004-01-12 Alexey Shchepin * tkabber.tcl: Bugfix 2004-01-11 Alexey Shchepin * login.tcl (client:reconnect): Bugfix * msgs/pt.msg: Updated (thanks to Miguel) 2004-01-08 Alexey Shchepin * chats.tcl: Bugfix 2004-01-07 Alexey Shchepin * plugins/windows/taskbar.tcl: Bugfix (thanks to Irek Chmielowiec) * plugins/unix/dockingtray.tcl: Likewise * browser.tcl: Fixed typos (thanks to Badlop) 2004-01-06 Alexey Shchepin * browser.tcl: Bugfix 2004-01-05 Alexey Shchepin * ifacetk/iroster.tcl: Bugfix 2004-01-04 Alexey Shchepin * pixmaps/*/services/jud.gif: New icons for JUD service (thanks to Sergei Golovan) * jabberlib-tclxml/jabberlib.tcl: Added predisconnected_hook (thanks to Sergei Golovan) * roster.tcl: Interface stuff moved to ifacetk/iroster.tcl (thanks to Sergei Golovan) * ifacetk/iroster.tcl: Likewise, added roster state autosave feature * chats.tcl: Updated roster stuff * messages.tcl: Likewise * search.tcl: Likewise * ifacetk/iface.tcl: Likewise * plugins/unix/wmdock.tcl: Likewise * msgs/pt.msg: Updated (thanks to Miguel) 2004-01-03 Alexey Shchepin * doc/tkabber.xml: Updated (thanks to Badlop) 2003-12-30 Alexey Shchepin * jabberlib-tclxml/jabberlib.tcl: Use poll keys only when http polling is enabled (thanks to Sergei Golovan) * ifacetk/iface.tcl: Bugfixes (thanks to Sergei Golovan) * ifaceck/*: Updated (not completed yet) (thanks to Sergei Golovan) * userinfo.tcl: Fixed tab bindings (thanks to Sergei Golovan) * tkabber.tcl: Minor changes (thanks to Sergei Golovan) * login.tcl: Fixed types for port variables, fixed option for poll security keys (thanks to Sergei Golovan) * ifacetk/ilogin.tcl: Likewise * default.tcl: Some parts moved to ifacetk/ (thanks to Sergei Golovan) * ckabber.tcl: Updated (thanks to Sergei Golovan) * bwidget_workarounds.tcl: Moved to ifacetk/ (thanks to Sergei Golovan) * browser.tcl: Changed packing order (thanks to Sergei Golovan) * disco.tcl: Likewise 2003-12-29 Alexey Shchepin * Makefile: Updated SUBDIRS, removed "*.xrdb" from "cp" * ifacetk/iface.tcl (ifacetk::update_ssl_ind): Bugfix (thanks to Sergei Golovan) 2003-12-28 Alexey Shchepin * muc.tcl (muc::receive_list): Fixed non-translatable string * plugins/unix/dockingtray.tcl: Added check for interface (thanks to Sergei Golovan) * plugins/windows/taskbar.tcl: Likewise * plugins/iq/last.tcl: Added option for reply denying (thanks to Sergei Golovan) * plugins/iq/time.tcl: Likewise * plugins/iq/version.tcl: Likewise * plugins/general/stats.tcl: Added optional arguments to handler (thanks to Sergei Golovan) * plugins/chat/highlight.tcl: Bugfix (thanks to Sergei Golovan) * msgs/ru.msg: Updated (thanks to Sergei Golovan) * ifacetk/*: Interface for Tk (thanks to Sergei Golovan) * ifaceck/*: Interface for Ck (not completed yet) (thanks to Sergei Golovan) * tkabber.tcl: Minor changes (thanks to Sergei Golovan) * roster.tcl: Bugfix, moved updating of "show only online users" button to iface (thanks to Sergei Golovan) * muc.tcl: Added possibility for reporting of current MUC rooms on disco#items query, slightly changed muc::join (thanks to Sergei Golovan) * iq.tcl: Added option for iq request displaying in status line (thanks to Sergei Golovan) * iface.tcl: Most of stuff moved to ifacetk/ (thanks to Sergei Golovan) * login.tcl: Likewise * disco.tcl: Now possible to register nodes, added type "client" (thanks to Sergei Golovan) * default.xrdb: Moved to ifacetk/default.xrdb (thanks to Sergei Golovan) * datagathering.tcl: Added optional arguments to data::request_data (thanks to Sergei Golovan) * ckabber.tcl: Startup file for tkabber with console interface (thanks to Sergei Golovan) * chats.tcl: "chats(messages,$chatid)" and "chats(messagestome,$chatid)" are moved to iface (thanks to Sergei Golovan) * browser.tcl: Few cosmetic changes, added -connection option to browser::open, and -category and -type to for handlers (thanks to Sergei Golovan) * disco.tcl: Likewise * register.tcl: Updated disco and browse handlers * search.tcl: Likewise * userinfo.tcl: Likewise 2003-12-24 Alexey Shchepin * msgs/pl.msg: Updated (thanks to Irek Chmielowiec) 2003-12-23 Alexey Shchepin * plugins/chat/irc_commands.tcl: Plugin for IRC-like commands (/topic, /join, /leave) (thanks to Sergei Golovan) * plugins/chat/nick_command.tcl: Removed * jabberlib-tclxml/jabberlib.tcl: Added two helper functions (thanks to Sergei Golovan) * examples/teopetuk.xrdb: Updated (thanks to Sergei Golovan) * roster.tcl: Updated "roster::addline", now possible to darg'n'drop JIDs not only on group name, fixed bugs with "Undefined" and "Active Chats" groups (thanks to Sergei Golovan) * login.tcl: Changed usage of "loginconf" array (thanks to Sergei Golovan) * joingrdialog.tcl: Added options to "add_group_dialog" (thanks to Sergei Golovan) * iface.tcl: Some parts of tkabber.tcl moved here (thanks to Sergei Golovan) * login.tcl: Likewise * tkabber.tcl: Likewise * datagathering.tcl: Updated mousewheel bindings (thanks to Sergei Golovan) * messages.tcl: Likewise * plugins/general/message_archive.tcl: Likewise * chats.tcl: Removed usage of "loginconf", updated "open_to_user" (thanks to Sergei Golovan) * jabberlib-tclxml/jabberlib.tcl: HTTP poll keys support (thanks to Alexander Timoshenko) * login.tcl: Likewise 2003-12-19 Alexey Shchepin * search.tcl: Bugfix (thanks to Sergei Golovan) * examples/badlop-config.tcl: Updated (thanks to Badlop) 2003-12-18 Alexey Shchepin * doc/tkabber.xml: Updated * examples/badlop-*: Updated (thanks to Badlop) * msgs/es.msg: Updated (thanks to Badlop) * msgs/ca.msg: Updated (thanks to rvalles) * plugins/chat/history.tcl: Added C-n and C-p bindings (thanks to Luis Peralta) 2003-12-13 Alexey Shchepin * bwidget_workarounds.tcl: Workaround for bwidget-1.6 (thanks to Sergei Golovan) * plugins/iq/browse.tcl: Updated to latest JEP-0011 (thanks to Sergei Golovan) * plugins/general/rawxml.tcl: Added headline template (thanks to Sergei Golovan) * msgs/ru.msg: Updated (thanks to Sergei Golovan) * utils.tcl: Fixed get_lang, updated bindscroll (thanks to Sergei Golovan) * search.tcl: Show message if search result is empty (thanks to Sergei Golovan) * register.tcl: Added window destroying (thanks to Sergei Golovan) * muc.tcl: Slightly changed items edit dialog, added mousewheel bindings (thanks to Sergei Golovan) * messages.tcl: Changed customization of options(headlines,multiple) (thanks to Sergei Golovan) * login.tcl: Minor interface changes (thanks to Sergei Golovan) * datagathering.tcl: Added registration in browser (thanks to Sergei Golovan) * custom.tcl: Added "radio" variable type (thanks to Sergei Golovan) * chats.tcl: Default message type now can be specified via customization interface (thanks to Sergei Golovan) * chats.tcl: Removed repeated code (thanks to Sergei Golovan) * gpgme.tcl: Likewise * messages.tcl: Likewise * roster.tcl: Likewise * utils.tcl: Likewise * browser.tcl: Minor changes (thanks to Sergei Golovan) 2003-12-04 Alexey Shchepin * msgs/ca.msg: Updated (thanks to Badlop) * msgs/es.msg: Updated (thanks to Badlop) * examples/badlop-*: Updated (thanks to Badlop) * userinfo.tcl: More i18n support (thanks to Sergei Golovan) * register.tcl: Minor interface changes, more i18n support (thanks to Sergei Golovan) * login.tcl: Login window now not resizeable (thanks to Sergei Golovan) * msgs/ru.msg: Updated (thanks to Sergei Golovan) * messages.tcl: More headlines options (thanks to Sergei Golovan) * custom.tcl: Variables color now customizable via XRDB, cleanup (thanks to Sergei Golovan) * browser.tcl: Bugfix * msgs/pl.msg: Updated (thanks to Irek Chmielowiec) 2003-12-02 Alexey Shchepin * plugins/general/conferenceinfo.tcl: Bugfix (thanks to Sergei Golovan) * msgs/ru.msg: Updated (thanks to Sergei Golovan) * userinfo.tcl: Changed description of namespaces in browser/disco (thanks to Sergei Golovan) * roster.tcl: Disabled displaying of subscription state in roster popup, added definition for error presence icon (thanks to Sergei Golovan) * register.tcl: Minor changes (thanks to Sergei Golovan) * muc.tcl: Function that called from browser/disco now displays group join dialog if called for groupchat service instead of conference room (thanks to Sergei Golovan) * login.tcl: Displaying of SSL certificate warnings now optional, minor update in tls_callback (thanks to Sergei Golovan) * iface.tcl: Simplified window with SSL certificate properties, changed balloon with certificate warnings (thanks to Sergei Golovan) * emoticons.tcl: Added missed handling of "" tag (thanks to Sergei Golovan) * emoticons-tkabber/icondef.xml: Updated (thanks to Sergei Golovan) * disco.tcl: Added "disco#items" handler, added icons for gateway, directory and headline categories (thanks to Sergei Golovan) * datagathering.tcl: Added better titles for registered fields, removed label "Instructions" (thanks to Sergei Golovan) * browser.tcl: Added headline icon (thanks to Sergei Golovan) 2003-11-29 Alexey Shchepin * filetransfer.tcl: Bugfix * aniemoteicons/: Imported modified "anigif" package (thanks to Sergei Golovan) * tkabber.tcl: Added loading of anigif * Makefile: Updated 2003-11-26 Alexey Shchepin * plugins/general/presenceinfo.tcl: Bugfix (thanks to Sergei Golovan) * roster.tcl: Now possible to display subscription in popup balloons, changed displying of conference participants lists (thanks to Sergei Golovan) * messages.tcl: Minor optimization (thanks to Sergei Golovan) * filetransfer.tcl: Assume that file sended using binary encoding, added processing of socket write errors (thanks to Sergei Golovan) * custom.tcl: Bugfix (thanks to Sergei Golovan) * emoticons.tcl: Slightly changed emoticons inserting, added support for latest JEP-0038 (thanks to Sergei Golovan) * chats.tcl: Likewise * emoticons-tkabber/icondef.xml: Updated 2003-11-21 Alexey Shchepin * messages.tcl (message::show_dialog): Bugfix 2003-11-20 Alexey Shchepin * login.tcl: Fixed error on autologin with SSL, added option for CA file, fixed type of loginconf(sslcertfile) option (thanks to Paul Argentoff) 2003-11-17 Alexey Shchepin * plugins/general/presenceinfo.tcl: Fixed regsub usage (thanks to Marshall T. Rose) * jabberlib-tclxml/jabberlib.tcl: Use logging rather that puts to stdout (thanks to Marshall T. Rose) * examples/mtr-config.tcl: Updated (thanks to Marshall T. Rose) * login.tcl: Additional instrumentation added to let users decide what to do when ssl is concerned about the cert (thanks to Marshall T. Rose) * gpgme.tcl: The heuristic used to decide whether to encrypt didn't take into account if we were sending to a groupchat (it would decide to use the key associated with one of the partipants) (thanks to Marshall T. Rose) * gpgme.tcl: There was a race condition with respect to setting ascii armor. In some cases, it was possible to send encrypted data in binary, instead (thanks to Marshall T. Rose) * gpgme.tcl: The balloon help indentation was off for email (thanks to Marshall T. Rose) 2003-11-16 Alexey Shchepin * chats.tcl (chat::open_to_user): Now raise tabs * roster.tcl: Added optional active chats group * chats.tcl (chat::close_window): Added close_chat_post_hook hook 2003-11-12 Alexey Shchepin * login.tcl: New option to make tkabber to retry to connect indefinitely, better message dialog when connect failed (thanks to Jan Hudec) * roster.tcl: Code from roster_nested.tcl moved here, few fixes, added "Show offline users" group menu (thanks to Sergei Golovan) * roster_nested.tcl: Removed (thanks to Sergei Golovan) 2003-11-08 Alexey Shchepin * msgs/pl.msg: Updated (thanks to Irek Chmielowiec) * plugins/chat/highlight.tcl: Plugin for highlighting words in groupchat messages (thanks to Sergei Golovan) * plugins/chat/draw_timestamp.tcl: Another timestamp for delayed messages is introduced (thanks to Sergei Golovan) * msgs/ru.msg: Updated (thanks to Sergei Golovan) * jabberlib-tclxml/jabberlib.tcl: Set status to "Waiting for roster" while requesting roster (thanks to Sergei Golovan) * userinfo.tcl: Bugfix for showing signed presence (thanks to Sergei Golovan) * roster_nested.tcl: Bugfix for incorrect processing of users with multiple resources, new option "Default nested group delimiter" (thanks to Sergei Golovan) * roster.tcl: Showing online users, transport icons, user transport icons now is configurable via Customize interface (thanks to Sergei Golovan) * joingrdialog.tcl: Makes -nick option optional (if it is unspecified, [get_group_nick] is used) (thanks to Sergei Golovan) * hooks.tcl: Bugfix (thanks to Sergei Golovan) * custom.tcl: Bugfix (thanks to Sergei Golovan) 2003-11-07 Alexey Shchepin * login.tcl: Login dialog now have SASL tab when TclSASL is available * jabberlib-tclxml/jabberlib.tcl: Updated SASL authentication 2003-11-06 Alexey Shchepin * plugins/chat/completion.tcl: Bugfix (thanks to Sergei Golovan) 2003-11-04 Alexey Shchepin * presence.tcl: Minor fix (thanks to Sergei Golovan) * msgs/pt.msg: Updated (thanks to Miguel) * plugins/chat/draw_info.tcl: Now info messages have emoticons and clickable URLs (thanks to Sergei Golovan) * plugins/chat/completion.tcl: If after completion at the end of input Return is pressed, then completion suffix is removed from message (thanks to Sergei Golovan) * msgs/ru.msg: Updated (thanks to Sergei Golovan) * msgs/ua.msg: Likewise * roster.tcl: Better indentation in conference popup window (thanks to Sergei Golovan) * utils.tcl: Changed function "check_message" (thanks to Sergei Golovan) * iface.tcl: Updated for new "check_message" function (thanks to Sergei Golovan) * sound.tcl: Likewise * plugins/chat/complete_last_nick.tcl: Likewise * plugins/chat/draw_normal_message.tcl: Likewise * gpgme.tcl: Aligned mail addresses in key description (thanks to Sergei Golovan) * chats.tcl: User status description now displayed in popup window (thanks to Sergei Golovan) * browser.tcl: Tab window renamed to "Browser" instead of "JBrowser" (thanks to Sergei Golovan) 2003-11-01 Alexey Shchepin * msgs/ru.msg: Updated (thanks to Sergei Golovan) * presence.tcl: Now is always present when GPG is enabled, added information about signed presence in popup window (thanks to Sergei Golovan) * gpgme.tcl: Likewise * plugins/general/presenceinfo.tcl: Likewise * chats.tcl: Fixed status displaying in chat windows (thanks to Sergei Golovan) 2003-10-30 Alexey Shchepin * msgs/ua.msg: Updated (thanks to Vladimir N. Velychko) * plugins/chat/complete_last_nick.tcl: Better behaviour (thanks to Sergei Golovan) * msgs/ru.msg: Updated (thanks to Sergei Golovan) * jabberlib-tclxml/jabberlib.tcl: Bugfix (thanks to Sergei Golovan) * browser.tcl: Added error handling (thanks to Sergei Golovan) 2003-10-26 Alexey Shchepin * msgs/ca.msg: Updated (thanks to Ager) * msgs/es.msg: Updated (thanks to Badlop) * examples/badlop-*: Updated (thanks to Badlop) * sounds/psi/: New sound theme (thanks to Badlop) 2003-10-22 Alexey Shchepin * msgs/ru.msg: Updated (thanks to Sergei Golovan) * presence.tcl: Support for changing of presence priority (thanks to Sergei Golovan) * iface.tcl: Likewise * plugins/general/autoaway.tcl: Likewise 2003-10-20 Alexey Shchepin * msgs/ru.msg: Updated (thanks to Sergei Golovan) * messages.tcl: Updated headline forwarding (thanks to Sergei Golovan) * login.tcl: Slightly changed interface, added bindings for C-PgUp and C-PgDown (thanks to Sergei Golovan) 2003-10-19 Alexey Shchepin * plugins/iq/version.tcl: Added support for PLD Linux * messages.tcl: Added history for message destinations * tkabber.tcl: Added command line options -chat, -message and -conference * xmppmime.tcl: Bugfix 2003-10-17 Alexey Shchepin * tkabber.tcl: Added support for command line options -user, -password, -resource, -port and -autologin 2003-10-15 Alexey Shchepin * plugins/iq/version.tcl (guess_linux_distribution): Added support for ASPLinux (thanks to Alexandr Kanevskiy) 2003-10-13 Alexey Shchepin * browser.tcl: Removed Conference-v2 support * chats.tcl: Likewise * joingrdialog.tcl: Likewise * plugins/chat/nick_command.tcl: Likewise * iface.tcl: Minor change (thanks to Sergei Golovan) * login.tcl: Added support for HTTP Polling (JEP-0025) (thanks to Sergei Golovan) * jabberlib-tclxml/jabberlib.tcl: Likewise * plugins/general/httpconn.tcl: Obsoleted * joingrdialog.tcl (ecursor_entry): Removed selection on FocusIn event (thanks to Sergei Golovan) * utils.tcl: Added Spinbox function (thanks to Sergei Golovan) * custom.tcl: Now uses Spinbox function (thanks to Sergei Golovan) * bwidget_workarounds.tcl: Now selected tree items can be copied via X selection (or clipboard on Windows) (thanks to Sergei Golovan) * messages.tcl: Likewise 2003-10-12 Alexey Shchepin * msgs/pt.msg: Updated (thanks to Miguel) * msgs/de.msg: Updated (thanks to Stephan Dietl) * roster.tcl (roster::send_users): Replaced "jabber:" with "xmpp:" (thanks to Sergei Golovan) * plugins/chat/info_commands.tcl: Fixed typos (thanks to Sergei Golovan) * msgs/ru.msg: Fixed typos (thanks to Sergei Golovan) 2003-10-08 Alexey Shchepin * msgs/eu.msg: New basque translation (thanks to Ibon Irijoa) 2003-10-07 Alexey Shchepin * plugins/chat/info_commands.tcl: Better behaviour (thanks to Sergei Golovan) * plugins/chat/logger.tcl: Fixed behaviour on resizing window (thanks to Sergei Golovan) * plugins/iq/version.tcl: Now tries to guess linux distribution (thanks to Sergei Golovan) 2003-10-04 Alexey Shchepin * jabberlib-tclxml/jabberlib.tcl (jlib::sasl_callback): Now convert values to utf-8 2003-10-03 Alexey Shchepin * chats.tcl: Added option for enabling/disabling of displaying of user status description in chat windows 2003-10-01 Alexey Shchepin * examples/badlop-*: New config example (thanks to Badlop) * msgs/es.msg: Updated (thanks to Badlop) * userinfo.tcl: Slightly changed behaviour in edit photo tab (thanks to Sergei Golovan) * messages.tcl: Bugfix (thanks to Sergei Golovan) 2003-09-27 Alexey Shchepin * msgs/pl.msg: Updated (thanks to Irek Chmielowiec) * msgs/pl.rc: Likewise * pixmaps/default/services/(gg|weather)_*.gif: New icons for Gadu-Gadu and WeatherAgent (thanks to Irek Chmielowiec) * browser.tcl: Likewise * disco.tcl: Likewise * roster.tcl: Likewise * messages.tcl: Fixed X selection in headlines window (thanks to Sergei Golovan) * doc/tkabber.xml: Added note about winico (thanks to Sergei Golovan) 2003-09-24 Alexey Shchepin * jabberlib-tclxml/jabberlib.tcl: Wait for features element before session initiation * msgs/pt.msg: New portuguese translation (thanks to Miguel) 2003-09-20 Alexey Shchepin * pixmaps/gnome/*/*.(gif|xpm): Updated (thanks to Sergei Golovan) * pixmaps/default/browser/glade-message.gif: Updated (thanks to Sergei Golovan) * examples/*.xrdb: Updated (thanks to Sergei Golovan) * msgs/ru.msg: Updated (thanks to Sergei Golovan) * messages.tcl: Various enhancements (thanks to Sergei Golovan) * itemedit.tcl: Fixed case when nick in vCard is emtpy (thanks to Sergei Golovan) * tkabber.tcl: Minor change in loading order (thanks to Sergei Golovan) * default.tcl: Configuring of bold and italic fonts moved here (thanks to Sergei Golovan) * chats.tcl: Likewise * bwidget_workarounds.tcl: Added bindings for C-button1 to select subtree (thanks to Sergei Golovan) * balloon.tcl: Added options -aspect and -width for balloon window (thanks to Sergei Golovan) * messages.tcl (message::show_subscribe_dialog): Bugfix (thanks to Sergei Golovan) 2003-09-18 Alexey Shchepin * presence.tcl (clear_presence_info): Bugfix * chats.tcl: Show status description in chat windows (thanks to Jacek Konieczny) * jabberlib-tclxml/jabberlib.tcl: Fixed tag name in session request (thanks to Jacek Konieczny) * presence.tcl: Don't send status if user didn't enter custom status (thanks to Jacek Konieczny) * roster.tcl: Send presence subscribe when adding user to roster (thanks to Sergei Golovan) * messages.tcl: Fixed bug that appear on Return key press in headlines window (thanks to Sergei Golovan) * itemedit.tcl: Lookup vCard for nick (thanks to Sergei Golovan) * iface.tcl: Interval between tkabber gets focus and redraws tab title now customizable (thanks to Sergei Golovan) * chats.tcl: Minor fix (thanks to Sergei Golovan) * bwidget_workarounds.tcl: Fixed bug with key scrolling in Tree widget (thanks to Sergei Golovan) * jabberlib-tclxml/jabberlib.tcl: Processing of "roster push" according to XMPP-IM (thanks to Sergei Golovan) 2003-09-09 Alexey Shchepin * examples/mtr-config.tcl: Updated (thanks to Marshall T. Rose) * jabberlib-tclxml/jabberlib.tcl: Updated version number (thanks to Marshall T. Rose) * xmppmime.tcl: Likewise * jabberlib-tclxml/pkgIndex.tcl: Likewise * plugins/general/rawxml.tcl: Now don't scroll text when scrollbar is not in lower position (thanks to Sergei Golovan) * jabberlib-tclxml/jabberlib.tcl: Fixed some typos, updated error list (thanks to Sergei Golovan) * plugins/general/message_archive.tcl: Fixed typo (thanks to Sergei Golovan) * roster.tcl (roster::addline): Bugfix (thanks to Sergei Golovan) 2003-09-06 Alexey Shchepin * msgs/ru.msg: Updated (thanks to Sergei Golovan) * jabberlib-tclxml/jabberlib.tcl: Support for JEP-0078 (thanks to Sergei Golovan) * iface.tcl: Likewise * login.tcl: Likewise 2003-09-01 Alexey Shchepin * plugins/general/rawxml.tcl: Added "clear" button (thanks to Dendik N.F.) 2003-08-21 Alexey Shchepin * msgs/ru.msg: Updated (thanks to Sergei Golovan) * chats.tcl: Fixed scrolling when "smart scroll" option enabled (thanks to Sergei Golovan) * plugins/chat/info_commands.tcl: More powrful and customizable /vcard command (thanks to Sergei Golovan) * custom.tcl: Added option type "list" (thanks to Sergei Golovan) 2003-08-20 Alexey Shchepin * msgs/pl.msg: Updated (thanks to Irek Chmielowiec) * msgs/pl.rc: Likewise * msgs/pl.msg: Now really commited (sorry) (thanks to Irek Chmielowiec) * msgs/pl.rc: Likewise 2003-08-18 Alexey Shchepin * privacy.tcl: Allow to edit list if error occured while receiving list from server 2003-08-16 Alexey Shchepin * userinfo.tcl: Fixed emphasizing (thanks to Sergei Golovan) * messages.tcl: Likewise * plugins/general/message_archive.tcl: Likewise * examples/mtr-config.tcl: Updated (thanks to Marshall T. Rose) 2003-08-15 Alexey Shchepin * plugins/chat/logger.tcl: Bugfixes 2003-08-13 Alexey Shchepin * roster.tcl (roster::draginitcmd): Bugfix (thanks to Michail Litvak) * plugins/chat/logger.tcl: History now separated by months. Added "export to XHTML" feature 2003-08-12 Alexey Shchepin * plugins/chat/info_commands.tcl: Added /vcard command, better handling of other commands (thanks to Sergei Golovan) * plugins/chat/draw_info.tcl: Plugin for drawing "info" messages inside chat windows (thanks to Sergei Golovan) * chats.tcl: Added XRDB resource for "info" message (thanks to Sergei Golovan) * info.tcl: Added level for "info" messages in alert_lvls (thanks to Sergei Golovan) * muc.tcl: Changed type for "whois" message to info (thanks to Sergei Golovan) * plugins/chat/history.tcl: Changed hook priority to better insert commands in history (thanks to Sergei Golovan) * plugins/chat/exec_command.tcl: Likewise * plugins/chat/info_commands.tcl: Likewise 2003-08-07 Alexey Shchepin * chats.tcl (chat::change_presence): Fixed bug with presence processing of users without resources (like ICQ contacts) * plugins/chat/info_commands.tcl: New plugin for /time, /last and /version (thanks to Sergei Golovan) 2003-08-04 Alexey Shchepin * msgs/ru.msg: Updated (thanks to Sergei Golovan) * iface.tcl: Workaround for processing of elided text regions for x-selection, various minor changes (thanks to Sergei Golovan) * gpgme.tcl: Change cursor for GPG label (thanks to Sergei Golovan) * **/*.xrdb: Updated (thanks to Sergei Golovan) * chats.tcl: Now possible to switch emphasizing (thanks to Sergei Golovan) * browser.tcl: Minor changes (thanks to Sergei Golovan) * sound.tcl: Likewise * splash: Likewise 2003-08-03 Alexey Shchepin * privacy.tcl: Partially updated to latest XMPP-IM 2003-07-31 Alexey Shchepin * roster_nested.tcl: Bugfix * examples/tools/jsend.tcl: Now able to do groupchat (thanks to Marshall T. Rose) * examples/mtr-config.tcl: Updated (thanks to Marshall T. Rose) * examples/*.xrdb: Added colors for gpg label (thanks to Sergei Golovan) * gpgme.tcl: Changed format of popup balloon to better look with proportionally-spaced fonts (thanks to Sergei Golovan) 2003-07-28 Alexey Shchepin * plugins/unix/dockingtray.tcl (dockingtray::load): Fixed absence of ::msgscat::mc in Presence menu * msgs/pl.msg: New polish translation (thanks to Irek Chmielowiec) * msgs/pl.rc: Likewise * msgs/ro.msg: Updated (thanks to Adrian Rapa) 2003-07-24 Alexey Shchepin * msgs/ro.msg: Updated (thanks to Adrian Rapa) 2003-07-22 Alexey Shchepin * examples/mtr-config.tcl: Updated (thanks to Marshall T. Rose) 2003-07-21 Alexey Shchepin * presence.tcl (clear_presence_info): Added clearing of missed presence array elements * muc.tcl (muc::process_unavailable): Process unavailable status 2003-07-19 Alexey Shchepin * chats.tcl: Slightly better emphasizing * custom.tcl (custom::defvar): Added -command menu for tracing variable 2003-07-15 Alexey Shchepin * bwidget_workarounds.tcl: Fixed calls to "eval" * gpgme.tcl: Show info when mouse over "signed" icon (thanks to Marshall T. Rose) * plugins/chat/draw_signed.tcl: Likewise 2003-07-14 Alexey Shchepin * msgs/fr.msg: Updated (thanks to Vincent Ricard) * contrib/extract-translations/extract.tcl: Updated (thanks to Vincent Ricard) * iface.tcl: Added SSL sertificate properties window, fixed race condition in SSL indicator processing (thanks to Sergei Golovan) 2003-07-11 Alexey Shchepin * utils.tcl (check_message): New function for checking that message addressed directly to user (thanks to Sergei Golovan) * plugins/chat/draw_normal_message.tcl: Use check_message (thanks to Sergei Golovan) * sound.tcl: Likewise * iface.tcl: Likewise 2003-07-10 Alexey Shchepin * login.tcl (client:reconnect): Fixed * jabberlib-tclxml/jabberlib.tcl: Better connid choosing * login.tcl (login): Pass username to jlib::connect * jabberlib-tclxml/jabberlib.tcl: Fixed usage of parse_end variable 2003-07-09 Alexey Shchepin * plugins/chat/draw_normal_message.tcl: Fixed regexp * iface.tcl: Added option for customizing displaying of number of unreaded messages in tab titles (thanks to Sergei Golovan) * datagathering.tcl: Added "wm iconname" command (thanks to Sergei Golovan) * plugins/chat/logger.tcl: Likewise * iface.tcl: Likewise * login.tcl: Likewise * messages.tcl: Likewise * muc.tcl: Likewise * register.tcl: Likewise * search.tcl: Likewise * userinfo.tcl: Likewise 2003-07-07 Alexey Shchepin * muc.tcl: Fixed MUC commands (/whois, /kick, /ban, etc...) * plugins/unix/wmdock.tcl: Fixed (thanks to Michail Litvak) * plugins/general/rawxml.tcl: Added "templates" button 2003-07-05 Alexey Shchepin * iface.tcl: Fixed SSL indicator, added displaying of amount of unreaded messages in tabs (thanks to Sergei Golovan) * chats.tcl: Likewise * login.tcl: Likewise * default.xrdb: Changed some colors (thanks to Sergei Golovan) * roster.tcl: Likewise * browser.tcl: Likewise * disco.tcl: Likewise * search.tcl: Bugfix, now works correctly with bwidget-1.6 (thanks to Sergei Golovan) 2003-07-04 Alexey Shchepin * jabberlib-tclxml/tclxml/tclparser-8.1.tcl: CR LF replaced to LF 2003-07-03 Alexey Shchepin * plugins/chat/draw_xhtml_message.tcl: Added support for
    ,
      ,
    1. , and
       tags
      
      	* jabberlib-tclxml/jabberlib.tcl: Fix in out_keepalive (thanks to
      	Sergei Golovan)
      
      	* plugins/chat/draw_normal_message.tcl: Highlight "2mynick:"
      	(thanks to Sergei Golovan)
      
      	* sound.tcl: New option "notify_online", fixed processing of
      	groupchat server messages, message that begins with "2mynick:"
      	also considered as addressed to user (thanks to Sergei Golovan)
      
      	* jabberlib-tclxml/: Fixed loading of tclxml (thanks to Sergei
      	Golovan)
      
      	* chats.tcl (chat::is_our_jid): Minor cleanup
      
      	* plugins/chat/nick_command.tcl: Bugfix
      
      	* jabberlib-tclxml/jabberlib.tcl: Fixed remote roster modification
      	bug
      
      2003-07-02  Alexey Shchepin  
      
      	* plugins/chat/draw_xhtml_message.tcl: XHTML support (JEP-0071)
      	(not completed yet: no lists, most of style properties not
      	supported), disabled by default
      
      	* plugins/general/rawxml.tcl (rawxml::send_xml): Minor fix
      
      	* msgs/es.msg: Updated (thanks to Luis Peralta)
      	* msgs/ca.msg: Likewise
      
      2003-06-30  Alexey Shchepin  
      
      	* disco.tcl: Dragging from disco now works
      
      	* jabberlib-tclxml/jabberlib.tcl: Fixes in disconnection
      	processing
      
      	* jabberlib-tclxml/jabberlib.tcl (jlib::error_to_list): Small fix
      
      	* muc.tcl: Better support for multiple logins
      
      	* iface.tcl: Removed default placement of main window
      
      2003-06-29  Alexey Shchepin  
      
      	* jabberlib-tclxml/jabberlib.tcl: Updated error codes to confirm
      	latest xmpp-core (thanks to Sergei Golovan)
      	* avatars.tcl: Likewise
      	* filetransfer.tcl: Likewise
      	* iq.tcl: Likewise
      	* negotiate.tcl: Likewise
      	* utils.tcl: Likewise
      	* plugins/general/conferenceinfo.tcl: Likewise
      	* plugins/iq/last.tcl: Likewise
      
      	* roster.tcl: Updated roster import/export
      
      2003-06-28  Alexey Shchepin  
      
      	* doc/tkabber.xml: Fix in installation section
      
      2003-06-27  Alexey Shchepin  
      
      	* roster_nested.tcl: Works again
      
      	* iface.tcl: Better X-selection support (thanks to Sergei Golovan)
      
      	* chats.tcl (chat::close_window): Minor fix
      	* chats.tcl (chat::open_window): Likewise
      
      	* presence.tcl (client:presence): Remember unavailable status for
      	users
      
      	* muc.tcl (muc::join): Fixed typo
      
      2003-06-26  Alexey Shchepin  
      
      	* plugins/iq/last.tcl: New plugins for replying on iq:last queries
      	(thanks to Sergei Golovan)
      
      	* plugins/general/autoaway.tcl: Variable "idle_command" is now
      	global (thanks to Sergei Golovan)
      
      	* jabberlib-tclxml/jabberlib.tcl: Added functions for creating
      	error elements (thanks to Sergei Golovan)
      
      	* presence.tcl (client:presence): Cleanups
      
      	* presence.tcl (check_signature): Fixed
      
      	* gpgme.tcl (ssj::encrypted:output): Fixed
      
      	* plugins/general/conferenceinfo.tcl: Fixed
      
      	* examples/mtr-config.tcl: Updated (thanks to Marshall T. Rose)
      
      	* jabberlib-tclxml/jabberlib.tcl: Updated version (thanks to
      	Marshall T. Rose)
      
      2003-06-25  Alexey Shchepin  
      
      	* chats.tcl: Invitations fixes
      
      	* presence.tcl (clear_presence_info): Fixed
      
      	* roster.tcl: Fixed contacts sending dialog
      
      2003-06-24  Alexey Shchepin  
      
      	* (all): More multi-logins support and fixes.  Now most of
      	features should work
      
      2003-06-23  Alexey Shchepin  
      
      	* (all): More multi-logins support and fixes
      
      2003-06-22  Alexey Shchepin  
      
      	* (all): More multi-logins support, many things works again
      
      2003-06-21  Alexey Shchepin  
      
      	* (all): More multi-logins support.  Not completed yet, many
      	things are broken, better to use 0.9.5beta until it will be
      	completed
      
      	* default.xrdb: Changed default font
      
      2003-06-19  Alexey Shchepin  
      
      	* roster.tcl: More support for multiple logins
      	* presence.tcl: Likewise
      
      	* chats.tcl: Fixed bug with jid with spaces in invitation code
      
      	* jabberlib-tclxml/jabberlib.tcl: Pass connid to client:presence
      
      2003-06-18  Alexey Shchepin  
      
      	* presence.tcl (get_jid_of_user): Performance improvements
      
      	* roster.tcl (roster::find_jid): Performance improvements
      
      	* roster.tcl: Fixed collapsed groups handling
      	* roster_nested.tcl: Likewise
      
      2003-06-17  Alexey Shchepin  
      
      	* roster_nested.tcl: Updated to work with multiple connections
      
      	* roster.tcl: roster::group_doubleclick renamed to
      	roster::group_click
      
      	* contrib/extract-translations/extract.tcl: Useful tool to find
      	untranslated messages (thanks to Vincent Ricard)
      
      2003-06-16  Alexey Shchepin  
      
      	* examples/mtr-config.tcl: Updated (thanks to Marshall T. Rose)
      
      	* chats.tcl: Updated invitation to conferences (thanks to Sergei
      	Golovan)
      	* messages.tcl: Likewise
      	* muc.tcl: Likewise
      	* roster.tcl: Likewise
      	* msgs/ru.msg: Updated (thanks to Sergei Golovan)
      
      	* chats.tcl: Don't include  inside subject changing
      	messages and properly display such messages (thanks to Sergei
      	Golovan)
      	* msgs/ru.msg: Updated (thanks to Sergei Golovan)
      
      	* (all): Basic support for several simultaneous logins (not fully
      	completed yet)
      
      2003-06-08  Alexey Shchepin  
      
      	* filetransfer.tcl: Enhancements in file transfer (thanks to
      	Sergei Golovan)
      
      2003-06-07  Alexey Shchepin  
      
      	* iface.tcl: Added SSL indicator (thanks to Sergei Golovan)
      	* login.tcl: Likewise
      	* msgs/ru.msg: Updated (thanks to Sergei Golovan)
      
      	* messages.tcl: Changed handling of x:data
      
      	* doc/tkabber.xml: Updated
      
      	* jabberlib-tclxml/jabberlib.tcl: SASL support updated to
      	xmpp-core-13
      
      2003-06-04  Alexey Shchepin  
      
      	* sound.tcl (sound::play): Fixed starting of external play program
      	(thanks to Michail Litvak)
      
      	* search.tcl: Change mouse cursor when waiting for results (thanks
      	to Sergei Golovan)
      
      	* utils.tcl: New function "bindscroll" to add mousewheel bindings
      	to windows (thanks to Sergei Golovan)
      	* chats.tcl: Now uses "bindscroll" (thanks to Sergei Golovan)
      	* gpgme.tcl: Likewise
      	* roster.tcl: Likewise
      
      2003-06-03  Alexey Shchepin  
      
      	* msgs/fr.msg: Updated (thanks to Vincent Ricard)
      
      2003-06-02  Alexey Shchepin  
      
      	* msgs/fr.msg: Updated (thanks to Vincent Ricard)
      
      2003-06-01  Alexey Shchepin  
      
      	* joingrdialog.tcl: Added options to "join_group_dialog" function
      	(thanks to Sergei Golovan)
      	* roster.tcl: Use new interface to "join_group_dialog" (thanks to
      	Sergei Golovan)
      	* browser.tcl: Likewise
      
      	* sound.tcl: Added option for setting parameters for external play
      	program (thanks to Michail Litvak)
      
      2003-05-31  Alexey Shchepin  
      
      	* jabberlib-tclxml/jabberlib.tcl: Updated SASL namespace
      
      2003-05-30  Alexey Shchepin  
      
      	* userinfo.tcl: Now  inside description text widget works
      	correctly
      
      2003-05-29  Alexey Shchepin  
      
      	* userinfo.tcl: Added descriptions to disco features
      
      	* disco.tcl (disco::browser::add_line): Reconfigure item if
      	description was changed
      
      	* plugins/chat/completion.tcl: Now completions can work in private
      	chats
      
      2003-05-24  Alexey Shchepin  
      
      	* datagathering.tcl: Now possible to set x:data windows geometry
      	via XRDB (using XData.geometry)
      
      2003-05-23  Alexey Shchepin  
      
      	* chats.tcl: Support for chat messages emphasize (e.g. *bold*,
      	/slanted/, _underlined_) (thanks to Vincent Ricard)
      
      2003-05-22  Alexey Shchepin  
      
      	* roster.tcl (roster::process_item): Bugfix for previous bugfix
      
      2003-05-21  Alexey Shchepin  
      
      	* roster.tcl: Fixed bug with roster icons (thanks to Tomas
      	Ebenlendr)
      
      	* tkabber.tcl: Removed superfluous jabberlib loading
      
      2003-05-20  Alexey Shchepin  
      
      	* xmppmime.tcl: Support for JEP-0081 (XMPP/Jabber MIME Type) (not
      	well tested yet)
      	* tkabber.tcl: Support for "-mime file" option for loading of mime
      	file
      
      2003-05-18  Alexey Shchepin  
      
      	* roster_nested.tcl: Support for nested roster groups (JEP-0083)
      	(currently only "::" separator supported)
      	* roster.tcl: Likewise
      
      2003-05-17  Alexey Shchepin  
      
      	* msgs/ru.msg: Updated (thanks to Sergei Golovan)
      
      	* disco.tcl: Added registration of disco namespaces in browser
      	(thanks to Sergei Golovan)
      	* muc.tcl: Likewise for conferences
      	* register.tcl: Likewise for jabber:iq:register
      	* search.tcl: Likewise for jabber:iq:search
      	* userinfo.tcl: Likewise for vcard-temp, iq:time, iq:last and
      	iq:version
      
      	* browser.tcl: Added interface to register functions for browser
      	namespaces (thanks to Sergei Golovan)
      
      2003-05-15  Alexey Shchepin  
      
      	* muc.tcl: Added registration of MUC disco feature
      
      	* disco.tcl: Changed register_feature_handler interface, added
      	description of features
      	* plugins/general/stats.tcl: Updated
      	* datagathering.tcl: Likewise
      
      2003-05-14  Alexey Shchepin  
      
      	* plugins/chat/events.tcl: Added translations for events
      	* msgs/ru.msg: Likewise
      
      	* chats.tcl: Added translations for room roster groups
      	* msgs/ru.msg: Likewise
      
      2003-05-13  Alexey Shchepin  
      
      	* msgs/es.msg: Updated (thanks to Luis Peralta)
      	* msgs/ca.msg: Likewise
      
      2003-05-12  Alexey Shchepin  
      
      	* utils.tcl: Updated error list, added function error_to_list
      	(thanks to Sergei Golovan)
      
      	* msgs/*.msg: Updated (thanks to Sergei Golovan)
      
      	* plugins/general/conferenceinfo.tcl: Support for discovering
      	(thanks to Sergei Golovan)
      
      	* iface.tcl: More translations (thanks to Sergei Golovan)
      	* plugins/chat/logger.tcl: Likewise
      	* plugins/general/stats.tcl: Likewise
      
      2003-05-11  Alexey Shchepin  
      
      	* login.tcl: Slightly changed behaviour (thanks to Sergei Golovan)
      
      	* joingrdialog.tcl: Updated history processing (thanks to Sergei
      	Golovan)
      
      	* browser.tcl: Added history to entries (thanks to Sergei Golovan)
      	* disco.tcl: Likewise
      	* userinfo.tcl: Likewise
      
      	* bwidget_workarounds.tcl: Fixed behaviour for non-unix systems
      	(thanks to Sergei Golovan)
      
      	* examples/*.xrdb: Updated (thanks to Sergei Golovan)
      
      2003-05-10  Alexey Shchepin  
      
      	* plugins/general/conferenceinfo.tcl: Use error_to_string to show
      	error
      
      2003-05-09  Alexey Shchepin  
      
      	* joingrdialog.tcl: Entries replaced with combo boxes with
      	history (thanks to Sergei Golovan)
      
      	* custom.tcl: Added support for hidden groups (thanks to Sergei
      	Golovan)
      
      	* bwidget_workarounds.tcl: Fixed support of -highlightthickness in
      	ComboBox (thanks to Sergei Golovan)
      
      	* examples/*.xrdb: Updated (thanks to Sergei Golovan)
      	* default.xrdb: Likewise
      
      	* userinfo.tcl: Open user info window on pressing on iq:time,
      	iq:last and iq:version features in disco window
      
      2003-05-06  Alexey Shchepin  
      
      	* chats.tcl: Update tab titles on roster events (thanks to Sergei
      	Golovan)
      	* roster.tcl: Likewise
      	* iface.tcl: Likewise
      
      	* examples/*.xrdb: Updated (thanks to Sergei Golovan)
      
      	* examples/dark2.xrdb: New theme (thanks to Sergei Golovan)
      
      	* balloon.tcl: Fixed balloon positioning (thanks to Sergei
      	Golovan)
      
      	* pixmaps/default/tkabber/mainlogo.gif: Better look on dark
      	background (thanks to Sergei Golovan)
      
      2003-05-03  Alexey Shchepin  
      
      	* plugins/chat/events.tcl (events::process_x_event): Bugfix with
      	sending of unneeded event when message haven't 
      	element
      
      2003-05-02  Alexey Shchepin  
      
      	* login.tcl: Request roster before sending first presence
      
      	* plugins/unix/dockingtray.tcl: Add "Quit" and "Log out with
      	reason..." menu to tray menu (thanks to Roger Sondermann)
      	* plugins/windows/taskbar.tcl: Likewise
      
      2003-05-01  Alexey Shchepin  
      
      	* avatars.tcl: Bugfix
      
      2003-04-28  Alexey Shchepin  
      
      	* chats.tcl: Added recognizing of https:// in URL regexp
      
      2003-04-17  Alexey Shchepin  
      
      	* register.tcl: Handle error reply
      
      2003-04-16  Alexey Shchepin  
      
      	* plugins/chat/draw_timestamp.tcl: Timestamp format now
      	customizable
      
      	* custom.tcl: Append subgroups in the end of the list
      
      	* plugins/chat/logger.tcl: Path to logs directory now
      	customizable, added options for disabling private and group chats
      
      2003-04-15  Alexey Shchepin  
      
      	* doc/tkabber.html: Updated
      
      2003-04-14  Alexey Shchepin  
      
      	* filters.tcl: Filters dialog creation moved to filters::recv,
      	added handling of error result
      
      2003-04-13  Alexey Shchepin  
      
      	* filters.tcl: Workaround for bug with filters dialog (it not
      	appears if ".filters draw" is called from procedure filters::recv,
      	dunno why)
      
      2003-04-10  Alexey Shchepin  
      
      	* examples/mtr-config.tcl: Updated (thanks to Marshall T. Rose)
      
      	* plugins/general/conferenceinfo.tcl: Bugfix for processing of
      	browse reply (thanks to Sergei Golovan)
      
      	* custom.tcl: Replaced "puts" with "debugmsg" (thanks to Sergei
      	Golovan)
      
      2003-04-07  Alexey Shchepin  
      
      	* tkabber.tcl (quit): Workaround for bug with "wish" which not
      	always exit (thanks to Tomas Ebenlendr)
      
      	* plugins/general/httpconn.tcl: HTTP Polling (JEP-0025) support
      	(thanks to Tomas Ebenlendr)
      
      	* pixmaps/gabber/docking/*: New docking icons for Gabber theme
      	(thanks to Roger Sondermann)
      
      	* utils.tcl: Changed stanza error namespace name due to last XMPP
      	Core changes
      
      2003-04-06  Alexey Shchepin  
      
      	* sound.tcl: Now possible to mute sound for delayed messages
      	(thanks to Denis Shaposhnikov and Sergei Golovan)
      
      	* plugins/iq/time.tcl: Workaround for Tcl bug on windows (thanks
      	to Sergei Golovan)
      
      	* chats.tcl: Autoscroll bugfix (thanks to Sergei Golovan)
      
      2003-03-27  Alexey Shchepin  
      
      	* muc.tcl (muc::request_destruction): Fixed typo
      	* muc.tcl (muc::process_gc_user): Likewise
      
      	* muc.tcl (muc::request_config): Add xml:lang attribute in config
      	request
      
      	* filetransfer.tcl: Default dir for downloaded file now
      	customizable (thanks to Vincent Ricard)
      
      2003-03-26  Alexey Shchepin  
      
      	* doc/tkabber.xml: Updated link to TclWinidle
      
      	* muc.tcl: muc::options(gen_events) now can be changed via
      	customization interface (thanks to Sergei Golovan)
      
      	* chats.tcl: Added more smart autoscroll and more customization
      	options (thanks to Sergei Golovan)
      	* iface.tcl: Menu item for "smart autoscroll" (thanks to Sergei
      	Golovan)
      
      	* plugins/chat/history.tcl: More correct cursor positioning
      	(thanks to Sergei Golovan)
      
      2003-03-25  Alexey Shchepin  
      
      	* examples/tkabber_setstatus: Script to set tkabber status (thanks
      	to Sergei Golovan)
      
      	* examples/tools/rssbot.tcl: Fix roster out-of-sync bug (thanks to
      	Marshall T. Rose)
      
      	* examples/mtr-config.tcl: Updated (thanks to Marshall T. Rose)
      
      	* chats.tcl (chat::open_window): Removed size limitations in
      	panned windows
      
      2003-03-23  Alexey Shchepin  
      
      	* chats.tcl (chat::process_message): Now use "error_to_string"
      	function for error processing
      
      	* jabberlib-tclxml/jabberlib.tcl: Support for parsing new-style
      	message errors
      
      2003-03-21  Alexey Shchepin  
      
      	* jabberlib-tclxml/jabberlib.tcl: Support for writing accept
      	components (thanks to Marshall T. Rose)
      
      	* examples/tools/jsend.tcl: Updated (thanks to Marshall T. Rose)
      
      	* examples/mtr-config.tcl: Updated (thanks to Marshall T. Rose)
      
      	* doc/tkabber.xml: Updated (thanks to Marshall T. Rose)
      
      2003-03-20  Alexey Shchepin  
      
      	* (all): Updated links to tkabber home page
      
      2003-03-18  Alexey Shchepin  
      
      	* presence.tcl: Replaced tk_dialog with MessageDlg
      
      2003-03-15  Alexey Shchepin  
      
      	* jabberlib-tclxml/jabberlib.tcl: Fixed handling of message
      	extension subelements
      
      	* jabberlib-tclxml/wrapper.tcl: Partially rewriten
      
      2003-03-13  Alexey Shchepin  
      
      	* jabberlib-tclxml/jabberlib.tcl: Fixed SASL service name ("xmpp"
      	instead of "jabber"), removed setting of ssf_external
      
      2003-03-12  Alexey Shchepin  
      
      	* examples/mtr-config.tcl: Updated (thanks to Marshall T. Rose)
      
      	* chats.tcl: Add incoming message hook (thanks to Marshall
      	T. Rose)
      
      	* browser.tcl: Added right-click to have a popup menu for browser
      	items (thanks to Marshall T. Rose)
      
      	* examples/tools/*.tcl: Updated (thanks to Marshall T. Rose)
      
      	* jabberlib-tclxml/jabberlib.tcl: SASL support fixes
      
      	* msgs/ca.msg: Catalan translation (thanks to Luis Peralta)
      
      2003-03-10  Alexey Shchepin  
      
      	* msgs/es.msg: Updated (thanks to Luis Peralta)
      
      2003-03-09  Alexey Shchepin  
      
      	* examples/tools/*: Jabber Tcl Tools updated and moved to
      	examples/tools, added HOWTO (thanks to Marshall T. Rose)
      
      	* login.tcl: Limited number of reconnections (thanks to Marshall
      	T. Rose)
      
      	* jabberlib-tclxml/jabberlib.tcl: SASL support (requires Tcl SASL
      	package, currently works at least with PLAIN mechanism)
      
      2003-03-08  Alexey Shchepin  
      
      	* jabberlib-tclxml/jabberlib.tcl: Support for receiving new-style
      	stanza errors
      	* utils.tcl: Likewise
      
      2003-03-05  Alexey Shchepin  
      
      	* examples/rssbot*: A little rssbot (thanks to Marshall T. Rose)
      
      	* examples/jbot: Invoke jsend under /etc/rc (thanks to Marshall
      	T. Rose)
      
      	* examples/jsend.tcl: Now knows about the roster (thanks to
      	Marshall T. Rose)
      
      	* messages.tcl: Don't put up balloon help on headlines missing a
      	body (thanks to Marshall T. Rose)
      
      2003-03-04  Alexey Shchepin  
      
      	* chats.tcl (chat::invite_dialog): Don't show non-groupchat tab
      	names in list (thanks to Vincent Ricard)
      
      2003-02-28  Alexey Shchepin  
      
      	* examples/jsend.tcl: Updated (thanks to Marshall T. Rose)
      
      2003-02-27  Alexey Shchepin  
      
      	* chats.tcl (chat::invite_dialog): Fixed nick evaluation
      
      	* msgs/de.msg: German translation (thanks to Stephan Dietl)
      
      2003-02-26  Alexey Shchepin  
      
      	* examples/mtr-config.tcl: Updated (thanks to Marshall T. Rose)
      
      	* chats.tcl: New hook normalize_chat_id_hook to allow modification
      	of chatid variable (thanks to Marshall T. Rose)
      
      	* msgs/ro.msg: Fixed typos (thanks to badlop)
      
      2003-02-25  Alexey Shchepin  
      
      	* jabberlib-tclxml/jabberlib.tcl: Remove fileevent script prior to
      	closing the socket when inside the fileevent script (otherwise on
      	some systems tclsh dumps core!) (thanks to Marshall T. Rose)
      
      	* examples/mtr-config.tcl: Updates (thanks to Marshall T. Rose)
      
      	* examples/jsend.tcl: Better failure recovery (thanks to Marshall
      	T. Rose)
      
      	* messages.tcl: Better "multiple" handling for headlines (thanks
      	to Marshall T. Rose)
      
      	* (all): Tkabber 0.9.4beta released
      
      	* msgs/ro.msg: Updated (thanks to Adrian Rapa)
      
      2003-02-23  Alexey Shchepin  
      
      	* datagathering.tcl: Support of jabber:iq:data namespace (which is
      	the same as jabber:x:data with allowing of using without
      	surrounding namespace and with "node" attribute)
      
      2003-02-22  Alexey Shchepin  
      
      	* plugins/general/rawxml.tcl: Fixed bug with indentation (thanks
      	to Sergei Golovan)
      
      	* gpgme.tcl: Removed unneeded "puts" (thanks to Sergei Golovan)
      
      2003-02-18  Alexey Shchepin  
      
      	* msgs/ro.msg: Updated (thanks to Adrian Rapa)
      
      2003-02-17  Alexey Shchepin  
      
      	* plugins/chat/logger.tcl: Now possible to search substrings in
      	history (thanks to Michail Litvak)
      	* iface.tcl: Likewise
      
      	* gpgme.tcl: Fixed non-modal dialogs, added option for entering
      	gpg password only once (thanks to Sergei Golovan)
      
      2003-02-16  Alexey Shchepin  
      
      	* plugins/unix/ispell.tcl: Bugfix, replaced "==" to "cequal" in
      	expressions (thanks to Marshall T. Rose)
      	* plugins/unix/menu.tcl: Likewise
      	* plugins/unix/menu8.4.tcl: Likewise
      	* plugins/unix/wmdock.tcl: Likewise
      
      	* plugins/chat/completion.tcl: Fixed bug with "%" in groupchat JID
      
      2003-02-15  Alexey Shchepin  
      
      	* default.xrdb: Explicitly define geometry of some Tkabber
      	windows (thanks to Sergei Golovan)
      	* doc/tkabber.xml: Updated (thanks to Sergei Golovan)
      
      	* muc.tcl: MUC compatibility now checked via disco
      
      	* disco.tcl: Now handlers can contain arguments
      
      2003-02-14  Alexey Shchepin  
      
      	* chats.tcl: Fixed joining of conferences with uppercase chars in
      	name
      	* joingrdialog.tcl (set_our_groupchat_nick): Likewise
      
      2003-02-13  Alexey Shchepin  
      
      	* datagathering.tcl (data::fill_field_x): Fixed bug with handling
      	x:data field without  subelement
      
      2003-02-11  Alexey Shchepin  
      
      	* messages.tcl: "To:" string now can be translated
      
      2003-02-10  Alexey Shchepin  
      
      	* userinfo.tcl: Now possible to open browser by clicking on "Web
      	Site", "Photo URL" and "About" fields (thanks to Sergei Golovan)
      
      2003-02-09  Alexey Shchepin  
      
      	* utils.tcl: New function to draw non-modal message dialogs
      	(thanks to Sergei Golovan)
      	* gpgme.tcl: Use non-modal dialogs to display errors (thanks to
      	Sergei Golovan)
      
      	* msgs/fr.msg: Added e-mail of the author
      
      2003-02-08  Alexey Shchepin  
      
      	* (all): Added emoticons and clickable URLs in normal messages,
      	fixed bug with logging of messages that not sended due to GPG
      	encryption error (thanks to Sergei Golovan)
      
      2003-02-05  Alexey Shchepin  
      
      	* messages.tcl: Workaround for Bwidget bug with long node names in
      	headlines tree (thanks to Marshall T. Rose)
      
      2003-02-04  Alexey Shchepin  
      
      	* jabberlib-tclxml/tclxml/sgmlparser.tcl: Changed requred version
      	of "uri" from 1.1 to 1.0 (thanks to Sergei Golovan)
      
      	* jabberlib-tclxml/jabberlib.tcl: Fixed processing of
      	"use_external_tclxml" option for tcl8.4 (thanks to Sergei Golovan)
      
      2003-02-03  Alexey Shchepin  
      
      	* msgs/fr.msg: French translation (thanks to Vincent Ricard)
      
      	* login.tcl (connected): Changed main window title (thanks to
      	Michal Bozon)
      
      2003-02-01  Alexey Shchepin  
      
      	* plugins/unix/ispell.tcl: Fixed typo (thanks to Sergei Golovan)
      
      	* datagathering.tcl (data::fill_field_x): Fixed binding of
      	 and added scrollbar in text-multi field.
      
      2003-01-31  Alexey Shchepin  
      
      	* plugins/chat/exec_command.tcl: New plugin that adds "/exec"
      	command in chats (e.g. "/exec uptime" to insert output of "uptime"
      	command to chat input window)
      
      	* msgs/es.msg: Fixed typo (thanks to Luis Peralta)
      
      	* msgs/ro.msg: Updated (thanks to Adrian Rapa)
      
      2003-01-30  Alexey Shchepin  
      
      	* plugins/unix/ispell.tcl: More configuration options (thanks to
      	Sergei Golovan)
      
      	* msgs/es.msg: Updated (thanks to Luis Peralta)
      
      2003-01-27  Alexey Shchepin  
      
      	* sound.tcl: Fixed muting, added sound setup via "customize"
      	(thanks to Sergei Golovan)
      	* msgs/ru.msg: Updated (thanks to Sergei Golovan)
      
      2003-01-24  Alexey Shchepin  
      
      	* iface.tcl: Removed duplicate of function "help_window" (thanks
      	to Michal Bozon)
      
      2003-01-20  Alexey Shchepin  
      
      	* messages.tcl: Added check of message type for storing only
      	messages with type='normal' (thanks to Sergei Golovan)
      
      2003-01-19  Alexey Shchepin  
      
      	* plugins/general/message_archive.tcl: New plugin for storing and
      	displaying mesage archive (thanks to Sergei Golovan)
      	* msgs/ru.msg: Updated (thanks to Sergei Golovan)
      
      	* datagathering.tcl: Added interaction with disco
      
      2003-01-17  Alexey Shchepin  
      
      	* plugins/chat/logger.tcl: Fixed history window resizing (thanks
      	to Michail Litvak)
      
      2003-01-15  Alexey Shchepin  
      
      	* pixmaps/default/services/rss*: RSS icons (thanks to Michal Bozon)
      	* roster.tcl: Support of RSS icons (thanks to Michal Bozon)
      
      	* pixmaps/psi/roster/stalker.gif: Stalker icon for "psi" theme
      	(thanks to Michal Bozon)
      
      	* plugins/iq/version.tcl: Show Tcl/Tk version in reply (thanks to
      	Sergei Golovan)
      
      	* gpgme.tcl: Bugfix (thanks to Sergei Golovan)
      
      	* (all): Interface changes, added many panned windows (thanks to
      	Sergei Golovan)
      
      2003-01-13  Alexey Shchepin  
      
      	* iface.tcl: Fixed typo that cause missing of roster group menu
      	(thanks to Sergei Golovan)
      
      	* utils.tcl: New function "format_time" (thanks to Sergei
      	Golovan)
      	* userinfo.tcl: Changed birthday entry, use "format_time" function
      	(thanks to Sergei Golovan)
      	* plugins/general/autoaway.tcl: Now use "format_time" function (thanks
      	to Sergei Golovan)
      	* msgs/ru.msg: Updated (thanks to Sergei Golovan)
      
      	* presence.tcl: Custom presence bugfix (thanks to Sergei Golovan)
      
      	* roster.tcl: Fixed bug caused by previous fix of roster users
      	with resource bug
      
      2003-01-12  Alexey Shchepin  
      
      	* plugins/general/stats.tcl: Updated
      
      	* roster.tcl: Fixed bug with roster users with resources
      
      	* browser.tcl: Fixed typo (thanks to Sergei Golovan)
      
      	* utils.tcl: New function "get_group_nick" (thanks to Sergei
      	Golovan)
      	* browser.tcl: Use this function (thanks to Sergei Golovan)
      	* tkabber/joingrdialog.tcl: Likewise
      	* tkabber/messages.tcl: Likewise
      	* tkabber/plugins/chat/logger.tcl: Likewise
      	* tkabber/roster.tcl: Likewise
      	* doc/tkabber.xml: Updated (thanks to Sergei Golovan)
      
      2003-01-11  Alexey Shchepin  
      
      	* plugins/general/stats.tcl: JEP-0039 support (not completed)
      
      	* roster.tcl (roster::redraw): Partially fixed bug with roster
      	users with resources
      
      2003-01-10  Alexey Shchepin  
      
      	* msgs/ru.msg: Updated (thanks to Sergei Golovan)
      
      	* iface.tcl: Fixed typo (thanks to Sergei Golovan)
      
      	* custom.tcl: Added option type "password", use spinbox widget if
      	tk8.4 present (thanks to Sergei Golovan)
      	* login.tcl: Use "password" option type for password customization
      	(thanks to Sergei Golovan)
      	* **/*.xrdb: Updated (thanks to Sergei Golovan)
      
      	* messages.tcl: Fixed behaviour of GPG icon (thanks to Marshall
      	T. Rose)
      
      2003-01-09  Alexey Shchepin  
      
      	* utils.tcl: New function "error_to_string" (thanks to Sergei
      	Golovan)
      	* (all): Changed error processing by using function
      	"error_to_string" (thanks to Sergei Golovan)
      	* msgs/ru.msg: Updated (thanks to Sergei Golovan)
      
      	* iface.tcl: Changed behaviour of "show only online users" button
      	(thanks to Sergei Golovan)
      	* roster.tcl: Likewise
      	* pixmaps/*/tkabber/glade-(off|on)line.gif: Updated (thanks to
      	Sergei Golovan)
      
      2003-01-08  Alexey Shchepin  
      
      	* msgs/it.msg: Italian translation (thanks to Antonino Iacono)
      
      2003-01-06  Alexey Shchepin  
      
      	* jabberlib-tclxml/tclxml/sgmlparser.tcl: Removed precessing of
      	":" in tag names (thanks to Sergei Golovan)
      
      	* jabberlib-tclxml/jabberlib.tcl: Call client:disconnect or
      	client:reconnect depends on disconnect reason (thanks to Sergei
      	Golovan)
      	* login.tcl: Added client:reconnect procedure
      
      	* iface.tcl: Use "custom" module to set some options
      	* plugins/general/autoaway.tcl: Likewise
      	* login.tcl: Likewise
      
      	* doc/tkabber.xml: Updated
      
      	* userinfo.tcl: Register disco browser handler for "vcard-temp"
      	namespace
      	* register.tcl: Likewise for "jabber:iq:register"
      
      	* search.tcl: Send "xml:lang" attribute in queries
      	* disco.tcl: Likewise
      
      	* utils.tcl: New function "get_lang"
      
      2003-01-05  Alexey Shchepin  
      
      	* disco.tcl: More translation strings (thanks to Sergei Golovan)
      	* msgs/ru.msg: Likewise
      	* plugins/general/conferenceinfo.tcl: Likewise
      	* plugins/unix/ispell.tcl: Likewise
      	* privacy.tcl: Likewise
      	* msgs/ru.msg: Updated (thanks to Sergei Golovan)
      
      	* bwidget_workarounds.tcl: Fixed tree view keyboard scrolling
      	(thanks to Sergei Golovan)
      
      2003-01-04  Alexey Shchepin  
      
      	* search.tcl: Fixed processing of "reported" fields in x:data
      	(thanks to Sergei Golovan)
      
      	* msgs/es.msg: Spanish translation (thanks to Luis Peralta)
      
      	* iface.tcl: Better roster collapse/uncollapse (thanks to Sergei
      	Golovan)
      
      2003-01-03  Alexey Shchepin  
      
      	* iface.tcl: Copyright update
      	* splash.tcl: Likewise
      	* doc/tkabber.xml: Likewise
      
      	* roster.tcl: Added "Show only online users" menu item
      
      	* jabberlib-tclxml/jabberlib.tcl: Flush stream before sending
      	"" (thanks to Sergei Golovan)
      
      	* datagathering.tcl: Mouse wheel bindings (thanks to Sergei
      	Golovan)
      
      	* plugins/general/autoaway.tcl: Change priority to 0 when in
      	autoaway state (thanks to Sergei Golovan)
      	* doc/tkabber.xml: Updated (thanks to Sergei Golovan)
      
      	* plugins/general/rawxml.tcl: Added scrollbar in input window
      	(thanks to Sergei Golovan)
      
      	* chats.tcl: Added scrollbar in input window, use scrollwindow
      	widget to show scrollbar in chat log window (thanks to Sergei
      	Golovan)
      
      2003-01-02  Alexey Shchepin  
      
      	* disco.tcl: Now possible to register handlers for different
      	features, that executed when user choose feature
      	* search.tcl: Register handler for "jabber:iq:search" namespace
      
      	* userinfo.tcl: Now really removed "prodid" and "version"
      	attributes from vCard queries
      
      	* msgs/ro.msg: Updated (thanks to Adrian Rapa)
      
      2003-01-01  Alexey Shchepin  
      
      	* msgs/eo.msg: Esperanto translation (thanks to Mike Mintz)
      
      	* userinfo.tcl: Removed "prodid" and "version" attributes from
      	vCard queries
      
      	* disco.tcl: Changed attribute "type" to "var" in "feature"
      	elements, slightly changed item's name generation, fixed small bug
      	with incorrect item's data generation in tree
      
      2002-12-30  Alexey Shchepin  
      
      	* disco.tcl: Support of 'node' attribute
      
      2002-12-29  Alexey Shchepin  
      
      	* plugins/chat/unisymbols.tcl: New plugin that allows to insert
      	arbitrary unicode symbol in chat windows (e.g. by entering "&256c"
      	and pressing C-;)
      
      	* msgs/ru.msg: Updated
      
      	* roster.tcl (roster::remove_item): Added unregistration from
      	services (thanks to Sergei Golovan)
      
      2002-12-28  Alexey Shchepin  
      
      	* msgs/ro.msg: Romanian translation (thanks to Adrian Rapa)
      
      2002-12-27  Alexey Shchepin  
      
      	* plugins/unix/ispell.tcl: Fixed race condition (thanks to
      	Marshall T. Rose)
      
      	* plugins/general/rawxml.tcl: Don't make error if admin menu not
      	exists (thanks to Marshall T. Rose)
      
      	* jabberlib-tclxml/tclxml/sgmlparser.tcl: Removed special
      	processing of "xmlns" attribute
      
      2002-12-26  Alexey Shchepin  
      
      	* plugins/general/rawxml.tcl (rawxml::pretty_print): Small fixes
      	(thanks to Sergei Golovan)
      
      2002-12-25  Alexey Shchepin  
      
      	* plugins/general/rawxml.tcl: color palette changed, sligthly
      	changed window layout, pretty printing with proportional font is
      	corrected (thanks to Sergei Golovan)
      
      	* custom.tcl: Added navigation bar, support for option type
      	"integer", list of parent groups
      	* plugins/general/rawxml.tcl: Use "custom" module to set options
      
      	* gpgme.tcl: Unicode support fixes (thanks to Sergei Golovan)
      
      	* jabberlib-tclxml/jabberlib.tcl: New procedure ::LOG_OUTPUT_XML
      	* plugins/general/rawxml.tcl: Highlight also output XML when
      	possible
      	* doc/tkabber.xml: Updated
      
      2002-12-24  Alexey Shchepin  
      
      	* custom.tcl: Support for customizating Tkabber via GUI (not
      	completed)
      	* iface.tcl: Added "Customize" menu
      	* tkabber.tcl: Added loading of "custom.tcl"
      	* plugins/general/conferenceinfo.tcl: Use "custom" module to set
      	options
      	* plugins/unix/ispell.tcl: Likewise
      
      2002-12-22  Alexey Shchepin  
      
      	* doc/tkabber.xml: Updated
      
      	* plugins/general/rawxml.tcl: Added bindings for history and
      	scrolling
      
      2002-12-21  Alexey Shchepin  
      
      	* plugins/general/rawxml.tcl: New plugin for raw XML input
      	* iface.tcl: Removed old raw XML input code
      	* jabberlib-tclxml/jabberlib.tcl: New procedures for logging:
      	::LOG_OUTPUT, ::LOG_INPUT and ::LOG_INPUT_XML
      
      2002-12-18  Alexey Shchepin  
      
      	* gpgme.tcl: Fixes for better unicode support (thanks to Sergei
      	Golovan)
      	* messages.tcl: Likewise
      	* login.tcl: Likewise
      
      2002-12-16  Alexey Shchepin  
      
      	* pixmaps/psi/roster/available-chat.gif: Changed icon (thanks to
      	Michal Bozon)
      
      	* jabberlib-tclxml/jabberlib.tcl: Removed back "-exact", added
      	variable use_external_tclxml
      	* jabberlib-tclxml/pkgIndex.tcl: Removed changing of auto_path
      	* doc/tkabber.xml: Updated
      
      2002-12-14  Alexey Shchepin  
      
      	* roster.tcl (roster::heuristically_get_category_and_subtype):
      	Add subtype "icq" to JIDs with domain started with "icqv7" (thanks
      	to Michal Bozon)
      
      	* jabberlib-tclxml/jabberlib.tcl: Added -exact to "package require
      	xml 2.0" to avoid loading of incompatible tclxml versions (thanks
      	to piotr@rokicki.net)
      	* jabberlib-tclxml/tclxml/pkgIndex.tcl: Likewise
      
      	* examples/mtr-config.tcl: Updated (thanks to Marshall T. Rose)
      
      	* plugins/unix/dockingtray.tcl: Updated (thanks to Marshall
      	T. Rose)
      
      	* Makefile: More correct install places for files
      
      2002-12-12  Alexey Shchepin  
      
      	* (all): Many fixes to work properly with tcl8.4 (thanks to Sergei
      	Golovan)
      
      2002-12-11  Alexey Shchepin  
      
      	* roster.tcl (roster::jid_doubleclick): Added highlighting of
      	roster conference icon when it opened
      
      	* presence.tcl: Bugfix: clear presence information after
      	disconnecting
      
      2002-12-08  Alexey Shchepin  
      
      	* examples/(ice|light|warm).xrdb: Updated (thanks to Sergei
      	Golovan)
      
      	* msgs/ru.msg: Updated (thanks to Sergei Golovan)
      
      	* search.tcl: Bugfix (thanks Sergei Golovan)
      
      	* messages.tcl: Added menu for sender (thanks to Sergei Golovan)
      
      2002-12-05  Alexey Shchepin  
      
      	* sound.tcl: Fixed bug with theme started from "~" with external
      	play program; support for temporary mute sound (thanks to Sergei
      	Golovan)
      	* iface.tcl: Added menu item for muting sounds
      	* plugins/general/autoaway.tcl: Mute sound in away mode
      
      	* msgs/ru.msg: Updated (thanks to Sergei Golovan)
      
      	* examples/teo-config.tcl: New config example (thanks to Sergei
      	Golovan)
      
      	* doc/tkabber.xml: Updates (thanks to Sergei Golovan)
      
      2002-12-04  Alexey Shchepin  
      
      	* splash.tcl (splash_start): Fixed commentary table
      
      	* chats.tcl (chat::redraw_roster): Show number of participants in
      	conference users list
      
      2002-12-03  Alexey Shchepin  
      
      	* examples/mtr-config.tcl: Updated (thanks to Marshall T. Rose)
      
      	* doc/tkabber.xml: Updates (thanks to Marshall T. Rose)
      
      	* messages.tcl: Fixed headline caching bug (thanks to Marshall
      	T. Rose)
      
      2002-11-27  Alexey Shchepin  
      
      	* userinfo.tcl (userinfo::manage_focus): Bugfix
      
      2002-11-24  Alexey Shchepin  
      
      	* iface.tcl: Workaround for one bwidget issue (thanks to Sergei
      	Golovan)
      
      	* examples/*.xrdb: Updates and new themes (warm.xrdb and
      	light.xrdb) (thanks to Sergei Golovan)
      
      	* chats.tcl: Added ability to have different default size for chat
      	and groupchat windows (thanks to Sergei Golovan)
      	* iface.tcl: Likewise
      	* default.xrdb: Likewise
      
      2002-11-23  Alexey Shchepin  
      
      	* examples/dark.xrdb: New color theme (thanks to Sergei Golovan)
      	* examples/ice.xrdb: Likewise
      	* examples/green.xrdb: Likewise (thanks to ukscone)
      
      	* pixmaps/icq/: New ICQ-like theme (thanks to Oleg V. Motienko)
      
      	* examples/teopetuk.xrdb: Updated, added descriptions of used
      	resources (thanks to Sergei Golovan)
      	* examples/ermine.xrdb: Likewise
      
      	* roster.tcl: Roster import/export support
      
      	* userinfo.tcl (userinfo::load_photo): Fixed error when user
      	clicks on "Cancel" button in load photo dialog
      
      2002-11-21  Alexey Shchepin  
      
      	* examples/mtr-config.tcl: Updated (thanks to Marshall T. Rose)
      
      	* plugins/unix/dockingtray.tcl: Fixed race condition (thanks to
      	Marshall T. Rose)
      
      	* plugins/windows/taskbar.tcl: Bugfix (thanks to Sergei Golovan)
      
      	* roster.tcl: Fixed roster scrolling (thanks to Sergei Golovan)
      
      	* plugins/windows/mousewheel.tcl: Plugin that make mousewheel work
      	on Windows (thanks to Sergei Golovan)
      
      	* plugins/general/autoaway.tcl: Autoaway plugin that works both on
      	Unix and on Windows (requires tclWinidle package) (thanks to
      	Sergei Golovan)
      
      2002-11-19  Alexey Shchepin  
      
      	* privacy.tcl (privacy::send_lists): Send all lists in different
      	iq packets to work with jabberd2.  Now waiting for next revision
      	of JEP-0016...
      
      	* plugins/general/conferenceinfo.tcl: If conference return error
      	reply, then wait longer period of time to ask again
      	* doc/tkabber.xml: Updated
      
      2002-11-18  Alexey Shchepin  
      
      	* login.tcl (show_login_dialog): Fixed tab order
      
      2002-11-17  Alexey Shchepin  
      
      	* roster.tcl: More performance improvements
      
      	* presence.tcl: Cleanups
      
      2002-11-15  Alexey Shchepin  
      
      	* plugins/windows/taskbar.tcl: Few changes (thanks to Sergei
      	Golovan)
      
      	* roster.tcl: More performance improvements
      
      2002-11-14  Alexey Shchepin  
      
      	* roster.tcl (roster::jid_doubleclick): Small fix to better work
      	with bookmark items -- jabberd2 removes all category and type
      	attributes
      
      	* joingrdialog.tcl: Add conference in  tag instead of 
      
      	* messages.tcl: Fixed some headline caching stuff (thanks to
      	Marshall T. Rose)
      
      	* examples/jsend.tcl: Small changes (thanks to Marshall T. Rose)
      	* examples/mtr-config.tcl: Likewise
      
      	* plugins/windows/taskbar.tcl: Few changes (thanks to Sergei
      	Golovan)
      
      	* pixmaps/jajc/docking/tkabber.ico: Windows icon for JAJC theme
      	(thanks to Sergei Golovan)
      
      	* userinfo.tcl: Added dialog for requesting info from arbitrary
      	JID (thanks to Sergei Golovan)
      
      	* roster.tcl: Performance improvements (better handling of big
      	rosters)
      	* presence.tcl: Likewise
      
      	* muc.tcl (muc::process_gc_user): Fixed typo with reason handling
      
      2002-11-13  Alexey Shchepin  
      
      	* privacy.tcl: Server-Based Privacy Rules support (JEP-0016)
      
      2002-11-12  Alexey Shchepin  
      
      	* plugins/unix/wmdock.tcl (::wmdock::showhide): Small fix (thanks
      	to Michail Litvak and Max Loparyev)
      
      2002-11-11  Alexey Shchepin  
      
      	* disco.tcl: Small improvements
      
      	* plugins/general/tkcon.tcl: Plugin that add support for tkcon
      	(thanks Marshall T. Rose)
      	* doc/tkabber.xml: Updated
      
      	* plugins/windows/taskbar.tcl: Plugin to let tkabber on windows
      	put a little icon in the systray (requires Winico package)
      	(thanks Marshall T. Rose)
      	* pixmaps/default/docking/tkabber.ico: Windows icon for systray
      
      	* plugins/general/conferenceinfo.tcl: Plugin for listing
      	participants of roster conferences when user not joined them
      	* doc/tkabber.xml: Updated
      
      2002-11-10  Alexey Shchepin  
      
      	* presence.tcl (get_jid_of_user): Fixed for case when jid priority
      	not known
      
      	* roster.tcl (roster::item_to_xml): Store category in attribute
      	instead of element name
      
      	* roster.tcl: Roster aliases support
      	* doc/tkabber.xml: Updated
      
      	* roster.tcl: Don't show "stalker" icon and foreground if received
      	non-unavailable presence
      
      2002-11-09  Alexey Shchepin  
      
      	* muc.tcl: Fixed client message for nick change
      
      	* muc.tcl: MUC-compatible invitation support
      
      	* messages.tcl: A new option for headlines that determines when
      	all headlines go in one window or not (thanks Marshall T. Rose)
      	* doc/tkabber.xml: Updated (thanks Marshall T. Rose)
      
      	* messages.tcl: Fixed miss of message::quote (thanks Sergei
      	Golovan)
      
      2002-11-07  Alexey Shchepin  
      
      	* examples/jsend.tcl: New version of jmail.tcl renamed to
      	jsend.tcl (thanks Marshall T. Rose)
      
      	* roster.tcl: Menu for roster users to send custom presence
      	* chats.tcl: Likewise for groupchats
      
      	* presence.tcl (send_custom_presence): Function to send custom
      	presence
      
      2002-11-06  Alexey Shchepin  
      
      	* jabberlib-tclxml/jabberlib.tcl: Workaround for expat bug
      
      	* iface.tcl: C-M-Prior/Next now move current tab left/right
      
      	* iface.tcl: Better title handling (thanks Sergei Golovan)
      
      	* plugins/chat/completion.tcl (completion::complete): More
      	correctly completion
      
      2002-11-05  Alexey Shchepin  
      
      	* roster.tcl: Adding group by regexp on roster jids
      	* iface.tcl: Menu item for this feature
      
      	* datagathering.tcl (data::draw_window): Return cancel form when
      	'Cancel' button pressed
      
      	* roster.tcl: Now possible to rename or remove roster group
      
      	* roster.tcl: New popup menu for roster groups
      
      	* roster.tcl: roster::group_popup_menu renamed to
      	roster::groupchat_popup_menu
      	* chats.tcl: Likewise
      
      	* disco.tcl: Removed all references to 'category' attribute for
      	'feature' element
      
      	* tkabber.tcl: Load iq.tcl before disco.tcl
      
      2002-11-04  Alexey Shchepin  
      
      	* chats.tcl (chat::change_presence): New hooks 'chat_user_enter'
      	and 'chat_user_exit'
      	* doc/tkabber.xml: Updated
      
      	* jidlink.tcl (jidlink::negotiate_handler): Return all options on
      	empty feature negotiation request
      
      	* disco.tcl: Answer to disco info queries
      
      	* examples/jmail.tcl: A stand-alone program that sends to a jabber
      	recipient (you can use it e.g. to "follow" syslogs) (thanks
      	Marshall T. Rose)
      
      	* jabberlib-tclxml/pkgIndex.tcl: New file to allow install
      	jabberlib in the tcl search path (thanks Marshall T. Rose)
      
      	* examples/mtr-config.tcl: A few changes (thanks Marshall T. Rose)
      
      	* iface.tcl: much better focus/tab-update handling (thanks
      	Marshall T. Rose)
      
      	* (all): Now keep alive interval stored in keep_alive_interval
      	variable (thanks Sergei Golovan)
      
      	* login.tcl: Now possible to connect to server by defining its
      	another name or ip (thanks Sergei Golovan)
      
      2002-11-03  Alexey Shchepin  
      
      	* (all): Tkabber 0.9.2beta released
      
      	* doc/tkabber.xml: Updated
      
      	* Makefile: Updated
      
      	* iface.tcl: Fixed "Quick Help" message
      
      	* iface.tcl: Added "Change password" dialog, some admin tools
      	(thanks Sergei Golovan)
      
      2002-11-02  Alexey Shchepin  
      
      	* messages.tcl (message::send_subscribe_dialog): Fixed typo
      	(thanks Sergei Golovan and ukscone)
      
      	* plugins/clientinfo.tcl: Moved to plugins/general/
      	* iq-plugins/: Moved to plugins/iq/
      	* chat-plugins/: Moved to plugins/chat/
      	* unix/: Moved to plugins/unix/
      
      	* roster.tcl: Changed interface to
      	roster::create_groupchat_user_menu and to
      	roster_create_groupchat_user_menu_hook
      	* muc.tcl (muc::add_groupchat_user_menu_items): Likewise
      	* doc/tkabber.xml: Updated
      
      	* chat-plugins/clear.tcl: Plugin that adds menu for clearing chat
      	window
      
      	* iface.tcl: Added info about M-[0-9] bindings to "Quick Help"
      
      	* muc.tcl (muc::process_gc_user): Generate events messages on kick
      	and ban
      	* muc.tcl: Switch on/of client message events via
      	muc::options(gen_events)
      
      	* presence.tcl: Slightly changed interface to presence_process_x
      
      2002-11-01  Alexey Shchepin  
      
      	* plugins/clientinfo.tcl (clientinfo::add_user_popup_info): Show
      	also vCard name of JID
      
      	* muc.tcl (muc::add_user_popup_info): Don't show real JID if it
      	not known
      
      	* userinfo.tcl (userinfo::make_adr_item): Store country info in
      	 element instead of 
      
      	* doc/tkabber.xml: Fixed some versions in "Requirements" section
      
      	* messages.tcl: Changed messages interface (thanks Sergei Golovan)
      
      	* iface.tcl (get_focus): Fixed tab highliting when main window
      	gets focus
      
      	* (all): Slightly changed chats interface, replaced "puts" to
      	"debugmsg" (thanks Marshall T. Rose)
      
      2002-10-31  Alexey Shchepin  
      
      	* iface.tcl: Augment the tabcolor code to see if the main window
      	is out-of-focus (thanks Marshall T. Rose)
      
      	* chats.tcl (chat::change_presence): Show custom messages on users
      	join/exiting
      
      	* iface.tcl: Switch between tabs via M-[0-9]
      
      	* muc.tcl: Don't allow to edit role and affiliation simultaneously
      	in lists
      
      2002-10-30  Alexey Shchepin  
      
      	* unix/menu8.4.tcl: menu.tcl version for Tcl/Tk 8.4
      
      	* messages.tcl: Fixed resizing of some windows (thanks Sergei
      	Golovan)
      
      	* iface.tcl (show_rawxml_dialog): Send XML on C-Return instead of
      	Return (thanks Sergei Golovan)
      
      	* chat-plugins/complete_last_nick.tcl: Add nick from last
      	groupchat message in beginning of completion list
      
      	* joingrdialog.tcl (join_group_dialog): Interface slightly changed
      
      	* muc.tcl (muc::join_group): MUC-compatible join
      	* joingrdialog.tcl (join_group): Use MUC join for MU-Conferences
      
      	* negotiate.tcl (negotiate::recv_request_response): Changed format
      	of returned data
      	* jidlink.tcl: Use new format
      
      	* disco.tcl: Show feature negotiation results in browser
      
      	* disco.tcl: Show error replies
      
      2002-10-29  Alexey Shchepin  
      
      	* iface.tcl: Show number of unreaded messages in title in tabbed
      	interface when window have no focus (thanks Sergei Golovan)
      
      	* sound.tcl: Don't play sounds when our status is "xa" or "dnd"
      	(thanks Sergei Golovan)
      
      	* disco.tcl: Service discovery support (JEP-0030)
      	* iface.tcl: Menu item for disco-browser
      	* default.xrdb: Resources for disco-browser
      
      2002-10-28  Alexey Shchepin  
      
      	* unix/menu.tcl: Disabled for tcl version != 8.3
      
      2002-10-27  Alexey Shchepin  
      
      	* (all): Some design changes (thanks Sergei Golovan)
      
      	* unix/menu.tcl: Menu behavior changed to what ukscone and velikan
      	wants (thanks Sergei Golovan)
      
      	* sound.tcl: If theme name started with "/" or "~", then it
      	considered as path directly to theme directory (thanks Sergei
      	Golovan)
      	* doc/tkabber.xml: Updated
      
      	* tkabber.tcl: New autologin variable to automatically login after
      	startup (thanks Sergei Golovan)
      	* doc/tkabber.xml: Updated
      
      	* muc.tcl: Fixed granting/revoking voice, added completions for
      	/admin and /deadmin commands
      
      	* datagathering.tcl: Support of new text-multi, jid-single and
      	jid-multi fields
      
      	* presence.tcl: Removed test_muc condition (thanks David Sutton)
      
      	* sound.tcl: Sound notifications support (thanks Sergei Golovan)
      	* sounds/default/: Default sound theme (thanks Sergei Golovan)
      	* doc/tkabber.xml: Updated
      
      2002-10-26  Alexey Shchepin  
      
      	* messages.tcl: Fixed typo (thanks Marshall T. Rose)
      
      	* muc.tcl: Rewrited code for editing lists, few code cleanups, new
      	commands /admin and /deadmin
      
      	* (all): More i18n, added bindings to many dialogs, focus
      	management in userinfo dialog (thanks Sergei Golovan)
      
      	* (all): better english usage in messages and in the docs.  if an
      	 comes back in a message/presence, don't try to check
      	signatures, etc.  have clientinfo:autoask default to off (thanks
      	Marshall T. Rose)
      
      2002-10-24  Alexey Shchepin  
      
      	* iq.tcl (iq::register_handler): Store all registered namespaces
      	* iq-plugins/browse.tcl (iq_browse_reply): Show all registered
      	namespaces
      
      	* roster.tcl: Internal changes of displaying popup balloons, more
      	correctly but more slowly
      
      2002-10-23  Alexey Shchepin  
      
      	* msgs/ru.msg: Updated (thanks Sergei Golovan)
      
      	* (all): Much more i18n (thanks Sergei Golovan)
      
      	* chats.tcl (chat::process_message): Ignore non-groupchat messages
      	with type="groupchat"
      
      	* roster.tcl (roster::addline): Small fix to more correctly show
      	popup info for online users with one resource
      
      	* presence.tcl (change_our_presence): Bugfix
      
      	* muc.tcl (muc::request_destruction): Fixed
      
      2002-10-21  Alexey Shchepin  
      
      	* muc.tcl (muc::add_user_popup_info): Show affiliation in popup
      	info
      
      	* plugins/clientinfo.tcl (clientinfo::on_presence): Don't ask
      	every JID more than once, even if it not answers
      
      	* doc/tkabber.xml: Updated
      
      	* roster.tcl (roster::user_popup_info): Corrected status and
      	description in roster popup hints for conference items
      
      	* roster.tcl (roster::addline): Removed is_user condition for jids
      	with multiple resources
      
      	* chats.tcl (chat::close_window): Remove participants presence
      	from memory
      
      	* chats.tcl (chat::redraw_roster): Don't draw affiliation groups
      
      	* muc.tcl: Fixed role and affiliation when trying to grant/revoke
      	moderator priveleges
      
      2002-10-20  Alexey Shchepin  
      
      	* roster.tcl (roster::redraw): Remove doubled jids from groups
      
      2002-10-19  Alexey Shchepin  
      
      	* muc.tcl: New commands /member, /demember, /moderator,
      	/demoderator.  All such commands now compatible with JEP-0045
      	v0.15
      
      	* roster.tcl: 'jlib::parse_roster_get' moved back to jabberlib.tcl
      	* jabberlib-tclxml/jabberlib.tcl: Likewise
      
      	* jabberlib-tclxml/jabberlib.tcl (jlib::send_msg): Fixed bug with
      	message thread handling
      
      	* presence.tcl (client:presence): Handle error presence packets
      	* jabberlib-tclxml/jabberlib.tcl: Likewise
      
      	* jidlink.tcl (jidlink::setup_menu): Added menu for
      	enabling/disabling jidlink transpotrs
      	* iface.tcl: Likewise
      
      	* muc.tcl (muc::process_gc_user): Handle roles and affiliations in
      	presence packets
      
      	* chats.tcl (chat::redraw_roster): Display roles and affiliations
      
      	* muc.tcl: List requests changes, due to JEP-0045 changes
      
      2002-10-17  Alexey Shchepin  
      
      	* plugins/jidlink/dtcp.tcl: Seems works, need to add more error
      	checks
      
      	* muc.tcl (muc::request_negotiation): Browse conference service
      	instead of conference room
      
      	* muc.tcl: Working with lists changed due to JEP-0045 changes
      
      	* filetransfer.tcl: Small fixes
      
      2002-10-16  Alexey Shchepin  
      
      	* plugins/jidlink/dtcp.tcl: DTCP support (JEP-0046) (not completed)
      
      	* jidlink.tcl: Changed transport registration
      	* plugins/jidlink/ibb.tcl: Likewise
      
      2002-10-15  Alexey Shchepin  
      
      	* plugins/jidlink/ibb.tcl: Inband Bytestream support (JEP-0047)
      
      	* filetransfer.tcl: Added support of file transfer via Jidlink
      	(JEP-0052)
      
      	* jidlink.tcl: Jidlink support (JEP-0041)
      
      	* negotiate.tcl: Negotiation support (JEP-0020)
      
      2002-10-14  Alexey Shchepin  
      
      	* msgs/ua.msg: Updated (thanks Vladimir Velychko)
      
      	* chat-plugins/logger.tcl (::logger::show_log): Move history view
      	to the end when window opened
      
      	* browser.tcl (browser::ns_binding): Join conference by pressing
      	on new conference namespace
      
      	* search.tcl: Works more correctly with x:data (thanks Sergei
      	Golovan)
      
      	* muc.tcl: Fixed configure and added admin list (thanks David
      	Sutton)
      
      2002-10-13  Alexey Shchepin  
      
      	* iq.tcl: Changed interface to iq handlers
      	* avatars.tcl: Use new interface
      	* iq-plugins/browse.tcl: Likewise
      	* iq-plugins/time.tcl: Likewise
      	* iq-plugins/version.tcl: Likewise
      
      2002-10-12  Alexey Shchepin  
      
      	* muc.tcl: Negotiation now work via iq:browse
      
      2002-10-10  Alexey Shchepin  
      
      	* joingrdialog.tcl (join_group_dialog): Join on pressing enter in
      	dialog window
      
      	* chats.tcl (chat::get_nick): Use roster name for JID as nick if
      	possible
      
      	* filetransfer.tcl (ft::send_file_dialog): Takes default IP
      	address from socket to server
      
      	* jabberlib-tclxml/jabberlib.tcl: Changed socket encoding to utf-8
      	instead of binary, to avoid some problems with blocking
      
      	* chats.tcl (chat::redraw_roster): redraw_roster moved back from
      	muc.tcl
      	* muc.tcl: Likewise
      
      	* muc.tcl: Removed test_muc condition
      
      	* muc.tcl (muc::commands_comps): Check room for MUC-compatibility
      	* muc.tcl (muc::add_conference_menu_items): Likewise
      
      	* joingrdialog.tcl (join_group): Make iq:negotiation before
      	joining room
      
      	* presence.tcl (presence_process_x): Fixed namespace for MUC
      
      	* datagathering.tcl (data::fill_field_x): Removed use of "min"
      	function, because it not exists in not-extended Tcl
      
      2002-10-09  Alexey Shchepin  
      
      	* muc.tcl: Changed namespaces, due to JEP-0045 changes
      
      	* datagathering.tcl (data::fill_field_x): Don't set height of
      	combo boxes more then needed
      
      	* plugins/clientinfo.tcl: Plugin for showing client information
      	and automatically ask about it
      
      	* presence.tcl (client:presence): New hook client_presence_hook
      
      	* userinfo.tcl (userinfo::request_iq): New function to send
      	various iq queries
      
      	* datagathering.tcl (data::draw_window): New function to draw
      	toplevel window with form
      	* muc.tcl: Changes to use data::draw_window
      
      	* datagathering.tcl (data::add_label): Don't add ":" to the end of
      	label if it ends with punctuation symbol
      
      	* muc.tcl (muc::add_user_popup_info): Add real JID to user popup
      	info if it known
      	* muc.tcl (muc::whois): Whois command now takes information from
      	cache, due to JEP-0045 changes
      
      	* roster.tcl (roster::user_popup_info): User popup info now
      	extendable via roster_user_popup_info_hook
      
      	* roster.tcl: More correct login menu for services (thanks Michail
      	Litvak)
      
      	* roster.tcl: Minor roster fixes (thanks Sergei Golovan)
      
      	* msgs/ua.msg: Fixed typo (thanks Vladimir Velychko)
      
      2002-10-05  Alexey Shchepin  
      
      	* iface.tcl: More geometry configuration via xrdb for non-tabbed
      	interface (thanks Sergei Golovan)
      
      	* msgs/ua.msg: Ukrainian localization (thanks Vladimir Velychko)
      
      2002-10-04  Alexey Shchepin  
      
      	* (all): More interface parameters now configurable via xrdb
      	(thanks Sergei Golovan)
      
      2002-10-03  Alexey Shchepin  
      
      	* muc.tcl (muc::send_ban_voice_list): Fixed namespace
      
      2002-10-01  Alexey Shchepin  
      
      	* muc.tcl: IQ negotiation support
      
      	* roster.tcl: Added Login/logout menu for services (thanks Michail
      	Litvak)
      
      	* datagathering.tcl (data::fill_fields_x):  tag support
      	and added attribute type='submit' into </x> tag for submited data
      
      2002-09-30  Alexey Shchepin  <alexey@sevcom.net>
      
      	* login.tcl (recv_register_result): Make full reconnect after
      	registration
      
      	* tkabber.tcl: I18n support (thanks Sergey Kalinin aka BanZaj)
      	* chats.tcl: Likewise
      	* roster.tcl: Likewise
      	* iface.tcl: Likewise
      	* login.tcl: Likewise
      	* msgs/: Directory for translation files
      
      2002-09-29  Alexey Shchepin  <alexey@sevcom.net>
      
      	* chat-plugins/logger.tcl: Logs now colored (thanks Sergei
      	Golovan)
      
      	* userinfo.tcl: Userinfo window now not a dialog (thanks Sergei
      	Golovan)
      
      2002-09-28  Alexey Shchepin  <alexey@sevcom.net>
      
      	* plugins.tcl (plugins::load_dir): New function to load plugins
      	hierarchy (thanks Sergey Kalinin)
      	* tkabber.tcl: Search plugins in ~/.tkabber/plugins
      
      	* doc/tkabber.xml: Updates
      
      	* search.tcl: Items in search result now numerated (thanks Sergei
      	Golovan)
      
      	* tkabber.tcl: Roster width now configurable via xrdb
      	* chats.tcl: Likewise for conference users list (thanks Sergei
      	Golovan)
      
      2002-09-27  Alexey Shchepin  <alexey@sevcom.net>
      
      	* chat-plugins/completion.tcl: Algorithm slightly changed to
      	support adding of completions via hook 'generate_completions_hook'
      	* chat-plugins/me_command.tcl: Added completion of /me command
      	* chat-plugins/nick_command.tcl: Added completion of /nick command
      	* muc.tcl: Added completions of various MUC commands
      
      	* iface.tcl (tab_set_updated): Fixed highliting of tabs on Windows
      	platform with zoomed main window (thanks Sergei Golovan)
      
      	* mclistbox-1.02/mclistbox.tcl: More correctly resize columns
      	(thanks Sergei Golovan)
      
      	* muc.tcl (muc::request_ban_voice_list): Use namespace
      	jabber:gc:admin instead of incorrect jabber:gc:owner
      
      2002-09-26  Alexey Shchepin  <alexey@sevcom.net>
      
      	* muc.tcl: Ban & voice lists support
      
      	* datagathering.tcl: Fixes to avoid errors in incorrect form
      
      	* muc.tcl: Support for room destruction
      
      	* doc/tkabber.xml: Fixed typo (thanks Marshall T. Rose)
      
      	* iface.tcl: Fixes in X selection support
      
      	* muc.tcl: Support for modifying voice attribute (new commands:
      	/voice and /devoice)
      
      	* muc.tcl (muc::handle_commands): Support for /kick, /ban & /whois
      	commands in groupchats
      
      2002-09-25  Alexey Shchepin  <alexey@sevcom.net>
      
      	* muc.tcl (chat::redraw_roster): Separate users with different
      	levels in conference userlist
      
      	* presence.tcl (presence_process_x): Support for jabber:gc:user
      	namespace
      	* muc.tcl (muc::process_gc_user): Likewise
      
      	* muc.tcl (muc::whois): 'set' changed to 'get'
      
      	* muc.tcl: Bugfixes in configuration procedures
      
      2002-09-24  Alexey Shchepin  <alexey@sevcom.net>
      
      	* unix/ispell.tcl: Show variants of misspelled word correction on
      	right mouse click (thanks Sergei Golovan)
      
      	* muc.tcl: Support for whois command and subsequent room
      	configuration
      
      	* doc/tkabber.xml: slightly better english
      	(thanks Marshall T. Rose)
      
      	* examples/mtr-config.tcl: slightly newer version
      	(thanks Marshall T. Rose)
      
      	* chats.tcl: New hooks chat_create_user_menu_hook and
      	chat_create_conference_menu_hook
      
      	* mclistbox-1.02/mclistbox.tcl: mclistbox v1.02 (c) Bryan Oakley
      	* search.tcl: Search results now displayed via mclistbox package
      	(thanks Sergei Golovan)
      
      2002-09-23  Alexey Shchepin  <alexey@sevcom.net>
      
      	* chats.tcl (chat::open_window): More correct selecting of tab
      	title
      
      	* datagathering.tcl (data::fill_field_x): Fixed bug with incorrect
      	sending of selection in list-multi if it not changed
      
      	* datagathering.tcl: Fixed bug with sending content of text-multi
      	field
      
      	* chat-plugins/events.tcl (events::setup_ui): Fixed bug with '%'
      	in jids
      
      2002-09-22  Alexey Shchepin  <alexey@sevcom.net>
      
      	* muc.tcl: Multi-User Chat support (not completed, enabled by
      	setting 'test_muc' to '1')
      
      	* messages.tcl: Support for x:data in messages
      
      	* chat-plugins/events.tcl: Show incoming events also in status
      	line in tabbed mode
      
      2002-09-21  Alexey Shchepin  <alexey@sevcom.net>
      
      	* chat-plugins/events.tcl (events::process_x_event): Don't send
      	x:event reply when recipient offline
      
      	* messages.tcl (message::send_subscribe): Bugfix in sending
      	presence status
      
      	* doc/tkabber.xml: Updates
      
      	* chat-plugins/events.tcl: Support of message events (JEP-0022)
      
      	* chat-plugins/empty_body.tcl: Don't draw messages with empty body
      
      	* jabberlib-tclxml/jabberlib.tcl (jlib::parse): Support of message
      	'id' attribute
      	* chats.tcl: Likewise
      
      	* unix/ispell.tcl: Fixed leak of text marks
      
      2002-09-20  Alexey Shchepin  <alexey@sevcom.net>
      
      	* doc/tkabber.xml: Updates
      
      	* datagathering.tcl: Support for jabber:x:data (JEP-0004)
      
      	* messages.tcl: display the body from the headline in popup
      	balloon (thanks Marshall T. Rose)
      
      2002-09-19  Alexey Shchepin  <alexey@sevcom.net>
      
      	* iface.tcl: New tabs menu items: "Close other tabs" & "Close all
      	tabs" (thanks Sergei Golovan)
      
      	* jabberlib-tclxml/jabberlib.tcl: New option keep_alive to
      	periodically send empty string to server (thanks Sergei Golovan)
      
      	* (all): put a catch around raising a tab in an "after idle". fix
      	a bug in hedaline caching. more info during splash screen. logout
      	with a reason fixed (thanks Marshall T. Rose)
      
      	* pixmaps/docking: pixmaps/feather22 moved to here
      
      2002-09-18  Alexey Shchepin  <alexey@sevcom.net>
      
      	* userinfo.tcl (userinfo::fill_user_description): Bugfix
      
      	* presence.tcl (change_our_presence): Bugfix
      
      	* iface.tcl: Logout binded to C-j
      
      	* doc/tkabber.xml: Updates
      
      	* roster.tcl (roster::clean): New procedure to clean up roster
      	* login.tcl: Cleanup roster after logout
      
      	* pixmaps/feather22: Roster icons 22x22 moved to here
      	* pixmaps/default: New roster icons 16x16
      
      2002-09-17  Alexey Shchepin  <alexey@sevcom.net>
      
      	* balloon.tcl: don't hide balloons under lower boundary of the
      	screen (thanks Michail Litvak)
      
      	* unix/ispell.tcl: New option 'check_every_symbol' (thanks Sergei
      	Golovan)
      
      	* hooks.tcl: put a "catch" around hook:run. add debugmsg to
      	hook::run. removed old debugging stuff from message headline
      	caching. run as a hook message headline caching. update docs
      	(thanks Marshall T. Rose)
      
      2002-09-16  Alexey Shchepin  <alexey@sevcom.net>
      
      	* iface.tcl (add_win): Fixed bug with not raising of first tab
      	when raise_new_tab=0
      
      	* userinfo.tcl (userinfo::parse_vcard_photo_item): Fixed bug with
      	empty BINVAL tag in PHOTO
      
      2002-09-15  Alexey Shchepin  <alexey@sevcom.net>
      
      	* unix/ispell.tcl: Bugfixes
      
      2002-09-14  Alexey Shchepin  <alexey@sevcom.net>
      
      	* iface.tcl: Tkabber interface
      	* tkabber.tcl: Moved interface code to iface.tcl
      
      	* default.tcl: Default config
      	* tkabber.tcl: Moved default config code to default.tcl
      
      	* userinfo.tcl: Photos in vCard
      
      	* messages.tcl: Fixed bug with double subscription request
      
      	* roster.tcl: Bugfixes
      
      2002-09-13  Alexey Shchepin  <alexey@sevcom.net>
      
      	* (all): Cosmetic changes (thanks Sergei Golovan)
      
      	* unix/ispell.tcl: Support for ispell (thanks Sergei Golovan)
      	* doc/tkabber.xml: Updates
      
      2002-09-09  Alexey Shchepin  <alexey@sevcom.net>
      
      	* chats.tcl (chat::open_window): Bindings to M-Prior and M-Next to
      	scroll text in chat window from input window
      
      	* roster.tcl (roster::heuristically_get_category_and_subtype):
      	Performance improvements
      
      	* doc/tkabber.xml: Updates
      
      	* tkabber.tcl: New hooks postload_hook and finload_hook.
      
      2002-09-08  Alexey Shchepin  <alexey@sevcom.net>
      
      	* splash.tcl: Show progress window at startup
      
      	* tkabber.tcl: Now main window geometry configurable via xrdb
      
      	* (all): Error dialog when user tries to store not defined avatar.
      	More parametrizations to roster look.  Documentation updates.
      	(thanks Marshall T. Rose)
      
      	* search.tcl: Now user can search again in the same search dialog
      	after receiving results
      
      	* tkabber.tcl (about_window): Bugfix
      
      2002-09-07  Alexey Shchepin  <alexey@sevcom.net>
      
      	* doc/tkabber.xml: Updates
      
      	* textundo/: Textundo package from Donal K. Fellows
      	* chats.tcl (chat::open_window): Undo/redo support for input
      	windows.  Undo binded to C-z, redo to C-Z.
      	* messages.tcl: Likewise
      
      	* chats.tcl (chat::redraw_roster): List of groupchat users sorted
      	more correctly
      
      	* login.tcl: HTTPS proxy auth support (thanks Alexander
      	Timoshenko)
      
      2002-09-06  Alexey Shchepin  <alexey@sevcom.net>
      
      	* (all): default_message_type now a chat::option.  some minor
      	debuging for the gpgme module.  more updates to the docs.  (thanks
      	Marshall T. Rose)
      
      	* default.xrdb: New default theme
      	* tkabber.tcl: New variable load_default_xrdb
      
      2002-09-05  Alexey Shchepin  <alexey@sevcom.net>
      
      	* presence.tcl: Bugfix
      
      	* roster.tcl: New hook roster_create_groupchat_user_menu_hook
      
      	* tkabber.tcl (add_win): New variable raise_new_tab
      
      	* roster.tcl (roster::create): Bindings for second mouse wheel
      
      	* presence.tcl (get_jids_of_user): Performance improvements
      
      2002-09-04  Alexey Shchepin  <alexey@sevcom.net>
      
      	* register.tcl: Fixed bug with sending <item> tag instead of
      	<query>
      
      	* tkabber.tcl: New dialog for raw XML input
      
      	* (all): better icons.  added encrypt button to chat windows.
      	added headline caching between Tkabber sessions.  lots of crypto
      	fixes.  small change to hook::add so that if you source the same
      	plugin multiple times, it doesn't get added multiple times.
      	bugfix to presence status.  (thanks Marshall T. Rose)
      
      
      2002-09-03  Alexey Shchepin  <alexey@sevcom.net>
      
      	* tkabber.tcl: Removed unsetting of 'rw' and 'nw' to make C-r work
      	correctly
      
      	* chats.tcl: stop_scroll renamed to options(stop_scroll)
      
      	* avatars.tcl: avatar(announce) & avatar(share) renamed to
      	options(...)
      
      	* tkabber.tcl (browseurl): Fixed call to exec for windows platform
      
      	* (all): Show resources for users that have few ones in roster
      	(thanks Sergei Golovan)
      
      2002-09-02  Alexey Shchepin  <alexey@sevcom.net>
      
      	* roster.tcl (roster::redraw_after_idle): New function to optimize
      	calls to roster::redraw
      	* chat.tcl (chat::redraw_roster_after_idle): Likewise for
      	chat::redraw_roster
      
      	* doc/: Now we have documentation! (thanks Marshall T. Rose)
      
      	* (all): i got ballooning working with the emoticon menu. wasn't
      	easy.  fixed a few corner cases in when tkabber decides to handle
      	crypto stuff.  a lot of little changes to make the documentation
      	easier.  you can now set presence status from the main menu, e.g.,
      	click on "Away" and then enter "at lunch..."  managed to get rid
      	of the jlib::presence calls in login.tcl first line of tkabber.tcl
      	is friendly in case wish not installed in /usr/bin/.  pixmap_theme
      	can now be a directory name.  things re-arranged a bit in
      	tkabber.tcl to support the documentation better.  various globals
      	unset after use.  my config file now has a splash screen. not all
      	that happy with it, but it's a start.  autoaway and dockingtray
      	now use fullblown namespaces
      	(thanks Marshall T. Rose)
      
      	* messages.tcl (message::send_subscribe): Fixed bug with adding
      	jids with uppercase letters
      
      2002-08-31  Alexey Shchepin  <alexey@sevcom.net>
      
      	* login.tcl: Login on "Return" in login dialog
      
      	* roster.tcl (roster::create_user_menu): Added new hook
      
      	* (all): fix SUBDIRS definition in Makefile.  fix some bugs in
      	putting icons in the chat window when sending.  replace a lot of
      	"$gw withdraw" with "destroy $gw".  have the emoticon menu put a
      	space around the emoticon (if necessary).  less paranoid
      	signature-checking.  typo in URL to Img package. (thanks Marshall
      	T. Rose)
      
      	* gpgme.tcl: Support for GPG (thanks Marshall T. Rose)
      
      2002-08-29  Alexey Shchepin  <alexey@sevcom.net>
      
      	* tkabber.tcl: Support for Unicode in X selection (idea taken from
      	alicq)
      
      2002-08-28  Alexey Shchepin  <alexey@sevcom.net>
      
      	* login.tcl: Remember presence status between logins
      
      	* roster.tcl: Ask user before removing item from roster
      
      	* messages.tcl (message::send_subscribe): Show item edit dialog
      	after receiving item in roster
      
      	* itemedit.tcl: New module for editing roster items
      	* editgroups.tcl: Joined into itemedit.tcl
      	* roster.tcl: Code for editing item's name moved to itemedit.tcl
      
      	* unix/wmdock.tcl (wmdock::msg_recv): Don't count messages in
      	non-tabs mode
      
      	* tkabber.tcl: Append to auto_path dir with tkabber.tcl instead of
      	current dir
      
      	* chats.tcl (chat::open_window): New variable raise_on_activity to
      	raise and deiconify windows in non-tabs mode
      
      	* userinfo.tcl: Show UTC and TZ tags in iq:time reply
      
      2002-08-27  Alexey Shchepin  <alexey@sevcom.net>
      
      	* chat-plugins/logger.tcl: Store private chats in conferences,
      	fixed bug with history in chats windows
      
      	* chats.tcl (chat::change_presence): Bugfix
      
      	* utils.tcl (double%): New function for doubling '%' symbol in
      	bind scripts, to avoid some bugs
      	* chat-plugins/history.tcl: Changed bindings to use double%
      	function
      	* chats.tcl: Likewise
      	* roster.tcl: Likewise
      
      2002-08-26  Alexey Shchepin  <alexey@sevcom.net>
      
      	* roster.tcl: New hook on changing other users presence
      
      	* presence.tcl: New hook on changing our presence
      
      	* login.tcl: New hooks for connected & disconnected procedures
      
      	* unix/wmdock.tcl: Support for WindowMaker dock (thanks Michail
      	Litvak)
      
      	* tkabber.tcl (fullpath): Works more correctly
      
      	* tkabber.tcl: make the about window it's own proc; fix
      	plugins::load typo for platform (had an extra call to fullpath)
      	(thanks Marshall T. Rose)
      
      	* tkabber.tcl (add_win): Change iconname of windows in non-tab
      	mode
      
      	* unix/autoaway.tcl: Fixed bug with calling of autoaway functions
      	when tkXwin package not present
      
      2002-08-25  Alexey Shchepin  <alexey@sevcom.net>
      
      	* chats.tcl (chat::add_emoteiconed_text): Limited output of
      	emoticons by number of it instead of body size
      
      	* login.tcl: New hooks on connection and disconnection from server
      
      	* filetransfer.tcl (ft::send_file_accept): Content type changed to
      	application/data to avoid corrupting of binary files
      
      	* hooks.tcl: All hooks functions moved from plugins.tcl to
      	hooks.tcl
      	* plugins.tcl: Likewise
      
      	* presence.tcl (get_jid_status): Bugfix
      
      	* (all): removed not needed "global w"; tab_set_updated now has
      	defaults for some of its arguments; fixed a typo introduced with
      	the silly entry .delete .insert thing; temporarily put a catch
      	around the creation of rostericon(user,invisible); tab_set_updated
      	is a bit more clever to figure out if an update has actually
      	happened (the dockingtray stuff needs that); put finload after the
      	invocation of the login dialog; cleaned up autoaway.tcl a bit
      	(thanks Marshall T. Rose)
      
      	* roster.tcl (roster::redraw): Don't show groups without online
      	users in "Show online users only" mode
      
      	* iq-plugins/time.tcl: Show timezone in <display/> tag
      
      2002-08-24  Alexey Shchepin  <alexey@sevcom.net>
      
      	* joingrdialog.tcl: New conference room creation dialog, but it
      	seems that room creation not implemented in jabberd
      
      	* chats.tcl: Colors of chat text can be configured via xrdb
      
      	* pixmaps/gabber/services/: New icons for gabber theme
      
      2002-08-23  Alexey Shchepin  <alexey@sevcom.net>
      
      	* unix/autoaway.tcl: New plugin for autoaway support
      
      	* chats.tcl: Change type of messages with empty type to
      	$default_message_type
      
      	* roster.tcl: Fixed showing of conference items foreground
      
      	* roster.tcl: Support for new icons
      
      	* jabberlib-tclxml/tclxml/: Added TclXML with tclparser
      
      	* jabberlib-tclxml/wrapper.tcl: Changes to support tclparser
      	library
      
      2002-08-22  Alexey Shchepin  <alexey@sevcom.net>
      
      	* (all): change a few puts into debugmsg. fix an interoperability
      	bug with gabber messages. double-sided clicks. a few more "..." in
      	the menus. better focus selection in the dialogs. a fix for an
      	amusing entry/disabled problem in windows. still another approach
      	to the "package require Tls" thing. rearrange the order of some
      	widget creations, so that TAB works as you'd expect. add a user
      	hook, [get_our_presence_status], that gives the <status/> on a
      	presence change. typo in browseurl. various little UI changes
      	(thanks Marshall T. Rose)
      
      	* chats.tcl (chat::change_presence): Bugfix
      
      2002-08-21  Alexey Shchepin  <alexey@sevcom.net>
      
      	* roster.tcl (roster::redraw): Items now sorted by names instead
      	of jids
      
      	* chats.tcl (chat::create_user_menu): More useful items in user's
      	menu
      
      	* joingrdialog.tcl: Checking for errors while joining conference
      	with v2 protocol.  Support for password-protected groups with v2
      	protocol
      
      	* chats.tcl: Fixed scrollbars in invitation dialog
      
      	* roster.tcl: Fixed scrollbars in 'send users' dialog
      
      	* tkabber.tcl: Menu for avatars
      
      	* avatars.tcl: Support for storing avatar on server and bugfixes
      
      	* chats.tcl (chat::process_message): Temporary workaround in bug
      	with empty message type
      
      	* avatars.tcl (avatar::get_image): Fixed typo with debugmg
      
      2002-08-20  Alexey Shchepin  <alexey@sevcom.net>
      
      	* (all): Changed work with icons; added some new icons (thanks
      	Sergei Golovan)
      
      	* (all): have avatar.tcl use debugmsg; enable right-clicks for
      	chat menubutton; add "..." to create_user_menu; better login/tls
      	prompting; small grammar correction (thanks Marshall T. Rose)
      
      	* examples/config.tcl: Expamle of using avatars and emoticons
      
      	* roster.tcl (roster::add_menu_item): Bugfix
      
      	* emoticons.tcl: Emoticons menu can also popup by A-e
      
      2002-08-19  Alexey Shchepin  <alexey@sevcom.net>
      
      	* chat-plugins/nick_command.tcl: Temporary solution for nick
      	changes in v1 protocol
      
      	* balloon.tcl: Small fixes to make Frink work more silently
      	* browser.tcl: Likewise
      	* chats.tcl: Likewise
      	* filters.tcl: Likewise
      	* plugins.tcl: Likewise
      
      	* roster.tcl: Now users can set default nicks via array
      	defaultnick
      	* examples/config.tcl: Example of using defaultnick
      
      	* emoticons.tcl: Now in chats we can popup menu with emoticons by
      	pressing M-e
      
      	* presence.tcl: Bugfixes
      
      	* roster.tcl: In user popup menu now possible to select different
      	resources of users
      
      	* (all): 1. replace remaining "puts" with "debugmsg" 2. menus
      	for headlines 3. small typos/capitalizations, e.g., "distrub",
      	"Histroy" 4. remove tearoff from the popupmenus (because these
      	expect $curuser to point to the current item, but that won't work
      	for a tearoff) 5. two new hooks: proc menuload to update the menu
      	specification, and proc finload, called right before the
      	login. (see examples/mtr-config.tcl for examples of their usage.)
      	6. sgml bug fixed. (thanks Marshall T. Rose)
      
      2002-08-18  Alexey Shchepin  <alexey@sevcom.net>
      
      	* userinfo.tcl: Show result of iq:last in more user-readable form
      
      	* avatars.tcl: Basic support for avatars
      	* userinfo.tcl: Likewise
      	* presence.tcl: Likewise
      
      	* browser.tcl: New icons for aim, icq, msn and yahoo transports
      	(thanks Sergei Golovan)
      
      	* roster.tcl: Changed button to show only online buttons (thanks
      	Sergei Golovan)
      	* tkabber.tcl: Likewise
      
      	* messages.tcl: Changed calls to base64 function
      
      	* roster.tcl: Items indent now less to avoid wasting of useful
      	space
      
      	* chats.tcl: Bugfixes
      
      	* roster.tcl: Bugfixes
      
      2002-08-17  Alexey Shchepin  <alexey@sevcom.net>
      
      	* roster.tcl: Now we have much more beautiful roster (thanks
      	Sergei Golovan)
      
      	* chats.tcl: Added menu entry in conferences to show history
      
      	* chat-plugins/logger.tcl: New format for history files, not
      	compatible with old
      
      	* (all): 1. for a group conference, have the "Subject:" button lie
      	flat and work on right-click, like the rest of the user
      	buttons. 2. use the stated priority when logging in. 3. add
      	"logout with reason". 4. a few more "..." to menu names, also use
      	"Cancel" instead of "Close" for many windows. 5. a lot of cleanups
      	for the headline code. it's pretty usable now. 6. still more work
      	on the user status popup 7. don't advertise conferences when
      	sending users or making invitations 8. better proc browseurl
      	9. put logs in ~/.tkabber/logs/ (thanks Marshall T. Rose)
      
      	* login.tcl: Now can send encrypted password (thanks Sergei Golovan)
      
      2002-08-16  Alexey Shchepin  <alexey@sevcom.net>
      
      	* chats.tcl: Added menu in every userchat for showing user
      	information and history
      
      	* roster.tcl: Different menu for conference items
      
      	* chats.tcl (chat::highlighttext): Changing form of mouse cursor,
      	when it on URL (thanks Sergei Golovan)
      
      	* (all): new image for headlines (taken from gabber); menubutton
      	to invite folks to join an existing conference; implemented
      	receiving x:roster and x:oob; implemented sending x:roster;
      	implemented resubscribe; for file transfer, will try to get a
      	default ip address other than 127.0.0.1; for the
      	filters/search/register windows, don't draw them until the server
      	responds; diddle status menubutton when starting and when
      	dis/connected; if disconnected by network, put up the login
      	dialog; many cosmetic changes (big thanks to Marshall T. Rose)
      
      	* chats.tcl: New variable 'url_regexp'
      
      	* tkabber.tcl (pixmap): New function for finding images with
      	different themes (thanks Sergei Golovan)
      	* browser.tcl: Using 'pixmap' for loading images
      	* roster.tcl: Likewise
      	* pixmaps/: New themes 'psi' & 'gabber'
      	* examples/config.tcl: Example of using different themes
      
      2002-08-15  Alexey Shchepin  <alexey@sevcom.net>
      
      	* Tclx.tcl (lmatch): Fixed bug with regexp processing
      
      	* chat-plugins/completion.tcl: Now completion work correctly with
      	nicks that contain non-latin1 characters and work like zsh with
      	AUTO_MENU option (cycle completion?)
      
      	* tkabber.tcl: Removed 'T' button from toolbar
      
      2002-08-14  Alexey Shchepin  <alexey@sevcom.net>
      
      	* browser.tcl: Now show number of children in popup balloon for each
      	item
      
      	* chats.tcl: Now autoscrolling in chats can be stopped
      	* tkabber.tcl: Added menu for stoping autoscroll
      
      	* chats.tcl: Highlighting URLs and start WEB-browser on click
      
      	* chat-plugins/draw_normal_message.tcl: Highlight user's nick at
      	begining of message
      
      	* tkabber.tcl (tab_set_updated): Added different levels of updates
      	in chats, that highlighted with different colors
      	* chat-plugins/draw_normal_message.tcl: Likewise
      	* chat-plugins/draw_server_message.tcl: Likewise
      	* chat-plugins/draw_error.tcl: Likewise
      
      	* (all): Replaced "Ok" to "OK" in dialog buttons
      
      	* tkabber.tcl: Changed grid weight for roster, because with old
      	value on some systems roster have null width
      	* chats.tcl: Likewise
      
      	* chat-plugins/draw_normal_message.tcl: Nick names also highlited
      
      	* examples/mtr-config.tcl: Updated
      
      	* messages.tcl: Bugfix in headlines processing (thanks Marshall
      	T. Rose)
      
      2002-08-13  Alexey Shchepin  <alexey@sevcom.net>
      
      	* userinfo.tcl: Support for editing user's vCard
      
      2002-08-12  Alexey Shchepin  <alexey@sevcom.net>
      
      	* emoticons.tcl: Basic support for JEP-0038 (image/gif only and no
      	sounds)
      
      	* (all): Support for headlines, invitations of users to join
      	chats, better support for configurable colors, fixing typos, and
      	replacing many functions of TclX (big thanks to Marshall T. Rose)
      
      2002-08-11  Alexey Shchepin  <alexey@sevcom.net>
      
      	* chats.tcl (chat::add_emoteiconed_text): Performance improvements
      
      	* userinfo.tcl: Now can query jabber:iq:last
      
      	* iq-plugins/version.tcl: Show also OS version
      
      	* browser.tcl: Fixed bug with spaces in jids
      
      	* utils.tcl: Added functions to simplify work with canvas tags
      
      	* login.tcl: Support for user's login profiles
      	* examples/config.tcl: Added examples of using login profiles
      
      2002-08-10  Alexey Shchepin  <alexey@sevcom.net>
      
      	* chats.tcl: Fixed bug with nicks containg glob-characters
      
      	* iq-plugins/browse.tcl: Answer on browser requests with supported
      	iq namespaces
      
      	* roster.tcl: Now roster don't change position on any change
      
      	* chats.tcl (chat::change_presence): Fixed bug with staying users
      	after exiting conference with v2 protocol
      
      	* browser.tcl: Now items can be draged to browser's entry field
      
      	* tkabber.tcl (tab_set_updated): Performance improvements
      
      2002-08-09  Alexey Shchepin  <alexey@sevcom.net>
      
      	* search.tcl: Now users can be added from search results
      
      	* joingrdialog.tcl: Conference-v2 support
      	* joingrdialog.tcl (join_group_dialog): Added checkbutton for
      	selecting conference protocol
      
      	* roster.tcl: Now items can be draged from browser to roster
      	* browser.tcl: Likewise
      
      	* messages.tcl: Processing of jabber:x:roster, jabber:x:oob &
      	jabber:x:conference (not completed)
      
      	* tkabber.tcl (debugmsg): New function for showing debug messages
      	* browser.tcl: Replaced "puts" to "debugmsg" calls
      	* chats.tcl: Likewise
      	* filetransfer.tcl: Likewise
      	* filters.tcl: Likewise
      	* iq.tcl: Likewise
      	* joingrdialog.tcl: Likewise
      	* plugins.tcl: Likewise
      	* presence.tcl: Likewise
      	* roster.tcl: Likewise
      	* search.tcl: Likewise
      	* userinfo.tcl: Likewise
      
      2002-08-08  Alexey Shchepin  <alexey@sevcom.net>
      
      	* joingrdialog.tcl: Conference-v2 support (not completed)
      
      	* login.tcl (show_login_dialog): Set focus by default on "Login"
      	button
      
      	* roster.tcl: Now in group names drawed how many online users in
      	this group
      
      	* browser.tcl: Bugfixes & removed old browser code
      
      	* tkabber.tcl: Reorganized main menu
      
      2002-08-07  Alexey Shchepin  <alexey@sevcom.net>
      
      	* userinfo.tcl: Changes to more correspond to
      	http://www.jabber.org/protocol/vcard-xml/vCard-XML-v2-20010520.dtd
      	(not completed)
      
      	* browser.tcl: New Jabber Browser interface
      
      2002-08-06  Alexey Shchepin  <alexey@sevcom.net>
      
      	* filters.tcl: Support for editing filters
      
      	* browser.tcl: Browser now can be scrolled with mousewheel (if it
      	binds to 4 and 5 mouse buttons).
      
      	* login.tcl (client:disconnect): New function, that called when
      	disconnecting
      
      	* tkabber.tcl: Now roster can be collapsed with C-r
      
      2002-08-05  Alexey Shchepin  <alexey@sevcom.net>
      
      	* roster.tcl: Scrollbars on roster now drawed only when needed
      
      	* search.tcl: Displaying of jids in search results and added
      	scrollbars
      
      	* (all): Tkabber now can be started from any directory
      
      	* login.tcl: Fixed typo which result in ignoring entered in login
      	dialog fields
      
      	* tkabber.tcl: Correctly logout when closing main window
      
      2002-08-03  Alexey Shchepin  <alexey@sevcom.net>
      
      	* emoticons.tcl: Changed emoticons API
      
      	* userinfo.tcl: Bugfix
      
      2002-08-02  Alexey Shchepin  <alexey@sevcom.net>
      
      	* examples: Added some examples of config file & xrdb files
      	(thanks Sergei Golovan)
      
      	* login.tcl: All data for login now stored in loginconf variable
      
      	* tkabber.tcl (tab_set_updated): Bugfix in tabs highlighting
      
      	* balloon.tcl: Added new tooltips engine (thanks Sergei Golovan)
      
      	* tkabber.tcl: Config now stored in ~/.tkabber/config.tcl
      
      	* tkabber.tcl: Fixed bug with incorrect closing of chat windows
      
      2002-08-01  Alexey Shchepin  <alexey@sevcom.net>
      
      	* chats.tcl (chat::open_window): Don't resize roster when resizing
      	window
      	* tkabber.tcl: Likewise
      
      	* messages.tcl (send_message_dialog): Now destination address can
      	be edited
      	* tkabber.tcl (menu): Added menu entry for sending new messages
      
      	* tkabber.tcl: Support for status line
      	* roster.tcl (roster::on_change_jid_presence): Likewise
      
      	* filetransfer.tcl: Bugfixes in sending file
      
      	* tkabber.tcl (tab_set_updated): Highlighting tabs in non-active
      	chats
      
      	* roster.tcl: Added dialog for editing names of roster items
      
      	* chats.tcl (chat::open_window): Now if jid have name in roster,
      	then this name used in titles.
      
      2002-07-31  Alexey Shchepin  <alexey@sevcom.net>
      
      	* tkabber.tcl (add_win): Temporary workaround for bug with tabs &
      	jids with spaces
      
      2002-07-30  Alexey Shchepin  <alexey@sevcom.net>
      
      	* roster.tcl (roster::addline): Collapsed groups now highlighted
      
      	* filetransfer.tcl: Basic support for file transfers
      	* iq-plugins/oob.tcl: Likewise
      
      	* iq.tcl: Answer "501 Not Implemented" on unknown iq requests
      
      2002-07-29  Alexey Shchepin  <alexey@sevcom.net>
      
      	* browser.tcl: Add checks to avoid errors when reply received in
      	closed window
      
      	* login.tcl: Now we can create new accounts
      
      	* editgroups.tcl (change_groups_to_user): Changes in roster item
      	groups now don't touch another item parameters
      	* roster.tcl (roster::item_to_xml): Likewise
      
      	* (all): Tkabber now parse xml stream via TclXML library
      	(http://tclxml.sf.net)
      
      	* utils.tcl (tolower_node_and_domain): Fixed stupid bug with
      	doubling of resource field in jids that have not node field
      
      	* tkabber.tcl: Fixed mistake in menu "Services"
      
      	* tkabber.tcl (add_win): Fixed mistake with "wm title"
      
      ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tkabber-0.11.1/default.tcl��������������������������������������������������������������������������0000644�0001750�0001750�00000007103�10566637612�014667� 0����������������������������������������������������������������������������������������������������ustar  �sergei��������������������������sergei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# $Id: default.tcl 954 2007-02-20 18:35:54Z sergei $
      
      if {$tcl_platform(platform) == "windows"} {
          package require dde
      }
      
      proc postload {} {}
      
      proc menuload {menudesc} { return $menudesc }
      
      proc finload  {} {}
      
      proc browser_loadopt {} {
          custom::defvar webbrowser "" \
      	[::msgcat::mc "Command to be run when you click a URL\
      in a message.  '%s' will be replaced with this URL (e.g. \"galeon -n %s\")."]\
      	-group IFace -type string
      }
      hook::add postload_hook browser_loadopt
      
      
      proc browseurl {url} {
          global env tcl_platform
      
          set_status $url
          update
      
          if {[info exists ::webbrowser] && \
      	    $::webbrowser != ""} {
      	# If user specified a browser, use it
      	eval exec [format $::webbrowser [list $url]] &
      	return
          }
      
          # Set the clipboard value to this url in-case the user needs to paste the 
          # url in (some windows systems).
          clipboard clear
          clipboard append $url
      
          switch -- $tcl_platform(platform) {
              windows {
                  # DDE uses commas to separate command parts
                  set url [string map {, %2c} $url]
      
                  # See if we can use dde and an existing browser.
                  set handled 0
                  foreach app {Firefox {Mozilla Firebird} Mozilla Netscape IExplore} {
                      if {[set srv [dde services $app WWW_OpenURL]] != {}} {
                          if {[catch {dde execute $app WWW_OpenURL $url} msg]} {
                              debugmsg browseurl "dde exec $app failed: \"$msg\""
                          } else {
                              set handled 1
                              break
                          }
                      }
      	    }
      
      	    # The windows NT shell treats '&' as a special character. Using
      	    # a '^' will escape it. See http://wiki.tcl.tk/557 for more info. 
                  if {! $handled} {
                      if {[string compare $tcl_platform(os) "Windows NT"] == 0} { 
                          set url [string map {& ^&} $url]
                      }
                      if {[catch {eval exec [auto_execok start] [list $url] &} emsg]} {
                          MessageDlg .browse_err -aspect 50000 -icon info \
      			-buttons ok -default 0 -cancel 0 -type user \
                              -message \
      			    [format \
      				 [::msgcat::mc "Error displaying %s in browser\n\n%s"] \
      				 $url $emsg]
                      }
                  }
              }
      
              macintosh {
                  if {![info exists env(BROWSER)]} {
                      set env(BROWSER) "Browse the Internet"
                      AppleScript execute \
                      "tell application \"env(BROWSER)\"\nopen url \"$url\"\nend tell\n"
                  }
              }
      
              default {
                  if {![info exists env(BROWSER)]} {
                      foreach b [list firefox galeon konqueror mozilla-firefox \
                                     mozilla-firebird mozilla netscape \
                                     iexplorer opera] {
                          if {[llength [set e [auto_execok $b]]] > 0} {
                              set env(BROWSER) [lindex $e 0]
                              break
                          }
                      }
                      if {![info exists env(BROWSER)]} {
      		    if {[cequal $tcl_platform(os) Darwin]} {
      			exec open $url &
      			set_status ""
      			return
      		    }
                          MessageDlg .browse_err -aspect 50000 -icon info \
                              -message [::msgcat::mc "Please define environment variable BROWSER"] \
      			-type user \
      			-buttons ok -default 0 -cancel 0
                          return
                      }
                  }
      
                  if {[catch { eval exec $env(BROWSER) -remote \"openURL($url, new-tab)\" }]} {
      		if {[catch { exec $env(BROWSER) -remote $url }]} {
      		    exec $env(BROWSER) $url &
      		}
      	    }
      	}
          }
      
          set_status ""
      }
      
      
      �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tkabber-0.11.1/pixmaps.tcl��������������������������������������������������������������������������0000644�0001750�0001750�00000013205�10624355635�014721� 0����������������������������������������������������������������������������������������������������ustar  �sergei��������������������������sergei�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������# $Id: pixmaps.tcl 1129 2007-05-21 17:49:17Z sergei $
      
      ###############################################################################
      
      catch {
          package require vfs::zip
      }
      
      ###############################################################################
      
      namespace eval pixmaps {
          variable theme_dirs \
      	[concat [glob -nocomplain -directory [fullpath pixmaps] *] \
      		[glob -nocomplain -directory [file join $::configdir pixmaps] *]]
      
          variable themes
          array set themes {}
      
          variable filenames
          array set filenames {}
      }
      
      ###############################################################################
      
      proc pixmaps::init_custom {} {
          variable options
          variable themes
      
          set values {}
          set theme_names [lsort [array names themes]]
          set idx [lsearch -exact $theme_names Default]
          set theme_names [linsert [lreplace $theme_names $idx $idx] 0 Default]
          foreach theme $theme_names {
      	lappend values $theme $theme
          }
      
          custom::defvar options(pixmaps_theme) Default \
      	[::msgcat::mc \
      	    "Tkabber icon theme. To make new theme visible for Tkabber\
      	     put it to some subdirectory of %s." \
      	     [file join $::configdir pixmaps]] \
      	-group IFace -type options -values $values \
      	-command [namespace current]::load_stored_theme
      }
      
      hook::add postload_hook [namespace current]::pixmaps::init_custom 45
      
      ###############################################################################
      
      proc pixmaps::load_stored_theme {args} {
          variable options
      
          if {[catch {load_theme $options(pixmaps_theme)}]} {
      	set options(pixmaps_theme) Default
          }
      
          hook::run set_theme_hook
      }
      
      hook::add postload_hook [namespace current]::pixmaps::load_stored_theme 70
      
      ###############################################################################
      
      proc pixmaps::load_themes {} {
          variable theme_dirs
      
          foreach dir $theme_dirs {
      	load_theme_name [namespace current]::themes $dir
          }
      }
      
      hook::add postload_hook [namespace current]::pixmaps::load_themes 40
      
      ###############################################################################
      
      proc pixmaps::load_theme_name {var dir} {
          set icondef_path [file join $dir icondef.xml]
          if {[file isfile $icondef_path]} {
      	set thdir $dir
          } elseif {![catch {::vfs::zip::Mount $dir $dir} mount_fd] && \
      	![catch {lindex [glob $dir/*/icondef.xml] 0} icondef_path]} {
      	set thdir [file dirname $icondef_path]
          } else {
      	return
          }
          if {![catch {open $icondef_path} f]} {
      	set icondef [read $f]
      	close $f
          } else {
      	catch {::vfs::zip::Unmount $mount_fd $dir}
      	return
          }
      
          set parser [jlib::wrapper:new "#" "#" \
      		    [list pixmaps::find_name $var $thdir]]
          jlib::wrapper:elementstart $parser stream:stream {} {}
          jlib::wrapper:parser $parser parse $icondef
          jlib::wrapper:parser $parser configure -final 0
          jlib::wrapper:free $parser
      }
      
      ###############################################################################
      
      proc pixmaps::find_name {var dir xmldata} {
          upvar #0 $var themes
      
          jlib::wrapper:splitxml $xmldata tag vars isempty cdata children
      
          if {$tag == "name"} {
      	set themes($cdata) $dir
      	return 1
          }
      
          set found 0
          foreach child $children {
      	if {[find_name $var $dir $child]} {
      	    return 1
      	}
          }
          return 0
      }
      
      ###############################################################################
      
      proc pixmaps::load_theme {theme} {
          variable themes
      
          load_dir $themes(Default)
          load_dir $themes($theme)
      }
      
      ###############################################################################
      
      proc pixmaps::load_dir {dir} {
          set icondef_path [file join $dir icondef.xml]
          if {![file isfile $icondef_path]} {
      	return -code error
          }
          set f [open $icondef_path]
          set icondef [read $f]
          close $f
      
          set parser [jlib::wrapper:new "#" "#" \
      		    [list pixmaps::parse_icondef $dir]]
          jlib::wrapper:elementstart $parser stream:stream {} {}
          jlib::wrapper:parser $parser parse $icondef
          jlib::wrapper:parser $parser configure -final 0
          jlib::wrapper:free $parser
      }
      
      ###############################################################################
      
      proc pixmaps::parse_icondef {dir xmldata} {
          jlib::wrapper:splitxml $xmldata tag vars isempty cdata children
      
          if {$tag != "icondef"} {
      	return -code error
          }
      
          foreach child $children {
      	parse_item $dir $child
          }
      
      }
      
      ###############################################################################
      
      proc pixmaps::parse_item {dir item} {
          jlib::wrapper:splitxml $item tag vars isempty cdata children
      
          switch -- $tag {
      	icon {
      	    parse_icon $dir $children
      	}
          }
      }
      
      ###############################################################################
      
      proc pixmaps::parse_icon {dir items} {
          variable filenames
      
          set type ""
          set image ""
          set object ""
          foreach item $items {
      	jlib::wrapper:splitxml $item tag vars isempty cdata children
      	switch -- $tag {
      	    image {
      		if {[jlib::wrapper:getattr $vars xmlns] == "tkimage"} {
      		    set image $cdata
      		}
      	    }
      	    object {
      		switch -glob -- [jlib::wrapper:getattr $vars mime] {
      		    image/ico {
      			set type ico
      			set object $cdata
      		    }
      		    image/* {
      			set object $cdata
      		    }
      		}
      	    }
      	}
          }
      
          if {$image == "" || $object == ""} return
      
          set filename [file join $dir $object]
          set filenames($image) $filename
      
          switch -- $type {
      	ico {}
      	default {
      	    image create photo $image -file $filename
      	}
          }
      }
      
      ###############################################################################
      
      proc pixmaps::get_filename {image} {
          variable filenames
      
          if {[info exists filenames($image)]} {
      	return $filenames($image)
          } else {
      	return -code error
          }
      }
      
      ###############################################################################
      
      �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������