OSDN Git Service

ruby-1.9.1-rc1
[splhack/AndroidRuby.git] / lib / ruby-1.9.1-rc1 / ext / tk / sample / tkextlib / treectrl / outlook-newgroup.rb
1 #
2 # Demo: Outlook Express newsgroup messages
3 #
4 def demoOutlookNewsgroup(t)
5   init_pics('outlook-*')
6
7   height = t.font.metrics(:linespace)
8   height = 18 if height < 18
9   t.configure(:itemheight=>height, :selectmode=>:browse, :showlines=>false, 
10               :showroot=>false, :showrootbutton=>false, :showbuttons=>true)
11
12   if $Version_1_1_OrLater
13     t.column_create(:image=>@images['outlook-clip'], :tag=>'clip')
14     t.column_create(:image=>@images['outlook-arrow'], :tag=>'arrow')
15     t.column_create(:image=>@images['outlook-watch'], :tag=>'watch')
16     t.column_create(:text=>'Subject', :width=>250, :tag=>'subject')
17     t.column_create(:text=>'From', :width=>150, :tag=>'from')
18     t.column_create(:text=>'Sent', :width=>150, :tag=>'sent')
19     t.column_create(:text=>'Size', :width=>60, :justify=>:right, :tag=>'size')
20   else # TreeCtrl 1.0
21     t.column_configure(0, :image=>@images['outlook-clip'], :tag=>'clip')
22     t.column_configure(1, :image=>@images['outlook-arrow'], :tag=>'arrow')
23     t.column_configure(2, :image=>@images['outlook-watch'], :tag=>'watch')
24     t.column_configure(3, :text=>'Subject', :width=>250, :tag=>'subject')
25     t.column_configure(4, :text=>'From', :width=>150, :tag=>'from')
26     t.column_configure(5, :text=>'Sent', :width=>150, :tag=>'sent')
27     t.column_configure(6, :text=>'Size', :width=>60, :justify=>:right, 
28                        :tag=>'size')
29   end
30
31   # Would be nice if I could specify a column -tag too
32   t.treecolumn = 3
33
34   # State for a read message
35   t.state_define('read')
36
37   # State for a message with unread descendants
38   t.state_define('unread')
39
40   t.element_create('elemImg', :image, 
41                    :image=>[
42                      @sel_images['outlook-read-2'], 
43                           ['selected', 'read', 'unread', '!open'], 
44                      @images['outlook-read-2'], ['read', 'unread', '!open'],
45                      @sel_images['outlook-read'], ['selected', 'read'], 
46                      @images['outlook-read'], ['read'], 
47                      @sel_images['outlook-unread'], ['selected'], 
48                      @images['outlook-unread'], []
49                    ])
50   t.element_create('elemTxt', :text, :lines=>1, 
51                    :fill=>[@SystemHighlightText, ['selected', 'focus']], 
52                    :font=>[
53                      t.font.dup.weight(:bold), ['read', 'unread', '!open'], 
54                      t.font.dup.weight(:bold), ['!read']
55                    ])
56   t.element_create('sel.e', :rect, :open=>:e, :showfocus=>true, 
57                    :fill=>[
58                      @SystemHighlight, ['selected', 'focus'], 
59                      'gray',  ['selected', '!focus']
60                    ])
61   t.element_create('sel.w', :rect, :open=>:w, :showfocus=>true, 
62                    :fill=>[
63                      @SystemHighlight, ['selected', 'focus'], 
64                      'gray',  ['selected', '!focus']
65                    ])
66   t.element_create('sel.we', :rect, :open=>:we, :showfocus=>true, 
67                    :fill=>[
68                      @SystemHighlight, ['selected', 'focus'], 
69                      'gray',  ['selected', '!focus']
70                    ])
71
72   # Image + text
73   s = t.style_create('s1')
74   t.style_elements(s, ['sel.e', 'elemImg', 'elemTxt'])
75   t.style_layout(s, 'elemImg', :expand=>:ns)
76   t.style_layout(s, 'elemTxt', :padx=>[2,6], :squeeze=>:x, :expand=>:ns)
77   t.style_layout(s, 'sel.e', :union=>['elemTxt'], 
78                  :iexpand=>:nes, :ipadx=>[2,0])
79
80   # Text
81   s = t.style_create('s2.we')
82   t.style_elements(s, ['sel.we', 'elemTxt'])
83   t.style_layout(s, 'elemTxt', :padx=>6, :squeeze=>:x, :expand=>:ns)
84   t.style_layout(s, 'sel.we', :detach=>true, :iexpand=>:es)
85
86   # Text
87   s = t.style_create('s2.w')
88   t.style_elements(s, ['sel.w', 'elemTxt'])
89   t.style_layout(s, 'elemTxt', :padx=>6, :squeeze=>:x, :expand=>:ns)
90   t.style_layout(s, 'sel.w', :detach=>true, :iexpand=>:es)
91
92   # Set default item style
93   if $Version_1_1_OrLater
94     t.defaultstyle = ['', '', '', 's1', 's2.we', 's2.we', 's2.w']
95   end
96
97   msgCnt = 100
98   thread = 0
99
100   @Message = Hash.new{|k, v| k[v] = Hash.new}
101   @Message[:count][0] = 0
102
103   items = [t.index(:root)]
104
105   (1...(msgCnt)).each{|i|
106     item_i = t.item_create
107     item_j = nil
108     j = nil
109     loop {
110       j = rand(i)
111       item_j = items[j]
112       break if j == 0
113       next if t.depth(item_j) == 5
114       next if @Message[:count][@Message[:thread][item_j]] == 15
115       break
116     }
117     t.item_lastchild(item_j, item_i)
118
119     @Message[:read][item_i] = (rand(2) == 0)
120     if j == 0
121       thread += 1
122       @Message[:thread][item_i] = thread
123       @Message[:seconds][item_i] = (Tk::Clock.seconds - rand(500000))
124       @Message[:seconds2][item_i] = @Message[:seconds][item_i]
125       @Message[:count][thread] = 1
126     else
127       @Message[:thread][item_i] = @Message[:thread][item_j]
128       @Message[:seconds][item_i] = (@Message[:seconds2][item_j] + rand(10000))
129       @Message[:seconds2][item_i] = @Message[:seconds][item_i]
130       @Message[:seconds2][item_j] = @Message[:seconds][item_i]
131       @Message[:count][@Message[:thread][item_j]] += 1
132     end
133     items << item_i
134   }
135
136   (1...(msgCnt)).each{|i|
137     item_i = items[i]
138     subject = "This is thread number #{@Message[:thread][item_i]}"
139     from = 'somebody@somewhere.net'
140     sent = Tk::Clock.format(@Message[:seconds][item_i], "%d/%m/%y %I:%M %p")
141     size = "#{1 + rand(10)}KB"
142
143     # This message has been read
144     t.item_state_set(item_i, 'read') if @Message[:read][item_i]
145
146     # This message has unread descendants
147     t.item_state_set(item_i, 'unread')  if anyUnreadDescendants(t, item_i)
148
149     if t.item_numchildren(item_i) > 0
150       if $Version_1_1_OrLater
151         t.item_configure(item_i, :button=>true)
152       else # TreeCtrl 1.0
153         t.item_hasbutton(item_i, true)
154       end
155
156       # Collapse some messages
157       if $Version_1_1_OrLater
158         t.item_collapse(item_i) if rand(2) == 0
159       else # TreeCtrl 1.0
160         t.collapse(item_i) if rand(2) == 0
161       end
162     end
163
164     unless $Version_1_1_OrLater
165       t.item_style_set(item_i, 3, 's1', 4, 's2.we', 5, 's2.we', 6, 's2.w')
166     end
167     t.item_text(item_i, 3, subject, 4, from, 5, sent, 6, size)
168   }
169
170   # Do something when the selection changes
171   t.notify_bind(t, 'Selection', 
172                 proc{|w|
173                   if w.selection_count == 1
174                     # One item is selected
175                     if @Message[:afterId][:id]
176                       Tk.after_cancel(@Message[:afterId][:id]) 
177                     end
178                     @Message[:afterId][:item] = w.selection_get[0]
179                     @Message[:afterId][:id] = Tk.after(500, proc{
180                                                          messageReadDelayed(w)
181                                                        })
182                   end
183                 }, '%T')
184 end
185
186 def messageReadDelayed(t)
187   @Message[:afterId].delete(:id)
188   i = @Message[:afterId][:item]
189   return unless t.selection_includes(i)
190
191   # This message is not read
192   unless @Message[:read][i]
193     # Read the message
194     t.item_state_set(i, 'read')
195     @Message[:read][i] = true
196
197     # Check ancestors (except root)
198     t.item_ancestors(i)[0..-2].each{|i2|
199       # This ancestor has no more unread descendants
200       t.item_state_set(i2, '!unread') unless anyUnreadDescendants(t, i2)
201     }
202   end
203 end
204
205 # Alternate implementation which does not rely on run-time states
206 def demoOutlookNewsgroup2(t)
207   init_pics('outlook-*')
208
209   height = t.font.metrics(:linespace)
210   height = 18 if height < 18
211   t.configure(:itemheight=>height, :selectmode=>:browse, :showlines=>false, 
212               :showroot=>false, :showrootbutton=>false, :showbuttons=>true)
213
214   if $Version_1_1_OrLater
215     t.column_create(:image=>@images['outlook-clip'], :tag=>'clip')
216     t.column_create(:image=>@images['outlook-arrow'], :tag=>'arrow')
217     t.column_create(:image=>@images['outlook-watch'], :tag=>'watch')
218     t.column_create(:text=>'Subject', :width=>250, :tag=>'subject')
219     t.column_create(:text=>'From', :width=>150, :tag=>'from')
220     t.column_create(:text=>'Sent', :width=>150, :tag=>'sent')
221     t.column_create(:text=>'Size', :width=>60, :justify=>:right, :tag=>'size')
222   else # TreeCtrl 1.0
223     t.column_configure(0, :image=>@images['outlook-clip'], :tag=>'clip')
224     t.column_configure(1, :image=>@images['outlook-arrow'], :tag=>'arrow')
225     t.column_configure(2, :image=>@images['outlook-watch'], :tag=>'watch')
226     t.column_configure(3, :text=>'Subject', :width=>250, :tag=>'subject')
227     t.column_configure(4, :text=>'From', :width=>150, :tag=>'from')
228     t.column_configure(5, :text=>'Sent', :width=>150, :tag=>'sent')
229     t.column_configure(6, :text=>'Size', :width=>60, :justify=>:right, 
230                        :tag=>'size')
231   end
232
233   t.treecolumn = 3
234
235   t.element_create('image.unread', :image, :image=>@images['outlook-unread'])
236   t.element_create('image.read', :image, :image=>@images['outlook-read'])
237   t.element_create('image.read2', :image, :image=>@images['outlook-read-2'])
238   t.element_create('text.read', :text, :lines=>1, 
239                    :fill=>[@SystemHighlightText, ['selected', 'focus']])
240   t.element_create('text.unread', :text, :lines=>1, 
241                    :fill=>[@SystemHighlightText, ['selected', 'focus']], 
242                    :font=>t.font.dup.weight(:bold))
243   t.element_create('sel.e', :rect, :open=>:e, :showfocus=>true, 
244                    :fill=>[
245                      @SystemHighlight, ['selected', 'focus'], 
246                      'gray',  ['selected', '!focus']
247                    ])
248   t.element_create('sel.w', :rect, :open=>:w, :showfocus=>true, 
249                    :fill=>[
250                      @SystemHighlight, ['selected', 'focus'], 
251                      'gray',  ['selected', '!focus']
252                    ])
253   t.element_create('sel.we', :rect, :open=>:we, :showfocus=>true, 
254                    :fill=>[
255                      @SystemHighlight, ['selected', 'focus'], 
256                      'gray',  ['selected', '!focus']
257                    ])
258
259   # Image + text
260   s = t.style_create('unread')
261   t.style_elements(s, ['sel.e', 'image.unread', 'text.unread'])
262   t.style_layout(s, 'image.unread', :expand=>:ns)
263   t.style_layout(s, 'text.unread', :padx=>[2,6], :squeeze=>:x, :expand=>:ns)
264   t.style_layout(s, 'sel.e', :union=>['text.unread'], 
265                  :iexpand=>:nes, :ipadx=>[2,0])
266
267   # Image + text
268   s = t.style_create('read')
269   t.style_elements(s, ['sel.e', 'image.read', 'text.read'])
270   t.style_layout(s, 'image.read', :expand=>:ns)
271   t.style_layout(s, 'text.read', :padx=>[2,6], :squeeze=>:x, :expand=>:ns)
272   t.style_layout(s, 'sel.e', :union=>['text.read'], 
273                  :iexpand=>:nes, :ipadx=>[2,0])
274
275   # Image + text
276   s = t.style_create('read2')
277   t.style_elements(s, ['sel.e', 'image.read2', 'text.unread'])
278   t.style_layout(s, 'image.read2', :expand=>:ns)
279   t.style_layout(s, 'text.unread', :padx=>[2,6], :squeeze=>:x, :expand=>:ns)
280   t.style_layout(s, 'sel.e', :union=>['text.unread'], 
281                  :iexpand=>:nes, :ipadx=>[2,0])
282
283   # Text
284   s = t.style_create('unread.we')
285   t.style_elements(s, ['sel.we', 'text.unread'])
286   t.style_layout(s, 'text.unread', :padx=>6, :squeeze=>:x, :expand=>:ns)
287   t.style_layout(s, 'sel.we', :detach=>true, :iexpand=>:es)
288
289   # Text
290   s = t.style_create('read.we')
291   t.style_elements(s, ['sel.we', 'text.read'])
292   t.style_layout(s, 'text.read', :padx=>6, :squeeze=>:x, :expand=>:ns)
293   t.style_layout(s, 'sel.we', :detach=>true, :iexpand=>:es)
294
295   # Text
296   s = t.style_create('unread.w')
297   t.style_elements(s, ['sel.w', 'text.unread'])
298   t.style_layout(s, 'text.unread', :padx=>6, :squeeze=>:x, :expand=>:ns)
299   t.style_layout(s, 'sel.w', :detach=>true, :iexpand=>:es)
300
301   # Text
302   s = t.style_create('read.w')
303   t.style_elements(s, ['sel.w', 'text.read'])
304   t.style_layout(s, 'text.read', :padx=>6, :squeeze=>:x, :expand=>:ns)
305   t.style_layout(s, 'sel.w', :detach=>true, :iexpand=>:es)
306
307   msgCnt = 100
308   thread = 0
309
310   @Message = Hash.new{|k, v| k[v] = Hash.new}
311   @Message[:count][0] = 0
312
313   (1...(msgCnt)).each{|i|
314     t.item_create
315     j = nil
316     loop {
317       j = rand(i)
318       break if j == 0
319       next if t.depth(j) == 5
320       next if @Message[:count][@Message[:thread][j]] == 15
321       break
322     }
323     t.item_lastchild(j, i)
324
325     @Message[:read][i] = (rand(2) == 0)
326     if j == 0
327       thread += 1
328       @Message[:thread][i] = thread
329       @Message[:seconds][i] = (Tk::Clock.seconds - rand(500000))
330       @Message[:seconds2][i] = @Message[:seconds][i]
331       @Message[:count][thread] = 1
332     else
333       @Message[:thread][i] = @Message[:thread][j]
334       @Message[:seconds][i] = (@Message[:seconds2][j] + rand(10000))
335       @Message[:seconds2][i] = @Message[:seconds][i]
336       @Message[:seconds2][j] = @Message[:seconds][i]
337       @Message[:count][@Message[:thread][j]] += 1
338     end
339   }
340
341   (1...(msgCnt)).each{|i|
342     subject = "This is thread number #{@Message[:thread][i]}"
343     from = 'somebody@somewhere.net'
344     sent = Tk::Clock.format(@Message[:seconds][i], "%d/%m/%y %I:%M %p")
345     size = "#{1 + rand(10)}KB"
346     if @Message[:read][i]
347       style = 'read'
348       style2 = 'read2'
349     else
350       style = 'unread'
351       style2 = 'unread2'
352     end
353     t.item_style_set(i, 3, style, 4, "#{style2}.we", 5, "#{style2}.we", 
354                      6, "#{style2}.w")
355     t.item_text(i, 3, subject, 4, from, 5, sent, 6, size)
356     if t.item_numchildren(i) > 0
357       t.item_configure(item_i, :button=>true)
358     end
359   }
360
361   # Do something when the selection changes
362   t.notify_bind(t, 'Selection', 
363                 proc{|w|
364                   if w.selection_count == 1
365                     i = t.selection_get[0]
366                     unless @Message[:read][i]
367                       if t.item_isopen(i) || !anyUnreadDescendants(t, i)
368                         # unread -> read
369                         t.item_style_map(i, 'subject', 'read', 
370                                          ['text.unread', 'text.read'])
371                         t.item_style_map(i, 'from', 'read.we', 
372                                          ['text.unread', 'text.read'])
373                         t.item_style_map(i, 'sent', 'read.we', 
374                                          ['text.unread', 'text.read'])
375                         t.item_style_map(i, 'size', 'read.w', 
376                                          ['text.unread', 'text.read'])
377                       else
378                         # unread -> read2
379                         t.item_style_map(i, 'subject', 'read2', 
380                                          ['text.unread', 'text.unread'])
381                       end
382
383                       @Message[:read][i] = true
384                       @display_styles_in_item.call(i)
385                     end
386                   end
387                 }, '%T')
388
389   t.notify_bind(t, 'Expand-after', 
390                 proc{|w, i|
391                   if @Messge[:read][i] && anyUnreadDescendants(t, i)
392                     # read2 -> read
393                     t.item_style_map(i, 'subject', 'read', 
394                                      ['text.unread', 'text.read'])
395                     # unread -> read
396                     t.item_style_map(i, 'from', 'read.we', 
397                                      ['text.unread', 'text.read'])
398                     t.item_style_map(i, 'sent', 'read.we', 
399                                      ['text.unread', 'text.read'])
400                     t.item_style_map(i, 'size', 'read.w', 
401                                      ['text.unread', 'text.read'])
402                   end
403                 }, '%T %I')
404
405   t.notify_bind(t, 'Collapse-after', 
406                 proc{|w, i|
407                   if @Messge[:read][i] && anyUnreadDescendants(t, i)
408                     # read -> read2
409                     t.item_style_map(i, 'subject', 'read2', 
410                                      ['text.read', 'text.unread'])
411                     # read -> unread
412                     t.item_style_map(i, 'from', 'unread.we', 
413                                      ['text.read', 'text.unread'])
414                     t.item_style_map(i, 'sent', 'unread.we', 
415                                      ['text.read', 'text.unread'])
416                     t.item_style_map(i, 'size', 'unread.w', 
417                                      ['text.read', 'text.unread'])
418                   end
419                 }, '%T %I')
420
421   (1...(msgCnt)).each{|i|
422     if rand(2) == 0
423       if t.item_numchildren(i) > 0
424         if $Version_1_1_OrLater
425           t.item_collapse(i)
426         else # TreeCtrl 1.0
427           t.collapse(i)
428         end
429       end
430     end
431   }
432 end
433
434 def anyUnreadDescendants(t, i)
435   itemList = []
436   item = t.item_firstchild(i)
437   itemList.push(item) if item != ''
438
439   while item = itemList.pop
440     return true unless @Message[:read][item]
441
442     item2 = t.item_nextsibling(item)
443     itemList.push(item2) if item2 != ''
444     item2 = t.item_firstchild(item)
445     itemList.push(item2) if item2 != ''
446   end
447   false
448 end