4 // MailMessageMatchRenderer.cs: Knows how to render MailMessage matches.
7 // Kevin Godby <godbyk@yahoo.com>
9 // FIXME: Add support for importance flag (if possible)
10 // FIXME: Output date in local format (internationalization) -- Is this working now?
13 // Copyright (C) 2003, 2004 Kevin Godby
14 // Copyright (C) 2004 Novell, Inc.
16 // Permission is hereby granted, free of charge, to any person obtaining a copy
17 // of this software and associated documentation files (the "Software"), to deal
18 // in the Software without restriction, including without limitation the rights
19 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
20 // copies of the Software, and to permit persons to whom the Software is
21 // furnished to do so, subject to the following conditions:
23 // The above copyright notice and this permission notice shall be included in all
24 // copies or substantial portions of the Software.
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
37 using System
.Collections
;
40 using System
.Globalization
;
42 //[assembly:Dashboard.MatchRendererFactory ("Dashboard.MailMessageMatchRenderer")]
46 public class MailMessageHitRenderer
: HitRendererHtml
{
48 public MailMessageHitRenderer ()
53 protected override string HitsToHtml (ArrayList hits
)
55 DateTime StartExec
= DateTime
.Now
;
57 StringWriter sw
= new StringWriter ();
58 XmlWriter xw
= new XmlTextWriter (sw
);
60 // Start the xhtml block
61 xw
.WriteStartElement ("div");
64 xw
.WriteStartElement ("table");
65 xw
.WriteAttributeString ("border", "0");
66 xw
.WriteAttributeString ("width", "100%");
67 xw
.WriteStartElement ("tr");
68 xw
.WriteStartElement ("td");
69 xw
.WriteAttributeString ("bgcolor", "#fffa6e");
70 xw
.WriteStartElement ("font");
71 xw
.WriteAttributeString ("size", "+2");
72 xw
.WriteString ("Email Messages");
73 xw
.WriteEndElement (); // font
74 xw
.WriteEndElement (); // td
75 xw
.WriteEndElement (); // tr
76 xw
.WriteEndElement (); // table
79 xw
.WriteStartElement ("table");
80 xw
.WriteAttributeString ("border", "0");
81 xw
.WriteAttributeString ("cellpadding", "0");
82 xw
.WriteAttributeString ("cellspacing", "0");
83 xw
.WriteAttributeString ("width", "100%");
85 // Sort results by date (newest first)
86 IComparer mailmessagedatecomparer
= new MailMessageDateComparer ();
87 hits
.Sort (mailmessagedatecomparer
);
89 bool color_band
= true;
90 foreach (Hit hit
in hits
) {
91 HTMLRenderSingleMailMessage (hit
, color_band
, xw
);
92 color_band
= ! color_band
;
95 xw
.WriteEndElement (); // table
96 xw
.WriteEndElement (); // div
98 // close the xhtml doc
101 // Console.WriteLine ("..Renderer: MailMessage.. elapsed time {0}", DateTime.Now - StartExec);
103 return sw
.ToString ();
106 private void HTMLRenderSingleMailMessage (Hit hit
, bool color_band
, XmlWriter xw
)
108 // Make the date look pretty
109 string maildate
= Convert
.ToString (hit
["SentDate"]);
110 string ParsedDate
= ParseMailDate (maildate
);
112 Message msg
= new Message ();
113 msg
.Initialize (hit
);
115 // Console.WriteLine ("To: {0}\nFrom: {1}\nSubject: {2}\nDate: {3}",
116 // msg.Recipient, msg.Sender, msg.Subject, msg.SentDate);
118 xw
.WriteStartElement ("tr");
120 xw
.WriteAttributeString ("bgcolor", "#eeeeee");
122 xw
.WriteStartElement ("a");
123 xw
.WriteAttributeString ("href", "exec:evolution-1.5 " + hit
.Uri
); // FIXME: Probably unsafe
124 xw
.WriteAttributeString ("style", "text-decoration: none; color: black;");
126 // new / read / replied-to icon
127 xw
.WriteStartElement ("td");
128 xw
.WriteAttributeString ("width", "1%");
129 xw
.WriteAttributeString ("valign", "top");
130 xw
.WriteStartElement ("img");
131 xw
.WriteAttributeString ("border", "0");
132 xw
.WriteAttributeString ("src", msg
.Icon
);
133 xw
.WriteEndElement (); // img
134 xw
.WriteEndElement (); // td
136 // sender (mail from)
137 xw
.WriteStartElement ("td");
138 // xw.WriteAttributeString ("nowrap", "true");
139 xw
.WriteAttributeString ("width", "98%");
140 xw
.WriteRaw (MarkupStatus (msg
.GetSenderName (), msg
));
141 xw
.WriteEndElement (); // td
144 xw
.WriteStartElement ("td");
145 xw
.WriteAttributeString ("colspan", "2");
146 xw
.WriteAttributeString ("align", "right");
147 xw
.WriteAttributeString ("nowrap", "1");
148 xw
.WriteAttributeString ("valign", "top");
149 xw
.WriteAttributeString ("width", "1%");
150 xw
.WriteRaw (MarkupStatus (ParsedDate
, msg
));
151 xw
.WriteEndElement (); // td
152 xw
.WriteEndElement (); // a href
153 xw
.WriteEndElement (); // tr
155 xw
.WriteStartElement ("tr");
157 xw
.WriteAttributeString ("bgcolor", "#eeeeee");
159 xw
.WriteStartElement ("a");
160 xw
.WriteAttributeString ("href", "exec:evolution-1.5 " + hit
.Uri
); // FIXME: Probably unsafe
161 xw
.WriteAttributeString ("style", "text-decoration: none; color: black");
164 xw
.WriteStartElement ("td");
165 xw
.WriteAttributeString ("width", "1%");
166 xw
.WriteAttributeString ("valign", "top");
167 xw
.WriteAttributeString ("align", "right");
169 if (msg
.HasAttachment
) {
170 xw
.WriteStartElement ("img");
171 xw
.WriteAttributeString ("border", "0");
172 xw
.WriteAttributeString ("src", "internal:attachment.png");
173 xw
.WriteEndElement (); // img
176 xw
.WriteEndElement (); // td
179 xw
.WriteStartElement ("td");
180 xw
.WriteAttributeString ("colspan", "2");
181 xw
.WriteAttributeString ("width", "98%");
182 xw
.WriteAttributeString ("valign", "top");
183 xw
.WriteStartElement ("font");
184 xw
.WriteAttributeString ("color", "#666666");
185 xw
.WriteRaw (MarkupStatus (msg
.Subject
, msg
));
186 xw
.WriteEndElement (); // font
187 xw
.WriteEndElement (); // td
189 xw
.WriteEndElement (); // a href
190 xw
.WriteEndElement (); // tr
193 private string ParseMailDate (string maildate
)
195 // The dates returned by these functions are UTC
196 DateTime ParsedDate
= DateTime
.Parse (maildate
);
197 DateTime today
= DateTime
.Today
;
199 // Display in the current time zone
200 TimeZone localZone
= TimeZone
.CurrentTimeZone
;
201 ParsedDate
= localZone
.ToLocalTime (ParsedDate
);
203 // Let's see if we can't use the proper date and time formats here...
204 CultureInfo ci
= new CultureInfo (CultureInfo
.CurrentCulture
.Name
);
206 if (today
.Date
== ParsedDate
.Date
) {
207 // Display the time only
208 return ParsedDate
.ToString ("t", ci
);
211 if (today
.Year
!= ParsedDate
.Year
) {
212 // Show the year mm/dd/yyyy or dd/mm/yyyy
213 return ParsedDate
.ToString ("d", ci
);
216 return ParsedDate
.ToString ("ddd, MMM d");
219 private string MakeHTMLSafe (string html
)
221 StringWriter sw
= new StringWriter ();
222 XmlWriter xw
= new XmlTextWriter (sw
);
223 xw
.WriteString (html
);
224 string safehtml
= sw
.ToString ();
231 private string MarkupStatus (string html
, Message msg
)
233 StringWriter sw
= new StringWriter ();
234 XmlWriter xw
= new XmlTextWriter (sw
);
236 if (msg
.IsDeleted
== true)
237 xw
.WriteStartElement ("strike");
238 if (msg
.IsNew
== true)
239 xw
.WriteStartElement ("b");
241 xw
.WriteRaw (MakeHTMLSafe (html
));
243 if (msg
.IsNew
== true)
244 xw
.WriteEndElement (); // b
245 if (msg
.IsDeleted
== true)
246 xw
.WriteEndElement (); //strike
248 html
= sw
.ToString ();
254 // this might fare better in utils/evolution/camel.cs
255 public enum CamelFlags
{
267 private int GetDateStamp (string maildate
)
269 DateTime xdate
= DateTime
.Parse (maildate
);
270 int DateStamp
= int.Parse (maildate
);
274 public class Message
{
275 private string subject
;
276 private string sender
;
277 private DateTime sentdate
;
279 private string recipient
;
281 private bool hasreply
;
282 private bool isdeleted
;
283 private bool isdraft
;
284 private bool isflagged
;
286 private bool hasattachment
;
287 private string sendername
;
288 private string senderaddress
;
290 public string Subject
{
291 get { return this.subject; }
292 set { this.subject = value; }
295 public string Sender
{
296 get { return this.sender; }
297 set { this.sender = value; }
300 public DateTime SentDate
{
301 get { return this.sentdate; }
302 set { this.sentdate = value; }
306 get { return this.icon; }
307 set { this.icon = value; }
310 public string Recipient
{
311 get { return this.recipient; }
312 set { this.recipient = value; }
316 get { return this.uid; }
317 set { this.uid = value; }
320 public bool HasAttachment
{
321 get { return this.hasattachment; }
322 set { this.hasattachment = value; }
325 public bool HasReply
{
326 get { return this.hasreply; }
327 set { this.hasreply = value; }
330 public bool IsDeleted
{
331 get { return this.isdeleted; }
332 set { this.isdeleted = value; }
335 public bool IsDraft
{
336 get { return this.isdraft; }
337 set { this.isdraft = value; }
340 public bool IsFlagged
{
341 get { return this.isflagged; }
342 set { this.isflagged = value; }
346 get { return this.isnew; }
347 set { this.isnew = value; }
350 public string GetSenderName ()
352 if (this.sender
.IndexOf ("<") == -1)
353 this.sendername
= this.sender
;
355 this.sendername
= this.sender
.Substring (0, (this.sender
.LastIndexOf ("<") - 1));
357 return this.sendername
;
360 public string GetIcon ()
363 this.icon
= "internal:mail-replied.png";
364 } else if (this.IsNew
) {
365 this.icon
= "internal:mail-new.png";
367 this.icon
= "internal:mail-read.png";
373 public void Initialize (Hit hit
)
375 // Set all the properties based on info from the provided Match
376 this.subject
= Convert
.ToString (hit
["Subject"]);
377 this.sender
= Convert
.ToString (hit
["From"]);
378 this.recipient
= Convert
.ToString (hit
["To"]);
379 this.sentdate
= DateTime
.Parse (Convert
.ToString (hit
["SentDate"]));
380 this.uid
= Convert
.ToString (hit
["UID"]);
382 // this.sendername = this.sender.Substring (0, (this.sender.LastIndexOf ("<") - 1));
384 // Parse the message flags
385 int flags
= int.Parse (Convert
.ToString (hit
["Flags"]));
387 if ((flags
& (int) CamelFlags
.ANSWERED
) == (int) CamelFlags
.ANSWERED
)
388 this.hasreply
= true;
390 if ((flags
& (int) CamelFlags
.DELETED
) == (int) CamelFlags
.DELETED
)
391 this.isdeleted
= true;
393 if ((flags
& (int) CamelFlags
.DRAFT
) == (int) CamelFlags
.DRAFT
)
396 if ((flags
& (int) CamelFlags
.FLAGGED
) == (int) CamelFlags
.FLAGGED
)
397 this.isflagged
= true;
399 if ((flags
& (int) CamelFlags
.SEEN
) == (int) CamelFlags
.SEEN
) {
405 if ((flags
& (int) CamelFlags
.ATTACHMENTS
) == (int) CamelFlags
.ATTACHMENTS
)
406 this.hasattachment
= true;
408 if ((flags
& (int) CamelFlags
.ANSWERED_ALL
) == (int) CamelFlags
.ATTACHMENTS
)
409 this.hasreply
= true;
413 this.icon
= "internal:mail-replied.png";
414 } else if (this.isnew
) {
415 this.icon
= "internal:mail-new.png";
417 this.icon
= "internal:mail-read.png";
424 public enum SortDirection
{
429 public class MailMessageDateComparer
: IComparer
{
431 // Reverse-sort -- newest messages first
432 private SortDirection m_direction
= SortDirection
.Descending
;
434 int IComparer
.Compare (Object x
, Object y
) {
436 Hit matchX
= (Hit
) x
;
437 Hit matchY
= (Hit
) y
;
439 DateTime DateX
= DateTime
.Parse (Convert
.ToString (matchX
["SentDate"]));
440 DateTime DateY
= DateTime
.Parse (Convert
.ToString (matchY
["SentDate"]));
442 if (matchX
== null && matchY
== null) {
444 } else if (matchX
== null && matchY
!= null) {
445 return (this.m_direction
== SortDirection
.Ascending
) ? -1 : 1;
446 } else if (matchX
!= null && matchY
== null) {
447 return (this.m_direction
== SortDirection
.Ascending
) ? 1 : -1;
449 return (this.m_direction
== SortDirection
.Ascending
) ?
450 DateX
.CompareTo (DateY
) :
451 DateY
.CompareTo (DateX
);