[Tkabber-dev] r485 - in trunk/plugins: . notes

tkabber-svn at jabber.ru tkabber-svn at jabber.ru
Fri Apr 1 03:58:43 MSD 2011


Author: Totktonada
Date: 2011-04-01 03:58:43 +0400 (Fri, 01 Apr 2011)
New Revision: 485

Added:
   trunk/plugins/notes/
   trunk/plugins/notes/LINKS
   trunk/plugins/notes/TODO
   trunk/plugins/notes/notes.tcl
   trunk/plugins/notes/proto
Log:
New plugin: notes. Only basic ability.

Added: trunk/plugins/notes/LINKS
===================================================================
--- trunk/plugins/notes/LINKS	                        (rev 0)
+++ trunk/plugins/notes/LINKS	2011-03-31 23:58:43 UTC (rev 485)
@@ -0,0 +1,4 @@
+"XEP-0049: Private XML Storage" - http://xmpp.org/extensions/xep-0049.html
+Source of Miranda "Jabber notes" plugin - http://code.google.com/p/miranda/source/browse/trunk/miranda/protocols/JabberG/jabber_notes.cpp
+Description for Psi+ "Storage Notes" plugin - http://psi-plus.com/wiki/doku.php/plugins#storage_notes_plugin
+Source of Psi+ "Storage Notes" plugin - http://psi-dev.googlecode.com/svn/trunk/plugins/generic/storagenotesplugin/

Added: trunk/plugins/notes/TODO
===================================================================
--- trunk/plugins/notes/TODO	                        (rev 0)
+++ trunk/plugins/notes/TODO	2011-03-31 23:58:43 UTC (rev 485)
@@ -0,0 +1,25 @@
+Примерные наброски идей на будущее.
+
+"/notes list"
+"/notes add" - появляется окошко с полями ввода
+"/notes del #n"
+"/notes edit #n" - окошко с полями ввода
+Длинные команды:
+
+/notes add
+tag1 tag2 tag3
+title
+text
+
+/notes edit #n
+tag tag tag
+title
+text
+
+Можно вообще таб в Juick-style сделать. Пишешь туда — добавляешь заметку. E #номер — редактирование. D #номер — удалить. #номер *tag — добавить/удалить тег. # — вывести все заметки.
+
+Быстрая запись в заметку жуйкосущностей, ссылок и прочего. Возможность прикрепить заметку к JID'у, смотреть из меню соотв. контакта. Сохранять время последней модицикации.
+
+Обработка разнообразных ошибок при чтении из хранилища или записи в него.
+
+Удаление заметок.

Added: trunk/plugins/notes/notes.tcl
===================================================================
--- trunk/plugins/notes/notes.tcl	                        (rev 0)
+++ trunk/plugins/notes/notes.tcl	2011-03-31 23:58:43 UTC (rev 485)
@@ -0,0 +1,365 @@
+package require msgcat
+
+namespace eval notes {
+    ::msgcat::mcload [file join [file dirname [info script]] msgs]
+
+    if {![::plugins::is_registered notes]} {
+	::plugins::register notes \
+			    -namespace [namespace current] \
+			    -source [info script] \
+			    -description [::msgcat::mc "Whether the Notes plugin is loaded."] \
+			    -loadcommand [namespace code load] \
+			    -unloadcommand [namespace code unload]
+	return
+    }
+}
+
+proc notes::load {} {
+    variable notes
+    hook::add finload_hook [namespace current]::setup_menu
+    setup_menu
+}
+
+proc notes::unload {} {
+    variable notes
+    hook::remove finload_hook [namespace current]::setup_menu
+    desetup_menu
+    catch {unset notes}
+}
+
+proc notes::open_window {} {
+    variable notes
+
+    # create tab
+    set w .notes
+    if {[winfo exists $w]} {
+	raise_win $w
+	return
+    }
+
+    create_notes_tab $w
+#    request_server_notes
+}
+
+# ############################
+# Register in the main menu
+
+proc notes::setup_menu {} {
+    catch {
+	set m [.mainframe getmenu plugins]
+	set ind [$m index end]
+
+	$m insert $ind command -label [::msgcat::mc "Notes"] \
+	    -command [list [namespace current]::open_window]
+    }
+}
+
+proc notes::desetup_menu {} {
+    catch {
+	set m [.mainframe getmenu plugins]
+	set ind [$m index [::msgcat::mc "Notes"]]
+
+	$m delete $ind
+    }
+}
+
+##############################################################################
+
+proc notes::request_server_notes {} {
+    set xlib [lindex [connections] 0]
+    ::xmpp::sendIQ $xlib get \
+        -query [ \
+            ::xmpp::xml::create "query" \
+            -xmlns "jabber:iq:private" \
+            -subelement [ \
+                ::xmpp::xml::create "storage" \
+                -xmlns "http://miranda-im.org/storage#notes" \
+            ] \
+        ] \
+        -command [list [namespace current]::receive_server_notes]
+}
+
+proc notes::receive_server_notes {res child0} {
+    variable notes
+    set notes {}
+
+    if {![string equal $res "ok"]} return
+
+    ::xmpp::xml::split $child0 tag0 xmlns0 attrs0 cdata0 subels0
+
+    if {![cequal $tag0 "query"]} return
+    if {![cequal $xmlns0 "jabber:iq:private"]} return
+
+    set child1 [lindex $subels0 0]
+    ::xmpp::xml::split $child1 tag1 xmlns1 attrs1 cdata1 subels1
+
+    if {![cequal $tag1 "storage"]} return
+    if {![cequal $xmlns1 "http://miranda-im.org/storage#notes"]} return
+
+    foreach child2 $subels1 {
+        array set current_note [list \
+            tags "" \
+            title "" \
+            text ""]
+        ::xmpp::xml::split $child2 tag2 xmlns2 attrs2 cdata2 subels2
+        if {![cequal $tag2 "note"]} continue
+
+        set current_note(tags) \
+            [split [::xmpp::xml::getAttr $attrs2 "tags"] " "]
+
+	foreach child3 $subels2 {
+            ::xmpp::xml::split $child3 tag3 xmlns3 attrs3 cdata3 subels3
+            switch -- $tag3 {
+                title -
+                text {
+                    set current_note($tag3) $cdata3
+                }
+            }
+        }
+
+	lappend notes [array get current_note]
+    }
+
+    puts $notes
+
+    update_lbox
+    return
+}
+
+proc notes::send_notes {} {
+    variable notes
+    set xlib [lindex [connections] 0]
+
+    ::xmpp::sendIQ $xlib set \
+        -query [ \
+            ::xmpp::xml::create "query" \
+            -xmlns "jabber:iq:private" \
+            -subelement [ \
+                ::xmpp::xml::create "storage" \
+                -xmlns "http://miranda-im.org/storage#notes" \
+                -subelements [notes_to_xml] \
+            ] \
+        ] \
+        -command [list [namespace current]::check_send_notes_result]
+}
+
+proc notes::notes_to_xml {} {
+    variable notes
+    set xml_notes {}
+
+    foreach note $notes {
+        set title ""
+        set tags_str ""
+        set text ""
+
+        foreach {key value} $note {
+            switch -- $key {
+                title -
+                text {
+                    set $key $value
+                }
+                tags {
+                    set tags_str [join $value " "]
+                }
+            }
+        }
+
+        lappend xml_notes [ \
+            ::xmpp::xml::create "note" \
+                -attrs [list "tags" $tags_str] \
+                -subelement [ \
+                    ::xmpp::xml::create "title" \
+                        -cdata $title \
+                ] \
+                -subelement [ \
+                    ::xmpp::xml::create "text" \
+                        -cdata $text \
+                ] \
+        ]
+    }
+
+    return $xml_notes
+}
+
+
+proc notes::check_send_notes_result {res child0} {
+# TODO
+}
+
+##############################################################################
+
+proc notes::create_notes_tab {w} {
+#    set w .notes
+#    if {![winfo exists $w]} return
+
+    # base widget
+    add_win $w -title [::msgcat::mc "Notes"] \
+	-tabtitle [::msgcat::mc "Notes"] \
+	-class Notes \
+	-raise 1
+
+    # button box
+    set tools [frame $w.tools -borderwidth 5]
+    pack $tools -side right -fill y -anchor w
+
+    set download_button [button $tools.download_button -text [::msgcat::mc "Download"] \
+        -command [list [namespace current]::request_server_notes]]
+    set upload_button [button $tools.upload_button -text [::msgcat::mc "Upload"] \
+        -command [list [namespace current]::send_notes]]
+    set new_button [button $tools.new_button -text [::msgcat::mc "New note"] \
+        -command [list [namespace current]::open_note "" -1 ""]]
+
+    pack $download_button -anchor w -side top
+    pack $upload_button -anchor w -side top
+    pack $new_button -anchor w -side top
+
+    # main frame
+    set main_frame [frame $w.main_frame]
+    pack $main_frame -side left -fill both -expand true -anchor w
+
+    # main frame widget
+    grid columnconfigure $main_frame 0 -weight 1
+    set sw [ScrolledWindow $main_frame.sw]
+
+    set lbox [listbox $main_frame.lbox -takefocus 1 -exportselection 0]
+    $lbox selection clear 0 end
+    $lbox selection set 0
+    focus $lbox
+
+# ==== Bind ====
+    # From ${PATH_TO_TKABBER}/plugins/chat/histool.tcl
+    # Workaround for a bug in listbox (can't get focus on mouse clicks):
+    bind Listbox <Button-1> {+ if {[winfo exists %W]} {focus %W}}
+
+    bind $lbox <Double-Button-1> [namespace code {
+	open_note %W [%W nearest %y]
+    }]
+
+    bind $lbox <Return> [namespace code {
+	open_note %W [%W index active]
+    }]
+# ====  ====
+
+    $sw setwidget $lbox
+    grid $sw -sticky news
+    grid rowconfigure $main_frame 0 -weight 1
+}
+
+proc notes::open_note {w idx args} {
+    variable notes
+
+    set title ""
+    set tags_str ""
+    set text ""
+
+    if {$idx >= 0} {
+        set source_note [lindex $notes $idx]
+        foreach {key value} $source_note {
+            switch -- $key {
+                title -
+                text {
+                    set $key $value
+                }
+                tags {
+                    set tags_str [join $value " "]
+                }
+            }
+        }
+    }
+
+    set dialog_w .edit_note
+    catch { destroy $dialog_w }
+    set dialog_w [Dialog $dialog_w -title [::msgcat::mc "Edit note"] \
+        -separator 1 \
+        -anchor e \
+        -default 0 \
+        -cancel 1 \
+        -modal none]
+
+    set dialog_frame [$dialog_w getframe]
+    grid columnconfigure $dialog_frame 1 -weight 1
+
+    label $dialog_frame.ltitle -text [::msgcat::mc "Title:"]
+    [entry $dialog_frame.title] insert end $title
+    label $dialog_frame.ltags  -text [::msgcat::mc "Tags:"]
+    [entry $dialog_frame.tags] insert end $tags_str
+    label $dialog_frame.ltext  -text [::msgcat::mc "Text:"]
+    [entry $dialog_frame.text] insert end $text
+
+    grid $dialog_frame.ltitle -row 0 -column 0 -sticky e
+    grid $dialog_frame.title  -row 0 -column 1 -sticky ew
+    grid $dialog_frame.ltags  -row 1 -column 0 -sticky e
+    grid $dialog_frame.tags   -row 1 -column 1 -sticky ew
+    grid $dialog_frame.ltext  -row 2 -column 0 -sticky e
+    grid $dialog_frame.text   -row 2 -column 1 -sticky ew
+
+    $dialog_w add -text [::msgcat::mc "Ok"] \
+        -command [list [namespace current]::update_one_note $idx $dialog_w]
+    $dialog_w add -text [::msgcat::mc "Cancel"] \
+        -command [list destroy $dialog_w]
+    $dialog_w draw $dialog_frame.title
+}
+
+proc notes::update_one_note {idx dialog_w} {
+    variable notes
+
+    set dialog_frame [$dialog_w getframe]
+
+    set title [$dialog_frame.title get]
+    set tags  [split [$dialog_frame.tags get] " "]
+    set text [$dialog_frame.text get]
+
+    set new_note [list \
+        title $title \
+        tags $tags \
+        text $text \
+    ]
+
+    if {$idx >= 0} {
+        lset notes $idx $new_note
+        update_lbox_at $idx $new_note
+    } else {
+        lappend notes $new_note
+        append_to_lbox $new_note
+    }
+    destroy $dialog_w
+}
+
+proc notes::update_lbox_at {idx new_note} {
+    variable notes
+    set lbox .notes.main_frame.lbox
+    $lbox delete $idx $idx
+    $lbox insert $idx [get_short_string $new_note]
+}
+
+proc notes::append_to_lbox {new_note} {
+    variable notes
+
+    set lbox .notes.main_frame.lbox
+    $lbox insert end [get_short_string $new_note]
+}
+
+proc notes::update_lbox {} {
+    variable notes
+
+    set lbox .notes.main_frame.lbox
+    $lbox delete 0 end
+
+    foreach note $notes {
+	$lbox insert end [get_short_string $note]
+    }
+#    $lbox selection clear 0 end
+#    $lbox selection set 0
+}
+
+proc notes::get_short_string {note} {
+    foreach {key value} $note {
+        switch -- $key {
+            title {
+                return $value
+	    }
+	}
+    }
+    return "Empty title?"
+}
+

Added: trunk/plugins/notes/proto
===================================================================
--- trunk/plugins/notes/proto	                        (rev 0)
+++ trunk/plugins/notes/proto	2011-03-31 23:58:43 UTC (rev 485)
@@ -0,0 +1,63 @@
+See XEP-0049.
+
+===================
+Request to receive notes:
+===================
+
+<iq type='get' id='id1'>
+    <query xmlns='jabber:iq:private'>
+        <storage xmlns='http://miranda-im.org/storage#notes'/>
+    </query>
+</iq>
+
+===================
+Positive response:
+===================
+
+<iq type='result' to='myjid at server.tld' id='id1'>
+    <query xmlns='jabber:iq:private'>
+        <storage xmlns='http://miranda-im.org/storage#notes'>
+
+            <note tags='tag1 tag2 tag3'>
+                <title>Title 1</title>
+                <text>Note body 1</text>
+            </note>
+
+            <note tags=''>
+                <title>Title 2</title>
+                <text>Note body 2</text>
+            </note>
+
+        </storage>
+    </query>
+</iq>
+
+===================
+Send notes to server:
+===================
+
+<iq type='set' id='id1'>
+    <query xmlns='jabber:iq:private'>
+        <storage xmlns='http://miranda-im.org/storage#notes'>
+	
+            <note tags='tag1 tag2 tag3'>
+                <title>Title 1</title>
+                <text>Note body</text>
+            </note>
+
+            <note tags=''>
+                <title>Title 2</title>
+                <text>Note body 2</text>
+            </note>
+
+        </storage>
+    </query>
+</iq>
+
+===================
+Positive response:
+===================
+
+<iq type='result' to='myjid at server.tld' id='id1'>
+    <query xmlns='jabber:iq:private'/>
+</iq>



More information about the Tkabber-dev mailing list