home *** CD-ROM | disk | FTP | other *** search
/ Practical Programming in Tcl & Tk (4th Edition) / TCLBOOK4.BIN / mac / extensions / tktreectrl / tktreectrl-1.0-7.tar.gz / tktreectrl-1.0-7.tar / tktreectrl-1.0-7 / demos / outlook-newgroup.tcl < prev    next >
Text File  |  2003-01-01  |  12KB  |  383 lines

  1. #
  2. # Demo: Outlook Express newsgroup messages
  3. #
  4. proc DemoOutlookNewsgroup {} {
  5.  
  6.     global Message
  7.  
  8.     InitPics outlook-*
  9.  
  10.     set T .f2.f1.t
  11.  
  12.     set height [font metrics [$T cget -font] -linespace]
  13.     if {$height < 18} {
  14.         set height 18
  15.     }
  16.     $T configure -itemheight $height -selectmode browse \
  17.         -showroot no -showrootbutton no -showbuttons yes -showlines no
  18.  
  19.     $T column configure 0 -image outlook-clip -tag clip
  20.     $T column configure 1 -image outlook-arrow -tag arrow
  21.     $T column configure 2 -image outlook-watch -tag watch
  22.     $T column configure 3 -text Subject -width 250 -tag subject
  23.     $T column configure 4 -text From -width 150 -tag from
  24.     $T column configure 5 -text Sent -width 150 -tag sent
  25.     $T column configure 6 -text Size -width 60 -justify right -tag size
  26.  
  27.     # Would be nice if I could specify a column -tag too
  28.     $T configure -treecolumn 3
  29.  
  30.     # State for a read message
  31.     $T state define read
  32.  
  33.     # State for a message with unread descendants
  34.     $T state define unread
  35.  
  36.     $T element create elemImg image -image {
  37.         outlook-read-2Sel {selected read unread !open}
  38.         outlook-read-2 {read unread !open}
  39.         outlook-readSel {selected read}
  40.         outlook-read {read}
  41.         outlook-unreadSel {selected}
  42.         outlook-unread {}
  43.     }
  44.     $T element create elemTxt text -fill [list $::SystemHighlightText {selected focus}] \
  45.         -font [list "[$T cget -font] bold" {read unread !open} "[$T cget -font] bold" {!read}] -lines 1
  46.     $T element create sel.e rect -fill [list $::SystemHighlight {selected focus} gray {selected !focus}] -open e -showfocus yes
  47.     $T element create sel.w rect -fill [list $::SystemHighlight {selected focus} gray {selected !focus}] -open w -showfocus yes
  48.     $T element create sel.we rect -fill [list $::SystemHighlight {selected focus} gray {selected !focus}] -open we -showfocus yes
  49.  
  50.     # Image + text
  51.     set S [$T style create s1]
  52.     $T style elements $S {sel.e elemImg elemTxt}
  53.     $T style layout $S elemImg -expand ns
  54.     $T style layout $S elemTxt -padx {2 6} -squeeze x -expand ns
  55.     $T style layout $S sel.e -union [list elemTxt] -iexpand nes -ipadx {2 0}
  56.  
  57.     # Text
  58.     set S [$T style create s2.we]
  59.     $T style elements $S {sel.we elemTxt}
  60.     $T style layout $S elemTxt -padx 6 -squeeze x -expand ns
  61.     $T style layout $S sel.we -detach yes -iexpand es
  62.  
  63.     # Text
  64.     set S [$T style create s2.w]
  65.     $T style elements $S {sel.w elemTxt}
  66.     $T style layout $S elemTxt -padx 6 -squeeze x -expand ns
  67.     $T style layout $S sel.w -detach yes -iexpand es
  68.  
  69.     set msgCnt 100
  70.  
  71.     set thread 0
  72.     set Message(count,0) 0
  73.     for {set i 1} {$i < $msgCnt} {incr i} {
  74.         $T item create
  75.         while 1 {
  76.             set j [expr {int(rand() * $i)}]
  77.             if {$j == 0} break
  78.             if {[$T depth $j] == 5} continue
  79.             if {$Message(count,$Message(thread,$j)) == 15} continue
  80.             break
  81.         }
  82.         $T item lastchild $j $i
  83.  
  84.         set Message(read,$i) [expr rand() * 2 > 1]
  85.         if {$j == 0} {
  86.             set Message(thread,$i) [incr thread]
  87.             set Message(seconds,$i) [expr {[clock seconds] - int(rand() * 500000)}]
  88.             set Message(seconds2,$i) $Message(seconds,$i)
  89.             set Message(count,$thread) 1
  90.         } else {
  91.             set Message(thread,$i) $Message(thread,$j)
  92.             set Message(seconds,$i) [expr {$Message(seconds2,$j) + int(rand() * 10000)}]
  93.             set Message(seconds2,$i) $Message(seconds,$i)
  94.             set Message(seconds2,$j) $Message(seconds,$i)
  95.             incr Message(count,$Message(thread,$j))
  96.         }
  97.     }
  98.  
  99.     for {set i 1} {$i < $msgCnt} {incr i} {
  100.         set subject "This is thread number $Message(thread,$i)"
  101.         set from somebody@somewhere.net
  102.         set sent [clock format $Message(seconds,$i) -format "%d/%m/%y %I:%M %p"]
  103.         set size [expr {1 + int(rand() * 10)}]KB
  104.  
  105.         # This message has been read
  106.         if {$Message(read,$i)} {
  107.             $T item state set $i read
  108.         }
  109.  
  110.         # This message has unread descendants
  111.         if {[AnyUnreadDescendants $T $i]} {
  112.             $T item state set $i unread
  113.         }
  114.  
  115.         if {[$T item numchildren $i]} {
  116.             $T item hasbutton $i yes
  117.  
  118.             # Collapse some messages
  119.             if {rand() * 2 > 1} {
  120.                 $T collapse $i
  121.             }
  122.         }
  123.  
  124.         $T item style set $i 3 s1 4 s2.we 5 s2.we 6 s2.w
  125.         $T item text $i 3 $subject 4 $from 5 $sent 6 $size
  126.     }
  127.  
  128.     # Do something when the selection changes
  129.     $T notify bind $T <Selection> {
  130.  
  131.         # One item is selected
  132.         if {[%T selection count] == 1} {
  133.             if {[info exists Message(afterId)]} {
  134.                 after cancel $Message(afterId)
  135.             }
  136.             set Message(afterId,item) [lindex [%T selection get] 0]
  137.             set Message(afterId) [after 500 MessageReadDelayed]
  138.         }
  139.     }
  140.  
  141.     return
  142. }
  143.  
  144. proc MessageReadDelayed {} {
  145.  
  146.     global Message
  147.  
  148.     set T .f2.f1.t
  149.  
  150.     unset Message(afterId)
  151.     set I $Message(afterId,item)
  152.     if {![$T selection includes $I]} return
  153.  
  154.     # This message is not read
  155.     if {!$Message(read,$I)} {
  156.  
  157.         # Read the message
  158.         $T item state set $I read
  159.         set Message(read,$I) 1
  160.  
  161.         # Check ancestors (except root)
  162.         foreach I2 [lrange [$T item ancestors $I] 0 end-1] {
  163.  
  164.             # This ancestor has no more unread descendants
  165.             if {![AnyUnreadDescendants $T $I2]} {
  166.                 $T item state set $I2 !unread
  167.             }
  168.         }
  169.     }
  170. }
  171.  
  172. # Alternate implementation which does not rely on run-time states
  173. proc DemoOutlookNewsgroup2 {} {
  174.  
  175.     global Message
  176.  
  177.     InitPics outlook-*
  178.  
  179.     set T .f2.f1.t
  180.  
  181.     set height [font metrics [$T cget -font] -linespace]
  182.     if {$height < 18} {
  183.         set height 18
  184.     }
  185.     $T configure -itemheight $height -selectmode browse \
  186.         -showroot no -showrootbutton no -showbuttons yes -showlines no
  187.  
  188.     $T column configure 0 -image outlook-clip -tag clip
  189.     $T column configure 1 -image outlook-arrow -tag arrow
  190.     $T column configure 2 -image outlook-watch -tag watch
  191.     $T column configure 3 -text Subject -width 250 -tag subject
  192.     $T column configure 4 -text From -width 150 -tag from
  193.     $T column configure 5 -text Sent -width 150 -tag sent
  194.     $T column configure 6 -text Size -width 60 -justify right -tag size
  195.  
  196.     $T configure -treecolumn 3
  197.  
  198.     $T element create image.unread image -image outlook-unread
  199.     $T element create image.read image -image outlook-read
  200.     $T element create image.read2 image -image outlook-read-2
  201.     $T element create text.read text -fill [list $::SystemHighlightText {selected focus}] \
  202.         -lines 1
  203.     $T element create text.unread text -fill [list $::SystemHighlightText {selected focus}] \
  204.         -font [list "[$T cget -font] bold"] -lines 1
  205.     $T element create sel.e rect -fill [list $::SystemHighlight {selected focus} gray {selected !focus}] -open e -showfocus yes
  206.     $T element create sel.w rect -fill [list $::SystemHighlight {selected focus} gray {selected !focus}] -open w -showfocus yes
  207.     $T element create sel.we rect -fill [list $::SystemHighlight {selected focus} gray {selected !focus}] -open we -showfocus yes
  208.  
  209.     # Image + text
  210.     set S [$T style create unread]
  211.     $T style elements $S {sel.e image.unread text.unread}
  212.     $T style layout $S image.unread -expand ns
  213.     $T style layout $S text.unread -padx {2 6} -squeeze x -expand ns
  214.     $T style layout $S sel.e -union [list text.unread] -iexpand nes -ipadx {2 0}
  215.  
  216.     # Image + text
  217.     set S [$T style create read]
  218.     $T style elements $S {sel.e image.read text.read}
  219.     $T style layout $S image.read -expand ns
  220.     $T style layout $S text.read -padx {2 6} -squeeze x -expand ns
  221.     $T style layout $S sel.e -union [list text.read] -iexpand nes -ipadx {2 0}
  222.  
  223.     # Image + text
  224.     set S [$T style create read2]
  225.     $T style elements $S {sel.e image.read2 text.unread}
  226.     $T style layout $S image.read2 -expand ns
  227.     $T style layout $S text.unread -padx {2 6} -squeeze x -expand ns
  228.     $T style layout $S sel.e -union [list text.unread] -iexpand nes -ipadx {2 0}
  229.  
  230.     # Text
  231.     set S [$T style create unread.we]
  232.     $T style elements $S {sel.we text.unread}
  233.     $T style layout $S text.unread -padx 6 -squeeze x -expand ns
  234.     $T style layout $S sel.we -detach yes -iexpand es
  235.  
  236.     # Text
  237.     set S [$T style create read.we]
  238.     $T style elements $S {sel.we text.read}
  239.     $T style layout $S text.read -padx 6 -squeeze x -expand ns
  240.     $T style layout $S sel.we -detach yes -iexpand es
  241.  
  242.     # Text
  243.     set S [$T style create unread.w]
  244.     $T style elements $S {sel.w text.unread}
  245.     $T style layout $S text.unread -padx 6 -squeeze x -expand ns
  246.     $T style layout $S sel.w -detach yes -iexpand es
  247.  
  248.     # Text
  249.     set S [$T style create read.w]
  250.     $T style elements $S {sel.w text.read}
  251.     $T style layout $S text.read -padx 6 -squeeze x -expand ns
  252.     $T style layout $S sel.w -detach yes -iexpand es
  253.  
  254.     set msgCnt 100
  255.  
  256.     set thread 0
  257.     set Message(count,0) 0
  258.     for {set i 1} {$i < $msgCnt} {incr i} {
  259.         $T item create
  260.         while 1 {
  261.             set j [expr {int(rand() * $i)}]
  262.             if {$j == 0} break
  263.             if {[$T depth $j] == 5} continue
  264.             if {$Message(count,$Message(thread,$j)) == 15} continue
  265.             break
  266.         }
  267.         $T item lastchild $j $i
  268.  
  269.         set Message(read,$i) [expr rand() * 2 > 1]
  270.         if {$j == 0} {
  271.             set Message(thread,$i) [incr thread]
  272.             set Message(seconds,$i) [expr {[clock seconds] - int(rand() * 500000)}]
  273.             set Message(seconds2,$i) $Message(seconds,$i)
  274.             set Message(count,$thread) 1
  275.         } else {
  276.             set Message(thread,$i) $Message(thread,$j)
  277.             set Message(seconds,$i) [expr {$Message(seconds2,$j) + int(rand() * 10000)}]
  278.             set Message(seconds2,$i) $Message(seconds,$i)
  279.             set Message(seconds2,$j) $Message(seconds,$i)
  280.             incr Message(count,$Message(thread,$j))
  281.         }
  282.     }
  283.  
  284.     for {set i 1} {$i < $msgCnt} {incr i} {
  285.         set subject "This is thread number $Message(thread,$i)"
  286.         set from somebody@somewhere.net
  287.         set sent [clock format $Message(seconds,$i) -format "%d/%m/%y %I:%M %p"]
  288.         set size [expr {1 + int(rand() * 10)}]KB
  289.         if {$Message(read,$i)} {
  290.             set style read
  291.             set style2 read
  292.         } else {
  293.             set style unread
  294.             set style2 unread
  295.         }
  296.         $T item style set $i 3 $style 4 $style2.we 5 $style2.we 6 $style2.w
  297.         $T item text $i 3 $subject 4 $from 5 $sent 6 $size
  298.         if {[$T item numchildren $i]} {
  299.             $T item hasbutton $i yes
  300.         }
  301.     }
  302.  
  303.     $T notify bind $T <Selection> {
  304.         if {[%T selection count] == 1} {
  305.             set I [lindex [%T selection get] 0]
  306.             if {!$Message(read,$I)} {
  307.                 if {[%T item isopen $I] || ![AnyUnreadDescendants %T $I]} {
  308.                     # unread ->read
  309.                     %T item style map $I subject read {text.unread text.read}
  310.                     %T item style map $I from read.we {text.unread text.read}
  311.                     %T item style map $I sent read.we {text.unread text.read}
  312.                     %T item style map $I size read.w {text.unread text.read}
  313.                 } else {
  314.                     # unread -> read2
  315.                     %T item style map $I subject read2 {text.unread text.unread}
  316.                 }
  317.                 set Message(read,$I) 1
  318.                 DisplayStylesInItem $I
  319.             }
  320.         }
  321.     }
  322.  
  323.     $T notify bind $T <Expand-after> {
  324.         if {$Message(read,%I) && [AnyUnreadDescendants %T %I]} {
  325.             # read2 -> read
  326.             %T item style map %I subject read {text.unread text.read}
  327.             # unread -> read
  328.             %T item style map %I from read.we {text.unread text.read}
  329.             %T item style map %I sent read.we {text.unread text.read}
  330.             %T item style map %I size read.w {text.unread text.read}
  331.         }
  332.     }
  333.  
  334.     $T notify bind $T <Collapse-after> {
  335.         if {$Message(read,%I) && [AnyUnreadDescendants %T %I]} {
  336.             # read -> read2
  337.             %T item style map %I subject read2 {text.read text.unread}
  338.             # read -> unread
  339.             %T item style map %I from unread.we {text.read text.unread}
  340.             %T item style map %I sent unread.we {text.read text.unread}
  341.             %T item style map %I size unread.w {text.read text.unread}
  342.         }
  343.     }
  344.  
  345.     for {set i 1} {$i < $msgCnt} {incr i} {
  346.         if {rand() * 2 > 1} {
  347.             if {[$T item numchildren $i]} {
  348.                 $T collapse $i
  349.             }
  350.         }
  351.     }
  352.  
  353.     return
  354. }
  355. proc AnyUnreadDescendants {T I} {
  356.  
  357.     global Message
  358.  
  359.     set itemList [$T item firstchild $I]
  360.     while {[llength $itemList]} {
  361.         # Pop
  362.         set item [lindex $itemList end]
  363.         set itemList [lrange $itemList 0 end-1]
  364.  
  365.         if {!$Message(read,$item)} {
  366.             return 1
  367.         }
  368.  
  369.         set item2 [$T item nextsibling $item]
  370.         if {$item2 ne ""} {
  371.             # Push
  372.             lappend itemList $item2
  373.         }
  374.         set item2 [$T item firstchild $item]
  375.         if {$item2 ne ""} {
  376.             # Push
  377.             lappend itemList $item2
  378.         }
  379.     }
  380.  
  381.     return 0
  382. }
  383.