Bug 454829 Summary page for collapsed threads and multiple selections. r=bienvenu

This commit is contained in:
David Ascher 2009-05-28 08:48:37 +01:00
Родитель ce412ed832
Коммит 5cff75761d
26 изменённых файлов: 1670 добавлений и 238 удалений

Просмотреть файл

@ -527,6 +527,8 @@ nsMsgSearchCommandUpdater.prototype =
SetNextMessageAfterDelete();
},
summarizeSelection : function() {},
QueryInterface : function(iid)
{
if (iid.equals(Components.interfaces.nsIMsgDBViewCommandUpdater) ||

Просмотреть файл

@ -52,10 +52,13 @@ var accountManager;
var gMessengerBundle;
var gBrandBundle;
var gContextMenu;
Components.utils.import("resource://app/modules/gloda/log4moz.js");
var gContextMenu;
var gMailWindowLog = Log4Moz.getConfiguredLogger("mailWindow", Log4Moz.Level.Debug, Log4Moz.Level.Debug, Log4Moz.Level.Debug);
var gAccountCentralLoaded = true;
function OnMailWindowUnload()
{
MailOfflineMgr.uninit();
@ -315,6 +318,7 @@ nsMsgStatusFeedback.prototype =
let progressCount = 0;
// For each activity that is in progress, get its status.
this._activeProcesses.forEach(function (element) {
if (element.state ==
Components.interfaces.nsIActivityProcess.STATE_INPROGRESS &&

Просмотреть файл

@ -185,6 +185,8 @@ nsMsgDBViewCommandUpdater.prototype =
SetNextMessageAfterDelete();
},
summarizeSelection : function() {},
QueryInterface : function(iid)
{
if (iid.equals(Components.interfaces.nsIMsgDBViewCommandUpdater) ||

Просмотреть файл

@ -176,6 +176,12 @@
disablesecurity="true" disablehistory="true" type="content-primary"
onresize="return messagePaneOnResize(event);" autofind="false"
src="about:blank" onclick="return contentAreaClick(event);" />
<iframe id="htmlpane"
style="height: 0px; min-height: 1px" flex="1" name="htmlpane"
hidden="true"
disablesecurity="true" disablehistory="true"
onresize="return htmlPaneOnResize(event);" autofind="false"
src="about:blank"/>
<splitter id="attachment-splitter" collapse="after" resizebefore="closest" resizeafter="closest" collapsed="true"/>
<hbox id="attachmentView"/>
<findbar id="FindToolbar" browserid="messagepane"/>

Просмотреть файл

@ -72,6 +72,7 @@
<stringbundleset id="stringbundleset">
<stringbundle id="bundle_brand" src="chrome://branding/locale/brand.properties"/>
<stringbundle id="bundle_search" src="chrome://messenger/locale/search.properties"/>
<stringbundle id="bundle_multimessages" src="chrome://messenger/locale/multimessageview.properties"/>
</stringbundleset>
<script type="application/javascript" src="chrome://global/content/globalOverlay.js"/>
@ -80,6 +81,7 @@
<script type="application/x-javascript" src="chrome://messenger/content/shareglue.js"/>
<script type="application/x-javascript" src="chrome://messenger/content/msgViewNavigation.js"/>
<script type="application/x-javascript" src="chrome://messenger/content/mailWindow.js"/>
<script type="application/x-javascript" src="chrome://messenger/content/selectionsummaries.js"/>
<script type="application/x-javascript" src="chrome://messenger/content/msgMail3PaneWindow.js"/>
<script type="application/x-javascript" src="chrome://messenger/content/specialTabs.js"/>
<script type="application/x-javascript" src="chrome://messenger/content/mail3PaneWindowCommands.js"/>
@ -330,18 +332,29 @@
<vbox id="messagepanebox" flex="2" minheight="100" height="200"
minwidth="100" width="200" persist="height width">
<hbox id="msgHeaderView"/>
<hbox id="editMessageBox"/>
<deck id="msgNotificationBar"/>
<browser id="messagepane" context="mailContext" autofind="false"
minheight="1" flex="1" name="messagepane" tooltip="aHTMLTooltip"
disablehistory="true" type="content-primary" src="about:blank"
onresize="return messagePaneOnResize(event);"
disablesecurity="true" onclick="return contentAreaClick(event);"/>
<splitter id="attachment-splitter" collapse="after" resizebefore="closest" resizeafter="closest" collapsed="true"/>
<hbox id="attachmentView"/>
<findbar id="FindToolbar" browserid="messagepane"/>
<!-- This next iframe is used to display summaries of -->
<!-- multiple selected messages or collapsed threads -->
<iframe id="multimessage"
style="height: 0px; min-height: 1px"
flex="1" name="multimessage"
hidden="true"
disablesecurity="true" disablehistory="true"
src="chrome://messenger/content/multimessageview.xhtml"
autofind="false"/>
<vbox id="singlemessage" flex="1">
<hbox id="msgHeaderView"/>
<hbox id="editMessageBox"/>
<deck id="msgNotificationBar"/>
<browser id="messagepane" context="mailContext" autofind="false"
minheight="1" flex="1" name="messagepane" tooltip="aHTMLTooltip"
disablehistory="true" type="content-primary" src="about:blank"
onresize="return messagePaneOnResize(event);"
disablesecurity="true" onclick="return contentAreaClick(event);"/>
<splitter id="attachment-splitter" collapse="after" resizebefore="closest" resizeafter="closest" collapsed="true"/>
<hbox id="attachmentView"/>
<findbar id="FindToolbar" browserid="messagepane"/>
</vbox>
</vbox>
</box>
</vbox>

Просмотреть файл

@ -0,0 +1,301 @@
/* Generic (cross-platform) multimessage view CSS. Some bits will be overriden
by theme specific files */
body {
font-family: sans-serif;
margin: 0px;
padding: 1ex 1em;
}
.star {
width: 16px;
height: 16px;
display: inline-block;
margin-left: 1ex;
}
#markButton {
width: 5em;
}
#multimessageview {
font-size: small;
}
#messages {
-moz-border-radius: 0.4ex;
border: 1px solid ThreeDShadow;
padding: 1ex 1em;
margin: 0px;
font-size: small;
}
#messagelist {
width: 100%;
display: table;
}
.message {
display: table-row;
}
.message > .header {
display: table-cell;
padding: 0.6ex 0px;
}
.subject {
display: inline-block;
}
.sender {
display: inline-block;
}
.author {
display: inline;
color: grey;
}
.count, .date {
display: table-cell;
padding: 0px 1em;
white-space: nowrap;
text-align: right;
color: InactiveCaptionText;
}
.wrappedsender, .wrappedsubject {
padding-right: 18px;
padding-top: 6px;
}
.message.unread > .header > .wrappedsubject > .subject,
.unread .subject_and_author,
.message.unread > .header > .wrappedsender > .sender {
font-weight: bold;
}
.message > .header > .wrappedsender > .sender:hover,
.message > .header > .wrappedsubject > .subject:hover {
text-decoration: underline;
cursor: pointer;
}
.message > .header > .snippet, .message .tags {
margin-left: 2em;
}
.message > .header > .snippet {
color: GrayText;
}
.message > .header > .senders {
color: GrayText;
}
.info {
font-size: small;
}
.heading.info {
font-size: medium;
font-weight: normal;
}
.tags {
padding-top: 2px;
}
.tag {
padding: 0.2ex 0.2em;
margin-right: 0.5em;
-moz-margin-start: 0px;
background-image: url("chrome://messenger/skin/tagbg.png");
color: InfoText;
-moz-border-radius: 2px;
}
#buttonbox {
display: table-cell;
text-align: right;
padding-bottom: 1ex;
font-size: 11px;
font-family: Lucida Grande;
border: 1px solid transparent;
}
#headingwrappertable {
display: table;
width: 100%;
}
#headingwrapper {
display: table-row;
margin-bottom: 1em;
border: 1px solid transparent;
}
.heading {
display: table-cell;
font-weight: bold;
font-size: medium;
margin: 0.5em;
border: 1px solid transparent;
padding-right: 1em;
}
.button {
display: inline;
}
#trash {
min-height: 16px !important;
min-width: 21px !important;
padding: 0px;
}
.hidden {
display: none;
}
#column {
float: right;
right: 1em;
top: 1em;
}
#foldericon {
z-index: -1;
min-width: 128px;
min-height: 128px;
background-image: url("chrome://messenger/skin/icons/largefolder.jpg");
background-repeat: no-repeat;
}
#tagpie {
display: block;
}
#tagdots {
display: block;
text-align: center;
padding: 1em;
}
.section_heading {
font-weight: bold;
padding-bottom: .5em;
color: #555;
}
#header {
border: 1px solid transparent;
}
.stats {
padding: 1em;
padding-top: 3em;
text-align: center;
font-size: small;
}
#mozupdate {
clear: both;
-moz-border-radius: 0.4ex;
border: 1px solid #FFD8B9;
left: 1em;
right: 1em;
padding: 0.5em;
}
a {
color: darkblue;
font-weight: bold;
}
a:hover {
text-decoration: underline;
}
#unread, #authors, #threads, #last_selected_wrapper {
display: inline-block;
padding: 1ex 1em;
margin: 0px;
margin-right: 1em;
margin-bottom: 1em;
font-size: small;
-moz-border-radius: 0.4ex;
border: 1px solid ThreeDShadow;
}
#last_selected_wrapper, #unread {
min-width: 40em;
}
#authors, #threads {
vertical-align: top;
}
#topten {
vertical-align: top;
}
#remotecontent {
-moz-border-radius: 0.4ex;
border: 1px solid ThreeDShadow;
background-color: #fafafa;
padding: 1ex 1em;
margin: 0px;
font-size: smaller;
}
.messagecount {
display: inline-block;
white-space: nowrap;
overflow: hidden;
}
.author, .subject {
display: inline;
overflow: hidden;
margin-right: 1em;
}
.subject_and_author {
white-space: nowrap;
overflow: hidden;
width: 38em;
margin-right: 1em;
}
.link:hover {
text-decoration: underline;
cursor: pointer;
}
.sparkline {
margin-left: .5em;
}
#last_selected_wrapper {
border: 1px solid orange;
}
.last_selected {
font-weight: normal;
display: inline;
}
.hidden {
visibility: hidden;
display: none !important;
}
.histogram {
display: inline;
padding-left: 1em;
}

Просмотреть файл

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<!-- ***** BEGIN LICENSE BLOCK *****
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
-
- The contents of this file are subject to the Mozilla Public License Version
- 1.1 (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
- http://www.mozilla.org/MPL/
-
- Software distributed under the License is distributed on an "AS IS" basis,
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- for the specific language governing rights and limitations under the
- License.
-
- The Original Code is Thunderbird multiple message summary pane.
-
- The Initial Developer of the Original Code is
- Mozilla Messaging.
- Portions created by the Initial Developer are Copyright (C) 2009
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
- David Ascher <dascher@mozillamessaging.com>
-
- Alternatively, the contents of this file may be used under the terms of
- either the GNU General Public License Version 2 or later (the "GPL"), or
- the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- in which case the provisions of the GPL or the LGPL are applicable instead
- of those above. If you wish to allow use of your version of this file only
- under the terms of either the GPL or the LGPL, and not to allow others to
- use your version of this file under the terms of the MPL, indicate your
- decision by deleting the provisions above and replace them with the notice
- and other provisions required by the LGPL or the GPL. If you do not delete
- the provisions above, a recipient may use your version of this file under
- the terms of any one of the MPL, the GPL or the LGPL.
-
- ***** END LICENSE BLOCK ***** -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"
[
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
%brandDTD;
<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
%globalDTD;
<!ENTITY % startDTD SYSTEM "chrome://messenger/locale/multimessageview.dtd">
%startDTD;
]>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<head>
<link rel="stylesheet" media="screen" type="text/css"
href="chrome://messenger/skin/messageHeader.css"/>
<link rel="stylesheet" media="screen" type="text/css"
href="chrome://messenger/skin/multimessageview.css"/>
<link rel="stylesheet" media="screen" type="text/css"
href="chrome://messenger/skin/tagColors.css"/>
<script type="application/x-javascript"
src="chrome://messenger/content/multimessageview.js"></script>
<title>&window.title;</title>
</head>
<body>
<div id="multimessageview">
<div id="headingwrappertable">
<div id="headingwrapper">
<div class="heading" id="heading">&selectedmessages.label;</div>
<div id="buttonbox"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<hbox id="buttonhbox" align="start">
<button id="archive" class="multimessage button"
onclick="window.top.MsgArchiveSelectedMessages(null)">&archive.label;</button>
<button id="trash" class="multimessage button trashButton"
onclick="window.top.DefaultController.doCommand('cmd_delete');"/>
</hbox>
</div>
</div>
</div>
<div id="messages">
<div id="messagelist"/>
<p>
<span class="info" id="size"></span> <span class="info" id="notice"></span>
</p>
</div>
</div>
</body>
</html>

Просмотреть файл

@ -0,0 +1,759 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is multiple message preview pane
*
* The Initial Developer of the Original Code is
* Mozilla Messaging
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* David Ascher <dascher@mozillamessaging.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
Components.utils.import("resource://gre/modules/DownloadUtils.jsm");
Components.utils.import("resource://gre/modules/PluralForm.jsm");
Components.utils.import("resource://app/modules/gloda/mimemsg.js");
let gSelectionSummaryStrings = {
selectedNMessages: "selectedNMessages",
acrossNThreads: "acrossNThreads",
numMsgs: "numMsgs",
countUnread: "countUnread",
Nmessages: "Nmessages",
messagesSize: "messagesSize",
yesterday: "yesterday",
noticeText: "noticeText",
noSubject: "noSubject",
}
/**
* loadSelectionSummaryStrings does the routine localization of non-pluralized
* strings, populating the gSelectionSummaryStrings array based on the current
* locale.
*/
function loadSelectionSummaryStrings()
{
// convert strings to those in the string bundle
let getStr = function(string) document.getElementById("bundle_multimessages").getString(string);
var strBundleService = Components.classes["@mozilla.org/intl/stringbundle;1"].getService();
strBundleService = strBundleService.QueryInterface(Components.interfaces.nsIStringBundleService);
for (let [name, value] in Iterator(gSelectionSummaryStrings))
gSelectionSummaryStrings[name] = typeof value == "string" ?
getStr(value) : value.map(gSelectionSummaryStrings);
}
loadSelectionSummaryStrings();
/**
* pickMessagePane is the toggle to figure out whether to use the standard
* message pane used to display message bodies (& headers), or whether to
* display an HTML iframe used for the multiple message summaries.
*
* @param visiblePaneId
* the ID of the pane that we want to make be the visible one.
* @return the DOM element corresponding to the selected pane.
*
*/
function pickMessagePane(visiblePaneId)
{
var paneIds = ['singlemessage', 'multimessage'];
// when we want to do folder and account summaries, we just need to add
// XUL elements for them, and add them to this list.
// 'foldersummary', 'accountsummary'];
for (let [,paneId] in Iterator(paneIds))
document.getElementById(paneId).hidden = paneId != visiblePaneId;
return document.getElementById(visiblePaneId);
}
// Ah, wouldn't it be nice if there was platform code to do the following...
/**
* the equivalent of jQuery's addClass. Avoids duplicates, nothing fancy.
*
* @param node
* any old DOM node
* @param classname
* a string, which will be added as a CSS class
*/
function _mm_addClass(node, classname)
{
let classes = [];
if (node.hasAttribute('class'))
classes = node.getAttribute('class').split(' ');
for each (klass in classes) {
if (klass == classname) // already have it
return;
}
classes.push(classname);
node.setAttribute('class', classes.join(' '));
}
/**
* the equivalent of jQuery's removeClass. Doesn't freak if the class name
* isn't in the class attribute.
*
* @param node
* any old DOM node
* @param classname
* a string, which will be removed from the class set.
*/
function _mm_removeClass(node, classname)
{
if (! node.hasAttribute('class'))
return;
let classes = node.getAttribute('class').split(' ');
let newclasses = [];
for each (klass in classes) {
if (klass != classname)
newclasses.push(klass);
}
node.setAttribute('class', newclasses.join(' '));
}
/**
* the MultiMessageSummary class is responsible for populating the message pane
* with a reasonable summary of a set of messages that span more than one
* thread.
*
* It uses the same multimessage iframe as ThreadSummary, so both it
* and ThreadSummary should be careful to clean up the other's work
* before inserting their DOM nodes into the frame.
*
* There's a two phase process: build the framework based on what's available
* from the msgHdr itself, and then spawn an aysnc Gloda query which will
* fetch the snippets, tags, etc.
*
* @param msgURIs
* array of message URIs
*/
function MultiMessageSummary(msgURIs) {
this._msgURIs = msgURIs;
}
MultiMessageSummary.prototype = {
init: function() {
this._msgHdrs = new Array();
this._glodaQueries = [];
this._headerNodes = {};
this._snippetNodes = {};
this._tagsNodes = {};
for (var i = 0; i < this._msgURIs.length; ++i)
this._msgHdrs.push(messenger.msgHdrFromURI(this._msgURIs[i]));
this.summarize();
},
/**
* Given a name (as one sees in email headers), strip eventual
* leading/trailing quotes (both single and double).
*
* @param senderName
* name which might be quoted
* @return
* name without quotes
**/
stripQuotes: function(senderName) {
if ((senderName[0] == "'" && senderName[senderName.length-1] == "'") ||
(senderName[0] == '"' && senderName[senderName.length-1] == '"'))
senderName = senderName.slice(1, -1);
return senderName;
},
/**
* Fill in the summary pane describing the selected messages
**/
summarize: function() {
let htmlpane = pickMessagePane('multimessage');
// First, we group the messages in threads.
// count threads
let threads = {};
let numThreads = 0;
for (let [,msgHdr] in Iterator(this._msgHdrs))
{
if (! threads[msgHdr.threadId]) {
threads[msgHdr.threadId] = [msgHdr];
numThreads += 1;
}
else
{
threads[msgHdr.threadId].push(msgHdr);
}
}
// set the heading based on the number of messages & threads
let heading = htmlpane.contentDocument.getElementById('heading');
_mm_addClass(heading, "heading");
_mm_addClass(heading, "info");
let numMessages = this._msgURIs.length;
let messagesTitle = PluralForm.get(numMessages, gSelectionSummaryStrings["selectedNMessages"]).replace('#1', numMessages);
messagesTitle += PluralForm.get(numThreads, gSelectionSummaryStrings["acrossNThreads"]).replace('#1', numThreads);
heading.innerHTML = messagesTitle;
// clear the messages list
let messagesElt = htmlpane.contentDocument.getElementById('messagelist');
while (messagesElt.firstChild)
messagesElt.removeChild(messagesElt.firstChild);
let MAXCOUNT = 100;
let count = 0;
let maxCountExceeded = false;
// we could consider sorting differently someday
for (let [thread,msgs] in Iterator(threads))
{
count += 1;
if (count > MAXCOUNT) {
maxCountExceeded = true;
break;
}
let countUnread = 0;
let countStarred = 0;
let header, subject, tags, countNode;
let msg = htmlpane.contentDocument.createElement("div");
_mm_addClass(msg, "message");
// we'll mark the thread unread if any messages in it are unread
for (let [, msgHdr] in Iterator(msgs)) {
if (! msgHdr.isRead)
countUnread += 1;
if (msgHdr.isFlagged)
countStarred += 1;
}
if (countUnread)
_mm_addClass(msg, 'unread');
header = htmlpane.contentDocument.createElement("div");
_mm_addClass(header, "header");
if (countStarred) {
_mm_addClass(msg, "starred");
}
let subjectText = msgs[0].mime2DecodedSubject || gSelectionSummaryStrings['noSubject'];
// Someday, we might want to handle multi-subject threads
subject = htmlpane.contentDocument.createElement("div");
_mm_addClass(subject, "subject");
subject.innerHTML = escapeXMLchars(subjectText);
let authorText = " " + msgs[0].mime2DecodedAuthor;
// Someday, we might want to handle multi-subject threads
let author = htmlpane.contentDocument.createElement("div");
_mm_addClass(author, "author");
author.innerHTML = escapeXMLchars(authorText);
let wrappedsubject = htmlpane.contentDocument.createElement("div");
_mm_addClass(wrappedsubject, 'wrappedsubject');
let star = htmlpane.contentDocument.createElement("div");
_mm_addClass(star, "star");
wrappedsubject.appendChild(subject);
wrappedsubject.appendChild(author);
header.appendChild(wrappedsubject);
// this feels ugly -- is there a better way to pass in data?
subject.msgs = msgs;
subject.addEventListener("click", function() {
selectMultipleMessagesByMsgHdr(this.msgs)
}, true);
_mm_addClass(subject, "link");
msg.appendChild(header);
let snippet = htmlpane.contentDocument.createElement("div");
_mm_addClass(snippet, "snippet");
header.appendChild(snippet);
tags = htmlpane.contentDocument.createElement("div");
_mm_addClass(tags, "tags");
header.appendChild(tags);
// use the first msgHdr in the thread for key purposes for snippets
this._snippetNodes[msgs[0].messageKey + msgs[0].folder.URI] = snippet;
// for tags, stars, and read/unread status, we want to map
// from all messages to one node
for each (msgHdr in msgs) {
this._headerNodes[msgHdr.messageKey + msgHdr.folder.URI] = header;
this._tagsNodes[msgHdr.messageKey + msgHdr.folder.URI] = tags;
}
let numMsgs = msgs.length;
countNode = htmlpane.contentDocument.createElement("div");
_mm_addClass(countNode, 'count');
if (numMsgs > 1) {
let label = "(";
label += PluralForm.get(numMsgs, gSelectionSummaryStrings["numMsgs"]).replace('#1', numMsgs);
if (countUnread)
label += PluralForm.get(numMsgs, gSelectionSummaryStrings["countUnread"]).replace('#1', countUnread);
label += ")";
countNode.innerHTML = label;
}
msg.appendChild(countNode);
countNode.appendChild(star);
messagesElt.appendChild(msg);
}
this.computeSize();
this.notifyMaxCountExceeded(numMessages, MAXCOUNT);
this._glodaQueries.push(Gloda.getMessageCollectionForHeaders(this._msgHdrs, this));
},
/**
* compute the size of the messages in the selection and display it
* in the element of id "size"
**/
computeSize: function() {
let htmlpane = pickMessagePane('multimessage');
let numThreads = 0;
let numBytes = 0;
for (let [,msgHdr] in Iterator(this._msgHdrs))
numBytes += msgHdr.messageSize; // XXX do something about news?
let [size, unit] = DownloadUtils.convertByteUnits(numBytes);
let sizeText = replaceInsert(gSelectionSummaryStrings.messagesSize, 1, size);
sizeText = replaceInsert(sizeText, 2, unit);
htmlpane.contentDocument.getElementById('size').innerHTML = sizeText;
},
/** compute the size of the messages in the selection and display it
* in the element of id "size"
**/
notifyMaxCountExceeded: function(numMessages, maxCount) {
let htmlpane = pickMessagePane('multimessage');
let notice = htmlpane.contentDocument.getElementById('notice');
if (numMessages > maxCount)
{
let noticeText = gSelectionSummaryStrings.noticeText;
noticeText = replaceInsert(noticeText, 1, numMessages);
noticeText = replaceInsert(noticeText, 2, maxCount);
notice.innerHTML = noticeText;
_mm_removeClass(notice, 'hidden');
} else {
_mm_addClass(notice, 'hidden');
}
},
// these are listeners for the gloda collections.
onItemsAdded: function(aItems) {
},
onItemsModified: function(aItems) {
this.processItems(aItems);
},
onItemsRemoved: function(aItems) {
},
/**
* Given a set of items from a gloda collection, process them and update
* the display accordingly.
*
* @param aItems
* contents of a gloda collection
**/
processItems: function(aItems) {
var tagService = Components.classes["@mozilla.org/messenger/tagservice;1"]
.getService(Components.interfaces.nsIMsgTagService);
let seenTagNode = {};
for (let [,glodaMsg] in Iterator(aItems)) {
let messageKey = glodaMsg.messageKey;
let domkey = messageKey + glodaMsg.folder.uri;
if (this._headerNodes) {
let headerNode = this._headerNodes[domkey];
// unread and starred will get set if any of the messages in a
// collapsed thread qualify
if (headerNode) {
if (! glodaMsg.read)
_mm_addClass(headerNode, "unread");
else
_mm_removeClass(headerNode, "unread");
if (glodaMsg.starred)
_mm_addClass(headerNode, "starred");
else
_mm_removeClass(headerNode, "starred");
}
}
if (this._snippetNodes) {
let snippetNode = this._snippetNodes[domkey];
MsgHdrToMimeMessage(glodaMsg.folderMessage, null, function(aMsgHdr, aMimeMsg) {
if (aMimeMsg == null)
return;
let text = Gloda.getMessageContent(glodaMsg, aMimeMsg).getContentSnippet(101);
if (snippetNode && text)
{
let kSnippetLength = 100;
if (text.length > kSnippetLength)
text = text.substring(0, kSnippetLength) + "\u2026"; // ellipsis
snippetNode.innerHTML = escapeXMLchars(text);
}
});
}
if (this._tagsNodes) {
// for tags, we need to do some fancy stuff, to figure out the set
// of tags that correspond to all of the messages in a collapsed
// thread.
let key = messageKey + glodaMsg.folder.uri;
let tagsNode = this._tagsNodes[key];
if (tagsNode) {
if (! seenTagNode[tagsNode]) {
// We haven't processed a message from this thread before
while (tagsNode.childNodes.length) {
// get rid of all tags
tagsNode.removeChild(tagsNode.firstChild);
}
seenTagNode[tagsNode] = {};
}
for each (let [,tag] in Iterator(glodaMsg.tags)) {
// have we already added this tag to the thread?
if (!(seenTagNode[tagsNode][tag.tag])) {
let tagNode = tagsNode.ownerDocument.createElement('span');
// see tagColors.css
let colorClass = "blc-" + tagService.getColorForKey(tag.key).substr(1);
_mm_addClass(tagNode, "tag " + tag.tag + " " + colorClass);
tagNode.innerHTML = tag.tag;
tagsNode.appendChild(tagNode);
seenTagNode[tagsNode][tag.tag] = true;
}
}
}
}
}
},
onQueryCompleted: function(aCollection) {
if (aCollection.items.length) {
this.processItems(aCollection.items);
}
}
}
/**
* the ThreadSummary class is responsible for populating the message pane
* with a reasonable summary of a set of messages that are are in a single
* thread.
*
* It uses the same multimessage iframe as MultiMessageSummary, so both it
* and MultiMessageSummary should be careful to clean up the other's work
* before inserting their DOM nodes into the frame.
*
* There's a two phase process: build the framework based on what's available
* from the msgHdr itself, and then spawn an aysnc Gloda query which will
* fetch the snippets, tags, etc.
*
* @param msgURIs
* array of message URIs
*/
function ThreadSummary(msgURIs)
{
this._msgURIs = msgURIs;
}
ThreadSummary.prototype = {
__proto__: MultiMessageSummary.prototype,
summarize: function() {
this._headerNodes = {};
this._snippetNodes = {};
let htmlpane = pickMessagePane('multimessage');
let firstMsgHdr = messenger.msgHdrFromURI(this._msgURIs[0]);
let numMessages = this._msgURIs.length;
let subject = (firstMsgHdr.mime2DecodedSubject || gSelectionSummaryStrings["noSubject"])
+ " "
+ PluralForm.get(numMessages, gSelectionSummaryStrings["Nmessages"]).replace('#1', numMessages);
let heading = htmlpane.contentDocument.getElementById('heading');
heading.setAttribute("class", "heading");
heading.innerHTML = escapeXMLchars(subject);
let messagesElt = htmlpane.contentDocument.getElementById('messagelist');
while (messagesElt.firstChild)
messagesElt.removeChild(messagesElt.firstChild);
let headerParser = Components.classes["@mozilla.org/messenger/headerparser;1"]
.getService(Components.interfaces.nsIMsgHeaderParser);
let msgHdrs = new Array();
let count = 0;
const MAXCOUNT = 100;
let maxCountExceeded = false;
for (var i = 0; i < this._msgURIs.length; ++i)
{
count += 1;
if (count > MAXCOUNT) {
maxCountExceeded = true;
break;
}
let msgHdr, msg, header, sender, snippet, tags;
msgHdr = messenger.msgHdrFromURI(this._msgURIs[i]);
msgHdrs.push(msgHdr);
msg = htmlpane.contentDocument.createElement("div");
let key = msgHdr.messageKey + msgHdr.folder.URI;
_mm_addClass(msg, "message");
if (! msgHdr.isRead)
_mm_addClass(msg, "unread");
header = htmlpane.contentDocument.createElement("div");
_mm_addClass(header, "header");
if (msgHdr.isFlagged)
_mm_addClass(msg, "starred");
let senderName = headerParser.extractHeaderAddressNames(msgHdr.mime2DecodedAuthor);
senderName = this.stripQuotes(senderName);
sender = htmlpane.contentDocument.createElement("div");
sender.msgHdr = msgHdr;
_mm_addClass(sender, "sender");
sender.addEventListener("click", function(e) {
// if the msg is the first message in a collapsed thread, we need to
// uncollapse it.
let origRowCount = gDBView.rowCount;
let viewIndex = gDBView.findIndexOfMsgHdr(e.target.msgHdr, true);
gDBView.selectFolderMsgByKey(this.folder, this.msgKey);
if (gDBView.rowCount != origRowCount)
gDBView.selectionChanged();
}, true);
_mm_addClass(sender, "link");
sender.innerHTML = escapeXMLchars(senderName); // escape?
sender.folder = msgHdr.folder;
sender.msgKey = msgHdr.messageKey;
let wrappedsender = htmlpane.contentDocument.createElement("div");
_mm_addClass(wrappedsender, "wrappedsender");
let star = htmlpane.contentDocument.createElement("div");
_mm_addClass(star, "star");
wrappedsender.appendChild(sender);
header.appendChild(wrappedsender);
snippet = htmlpane.contentDocument.createElement("div");
_mm_addClass(snippet, "snippet");
header.appendChild(snippet);
tags = htmlpane.contentDocument.createElement("div");
_mm_addClass(tags, "tags");
header.appendChild(tags);
this._headerNodes[key] = msg;
this._snippetNodes[key] = snippet;
this._tagsNodes[key] = tags;
msg.appendChild(header);
let dateNode = htmlpane.contentDocument.createElement("div");
dateNode.innerHTML = makeFriendlyDateAgo(new Date(msgHdr.date/1000));
dateNode.appendChild(star);
_mm_addClass(dateNode, "date");
msg.appendChild(dateNode);
messagesElt.appendChild(msg);
}
// stash somewhere so it doesn't get GC'ed
this._glodaQueries.push(Gloda.getMessageCollectionForHeaders(msgHdrs, this));
this.notifyMaxCountExceeded(numMessages, MAXCOUNT);
this.computeSize();
}
}
// We use a global to prevent GC of gloda collection (and we reuse it to prevent
// leaks). Without a global, the GC is aggressive enough that the gloda query
// is gone before it returns.
var gSummary;
/**
* Given an array of message URIs which are all in the
* same thread, summarize them.
*
* @param selectedMsgUris
* array of message URIs
*/
function summarizeThread(selectedMsgUris)
{
if (selectedMsgUris.length == 0)
return;
gSummary = new ThreadSummary(selectedMsgUris);
gSummary.init();
}
/**
* Given an array of message URIs, cause the message pane
* to display a summary of them.
*
* @param selectedMsgUris
* array of message URIs
*/
function summarizeMultipleSelection(selectedMsgUris)
{
if (selectedMsgUris.length == 0)
return;
gSummary = new MultiMessageSummary(selectedMsgUris);
gSummary.init();
}
/**
* Given an array of nsMsgHdrs, select all of them. This will uncollapse
* threads that are collapsed as necessary.
*
* @param msgHdrs
* array of msgHdr's
*/
function selectMultipleMessagesByMsgHdr(msgHdrs)
{
let treeView = gDBView.QueryInterface(Components.interfaces.nsITreeView);
if (msgHdrs.length == 1) {
gDBView.selectFolderMsgByKey(msgHdrs[0].folder, msgHdrs[0].messageKey);
} else {
let treeSelection = treeView.selection;
treeSelection.clearSelection();
for (let [, msgHdr] in Iterator(msgHdrs))
{
let viewIndex = gDBView.findIndexOfMsgHdr(msgHdr, false);
let thread = gDBView.getThreadContainingIndex(viewIndex);
let flags = gDBView.getFlagsAt(viewIndex);
if (flags & Components.interfaces.nsMsgMessageFlags.Elided)
treeView.toggleOpenState(viewIndex);
treeSelection.rangedSelect(viewIndex, viewIndex, true);
}
}
}
/**
* Helper function to generate a localized "friendly" representation of
* time relative to the present. If the time input is "today", it returns
* a string corresponding to just the time. If it's yesterday, it returns
* "yesterday" (localized). If it's in the last week, it returns the day
* of the week. If it's before that, it returns the date.
*
* @param time
* the time (better be in the past!)
* @return The string with a "human-friendly" representation of that time
* relative to now.
*/
function makeFriendlyDateAgo(time)
{
let dts = Components.classes["@mozilla.org/intl/scriptabledateformat;1"]
.getService(Components.interfaces.nsIScriptableDateFormat);
// Figure out when today begins
let now = new Date();
let today = new Date(now.getFullYear(), now.getMonth(),
now.getDate());
// Get the end time to display
let end = time;
// Figure out if the end time is from today, yesterday,
// this week, etc.
let dateTime;
let kDayInMsecs = 24 * 60 * 60 * 1000;
let k6DaysInMsecs = 6 * kDayInMsecs;
if (end >= today) {
// activity finished after today started, show the time
dateTime = dts.FormatTime("", dts.timeFormatNoSeconds,
end.getHours(), end.getMinutes(),0);
} else if (today - end < kDayInMsecs) {
// activity finished after yesterday started, show yesterday
dateTime = gSelectionSummaryStrings.yesterday;
} else if (today - end < k6DaysInMsecs) {
// activity finished after last week started, show day of week
dateTime = end.toLocaleFormat("%A");
} else if (now.getFullYear() == end.getFullYear()) {
// activity must have been from some time ago.. show month/day
let month = end.toLocaleFormat("%B");
// Remove leading 0 by converting the date string to a number
let date = Number(end.toLocaleFormat("%d"));
//dateTime = replaceInsert(this.text.monthDate, 1, month);
dateTime = replaceInsert("#1 #2", 1, month);
dateTime = replaceInsert(dateTime, 2, date);
} else {
// not this year, so show year as wel
let month = end.toLocaleFormat("%B");
let year = end.toLocaleFormat("%Y");
// Remove leading 0 by converting the date string to a number
let date = Number(end.toLocaleFormat("%d"));
//dateTime = replaceInsert(this.text.monthDate, 1, month);
dateTime = replaceInsert("#1 #2 #3", 1, month);
dateTime = replaceInsert(dateTime, 2, date);
dateTime = replaceInsert(dateTime, 3, year);
}
return dateTime;
}
/**
* Helper function to replace a placeholder string with a real string
*
* @param aText
* Source text containing placeholder (e.g., #1)
* @param aIndex
* Index number of placeholder to replace
* @param aValue
* New string to put in place of placeholder
* @return The string with placeholder replaced with the new string
*/
function replaceInsert(aText, aIndex, aValue)
{
return aText.replace("#" + aIndex, aValue);
}
/**
* Helper function to escape some XML chars, so they display properly in
* innerHTML.
*
* @param s
* input text
* @return The string with <, >, and & replaced by the corresponding entities.
*/
function escapeXMLchars(s)
{
return s.replace(/[<>&]/g, function(s) {
switch (s) {
case "<": return "&lt;";
case ">": return "&gt;";
case "&": return "&amp;";
default: throw Error("Unexpected match");
}
}
);
}

Просмотреть файл

@ -116,12 +116,36 @@ nsMsgDBViewCommandUpdater.prototype =
SetNextMessageAfterDelete();
},
summarizeSelection: function()
{
let selectedMsgUris = GetSelectedMessages();
if (!selectedMsgUris || (selectedMsgUris.length == 1)) {
pickMessagePane("singlemessage");
return;
}
if (! gPrefBranch.getBoolPref("mail.operate_on_msgs_in_collapsed_threads")) {
ClearMessagePane();
return;
}
let firstThreadId = messenger.msgHdrFromURI(selectedMsgUris[0]).threadId;
for (let i = 1; i < selectedMsgUris.length; ++i)
{
let msgHdr = messenger.msgHdrFromURI(selectedMsgUris[i]);
if (msgHdr.threadId != firstThreadId) // at least more than one thread
return summarizeMultipleSelection(selectedMsgUris);
}
// must be just one thread.
summarizeThread(selectedMsgUris);
},
QueryInterface : function(iid)
{
if (iid.equals(Components.interfaces.nsIMsgDBViewCommandUpdater) ||
iid.equals(Components.interfaces.nsISupports))
return this;
throw Components.results.NS_NOINTERFACE;
}
}

Просмотреть файл

@ -74,6 +74,9 @@ messenger.jar:
content/messenger/macMenuOverlay.xul (content/macMenuOverlay.xul)
#endif
* content/messenger/baseMenuOverlay.xul (content/baseMenuOverlay.xul)
content/messenger/selectionsummaries.js (content/selectionsummaries.js)
content/messenger/multimessageview.css (content/multimessageview.css)
content/messenger/multimessageview.xhtml (content/multimessageview.xhtml)
comm.jar:
% content communicator %content/communicator/ xpcnativewrappers=yes

Просмотреть файл

@ -174,7 +174,6 @@ outboxFolderName=Outbox
junkFolderName=Junk
archivesFolderName=Archives
# Error message for special folder deletion on imap accounts
# LOCALIZATION NOTE (specialFolderDeletionErr): Do not translate "IMAP" in the line below
specialFolderDeletionErr=Deletion of special folder %S is not allowed for IMAP accounts.

Просмотреть файл

@ -0,0 +1,3 @@
<!ENTITY window.title "Message Summary">
<!ENTITY selectedmessages.label "Selected Messages">
<!ENTITY archive.label "archive">

Просмотреть файл

@ -0,0 +1,19 @@
# LOCALIZATION NOTE (selectedNMessages, acrossNThreads): Semi-colon list of plural forms.
# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
# #1 number of messages
# example: Selected: 23 messages
selectedNMessages=Selected: #1 message;Selected: #1 messages
# #1 number of threads
# example: across 3 threads
acrossNThreads= across #1 thread; across #1 threads
numMsgs=#1 message;#1 messages
countUnread=, #1 unread;, #1 unread
Nmessages=(#1 message);(#1 messages)
noSubject=(no subject)
# thread and multiple message selection summaries
messagesSize=These messages take up: #1 #2.
yesterday=yesterday
noticeText= (Note: #1 messages are selected, the first #2 are shown)

Просмотреть файл

@ -1,3 +1,4 @@
#filter substitution
@AB_CD@.jar:
@ -11,6 +12,8 @@
locale/@AB_CD@/messenger/systemIntegrationDialog.dtd (%chrome/messenger/systemIntegrationDialog.dtd)
locale/@AB_CD@/messenger/virtualFolderProperties.dtd (%chrome/messenger/virtualFolderProperties.dtd)
locale/@AB_CD@/messenger/virtualFolderListDialog.dtd (%chrome/messenger/virtualFolderListDialog.dtd)
locale/@AB_CD@/messenger/multimessageview.properties (%chrome/messenger/multimessageview.properties)
locale/@AB_CD@/messenger/multimessageview.dtd (%chrome/messenger/multimessageview.dtd)
locale/@AB_CD@/messenger/mailOverlay.dtd (%chrome/messenger/mailOverlay.dtd)
locale/@AB_CD@/messenger/messenger.dtd (%chrome/messenger/messenger.dtd)
locale/@AB_CD@/messenger/baseMenuOverlay.dtd (%chrome/messenger/baseMenuOverlay.dtd)

Просмотреть файл

@ -25,6 +25,7 @@ classic.jar:
skin/classic/messenger/searchDialog.css (mail/searchDialog.css)
skin/classic/messenger/msgSelectOffline.css (mail/msgSelectOffline.css)
skin/classic/messenger/filterDialog.css (mail/filterDialog.css)
skin/classic/messenger/multimessageview.css (mail/multimessageview.css)
skin/classic/messenger/dialogs.css (mail/dialogs.css)
skin/classic/messenger/newmailalert.css (mail/newmailalert.css)
* skin/classic/messenger/tabmailBindings.xml (mail/tabmailBindings.xml)

Просмотреть файл

@ -0,0 +1,61 @@
@import url("chrome://messenger/content/multimessageview.css");
/* gnomestripe-specific overrides for multimessageview.css*/
/* mostly it's about CSS colors not being reliable */
body {
background-color: white;
}
.heading.info {
color: CaptionText;
}
.count, .date {
color: InactiveCaptionText;
}
.info,
.message > .header > .snippet,
.message > .header > .senders {
color: GrayText;
}
/* buttons are always tricky */
.button {
-moz-appearance: button;
font: message-box;
min-width: 32px !important;
margin-bottom: 2em;
}
/* and every trash is different */
#trash {
min-height: 28px !important;
min-width: 32px !important;
padding: 0px;
}
.trashButton {
padding: 2px;
list-style-image: url("moz-icon://stock/gtk-delete?size=menu");
min-height: 16px !important;
min-width: 16px !important;
width: 16px;
height: 16px;
}
.star {
width: 12px;
height: 12px;
margin-right: 0.5em;
}
.starred .star {
background-image: url("chrome://messenger/skin/icons/flag-col.png");
}

Просмотреть файл

@ -1,5 +1,6 @@
classic.jar:
% skin messenger classic/1.0 %skin/classic/messenger/
skin/classic/messenger/multimessageview.css (mail/multimessageview.css)
skin/classic/messenger/dialogs.css (mail/dialogs.css)
skin/classic/messenger/messenger.css (mail/messenger.css)
skin/classic/messenger/primaryToolbar.css (mail/primaryToolbar.css)

Просмотреть файл

@ -0,0 +1,72 @@
@import url("chrome://messenger/content/multimessageview.css");
/* pinstripe-specific overrides for multimessageview.css*/
.button {
vertical-align: middle;
margin: 0px 2px;
-moz-margin-start: 0px;
-moz-margin-end: 5px;
-moz-appearance: none;
border: 1px solid #5F5F5F;
-moz-border-radius: 4px;
background: url(chrome://global/skin/icons/white-gray-gradient.gif) #A09E9D repeat-x top center;
min-height: 0;
min-width: 0;
padding: 3px;
min-height: 16px;
}
.button:hover:active:not([disabled="true"]) {
background-image: url(chrome://global/skin/icons/white-gray-gradient-active.gif);
}
.dualButton {
-moz-appearance: dualbutton;
}
.dualButton > .button-menubutton-button {
-moz-appearance: none;
padding: 0;
margin: 0;
-moz-padding-start: 0px;
-moz-padding-end: 0px;
-moz-margin-start: 0px;
-moz-margin-end: 0px;
min-width: 1em;
min-height: 1ex;
}
.multimessage {
min-height: 15px;
margin-top: 3px;
margin-bottom: 3px;
}
.starred .star {
background-image: url("chrome://messenger/skin/icons/flaggedmail.png");
}
.info {
color: GrayText;
}
.heading.info {
color: GrayText;
}
#trash {
min-height: 22px !important;
min-width: 28px !important;
padding-left: 3px;
}
.trashButton {
padding: 2px;
list-style-image: url("chrome://messenger/skin/icons/folder-trash.png");
min-height: 16px !important;
min-width: 16px !important;
width: 16px;
height: 16px;
}

Просмотреть файл

@ -1,216 +1,217 @@
classic.jar:
+ skin/classic/global/tree.css (mail/tree.css)
+ skin/classic/global/tree/sort-asc.gif (mail/icons/sort-asc.gif)
+ skin/classic/global/tree/sort-dsc.gif (mail/icons/sort-dsc.gif)
skin/classic/communicator/smileys.css (mail/smileys.css)
% skin messenger classic/1.0 %skin/classic/messenger/
skin/classic/messenger/primaryToolbar.css (mail/primaryToolbar.css)
skin/classic/messenger/accountCentral.css (mail/accountCentral.css)
classic.jar:
+ skin/classic/global/tree.css (mail/tree.css)
+ skin/classic/global/tree/sort-asc.gif (mail/icons/sort-asc.gif)
+ skin/classic/global/tree/sort-dsc.gif (mail/icons/sort-dsc.gif)
skin/classic/communicator/smileys.css (mail/smileys.css)
% skin messenger classic/1.0 %skin/classic/messenger/
skin/classic/messenger/primaryToolbar.css (mail/primaryToolbar.css)
skin/classic/messenger/accountCentral.css (mail/accountCentral.css)
skin/classic/messenger/accountCreation.css (mail/accountCreation.css)
skin/classic/messenger/accountManage.css (mail/accountManage.css)
skin/classic/messenger/accountWizard.css (mail/accountWizard.css)
skin/classic/messenger/messageHeader.css (mail/messageHeader.css)
skin/classic/messenger/messageBody.css (mail/messageBody.css)
skin/classic/messenger/messageQuotes.css (mail/messageQuotes.css)
skin/classic/messenger/messenger.css (mail/messenger.css)
skin/classic/messenger/mailWindow1.css (mail/mailWindow1.css)
skin/classic/messenger/tagColors.css (mail/tagColors.css)
skin/classic/messenger/messageWindow.css (mail/messageWindow.css)
skin/classic/messenger/searchBox.css (mail/searchBox.css)
skin/classic/messenger/junkMail.css (mail/junkMail.css)
skin/classic/messenger/folderMenus.css (mail/folderMenus.css)
skin/classic/messenger/folderPane.css (mail/folderPane.css)
skin/classic/messenger/subscribe.css (mail/subscribe.css)
skin/classic/messenger/virtualFolderListDialog.css (mail/virtualFolderListDialog.css)
skin/classic/messenger/searchDialog.css (mail/searchDialog.css)
skin/classic/messenger/msgSelectOffline.css (mail/msgSelectOffline.css)
skin/classic/messenger/filterDialog.css (mail/filterDialog.css)
skin/classic/messenger/dialogs.css (mail/dialogs.css)
skin/classic/messenger/newmailalert.css (mail/newmailalert.css)
* skin/classic/messenger/tabmailBindings.xml (mail/tabmailBindings.xml)
skin/classic/messenger/tabmail.css (mail/tabmail.css)
skin/classic/messenger/editContactOverlay.css (mail/editContactOverlay.css)
skin/classic/messenger/starred48.png (mail/starred48.png)
skin/classic/messenger/contactStarred.png (mail/contactStarred.png)
skin/classic/messenger/starContact.png (mail/starContact.png)
skin/classic/messenger/activity/activity.css (mail/activity/activity.css)
skin/classic/messenger/activity/buttons.png (mail/activity/buttons.png)
skin/classic/messenger/activity/defaultProcessIcon.png (mail/activity/defaultProcessIcon.png)
skin/classic/messenger/activity/defaultEventIcon.png (mail/activity/defaultEventIcon.png)
skin/classic/messenger/activity/defaultWarningIcon.png (mail/activity/defaultWarningIcon.png)
skin/classic/messenger/activity/undoIcon.png (mail/activity/undoIcon.png)
skin/classic/messenger/activity/syncMailIcon.png (mail/activity/syncMailIcon.png)
skin/classic/messenger/activity/sendMailIcon.png (mail/activity/sendMailIcon.png)
skin/classic/messenger/activity/removeItemIcon.png (mail/activity/removeItemIcon.png)
skin/classic/messenger/activity/addItemIcon.png (mail/activity/addItemIcon.png)
skin/classic/messenger/activity/moveMailIcon.png (mail/activity/moveMailIcon.png)
skin/classic/messenger/activity/copyMailIcon.png (mail/activity/copyMailIcon.png)
skin/classic/messenger/activity/deleteMailIcon.png (mail/activity/deleteMailIcon.png)
skin/classic/messenger/activity/compactMailIcon.png (mail/activity/compactMailIcon.png)
skin/classic/messenger/activity/indexMailIcon.png (mail/activity/indexMailIcon.png)
skin/classic/messenger/addressbook/addressbook.css (mail/addrbook/addressbook.css)
skin/classic/messenger/addressbook/abContactsPanel.css (mail/addrbook/abContactsPanel.css)
skin/classic/messenger/addressbook/cardDialog.css (mail/addrbook/cardDialog.css)
skin/classic/messenger/addressbook/abResultsPane.css (mail/addrbook/abResultsPane.css)
skin/classic/messenger/addressbook/icons/abcard.png (mail/addrbook/abcard.png)
skin/classic/messenger/addressbook/icons/addrbook.png (mail/addrbook/addrbook.png)
skin/classic/messenger/addressbook/icons/ablist.png (mail/addrbook/ablist.png)
skin/classic/messenger/addressbook/icons/addressbook-toolbar.png (mail/addrbook/addressbook-toolbar.png)
skin/classic/messenger/addressbook/icons/addressbook-toolbar-small.png (mail/addrbook/addressbook-toolbar-small.png)
skin/classic/messenger/addressbook/icons/abcard-large.png (mail/addrbook/abcard-large.png)
skin/classic/messenger/addressbook/icons/remote-addrbook.png (mail/addrbook/remote-addrbook.png)
skin/classic/messenger/addressbook/icons/remote-addrbook-error.png (mail/addrbook/remote-addrbook-error.png)
skin/classic/messenger/addressbook/icons/secure-remote-addrbook.png (mail/addrbook/secure-remote-addrbook.png)
skin/classic/messenger/messengercompose/messengercompose.css (mail/compose/messengercompose.css)
skin/classic/messenger/messengercompose/compose-toolbar.png (mail/compose/compose-toolbar.png)
skin/classic/messenger/messengercompose/compose-toolbar-small.png (mail/compose/compose-toolbar-small.png)
skin/classic/messenger/messengercompose/format-buttons.png (mail/compose/format-buttons.png)
% skin messenger-newsblog classic/1.0 %skin/classic/messenger-newsblog/
skin/classic/messenger-newsblog/feed-subscriptions.css (mail/newsblog/feed-subscriptions.css)
skin/classic/messenger-newsblog/icons/rss-feed.png (mail/newsblog/rss-feed.png)
skin/classic/messenger-newsblog/icons/server-rss.png (mail/newsblog/server-rss.png)
skin/classic/messenger/preferences/preferences.css (mail/preferences/preferences.css)
skin/classic/messenger/preferences/general.png (mail/preferences/general.png)
skin/classic/messenger/preferences/display.png (mail/preferences/display.png)
skin/classic/messenger/preferences/composition.png (mail/preferences/composition.png)
skin/classic/messenger/preferences/security.png (mail/preferences/security.png)
skin/classic/messenger/preferences/attachments.png (mail/preferences/attachments.png)
skin/classic/messenger/preferences/advanced.png (mail/preferences/advanced.png)
skin/classic/messenger/preferences/background.png (mail/preferences/background.png)
skin/classic/messenger/preferences/hover.png (mail/preferences/hover.png)
skin/classic/messenger/preferences/selected.png (mail/preferences/selected.png)
skin/classic/messenger/smime/msgCompSMIMEOverlay.css (mail/smime/msgCompSMIMEOverlay.css)
skin/classic/messenger/smime/msgHdrViewSMIMEOverlay.css (mail/smime/msgHdrViewSMIMEOverlay.css)
skin/classic/messenger/smime/msgReadSMIMEOverlay.css (mail/smime/msgReadSMIMEOverlay.css)
skin/classic/messenger/smime/msgReadSecurityInfo.css (mail/smime/msgReadSecurityInfo.css)
skin/classic/messenger/smime/msgCompSecurityInfo.css (mail/smime/msgCompSecurityInfo.css)
skin/classic/messenger/smime/certFetchingStatus.css (mail/smime/certFetchingStatus.css)
skin/classic/messenger/smime/icons/hdrCryptoNotOk.png (mail/smime/hdrCryptoNotOk.png)
skin/classic/messenger/smime/icons/hdrCryptoOk.png (mail/smime/hdrCryptoOk.png)
skin/classic/messenger/smime/icons/hdrSignNotOk.png (mail/smime/hdrSignNotOk.png)
skin/classic/messenger/smime/icons/hdrSignOk.png (mail/smime/hdrSignOk.png)
skin/classic/messenger/smime/icons/hdrSignUnknown.png (mail/smime/hdrSignUnknown.png)
skin/classic/messenger/smime/icons/sbCryptoNotOk.png (mail/smime/sbCryptoNotOk.png)
skin/classic/messenger/smime/icons/sbCryptoOk.png (mail/smime/sbCryptoOk.png)
skin/classic/messenger/smime/icons/sbSignNotOk.png (mail/smime/sbSignNotOk.png)
skin/classic/messenger/smime/icons/sbSignOk.png (mail/smime/sbSignOk.png)
skin/classic/messenger/smime/icons/sbSignUnknown.png (mail/smime/sbSignUnknown.png)
skin/classic/messenger/icons/new-mail-alert.png (mail/icons/new-mail-alert.png)
skin/classic/messenger/icons/readmail.png (mail/icons/readmail.png)
skin/classic/messenger/icons/mail-toolbar.png (mail/icons/mail-toolbar.png)
skin/classic/messenger/icons/mail-toolbar-small.png (mail/icons/mail-toolbar-small.png)
skin/classic/messenger/icons/folder.png (mail/icons/folder.png)
skin/classic/messenger/icons/message.png (mail/icons/message.png)
skin/classic/messenger/icons/attachment-deleted.png (mail/icons/attachment-deleted.png)
skin/classic/messenger/icons/attachment-deleted-large.png (mail/icons/attachment-deleted-large.png)
skin/classic/messenger/icons/attachment-col.png (mail/icons/attachment-col.png)
skin/classic/messenger/icons/attachment.png (mail/icons/attachment.png)
skin/classic/messenger/icons/junk-col.png (mail/icons/junk-col.png)
skin/classic/messenger/icons/thread-col.png (mail/icons/thread-col.png)
skin/classic/messenger/icons/thread-col-sorta.png (mail/icons/thread-col-sorta.png)
skin/classic/messenger/icons/thread-col-sortd.png (mail/icons/thread-col-sortd.png)
skin/classic/messenger/icons/thread.png (mail/icons/thread.png)
skin/classic/messenger/icons/thread-ignored.png (mail/icons/thread-ignored.png)
skin/classic/messenger/icons/message-ignored.png (mail/icons/message-ignored.png)
skin/classic/messenger/icons/thread-watched.png (mail/icons/thread-watched.png)
skin/classic/messenger/icons/flag-col.png (mail/icons/flag-col.png)
skin/classic/messenger/icons/flag.png (mail/icons/flag.png)
skin/classic/messenger/icons/flag-empty.png (mail/icons/flag-empty.png)
skin/classic/messenger/icons/server.png (mail/icons/server.png)
skin/classic/messenger/icons/readcol.png (mail/icons/readcol.png)
skin/classic/messenger/icons/unreadmail.png (mail/icons/unreadmail.png)
skin/classic/messenger/icons/Search-bar.png (mail/icons/Search-bar.png)
skin/classic/messenger/icons/search-arrow.gif (mail/icons/search-arrow.gif)
skin/classic/messenger/icons/quick-search-clear.png (mail/icons/quick-search-clear.png)
skin/classic/messenger/icons/close-button.png (mail/icons/close-button.png)
skin/classic/messenger/icons/remote-blocked.png (mail/icons/remote-blocked.png)
skin/classic/messenger/icons/phishing.png (mail/icons/phishing.png)
skin/classic/messenger/icons/junk.png (mail/icons/junk.png)
skin/classic/messenger/icons/check.gif (mail/icons/check.gif)
skin/classic/messenger/icons/notchecked.gif (mail/icons/notchecked.gif)
skin/classic/messenger/icons/online.png (mail/icons/online.png)
skin/classic/messenger/icons/offline.png (mail/icons/offline.png)
skin/classic/messenger/icons/row.png (mail/icons/row.png)
skin/classic/messenger/accountManage.css (mail/accountManage.css)
skin/classic/messenger/accountWizard.css (mail/accountWizard.css)
skin/classic/messenger/messageHeader.css (mail/messageHeader.css)
skin/classic/messenger/messageBody.css (mail/messageBody.css)
skin/classic/messenger/messageQuotes.css (mail/messageQuotes.css)
skin/classic/messenger/messenger.css (mail/messenger.css)
skin/classic/messenger/mailWindow1.css (mail/mailWindow1.css)
skin/classic/messenger/tagColors.css (mail/tagColors.css)
skin/classic/messenger/messageWindow.css (mail/messageWindow.css)
skin/classic/messenger/searchBox.css (mail/searchBox.css)
skin/classic/messenger/junkMail.css (mail/junkMail.css)
skin/classic/messenger/folderMenus.css (mail/folderMenus.css)
skin/classic/messenger/folderPane.css (mail/folderPane.css)
skin/classic/messenger/subscribe.css (mail/subscribe.css)
skin/classic/messenger/virtualFolderListDialog.css (mail/virtualFolderListDialog.css)
skin/classic/messenger/searchDialog.css (mail/searchDialog.css)
skin/classic/messenger/msgSelectOffline.css (mail/msgSelectOffline.css)
skin/classic/messenger/filterDialog.css (mail/filterDialog.css)
skin/classic/messenger/dialogs.css (mail/dialogs.css)
skin/classic/messenger/multimessageview.css (mail/multimessageview.css)
skin/classic/messenger/newmailalert.css (mail/newmailalert.css)
* skin/classic/messenger/tabmailBindings.xml (mail/tabmailBindings.xml)
skin/classic/messenger/tabmail.css (mail/tabmail.css)
skin/classic/messenger/editContactOverlay.css (mail/editContactOverlay.css)
skin/classic/messenger/starred48.png (mail/starred48.png)
skin/classic/messenger/contactStarred.png (mail/contactStarred.png)
skin/classic/messenger/starContact.png (mail/starContact.png)
skin/classic/messenger/activity/activity.css (mail/activity/activity.css)
skin/classic/messenger/activity/buttons.png (mail/activity/buttons.png)
skin/classic/messenger/activity/defaultProcessIcon.png (mail/activity/defaultProcessIcon.png)
skin/classic/messenger/activity/defaultEventIcon.png (mail/activity/defaultEventIcon.png)
skin/classic/messenger/activity/defaultWarningIcon.png (mail/activity/defaultWarningIcon.png)
skin/classic/messenger/activity/undoIcon.png (mail/activity/undoIcon.png)
skin/classic/messenger/activity/syncMailIcon.png (mail/activity/syncMailIcon.png)
skin/classic/messenger/activity/sendMailIcon.png (mail/activity/sendMailIcon.png)
skin/classic/messenger/activity/removeItemIcon.png (mail/activity/removeItemIcon.png)
skin/classic/messenger/activity/addItemIcon.png (mail/activity/addItemIcon.png)
skin/classic/messenger/activity/moveMailIcon.png (mail/activity/moveMailIcon.png)
skin/classic/messenger/activity/copyMailIcon.png (mail/activity/copyMailIcon.png)
skin/classic/messenger/activity/deleteMailIcon.png (mail/activity/deleteMailIcon.png)
skin/classic/messenger/activity/compactMailIcon.png (mail/activity/compactMailIcon.png)
skin/classic/messenger/activity/indexMailIcon.png (mail/activity/indexMailIcon.png)
skin/classic/messenger/addressbook/addressbook.css (mail/addrbook/addressbook.css)
skin/classic/messenger/addressbook/abContactsPanel.css (mail/addrbook/abContactsPanel.css)
skin/classic/messenger/addressbook/cardDialog.css (mail/addrbook/cardDialog.css)
skin/classic/messenger/addressbook/abResultsPane.css (mail/addrbook/abResultsPane.css)
skin/classic/messenger/addressbook/icons/abcard.png (mail/addrbook/abcard.png)
skin/classic/messenger/addressbook/icons/addrbook.png (mail/addrbook/addrbook.png)
skin/classic/messenger/addressbook/icons/ablist.png (mail/addrbook/ablist.png)
skin/classic/messenger/addressbook/icons/addressbook-toolbar.png (mail/addrbook/addressbook-toolbar.png)
skin/classic/messenger/addressbook/icons/addressbook-toolbar-small.png (mail/addrbook/addressbook-toolbar-small.png)
skin/classic/messenger/addressbook/icons/abcard-large.png (mail/addrbook/abcard-large.png)
skin/classic/messenger/addressbook/icons/remote-addrbook.png (mail/addrbook/remote-addrbook.png)
skin/classic/messenger/addressbook/icons/remote-addrbook-error.png (mail/addrbook/remote-addrbook-error.png)
skin/classic/messenger/addressbook/icons/secure-remote-addrbook.png (mail/addrbook/secure-remote-addrbook.png)
skin/classic/messenger/messengercompose/messengercompose.css (mail/compose/messengercompose.css)
skin/classic/messenger/messengercompose/compose-toolbar.png (mail/compose/compose-toolbar.png)
skin/classic/messenger/messengercompose/compose-toolbar-small.png (mail/compose/compose-toolbar-small.png)
skin/classic/messenger/messengercompose/format-buttons.png (mail/compose/format-buttons.png)
% skin messenger-newsblog classic/1.0 %skin/classic/messenger-newsblog/
skin/classic/messenger-newsblog/feed-subscriptions.css (mail/newsblog/feed-subscriptions.css)
skin/classic/messenger-newsblog/icons/rss-feed.png (mail/newsblog/rss-feed.png)
skin/classic/messenger-newsblog/icons/server-rss.png (mail/newsblog/server-rss.png)
skin/classic/messenger/preferences/preferences.css (mail/preferences/preferences.css)
skin/classic/messenger/preferences/general.png (mail/preferences/general.png)
skin/classic/messenger/preferences/display.png (mail/preferences/display.png)
skin/classic/messenger/preferences/composition.png (mail/preferences/composition.png)
skin/classic/messenger/preferences/security.png (mail/preferences/security.png)
skin/classic/messenger/preferences/attachments.png (mail/preferences/attachments.png)
skin/classic/messenger/preferences/advanced.png (mail/preferences/advanced.png)
skin/classic/messenger/preferences/background.png (mail/preferences/background.png)
skin/classic/messenger/preferences/hover.png (mail/preferences/hover.png)
skin/classic/messenger/preferences/selected.png (mail/preferences/selected.png)
skin/classic/messenger/smime/msgCompSMIMEOverlay.css (mail/smime/msgCompSMIMEOverlay.css)
skin/classic/messenger/smime/msgHdrViewSMIMEOverlay.css (mail/smime/msgHdrViewSMIMEOverlay.css)
skin/classic/messenger/smime/msgReadSMIMEOverlay.css (mail/smime/msgReadSMIMEOverlay.css)
skin/classic/messenger/smime/msgReadSecurityInfo.css (mail/smime/msgReadSecurityInfo.css)
skin/classic/messenger/smime/msgCompSecurityInfo.css (mail/smime/msgCompSecurityInfo.css)
skin/classic/messenger/smime/certFetchingStatus.css (mail/smime/certFetchingStatus.css)
skin/classic/messenger/smime/icons/hdrCryptoNotOk.png (mail/smime/hdrCryptoNotOk.png)
skin/classic/messenger/smime/icons/hdrCryptoOk.png (mail/smime/hdrCryptoOk.png)
skin/classic/messenger/smime/icons/hdrSignNotOk.png (mail/smime/hdrSignNotOk.png)
skin/classic/messenger/smime/icons/hdrSignOk.png (mail/smime/hdrSignOk.png)
skin/classic/messenger/smime/icons/hdrSignUnknown.png (mail/smime/hdrSignUnknown.png)
skin/classic/messenger/smime/icons/sbCryptoNotOk.png (mail/smime/sbCryptoNotOk.png)
skin/classic/messenger/smime/icons/sbCryptoOk.png (mail/smime/sbCryptoOk.png)
skin/classic/messenger/smime/icons/sbSignNotOk.png (mail/smime/sbSignNotOk.png)
skin/classic/messenger/smime/icons/sbSignOk.png (mail/smime/sbSignOk.png)
skin/classic/messenger/smime/icons/sbSignUnknown.png (mail/smime/sbSignUnknown.png)
skin/classic/messenger/icons/new-mail-alert.png (mail/icons/new-mail-alert.png)
skin/classic/messenger/icons/readmail.png (mail/icons/readmail.png)
skin/classic/messenger/icons/mail-toolbar.png (mail/icons/mail-toolbar.png)
skin/classic/messenger/icons/mail-toolbar-small.png (mail/icons/mail-toolbar-small.png)
skin/classic/messenger/icons/folder.png (mail/icons/folder.png)
skin/classic/messenger/icons/message.png (mail/icons/message.png)
skin/classic/messenger/icons/attachment-deleted.png (mail/icons/attachment-deleted.png)
skin/classic/messenger/icons/attachment-deleted-large.png (mail/icons/attachment-deleted-large.png)
skin/classic/messenger/icons/attachment-col.png (mail/icons/attachment-col.png)
skin/classic/messenger/icons/attachment.png (mail/icons/attachment.png)
skin/classic/messenger/icons/junk-col.png (mail/icons/junk-col.png)
skin/classic/messenger/icons/thread-col.png (mail/icons/thread-col.png)
skin/classic/messenger/icons/thread-col-sorta.png (mail/icons/thread-col-sorta.png)
skin/classic/messenger/icons/thread-col-sortd.png (mail/icons/thread-col-sortd.png)
skin/classic/messenger/icons/thread.png (mail/icons/thread.png)
skin/classic/messenger/icons/thread-ignored.png (mail/icons/thread-ignored.png)
skin/classic/messenger/icons/message-ignored.png (mail/icons/message-ignored.png)
skin/classic/messenger/icons/thread-watched.png (mail/icons/thread-watched.png)
skin/classic/messenger/icons/flag-col.png (mail/icons/flag-col.png)
skin/classic/messenger/icons/flag.png (mail/icons/flag.png)
skin/classic/messenger/icons/flag-empty.png (mail/icons/flag-empty.png)
skin/classic/messenger/icons/server.png (mail/icons/server.png)
skin/classic/messenger/icons/readcol.png (mail/icons/readcol.png)
skin/classic/messenger/icons/unreadmail.png (mail/icons/unreadmail.png)
skin/classic/messenger/icons/Search-bar.png (mail/icons/Search-bar.png)
skin/classic/messenger/icons/search-arrow.gif (mail/icons/search-arrow.gif)
skin/classic/messenger/icons/quick-search-clear.png (mail/icons/quick-search-clear.png)
skin/classic/messenger/icons/close-button.png (mail/icons/close-button.png)
skin/classic/messenger/icons/remote-blocked.png (mail/icons/remote-blocked.png)
skin/classic/messenger/icons/phishing.png (mail/icons/phishing.png)
skin/classic/messenger/icons/junk.png (mail/icons/junk.png)
skin/classic/messenger/icons/check.gif (mail/icons/check.gif)
skin/classic/messenger/icons/notchecked.gif (mail/icons/notchecked.gif)
skin/classic/messenger/icons/online.png (mail/icons/online.png)
skin/classic/messenger/icons/offline.png (mail/icons/offline.png)
skin/classic/messenger/icons/row.png (mail/icons/row.png)
skin/classic/messenger/icons/secure.png (mail/icons/secure.png)
skin/classic/messenger/icons/insecure.png (mail/icons/insecure.png)
skin/classic/messenger/icons/identity.png (mail/icons/identity.png)
skin/classic/messenger/icons/tick.png (mail/icons/tick.png)
skin/classic/messenger/icons/error.png (mail/icons/error.png)
skin/classic/messenger/icons/cancel.png (mail/icons/cancel.png)
skin/classic/messenger/icons/alltabs-box-overflow-end-bkgnd.png (mail/icons/alltabs-box-overflow-end-bkgnd.png)
skin/classic/messenger/icons/alltabs-box-overflow-end-bkgnd-animate.png (mail/icons/alltabs-box-overflow-end-bkgnd-animate.png)
skin/classic/messenger/icons/alltabs-box-overflow-end-bkgnd-hover.png (mail/icons/alltabs-box-overflow-end-bkgnd-hover.png)
skin/classic/messenger/icons/alltabs-box-overflow-start-bkgnd.png (mail/icons/alltabs-box-overflow-start-bkgnd.png)
skin/classic/messenger/icons/alltabs-box-overflow-start-bkgnd-animate.png (mail/icons/alltabs-box-overflow-start-bkgnd-animate.png)
skin/classic/messenger/icons/alltabs-box-overflow-start-bkgnd-hover.png (mail/icons/alltabs-box-overflow-start-bkgnd-hover.png)
skin/classic/messenger/icons/tab-arrow-end.png (mail/icons/tab-arrow-end.png)
skin/classic/messenger/icons/tab-arrow-end-bkgnd-animate.png (mail/icons/tab-arrow-end-bkgnd-animate.png)
skin/classic/messenger/icons/tab-arrow-end-bkgnd-disabled.png (mail/icons/tab-arrow-end-bkgnd-disabled.png)
skin/classic/messenger/icons/tab-arrow-end-bkgnd-enabled.png (mail/icons/tab-arrow-end-bkgnd-enabled.png)
skin/classic/messenger/icons/tab-arrow-end-bkgnd-hover.png (mail/icons/tab-arrow-end-bkgnd-hover.png)
skin/classic/messenger/icons/tab-arrow-start.png (mail/icons/tab-arrow-start.png)
skin/classic/messenger/icons/tab-arrow-start-bkgnd-animate.png (mail/icons/tab-arrow-start-bkgnd-animate.png)
skin/classic/messenger/icons/tab-arrow-start-bkgnd-disabled.png (mail/icons/tab-arrow-start-bkgnd-disabled.png)
skin/classic/messenger/icons/tab-arrow-start-bkgnd-enabled.png (mail/icons/tab-arrow-start-bkgnd-enabled.png)
skin/classic/messenger/icons/tab-arrow-start-bkgnd-hover.png (mail/icons/tab-arrow-start-bkgnd-hover.png)
skin/classic/messenger/icons/tabmail-tabs-bkgnd.png (mail/icons/tabmail-tabs-bkgnd.png)
skin/classic/messenger/icons/tabDragIndicator.png (mail/icons/tabDragIndicator.png)
skin/classic/messenger/icons/tab-left.png (mail/icons/tab-left.png)
skin/classic/messenger/icons/tab-left-bkgnd.png (mail/icons/tab-left-bkgnd.png)
skin/classic/messenger/icons/tab-middle.png (mail/icons/tab-middle.png)
skin/classic/messenger/icons/tab-middle-bkgnd.png (mail/icons/tab-middle-bkgnd.png)
skin/classic/messenger/icons/tab-right.png (mail/icons/tab-right.png)
skin/classic/messenger/icons/tab-right-bkgnd.png (mail/icons/tab-right-bkgnd.png)
skin/classic/messenger/icons/tabstrip-bottom.png (mail/icons/tabstrip-bottom.png)
% skin communicator classic/1.0 %skin/classic/communicator/
skin/classic/communicator/communicator.css (mail/communicator.css)
skin/classic/communicator/icons/smileys/smiley-smile.png (mail/icons/smiley-smile.png)
skin/classic/communicator/icons/smileys/smiley-frown.png (mail/icons/smiley-frown.png)
skin/classic/communicator/icons/smileys/smiley-wink.png (mail/icons/smiley-wink.png)
skin/classic/communicator/icons/smileys/smiley-tongue-out.png (mail/icons/smiley-tongue-out.png)
skin/classic/communicator/icons/smileys/smiley-laughing.png (mail/icons/smiley-laughing.png)
skin/classic/communicator/icons/smileys/smiley-embarassed.png (mail/icons/smiley-embarassed.png)
skin/classic/communicator/icons/smileys/smiley-undecided.png (mail/icons/smiley-undecided.png)
skin/classic/communicator/icons/smileys/smiley-surprised.png (mail/icons/smiley-surprised.png)
skin/classic/communicator/icons/smileys/smiley-kiss.png (mail/icons/smiley-kiss.png)
skin/classic/communicator/icons/smileys/smiley-yell.png (mail/icons/smiley-yell.png)
skin/classic/communicator/icons/smileys/smiley-cool.png (mail/icons/smiley-cool.png)
skin/classic/communicator/icons/smileys/smiley-money-mouth.png (mail/icons/smiley-money-mouth.png)
skin/classic/communicator/icons/smileys/smiley-foot-in-mouth.png (mail/icons/smiley-foot-in-mouth.png)
skin/classic/communicator/icons/smileys/smiley-innocent.png (mail/icons/smiley-innocent.png)
skin/classic/communicator/icons/smileys/smiley-cry.png (mail/icons/smiley-cry.png)
skin/classic/communicator/icons/smileys/smiley-sealed.png (mail/icons/smiley-sealed.png)
skin/classic/messenger/accountcentral/read-messages.png (mail/accountcentral/read-messages.png)
skin/classic/messenger/accountcentral/write-message.png (mail/accountcentral/write-message.png)
skin/classic/messenger/accountcentral/create-account.png (mail/accountcentral/create-account.png)
skin/classic/messenger/accountcentral/account-settings.png (mail/accountcentral/account-settings.png)
skin/classic/messenger/accountcentral/search-messages.png (mail/accountcentral/search-messages.png)
skin/classic/messenger/accountcentral/manage-filters.png (mail/accountcentral/manage-filters.png)
skin/classic/messenger/accountcentral/offline-settings.png (mail/accountcentral/offline-settings.png)
skin/classic/messenger/accountcentral/manage-imap.png (mail/accountcentral/manage-imap.png)
skin/classic/messenger/accountcentral/manage-newsgroups.png (mail/accountcentral/manage-newsgroups.png)
skin/classic/messenger/accountcentral/manage-rss.png (mail/accountcentral/manage-rss.png)
skin/classic/messenger/icons/arrow-dn-grey.png (mail/icons/arrow-dn-grey.png)
skin/classic/messenger/icons/arrow-dn-black.png (mail/icons/arrow-dn-black.png)
skin/classic/messenger/icons/arrow-dn-blue.png (mail/icons/arrow-dn-blue.png)
skin/classic/messenger/icons/arrow/arrow-left.png (mail/icons/arrow/arrow-left.png)
skin/classic/messenger/icons/arrow/arrow-right.png (mail/icons/arrow/arrow-right.png)
skin/classic/messenger/icons/arrow/arrow-up.png (mail/icons/arrow/arrow-up.png)
skin/classic/messenger/icons/arrow/arrow-down.png (mail/icons/arrow/arrow-down.png)
skin/classic/messenger/icons/arrow/arrow-left-dim.png (mail/icons/arrow/arrow-left-dim.png)
skin/classic/messenger/icons/arrow/arrow-right-dim.png (mail/icons/arrow/arrow-right-dim.png)
skin/classic/messenger/icons/arrow/arrow-up-dim.png (mail/icons/arrow/arrow-up-dim.png)
skin/classic/messenger/icons/arrow/arrow-down-dim.png (mail/icons/arrow/arrow-down-dim.png)
skin/classic/messenger/icons/chevron.png (mail/icons/chevron.png)
skin/classic/messenger/icons/croppedchevron.png (mail/icons/croppedchevron.png)
skin/classic/messenger/tagbg.png (mail/tagbg.png)
icon.png (mail/icon.png)
preview.png (mail/preview.png)
% skin editor classic/1.0 %skin/classic/editor/
skin/classic/editor/editor.css (editor/editor.css)
skin/classic/editor/EditorDialog.css (editor/EditorDialog.css)
skin/classic/editor/icons/img-align-bottom.gif (editor/img-align-bottom.gif)
skin/classic/editor/icons/img-align-left.gif (editor/img-align-left.gif)
skin/classic/editor/icons/img-align-middle.gif (editor/img-align-middle.gif)
skin/classic/editor/icons/img-align-right.gif (editor/img-align-right.gif)
skin/classic/editor/icons/img-align-top.gif (editor/img-align-top.gif)
skin/classic/messenger/icons/alltabs-box-overflow-end-bkgnd.png (mail/icons/alltabs-box-overflow-end-bkgnd.png)
skin/classic/messenger/icons/alltabs-box-overflow-end-bkgnd-animate.png (mail/icons/alltabs-box-overflow-end-bkgnd-animate.png)
skin/classic/messenger/icons/alltabs-box-overflow-end-bkgnd-hover.png (mail/icons/alltabs-box-overflow-end-bkgnd-hover.png)
skin/classic/messenger/icons/alltabs-box-overflow-start-bkgnd.png (mail/icons/alltabs-box-overflow-start-bkgnd.png)
skin/classic/messenger/icons/alltabs-box-overflow-start-bkgnd-animate.png (mail/icons/alltabs-box-overflow-start-bkgnd-animate.png)
skin/classic/messenger/icons/alltabs-box-overflow-start-bkgnd-hover.png (mail/icons/alltabs-box-overflow-start-bkgnd-hover.png)
skin/classic/messenger/icons/tab-arrow-end.png (mail/icons/tab-arrow-end.png)
skin/classic/messenger/icons/tab-arrow-end-bkgnd-animate.png (mail/icons/tab-arrow-end-bkgnd-animate.png)
skin/classic/messenger/icons/tab-arrow-end-bkgnd-disabled.png (mail/icons/tab-arrow-end-bkgnd-disabled.png)
skin/classic/messenger/icons/tab-arrow-end-bkgnd-enabled.png (mail/icons/tab-arrow-end-bkgnd-enabled.png)
skin/classic/messenger/icons/tab-arrow-end-bkgnd-hover.png (mail/icons/tab-arrow-end-bkgnd-hover.png)
skin/classic/messenger/icons/tab-arrow-start.png (mail/icons/tab-arrow-start.png)
skin/classic/messenger/icons/tab-arrow-start-bkgnd-animate.png (mail/icons/tab-arrow-start-bkgnd-animate.png)
skin/classic/messenger/icons/tab-arrow-start-bkgnd-disabled.png (mail/icons/tab-arrow-start-bkgnd-disabled.png)
skin/classic/messenger/icons/tab-arrow-start-bkgnd-enabled.png (mail/icons/tab-arrow-start-bkgnd-enabled.png)
skin/classic/messenger/icons/tab-arrow-start-bkgnd-hover.png (mail/icons/tab-arrow-start-bkgnd-hover.png)
skin/classic/messenger/icons/tabmail-tabs-bkgnd.png (mail/icons/tabmail-tabs-bkgnd.png)
skin/classic/messenger/icons/tabDragIndicator.png (mail/icons/tabDragIndicator.png)
skin/classic/messenger/icons/tab-left.png (mail/icons/tab-left.png)
skin/classic/messenger/icons/tab-left-bkgnd.png (mail/icons/tab-left-bkgnd.png)
skin/classic/messenger/icons/tab-middle.png (mail/icons/tab-middle.png)
skin/classic/messenger/icons/tab-middle-bkgnd.png (mail/icons/tab-middle-bkgnd.png)
skin/classic/messenger/icons/tab-right.png (mail/icons/tab-right.png)
skin/classic/messenger/icons/tab-right-bkgnd.png (mail/icons/tab-right-bkgnd.png)
skin/classic/messenger/icons/tabstrip-bottom.png (mail/icons/tabstrip-bottom.png)
% skin communicator classic/1.0 %skin/classic/communicator/
skin/classic/communicator/communicator.css (mail/communicator.css)
skin/classic/communicator/icons/smileys/smiley-smile.png (mail/icons/smiley-smile.png)
skin/classic/communicator/icons/smileys/smiley-frown.png (mail/icons/smiley-frown.png)
skin/classic/communicator/icons/smileys/smiley-wink.png (mail/icons/smiley-wink.png)
skin/classic/communicator/icons/smileys/smiley-tongue-out.png (mail/icons/smiley-tongue-out.png)
skin/classic/communicator/icons/smileys/smiley-laughing.png (mail/icons/smiley-laughing.png)
skin/classic/communicator/icons/smileys/smiley-embarassed.png (mail/icons/smiley-embarassed.png)
skin/classic/communicator/icons/smileys/smiley-undecided.png (mail/icons/smiley-undecided.png)
skin/classic/communicator/icons/smileys/smiley-surprised.png (mail/icons/smiley-surprised.png)
skin/classic/communicator/icons/smileys/smiley-kiss.png (mail/icons/smiley-kiss.png)
skin/classic/communicator/icons/smileys/smiley-yell.png (mail/icons/smiley-yell.png)
skin/classic/communicator/icons/smileys/smiley-cool.png (mail/icons/smiley-cool.png)
skin/classic/communicator/icons/smileys/smiley-money-mouth.png (mail/icons/smiley-money-mouth.png)
skin/classic/communicator/icons/smileys/smiley-foot-in-mouth.png (mail/icons/smiley-foot-in-mouth.png)
skin/classic/communicator/icons/smileys/smiley-innocent.png (mail/icons/smiley-innocent.png)
skin/classic/communicator/icons/smileys/smiley-cry.png (mail/icons/smiley-cry.png)
skin/classic/communicator/icons/smileys/smiley-sealed.png (mail/icons/smiley-sealed.png)
skin/classic/messenger/accountcentral/read-messages.png (mail/accountcentral/read-messages.png)
skin/classic/messenger/accountcentral/write-message.png (mail/accountcentral/write-message.png)
skin/classic/messenger/accountcentral/create-account.png (mail/accountcentral/create-account.png)
skin/classic/messenger/accountcentral/account-settings.png (mail/accountcentral/account-settings.png)
skin/classic/messenger/accountcentral/search-messages.png (mail/accountcentral/search-messages.png)
skin/classic/messenger/accountcentral/manage-filters.png (mail/accountcentral/manage-filters.png)
skin/classic/messenger/accountcentral/offline-settings.png (mail/accountcentral/offline-settings.png)
skin/classic/messenger/accountcentral/manage-imap.png (mail/accountcentral/manage-imap.png)
skin/classic/messenger/accountcentral/manage-newsgroups.png (mail/accountcentral/manage-newsgroups.png)
skin/classic/messenger/accountcentral/manage-rss.png (mail/accountcentral/manage-rss.png)
skin/classic/messenger/icons/arrow-dn-grey.png (mail/icons/arrow-dn-grey.png)
skin/classic/messenger/icons/arrow-dn-black.png (mail/icons/arrow-dn-black.png)
skin/classic/messenger/icons/arrow-dn-blue.png (mail/icons/arrow-dn-blue.png)
skin/classic/messenger/icons/arrow/arrow-left.png (mail/icons/arrow/arrow-left.png)
skin/classic/messenger/icons/arrow/arrow-right.png (mail/icons/arrow/arrow-right.png)
skin/classic/messenger/icons/arrow/arrow-up.png (mail/icons/arrow/arrow-up.png)
skin/classic/messenger/icons/arrow/arrow-down.png (mail/icons/arrow/arrow-down.png)
skin/classic/messenger/icons/arrow/arrow-left-dim.png (mail/icons/arrow/arrow-left-dim.png)
skin/classic/messenger/icons/arrow/arrow-right-dim.png (mail/icons/arrow/arrow-right-dim.png)
skin/classic/messenger/icons/arrow/arrow-up-dim.png (mail/icons/arrow/arrow-up-dim.png)
skin/classic/messenger/icons/arrow/arrow-down-dim.png (mail/icons/arrow/arrow-down-dim.png)
skin/classic/messenger/icons/chevron.png (mail/icons/chevron.png)
skin/classic/messenger/icons/croppedchevron.png (mail/icons/croppedchevron.png)
skin/classic/messenger/tagbg.png (mail/tagbg.png)
icon.png (mail/icon.png)
preview.png (mail/preview.png)
% skin editor classic/1.0 %skin/classic/editor/
skin/classic/editor/editor.css (editor/editor.css)
skin/classic/editor/EditorDialog.css (editor/EditorDialog.css)
skin/classic/editor/icons/img-align-bottom.gif (editor/img-align-bottom.gif)
skin/classic/editor/icons/img-align-left.gif (editor/img-align-left.gif)
skin/classic/editor/icons/img-align-middle.gif (editor/img-align-middle.gif)
skin/classic/editor/icons/img-align-right.gif (editor/img-align-right.gif)
skin/classic/editor/icons/img-align-top.gif (editor/img-align-top.gif)

Просмотреть файл

@ -0,0 +1,55 @@
@import url("chrome://messenger/content/multimessageview.css");
/* qute-specific overrides for multimessageview.css*/
/* mostly it's about CSS colors not being reliable */
body {
background-color: white;
}
.heading.info {
color: ButtonText;
}
.info,
.count, .date,
.message > .header > .snippet,
.message > .header > .senders {
color: GrayText;
}
/* buttons aren't reliable either */
.button {
-moz-appearance: button;
font: message-box;
min-width: 32px !important;
}
/* and trash icon URLs aren't either */
#trash {
min-height: 28px !important;
min-width: 32px !important;
padding: 0px;
}
.trashButton {
list-style-image: url("chrome://messenger/skin/icons/folder.png") !important;
-moz-image-region: rect(0px 144px 16px 128px);
width: 16px;
height: 16px;
}
.star {
width: 12px;
height: 12px;
margin-right: 0.5em;
}
.starred .star {
background-image: url("chrome://messenger/skin/icons/flag-col.png");
}

Просмотреть файл

@ -419,7 +419,7 @@ interface nsIMsgDBView : nsISupports
FE updater interface to handle changes in the view
*/
[scriptable, uuid(65FC9AD5-0912-11d5-9901-001083010E9B)]
[scriptable, uuid(ce8f52ee-e742-4b31-8bdd-2b3a8168a117)]
interface nsIMsgDBViewCommandUpdater : nsISupports
{
/* Eventually we'll flush this out into some kind of rich interface
@ -439,4 +439,10 @@ interface nsIMsgDBViewCommandUpdater : nsISupports
* which message we should selet after a delete or move
*/
void updateNextMessageAfterDelete();
/**
* tell the front end that the selection has changed, and may need to be
* resummarized
*/
void summarizeSelection();
};

Просмотреть файл

@ -53,7 +53,7 @@ interface nsIMsgWindowCommands : nsISupports {
void clearMsgPane();
};
[scriptable, uuid(7e8fbaaa-d2f1-4751-af8e-8213fdb60a02)]
[scriptable, uuid(7e8fbaaa-d2f1-4751-af8e-8213fdb60a03)]
interface nsIMsgWindow : nsISupports {
attribute nsIMsgStatusFeedback statusFeedback;
attribute nsIMsgWindowCommands windowCommands;

Просмотреть файл

@ -1071,17 +1071,13 @@ NS_IMETHODIMP nsMsgDBView::SelectionChanged()
m_currentlyDisplayedMsgKey = nsMsgKey_None;
m_currentlyDisplayedMsgUri.Truncate();
m_currentlyDisplayedViewIndex = nsMsgViewIndex_None;
// if we used to have one item selected, and now we have zero or more than one, we should clear the message pane.
nsCOMPtr<nsIMsgWindow> msgWindow(do_QueryReferent(mMsgWindowWeak));
nsCOMPtr <nsIMsgWindowCommands> windowCommands;
if ((mNumSelectedRows == 1) && (numSelected != 1) && msgWindow
&& NS_SUCCEEDED(msgWindow->GetWindowCommands(getter_AddRefs(windowCommands)))
&& windowCommands) {
windowCommands->ClearMsgPane();
}
}
// let the front-end adjust the message pane appropriately with either
// the message body, or a summary of the selection
if (mCommandUpdater)
mCommandUpdater->SummarizeSelection();
// determine if we need to push command update notifications out to the UI or not.
// we need to push a command update notification iff, one of the following conditions are met
@ -2191,6 +2187,7 @@ NS_IMETHODIMP nsMsgDBView::GetURIsForSelection(PRUint32 *length, char ***uris)
NS_ENSURE_ARG_POINTER(length);
*length = 0;
NS_ENSURE_ARG_POINTER(uris);
*uris = nsnull;
@ -4487,6 +4484,7 @@ nsresult nsMsgDBView::ExpansionDelta(nsMsgViewIndex index, PRInt32 *expansionDel
nsresult nsMsgDBView::ToggleExpansion(nsMsgViewIndex index, PRUint32 *numChanged)
{
nsresult rv;
NS_ENSURE_ARG(numChanged);
*numChanged = 0;
nsMsgViewIndex threadIndex = GetThreadIndex(index);
@ -4502,10 +4500,13 @@ nsresult nsMsgDBView::ToggleExpansion(nsMsgViewIndex index, PRUint32 *numChanged
if (!(flags & MSG_VIEW_FLAG_ISTHREAD) || !(flags & MSG_VIEW_FLAG_HASCHILDREN))
return NS_MSG_MESSAGE_NOT_FOUND;
if (flags & nsMsgMessageFlags::Elided)
return ExpandByIndex(threadIndex, numChanged);
rv = ExpandByIndex(threadIndex, numChanged);
else
return CollapseByIndex(threadIndex, numChanged);
rv = CollapseByIndex(threadIndex, numChanged);
// if we collaps/uncollapse a thread, this changes the selected URIs
SelectionChanged();
return rv;
}
nsresult nsMsgDBView::ExpandAndSelectThread()

Просмотреть файл

@ -184,6 +184,8 @@ nsMsgDBViewCommandUpdater.prototype =
SetNextMessageAfterDelete();
},
summarizeSelection: function() {},
QueryInterface : function(iid)
{
if (iid.equals(Components.interfaces.nsIMsgDBViewCommandUpdater) ||

Просмотреть файл

@ -527,6 +527,8 @@ nsMsgSearchCommandUpdater.prototype =
SetNextMessageAfterDelete();
},
summarizeSelection: function() {},
QueryInterface : function(iid)
{
if (iid.equals(Components.interfaces.nsIMsgDBViewCommandUpdater) ||

Просмотреть файл

@ -116,6 +116,8 @@ nsMsgDBViewCommandUpdater.prototype =
SetNextMessageAfterDelete();
},
summarizeSelection: function() {},
QueryInterface : function(iid)
{
if (iid.equals(Components.interfaces.nsIMsgDBViewCommandUpdater) ||