Initial revision
[themes.git] / EarlyBlue / messenger / skin / mailWidgets.xml
1 <?xml version="1.0"?>\r
2 \r
3 <bindings   id="mailBindings"\r
4             xmlns="http://www.mozilla.org/xbl"\r
5             xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">\r
6   \r
7   <!-- Message Pane Widgets -->\r
8   <binding id="mail-emailaddress" extends="chrome://global/content/xulBindings.xml#basetext">\r
9     <content excludes="observes,template">\r
10         <xul:box inherits="orient" autostretch="never" flex="1">\r
11           <xul:box orient="vertical"  autostretch="never" flex="1">\r
12             <xul:text class="emailDisplayButton" context="emailAddressPopup" inherits="value,accesskey,crop"/>\r
13           </xul:box>\r
14           <xul:image class="emailDisplayImage" inherits="src"/>\r
15         </xul:box>\r
16     </content>\r
17     \r
18     <interface>  \r
19       <method name="setTextAttribute">\r
20         <argument name="attributeName"/>\r
21         <argument name="attributeValue"/>\r
22         <body>\r
23           <![CDATA[            \r
24             var textNode = document.getAnonymousNodes(this)[0].firstChild.firstChild;\r
25             textNode.setAttribute(attributeName, attributeValue);\r
26           ]]>\r
27         </body>\r
28       </method>\r
29 \r
30       <method name="getTextAttribute">\r
31         <argument name="attributeName"/>\r
32         <argument name="attributeValue"/>\r
33         <body>\r
34           <![CDATA[            \r
35             var textNode = document.getAnonymousNodes(this)[0].firstChild.firstChild;\r
36             return textNode.getAttribute(attributeName, attributeValue);\r
37           ]]>\r
38         </body>\r
39       </method>\r
40     </interface>\r
41   </binding>\r
42 \r
43   <binding id="search-menulist-abstract" extends="xul:box">\r
44     <content>\r
45       <xul:menulist inherits="flex" oncommand="this.parentNode.onSelect(event)">\r
46         <xul:menupopup/>\r
47       </xul:menulist>\r
48     </content>\r
49 \r
50     <interface>\r
51       <property readonly="true" name="validityManager">\r
52         <![CDATA[\r
53            Components.classes['mozilla.mail.search.validityManager.1'].getService(Components.interfaces.nsIMsgSearchValidityManager);\r
54         ]]>\r
55       </property>\r
56       <property name="searchScope" onget="return this.internalScope;">\r
57         <!-- scope ID - retrieve the table -->\r
58         <setter>\r
59           <![CDATA[\r
60             // if scope isn't changing this is a noop\r
61             if (this.internalScope == val) return;\r
62 \r
63             this.internalScope = val;\r
64             this.refreshList();\r
65             var targets = this.targets;\r
66             if (targets) {\r
67               for (var i=0; i< targets.length; i++) {\r
68                 targets[i].searchScope = val;\r
69               }\r
70             }\r
71           ]]>\r
72         </setter>\r
73       </property>\r
74 \r
75       <property name="validityTable" readonly="true" onget="return this.validityManager.getTable(this.searchScope)"/>\r
76 \r
77       <property name="valueStrings" readonly="true">\r
78         <getter>\r
79           <![CDATA[\r
80             var strings = new Array;\r
81             var ids = this.valueIds;\r
82             var bundle = this.stringBundle;\r
83             for (var i=0; i<ids.length; i++)\r
84                 strings[i] = this.stringBundle.GetStringFromID(ids[i]);\r
85             return strings;\r
86           ]]>\r
87         </getter>\r
88       </property>\r
89       <property name="targets" readonly="true">\r
90         <getter>\r
91           <![CDATA[\r
92             var forAttrs =  this.getAttribute("for");\r
93             if (!forAttrs) return null;\r
94             var targetIds = forAttrs.split(",");\r
95             if (targetIds.length == 0) return null;\r
96 \r
97             var targets = new Array;\r
98             var j=0;\r
99             for (var i=0; i<targetIds.length;i++) {\r
100               var target = document.getElementById(targetIds[i]);\r
101               if (target) targets[j++] = target;\r
102             }\r
103             return targets;\r
104           ]]>\r
105         </getter>\r
106       </property>\r
107 \r
108       <!-- value forwards to the internal menulist's "data" attribute -->\r
109       <property name="value" onget="return document.getAnonymousNodes(this)[0].selectedItem.getAttribute('data');">\r
110         <setter>\r
111           <![CDATA[\r
112             var menulist = document.getAnonymousNodes(this)[0];\r
113             var dataItems = menulist.getElementsByAttribute("data", val);\r
114             if (dataItems.length > 0)\r
115                 menulist.selectedItem = dataItems[0];\r
116           ]]>\r
117         </setter>\r
118       </property>\r
119       <method name="refreshList">\r
120         <body>\r
121           <![CDATA[\r
122             var menuItemIds = this.valueIds;\r
123             var menuItemStrings = this.valueStrings;\r
124 \r
125             var menulist = document.getAnonymousNodes(this)[0];\r
126             var popup = menulist.firstChild;\r
127 \r
128             // save our old "data" so we can restore it later\r
129             var oldData = menulist.data;\r
130 \r
131             // remove the old popup children\r
132             while (popup.hasChildNodes())\r
133               popup.removeChild(popup.lastChild);\r
134 \r
135             var newSelection;\r
136             for (var i=0; i<menuItemIds.length; i++) {\r
137               // create the menuitem\r
138               var menuitem = document.createElement("menuitem");\r
139               menuitem.setAttribute("value", menuItemStrings[i]);\r
140               menuitem.setAttribute("data", menuItemIds[i]);\r
141               popup.appendChild(menuitem);\r
142 \r
143               // try to restore the selection\r
144               if (!newSelection || oldData == menuItemIds[i].toString()) {\r
145                 newSelection = menuitem;\r
146               }\r
147             }\r
148 \r
149             // now restore the selection\r
150             menulist.selectedItem = newSelection\r
151           ]]>\r
152         </body>\r
153       </method>\r
154       <method name="onSelect">\r
155         <argument name="event"/>\r
156         <body>\r
157           <![CDATA[\r
158             var menulist = document.getAnonymousNodes(this)[0];\r
159 \r
160             // notify targets\r
161             var targets = this.targets;\r
162             if (targets) {\r
163               for (var i=0; i< targets.length; i++) {\r
164                 targets[i].parentValue = menulist.data;\r
165               }\r
166             }\r
167           ]]>\r
168         </body>\r
169       </method>\r
170     </interface>\r
171   </binding>\r
172 \r
173   <!-- searchattribute - Subject, Sender, To, CC, etc. -->\r
174   <binding id="searchattribute"\r
175            extends="chrome://messenger/skin/mailWidgets.xml#search-menulist-abstract">\r
176     <interface>\r
177       <property name="stringBundle">\r
178           <![CDATA[\r
179            srGetStrBundle("chrome://messenger/locale/search-attributes.properties");\r
180           ]]>\r
181       </property>\r
182       <property name="valueIds" readonly="true">\r
183         <getter>\r
184           <![CDATA[\r
185             var length = new Object;\r
186             return this.validityTable.getAvailableAttributes(length);\r
187           ]]>\r
188         </getter>\r
189       </property>\r
190     </interface>\r
191   </binding>\r
192 \r
193   <!-- searchoperator - Contains, Is Less than, etc -->\r
194   <binding id="searchoperator"\r
195            extends="chrome://messenger/skin/mailWidgets.xml#search-menulist-abstract">\r
196     <interface>\r
197       <property name="stringBundle">\r
198           <![CDATA[\r
199             srGetStrBundle("chrome://messenger/locale/search-operators.properties");\r
200           ]]>\r
201       </property>\r
202       <property name="valueIds" readonly="true">\r
203         <getter>\r
204           <![CDATA[\r
205             var length = new Object;\r
206             return this.validityTable.getAvailableOperators(this.searchAttribute,length);\r
207           ]]>\r
208         </getter>\r
209       </property>\r
210       <property name="parentValue">\r
211         <setter>\r
212           <![CDATA[\r
213             if (this.searchAttribute == val) return;\r
214             this.searchAttribute = val;\r
215             this.refreshList();\r
216           ]]>\r
217         </setter>\r
218         <getter>\r
219           <![CDATA[\r
220             return this.searchAttribute;\r
221           ]]>\r
222         </getter>\r
223       </property>\r
224     </interface>\r
225   </binding>\r
226 \r
227   <!-- searchvalue - a widget which dynamically changes it's user interface\r
228        depending on what type of data it's supposed to be showing\r
229        currently handles arbitrary text entry, and menulists for priority and\r
230        status\r
231   -->\r
232   <binding id="searchvalue" extends="xul:deck">\r
233     <!-- yeah yeah, this stuff needs to be localized. I'm working on it! -->\r
234     <content>\r
235       <xul:textfield flex="1" />\r
236       <xul:menulist flex="1" >\r
237         <xul:menupopup>\r
238           <xul:menuitem value="Lowest"/>\r
239           <xul:menuitem value="Low"/>\r
240           <xul:menuitem value="Normal"/>\r
241           <xul:menuitem value="High"/>\r
242           <xul:menuitem value="Highest"/>\r
243         </xul:menupopup>\r
244       </xul:menulist>\r
245       <xul:menulist flex="1" >\r
246         <xul:menupopup>\r
247           <xul:menuitem value="read"/>\r
248           <xul:menuitem value="replied"/>\r
249         </xul:menupopup>\r
250       </xul:menulist>\r
251     </content>\r
252     <interface>\r
253       <!-- parentValue forwards to the attribute -->\r
254       <property name="parentValue" onset="this.searchAttribute=val;"\r
255                                    onget="return this.searchAttribute;"/>\r
256       <property name="searchAttribute" onget="return this.internalAttribute;">\r
257         <setter>\r
258           <![CDATA[\r
259             // noop if we're not changing it\r
260             if (this.internalAttribute == val) return;\r
261             this.internalAttribute = val;\r
262             // we inherit from a deck, so just use it's index attribute\r
263             // to hide/show widgets\r
264             if (val == Components.interfaces.nsMsgSearchAttrib.Priority)\r
265               this.setAttribute("index", "1");\r
266             else if (val == Components.interfaces.nsMsgSearchAttrib.MsgStatus)\r
267               this.setAttribute("index", "2");\r
268             else\r
269               this.setAttribute("index", "0");\r
270           ]]>\r
271         </setter>\r
272       </property>\r
273       <property name="value" onget="return this.internalValue;">\r
274         <setter>\r
275           <![CDATA[\r
276           // val is a nsIMsgSearchValue object\r
277           this.internalValue = val;\r
278           var attrib = val.attrib;\r
279           this.searchAttribute = attrib;\r
280           if (attrib == Components.interfaces.nsMsgSearchAttrib.Priority)\r
281             document.getAnonymousNodes(this)[1].data=val.priority;\r
282           else if (attrib == Components.interfaces.nsMsgSearchAttrib.MsgStatus)\r
283             document.getAnonymousNodes(this)[2].data=val.status;\r
284           else\r
285             document.getAnonymousNodes(this)[0].value = val.str;\r
286           ]]>\r
287         </setter>\r
288       </property>\r
289       <method name="save">\r
290         <body>\r
291           <![CDATA[\r
292             var searchValue = this.value;\r
293             var searchAttribute = this.searchAttribute;\r
294             var nsMsgSearchAttrib = Components.interfaces.nsMsgSearchAttrib;\r
295 \r
296             searchValue.attrib = searchAttribute;\r
297             if (searchAttribute == nsMsgSearchAttrib.Priority)\r
298                searchValue.priority = document.getAnonymousNodes(this)[1].selectedItem.data;\r
299             else if (searchAttribute == nsMsgSearchAttrib.MsgStatus)\r
300                searchValue.status = document.getAnonymousNodes(this)[2].selectedItem.data;\r
301             else\r
302                searchValue.str = document.getAnonymousNodes(this)[0].value;\r
303           ]]>\r
304         </body>\r
305       </method>\r
306       <method name="saveTo">\r
307         <argument name="searchValue"/>\r
308         <body>\r
309           <![CDATA[\r
310             this.internalValue = searchValue;\r
311             this.save();\r
312           ]]>\r
313         </body>\r
314       </method>\r
315     </interface>\r
316   </binding>\r
317   <binding id="searchterm" extends="xul:box">\r
318     <interface>\r
319       <!-- the actual nsIMsgSearchTerm object -->\r
320       <property name="searchTerm" onget="return this.internalSearchTerm">\r
321         <setter>\r
322           <![CDATA[\r
323             this.internalSearchTerm = val;\r
324 \r
325             var term = val;\r
326             // val is a nsIMsgSearchTerm\r
327             var searchAttribute=this.searchattribute;\r
328             var searchOperator=this.searchoperator;\r
329             var searchValue=this.searchvalue;\r
330 \r
331             // now reflect all attributes of the searchterm into the widgets\r
332             if (searchAttribute) searchAttribute.value = term.attrib;\r
333             if (searchOperator) searchOperator.value = val.op;\r
334             if (searchValue) searchValue.value = term.value;\r
335 \r
336             this.booleanAnd = val.booleanAnd;\r
337           ]]>\r
338         </setter>\r
339       </property>\r
340  \r
341       <property name="searchScope">\r
342         <getter>\r
343           <![CDATA[\r
344              var searchAttribute = this.searchattribute;\r
345              if (searchAttribute)\r
346                return searchAttribute.searchScope;\r
347              return undefined;\r
348            ]]>\r
349         </getter>\r
350         <setter>\r
351           <![CDATA[\r
352             var searchAttribute = this.searchattribute;\r
353             if (searchAttribute) searchAttribute.searchScope=val;\r
354            ]]>\r
355         </setter>\r
356       </property>\r
357       <!-- the three tags that make up a term - to use, set the\r
358            attribute in the XUL to the ID of the term.\r
359         -->\r
360       <property name="searchattribute" \r
361                 onget="return document.getElementById(this.getAttribute('searchattribute'));"\r
362                 onset="this.setAttribute('searchattribute',val.id)"/>\r
363 \r
364       <property name="searchoperator" \r
365                 onget="return document.getElementById(this.getAttribute('searchoperator'));"\r
366                 onset="this.setAttribute('searchoperator',val.id)"/>\r
367 \r
368       <property name="searchvalue" \r
369                 onget="return document.getElementById(this.getAttribute('searchvalue'));"\r
370                 onset="this.setAttribute('searchvalue',val.id)"/>\r
371       <property name="booleanNodes">\r
372         <![CDATA[\r
373           null;\r
374         ]]>\r
375       </property>\r
376       <property name="stringBundle">\r
377           <![CDATA[\r
378              srGetStrBundle("chrome://messenger/locale/search.properties");\r
379           ]]>\r
380       </property>\r
381       <property name="booleanAnd" onget="return this.internalBooleanAnd">\r
382         <setter>\r
383           <![CDATA[\r
384             // whenever you set this, all nodes in booleanNodes\r
385             // are updated to reflect the string\r
386 \r
387             if (this.internalBooleanAnd == val) return;\r
388             this.internalBooleanAnd = val;\r
389 \r
390             var booleanNodes = this.booleanNodes;\r
391             if (!booleanNodes) return;\r
392 \r
393             var stringBundle = this.stringBundle;\r
394             var andString = val ? "And" : "Or";\r
395             for (var i=0; i<booleanNodes.length; i++) {\r
396               try {              \r
397                 var staticString =\r
398                     stringBundle.GetStringFromName("search" + andString + i);\r
399                 if (staticString && staticString.length>0)\r
400                     booleanNodes[i].setAttribute("value", staticString);\r
401               } catch (ex) { /* no error, means string not found */}\r
402             }\r
403           ]]>\r
404         </setter>\r
405       </property>\r
406       <method name="save">\r
407         <body>\r
408           <![CDATA[\r
409             var searchTerm = this.searchTerm;\r
410             searchTerm.attrib = this.searchattribute.value;\r
411             searchTerm.op = this.searchoperator.value;\r
412             if (this.searchvalue.value)\r
413               this.searchvalue.save();\r
414             else\r
415               this.searchvalue.saveTo(searchTerm.value);\r
416             searchTerm.value = this.searchvalue.value;\r
417             searchTerm.booleanAnd = this.booleanAnd;\r
418           ]]>\r
419         </body>\r
420       </method>\r
421       <!-- if you have a search term element with no search term -->\r
422       <method name="saveTo">\r
423         <argument name="searchTerm"/>\r
424         <body>\r
425           <![CDATA[\r
426             this.internalSearchTerm = searchTerm;\r
427             this.save();\r
428           ]]>\r
429         </body>\r
430       </method>\r
431     </interface>\r
432   </binding>\r
433 </bindings>\r