Bug #178091 --> implement Mail.app / 4.x Mac communicator like versions of the "move/copy" menus. Use

a single menu list, indenting subfolders, instead of using submenus for each folder level.

Currently only the folder picker in the search dialog has been convertered to use this.

patch by Neil
r=mscott
sr=bienvenu
a=asa
This commit is contained in:
scott%scott-macgregor.org 2005-06-20 18:44:23 +00:00
Родитель d002b1789c
Коммит f021cf5597
6 изменённых файлов: 261 добавлений и 46 удалений

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

@ -107,7 +107,9 @@
<hbox align="center">
<label value="&searchHeading.label;" accesskey="&searchHeading.accesskey;"
control="searchableFolders"/>
<menulist id="searchableFolders" flex="2"/>
<menulist id="searchableFolders" flex="2">
<menupopup class="searchPopup" oncommand="updateSearchFolderPicker(this.getAttribute('uri'));"/>
</menulist>
<spacer flex="10"/>
<button label="&searchButton.label;" id="search-button" oncommand="onSearchButton(event);" default="true" accesskey="&searchButton.accesskey;"/>

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

@ -114,3 +114,30 @@ dummy.usesMailWidgets {
cursor: default;
-moz-user-focus: none;
}
.searchPopup {
display: -moz-popup;
-moz-binding: url("chrome://messenger/content/mailWidgets.xml#searchpopup");
}
.foldersTree
{
margin: 0px;
border: none;
-moz-user-focus: ignore;
}
.foldersTreeChildren
{
-moz-binding: url("chrome://global/content/bindings/tree.xml#tree-base");
}
.foldersTreeChildren::-moz-tree-twisty
{
width: 0px;
}
.foldersTreeChildren::-moz-tree-line
{
visibility: hidden;
}

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

@ -1699,4 +1699,204 @@
</method>
</implementation>
</binding>
<!-- Folder picker helper widgets -->
<binding id="popup-base" extends="chrome://global/content/bindings/popup.xml#popup">
<implementation>
<field name="tree" readonly="true">
document.getAnonymousNodes(this)[0];
</field>
<method name="updateHover">
<parameter name="event"/>
<body>
<![CDATA[
var box = this.tree.boxObject;
if (event.originalTarget == box.treeBody) {
var eventX = event.screenX - box.screenX + box.x;
var eventY = event.screenY - box.screenY + box.y;
box.view.selection.select(box.getRowAt(eventX, eventY));
}
]]>
</body>
</method>
<method name="fire">
<body>
<![CDATA[
this.hidePopup();
if (this.tree.currentIndex >= 0) {
this.setAttribute("uri", this.tree.builderView.getResourceAtIndex(this.tree.currentIndex).Value);
this.doCommand();
}
]]>
</body>
</method>
<method name="onBlurMenuList">
<parameter name="event"/>
<body>
<![CDATA[
this.boxObject.QueryInterface(Components.interfaces.nsIMenuBoxObject).openMenu(false);
]]>
</body>
</method>
<field name="onKeyDownMenuList" readonly="true">
<![CDATA[
({
parentNode: this.parentNode,
handleEvent: function handleEvent(event) {
if (this.parentNode.hasAttribute("open"))
event.stopPropagation();
}
})
]]>
</field>
<field name="onKeyPressMenuList" readonly="true">
<![CDATA[
({
self: this,
tree: this.tree,
parentNode: this.parentNode,
getLastVisibleRow: function getLastVisibleRow(box) {
var f = box.getFirstVisibleRow();
var p = box.getPageCount();
var l = box.view.rowCount;
return (l < f + p ? l : f + p) - 1;
},
handleEvent: function handleEvent(event) {
if (this.parentNode.hasAttribute("open")) {
event.stopPropagation();
var index = this.tree.currentIndex;
var box = this.tree.treeBoxObject;
switch (event.keyCode) {
case event.DOM_VK_ESCAPE:
this.self.hidePopup();
return;
case event.DOM_VK_UP:
if (index <= 0) return;
index--;
break;
case event.DOM_VK_DOWN:
index++;
if (index == box.view.rowCount) return;
break;
case event.DOM_VK_PAGE_UP:
if (index == box.getFirstVisibleRow())
box.scrollByPages(-1);
index = box.getFirstVisibleRow();
break;
case event.DOM_VK_PAGE_DOWN:
if (index == this.getLastVisibleRow(box))
box.scrollByPages(1);
index = this.getLastVisibleRow(box);
break;
case event.DOM_VK_HOME:
index = 0;
break;
case event.DOM_VK_END:
index = box.view.rowCount - 1;
break;
case event.DOM_VK_ENTER:
case event.DOM_VK_RETURN:
this.self.fire();
return;
default:
return;
}
box.view.selection.select(index);
box.ensureRowIsVisible(index);
}
}
})
]]>
</field>
</implementation>
<handlers>
<handler event="mousemove" action="this.updateHover(event);"/>
<handler event="click" action="this.updateHover(event);this.fire();"/>
<handler event="popupshowing">
<![CDATA[
this.parentNode.addEventListener("blur", this.onBlurMenuList, false);
window.top.document.addEventListener("keydown", this.onKeyDownMenuList, true);
window.top.document.addEventListener("keypress", this.onKeyPressMenuList, true);
var box = this.tree.treeBoxObject;
box.focused = true;
var view = box.view;
view.selection.selectEventsSuppressed = true;
for (var i = 0; i < view.rowCount; i++) {
if (view.isContainer(i)) {
if (view.isContainerEmpty(i) == view.isContainerOpen(i))
view.toggleOpenState(i);
if (view.isContainerOpen(i)) {
if (i + 1 == view.rowCount ||
view.getLevel(i + 1) <= view.getLevel(i)) {
view.toggleOpenState(i);
}
}
}
}
var height = view.rowCount * box.rowHeight;
height += this.boxObject.height - box.treeBody.boxObject.height;
this.height = height;
var RDF = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
var index = this.tree.builderView.getIndexOfResource(RDF.GetResource(this.parentNode.getAttribute("uri")));
if (index >= 0) {
view.selection.select(index);
setTimeout(function() { box.ensureRowIsVisible(index); }, 0);
}
]]>
</handler>
<handler event="popuphiding">
<![CDATA[
this.parentNode.removeEventListener("blur", this.onBlurMenuList, false);
window.top.document.removeEventListener("keydown", this.onKeyDownMenuList, true);
window.top.document.removeEventListener("keypress", this.onKeyPressMenuList, true);
]]>
</handler>
</handlers>
</binding>
<binding id="locationpopup" extends="chrome://messenger/content/mailWidgets.xml#popup-base">
<xbl:content xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<tree class="foldersTree" flex="1" datasources="rdf:null" flags="dont-build-content" selstyle="primary" hidecolumnpicker="true">
<treecols>
<treecol flex="1" primary="true" sort="rdf:http://home.netscape.com/NC-rdf#FolderTreeName?sort=true" sortActive="true" sortDirection="ascending" crop="center" hideheader="true"/>
</treecols>
<treechildren class="foldersTreeChildren"/>
<template>
<rule>
<treechildren>
<treeitem uri="rdf:*">
<treerow sort="rdf:http://home.netscape.com/NC-rdf#FolderTreeName?sort=true">
<treecell label="rdf:http://home.netscape.com/NC-rdf#FolderTreeName"
properties="folderNameCol specialFolder-rdf:http://home.netscape.com/NC-rdf#SpecialFolder biffState-rdf:http://home.netscape.com/NC-rdf#BiffState isServer-rdf:http://home.netscape.com/NC-rdf#IsServer newMessages-rdf:http://home.netscape.com/NC-rdf#NewMessages hasUnreadMessages-rdf:http://home.netscape.com/NC-rdf#HasUnreadMessages isSecure-rdf:http://home.netscape.com/NC-rdf#IsSecure serverType-rdf:http://home.netscape.com/NC-rdf#ServerType noSelect-rdf:http://home.netscape.com/NC-rdf#NoSelect"/>
</treerow>
</treeitem>
</treechildren>
</rule>
</template>
</tree>
</xbl:content>
</binding>
<binding id="searchpopup" extends="chrome://messenger/content/mailWidgets.xml#popup-base">
<xbl:content xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<tree class="foldersTree" flex="1" datasources="rdf:msgaccountmanager rdf:mailnewsfolders" ref="msgaccounts:/" flags="dont-build-content" selstyle="primary" hidecolumnpicker="true">
<treecols>
<treecol flex="1" primary="true" sort="rdf:http://home.netscape.com/NC-rdf#FolderTreeName?sort=true" sortActive="true" sortDirection="ascending" crop="center" hideheader="true"/>
</treecols>
<treechildren class="foldersTreeChildren"/>
<template>
<rule nc:CanSearchMessages="true" nc:Virtual="false">
<treechildren>
<treeitem uri="rdf:*">
<treerow sort="rdf:http://home.netscape.com/NC-rdf#FolderTreeName?sort=true">
<treecell label="rdf:http://home.netscape.com/NC-rdf#FolderTreeSimpleName"
properties="folderNameCol specialFolder-rdf:http://home.netscape.com/NC-rdf#SpecialFolder isServer-rdf:http://home.netscape.com/NC-rdf#IsServer isSecure-rdf:http://home.netscape.com/NC-rdf#IsSecure serverType-rdf:http://home.netscape.com/NC-rdf#ServerType noSelect-rdf:http://home.netscape.com/NC-rdf#NoSelect"/>
</treerow>
</treeitem>
</treechildren>
</rule>
</template>
</tree>
</xbl:content>
</binding>
</bindings>

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

@ -92,6 +92,33 @@ searchterm {
-moz-binding: url("chrome://messenger/content/mailWidgets.xml#searchterm");
}
.searchPopup {
display: -moz-popup;
-moz-binding: url("chrome://messenger/content/mailWidgets.xml#searchpopup");
}
.foldersTree
{
margin: 0px;
border: none;
-moz-user-focus: ignore;
}
.foldersTreeChildren
{
-moz-binding: url("chrome://global/content/bindings/tree.xml#tree-base");
}
.foldersTreeChildren::-moz-tree-twisty
{
width: 0px;
}
.foldersTreeChildren::-moz-tree-line
{
visibility: hidden;
}
dummy.usesMailWidgets {
-moz-binding: url("chrome://messenger/content/mailWidgets.xml#dummy");
}

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

@ -37,6 +37,7 @@
***** END LICENSE BLOCK ***** -->
<?xml-stylesheet href="chrome://messenger/skin/folderMenus.css" type="text/css"?>
<?xml-stylesheet href="chrome://messenger/skin/folderPane.css" type="text/css"?>
<!DOCTYPE overlay SYSTEM "chrome://messenger/locale/msgFolderPickerOverlay.dtd">
@ -424,50 +425,6 @@
<menupopup />
</menulist>
<menulist id="searchableFolders"
sortResource="http://home.netscape.com/NC-rdf#FolderTreeName"
sortDirection="ascending"
datasources="rdf:msgaccountmanager rdf:mailnewsfolders"
ref="msgaccounts:/">
<template>
<rule nc:CanSearchMessages="false">
<!-- don't show servers which do not allow message searching -->
</rule>
<rule iscontainer="true" isempty="false" nc:CanSearchMessages="true">
<menupopup>
<menu uri="..."
class="folderMenuItem menu-iconic"
oncommand="onChooseFolder(event.target)"
SpecialFolder="rdf:http://home.netscape.com/NC-rdf#SpecialFolder"
BiffState="rdf:http://home.netscape.com/NC-rdf#BiffState"
IsServer="rdf:http://home.netscape.com/NC-rdf#IsServer"
IsSecure="rdf:http://home.netscape.com/NC-rdf#IsSecure"
ServerType="rdf:http://home.netscape.com/NC-rdf#ServerType"
label="rdf:http://home.netscape.com/NC-rdf#Name">
<menupopup class="menulist-menupopup">
<menuitem label="&filemessageschoosethis.label;"
oncommand="onChooseFolder(event.target.parentNode.parentNode)"/>
<menuseparator/>
</menupopup>
</menu>
</menupopup>
</rule>
<rule nc:CanSearchMessages="true" nc:Virtual="false">
<menupopup>
<menuitem uri="..." value="..."
class="folderMenuItem menuitem-iconic"
oncommand="onChooseFolder(event.target)"
SpecialFolder="rdf:http://home.netscape.com/NC-rdf#SpecialFolder"
BiffState="rdf:http://home.netscape.com/NC-rdf#BiffState"
IsServer="rdf:http://home.netscape.com/NC-rdf#IsServer"
IsSecure="rdf:http://home.netscape.com/NC-rdf#IsSecure"
ServerType="rdf:http://home.netscape.com/NC-rdf#ServerType"
label="rdf:http://home.netscape.com/NC-rdf#Name"/>
</menupopup>
</rule>
</template>
</menulist>
<menulist id="actionTargetFolder"
containment="http://home.netscape.com/NC-rdf#child"
sortResource="http://home.netscape.com/NC-rdf#FolderTreeName"

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

@ -103,7 +103,9 @@
<hbox align="center">
<label value="&searchHeading.label;" accesskey="&searchHeading.accesskey;"
control="searchableFolders"/>
<menulist id="searchableFolders" flex="2"/>
<menulist id="searchableFolders" flex="2">
<menupopup class="searchPopup" oncommand="updateSearchFolderPicker(this.getAttribute('uri'));"/>
</menulist>
<spacer flex="10"/>
<button label="&searchButton.label;" id="search-button" oncommand="onSearchButton(event);" default="true" accesskey="&searchButton.accesskey;"/>