factor out search query code from the filter code in preparation for a search dialog

r=sspitzer
(approved feature bug)
This commit is contained in:
alecf%netscape.com 2000-05-31 20:51:31 +00:00
Родитель a38a3c099d
Коммит 5ecee565e5
9 изменённых файлов: 303 добавлений и 296 удалений

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

@ -23,7 +23,6 @@
// the actual filter that we're editing
var gFilter;
var gSearchScope;
// cache the key elements we need
var gFilterNameElement;
@ -31,16 +30,9 @@ var gActionElement;
var gActionTargetElement;
// search stuff (move to overlay)
var gTotalSearchTerms=0;
var gSearchRowContainer;
var gSearchTermContainer;
var gSearchRemovedTerms = new Array;
var nsIMsgSearchValidityManager = Components.interfaces.nsIMsgSearchValidityManager;
var nsMsgFilterAction = Components.interfaces.nsMsgFilterAction;
var nsIMsgSearchTerm = Components.interfaces.nsIMsgSearchTerm;
function filterEditorOnLoad()
{
@ -73,32 +65,6 @@ function onOk()
window.close();
}
// move to overlay
// set scope on all visible searhattribute tags
function setSearchScope(scope) {
gSearchScope = scope;
var searchTermElements = gSearchTermContainer.childNodes;
if (!searchTermElements) return;
for (var i=0; i<searchTermElements.length; i++) {
searchTermElements[i].searchattribute.searchScope = scope;
}
}
function booleanChanged(event) {
// when boolean changes, we have to update all the attributes on the
// filter terms
var newBoolValue =
(event.target.getAttribute("data") == "and") ? true : false;
searchTermElements = gSearchTermContainer.childNodes;
if (!searchTermElements) return;
for (var i=0; i<searchTermElements.length; i++) {
var searchTerm = searchTermElements[i];
searchTerm.booleanAnd = newBoolValue;
}
dump("Boolean is now " + event.target.data + "\n");
}
function getScopeFromFilterList(filterList)
{
if (!filterList) return;
@ -142,159 +108,8 @@ function initializeDialog(filter)
initializeSearchRows(scope, filter.searchTerms)
}
function initializeSearchWidgets() {
gSearchBooleanRadiogroup = document.getElementById("booleanAndGroup");
gSearchRowContainer = document.getElementById("searchTermList");
gSearchTermContainer = document.getElementById("searchterms");
}
function initializeBooleanWidgets() {
var booleanAnd = true;
// get the boolean value from the first term
var firstTerm = gSearchTermContainer.firstChild;
if (firstTerm)
booleanAnd = firstTerm.booleanAnd;
// target radio items have data="and" or data="or"
targetValue = "or";
if (booleanAnd) targetValue = "and";
targetElement = gSearchBooleanRadiogroup.getElementsByAttribute("data", targetValue)[0];
gSearchBooleanRadiogroup.selectedItem = targetElement;
}
// move to overlay
function initializeSearchRows(scope, searchTerms)
{
gTotalSearchTerms = searchTerms.Count();
for (var i=0; i<gTotalSearchTerms; i++) {
var searchTerm = searchTerms.QueryElementAt(i, nsIMsgSearchTerm);
createSearchRow(i, scope, searchTerm);
}
initializeBooleanWidgets();
}
// move to overlay
function createSearchRow(index, scope, searchTerm)
{
var searchAttr = document.createElement("searchattribute");
var searchOp = document.createElement("searchoperator");
var searchVal = document.createElement("searchvalue");
// now set up ids:
searchAttr.id = "searchAttr" + index;
searchOp.id = "searchOp" + index;
searchVal.id = "searchVal" + index;
searchAttr.setAttribute("for", searchOp.id + "," + searchVal.id);
var rowdata = new Array(null, searchAttr,
null, searchOp,
null, searchVal,
null);
var searchrow = constructRow(rowdata);
searchrow.id = "searchRow" + index;
// should this be done with XBL or just straight JS?
// probably straight JS but I don't know how that's done.
var searchTermElement = document.createElement("searchterm");
searchTermElement.id = "searchTerm" + index;
gSearchTermContainer.appendChild(searchTermElement);
searchTermElement = document.getElementById(searchTermElement.id);
searchTermElement.searchattribute = searchAttr;
searchTermElement.searchoperator = searchOp;
searchTermElement.searchvalue = searchVal;
// and/or string handling:
// this is scary - basically we want to take every other
// treecell, (note the i+=2) which will be a text label,
// and set the searchTermElement's
// booleanNodes to that
var stringNodes = new Array;
var treecells = searchrow.firstChild.childNodes;
var j=0;
for (var i=0; i<treecells.length; i+=2) {
stringNodes[j++] = treecells[i];
}
searchTermElement.booleanNodes = stringNodes;
gSearchRowContainer.appendChild(searchrow);
searchTermElement.searchScope = scope;
if (searchTerm)
searchTermElement.searchTerm = searchTerm;
else
searchTermElement.booleanAnd = getBooleanAnd();
}
// creates a <treerow> using the array treeCellChildren as
// the children of each treecell
function constructRow(treeCellChildren)
{
var treeitem = document.createElement("treeitem");
var row = document.createElement("treerow");
for (var i = 0; i<treeCellChildren.length; i++) {
var treecell = document.createElement("treecell");
// it's ok to have empty cells
if (treeCellChildren[i]) {
treecell.setAttribute("allowevents", "true");
treeCellChildren[i].setAttribute("flex", "1");
treecell.appendChild(treeCellChildren[i]);
}
row.appendChild(treecell);
}
treeitem.appendChild(row);
return treeitem;
}
function removeSearchRow(index)
{
dump("removing search term " + index + "\n");
var searchTermElement = document.getElementById("searchTerm" + index);
if (!searchTermElement) {
dump("removeSearchRow: couldn't find search term " + index + "\n");
return;
}
// need to remove row from tree, so walk upwards from the
// searchattribute to find the first <treeitem>
var treeItemRow = searchTermElement.searchattribute;
while (treeItemRow) {
if (treeItemRow.tagName == "treeitem") break;
treeItemRow = treeItemRow.parentNode;
}
if (!treeItemRow) {
dump("Error: couldn't find parent treeitem!\n");
return;
}
if (searchTermElement.searchTerm) {
dump("That was a real row! queuing " + searchTermElement.searchTerm + " for disposal\n");
gSearchRemovedTerms[gSearchRemovedTerms.length] = searchTermElement.searchTerm;
} else {
dump("That wasn't real. ignoring \n");
}
treeItemRow.parentNode.removeChild(treeItemRow);
searchTermElement.parentNode.removeChild(searchTermElement);
}
function getBooleanAnd()
{
if (gSearchBooleanRadiogroup.selectedItem)
return (booleanAndElement.selectedItem.getAttribute("data") == "and") ? true : false;
// default to false
return false;
}
function saveFilter() {
@ -322,48 +137,3 @@ function saveFilter() {
gFilterList.insertFilterAt(0, gFilter);
}
// move to overlay
function saveSearchTerms(searchTerms, termOwner)
{
var searchTermElements =
gSearchTermContainer.childNodes;
for (var i = 0; i<searchTermElements.length; i++) {
try {
dump("Saving search element " + i + "\n");
var searchTerm = searchTermElements[i].searchTerm;
if (searchTerm)
searchTermElements[i].save();
else {
// need to create a new searchTerm, and somehow save it to that
dump("Need to create searchterm " + i + "\n");
searchTerm = termOwner.createTerm();
searchTermElements[i].saveTo(searchTerm);
termOwner.appendTerm(searchTerm);
}
} catch (ex) {
dump("** Error: " + ex + "\n");
}
}
// now remove the queued elements
for (var i=0; i<gSearchRemovedTerms.length; i++) {
// this is so nasty, we have to iterate through
// because GetIndexOf is acting funny
var searchTermSupports =
gSearchRemovedTerms[i].QueryInterface(Components.interfaces.nsISupports);
searchTerms.RemoveElement(searchTermSupports);
}
}
function onMore(event)
{
createSearchRow(gTotalSearchTerms++, gSearchScope, null);
}
function onLess(event)
{
removeSearchRow(--gTotalSearchTerms);
}

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

@ -22,6 +22,7 @@ Rights Reserved.
<?xml-stylesheet href="chrome://messenger/skin/messenger.css" type="text/css"?>
<?xul-overlay href="chrome://global/content/dialogOverlay.xul">
<?xul-overlay href="chrome://messenger/content/msgFolderPickerOverlay.xul"?>
<?xul-overlay href="chrome://messenger/content/searchTermOverlay.xul"?>
<!DOCTYPE window SYSTEM "chrome://messenger/locale/FilterEditor.dtd" >
<window class="dialog"
@ -36,70 +37,11 @@ Rights Reserved.
<script language="JavaScript" src="chrome://messenger/content/FilterEditor.js"/>
<script language="JavaScript" src="chrome://global/content/strres.js"/>
<keyset id="keyset"/>
<titledbox id="searchTermListBox"/>
<box orient="horizontal" class="padded">
<text value="&filterName.label;"/>
<textfield flex="1" id="filterName"/>
</box>
<titledbox orient="vertical">
<title>
<text value="&conditions.label;"/>
</title>
<text value="&conditionDesc.label;"/>
<radiogroup id="booleanAndGroup" oncommand="booleanChanged(event);">
<radio group="booleanAndGroup" data="and" value="&matchAll.label;"/>
<radio group="booleanAndGroup" data="or" value="&matchAny.label;"/>
</radiogroup>
<spring class="spacer"/>
<box style="min-height:200px">
<searchterms id="searchterms"/>
<tree class="inset" flex="1" id="searchTermTree">
<treecol width="1*"/>
<treecol width="4*"/>
<treecol width="0*"/>
<treecol width="4*"/>
<treecol width="0*"/>
<treecol width="4*"/>
<treecol width="0*"/>
<treechildren id="searchTermList">
<!-- this is what the treerows will look like:
<treeitem id="searchListItem">
<treerow>
<treecell id="preSearchAttr"/>
<treecell allowevents="true">
<searchattribute id="searchAttr" for="searchOp,searchValue" flex="1"/>
</treecell>
<treecell id="preSearchOp"/>
<treecell allowevents="true">
<searchoperator id="searchOp" flex="1"/>
</treecell>
<treecell id="preSearchValue"/>
<treecell allowevents="true" >
<searchvalue id="searchValue" flex="1"/>
</treecell>
<treecell id="postSearchValue"/>
</treerow>
</treeitem>
<treeitem>
<treerow>
<treecell value="the.."/>
<treecell value="contains.."/>
<treecell value="text here"/>
</treerow>
</treeitem>
-->
</treechildren>
</tree>
</box>
<box>
<button value="&more.label;" onclick="onMore(event);"/>
<button value="&less.label;" onclick="onLess(event);"/>
</box>
</titledbox>
<titledbox>
<title>
<text value="&filterAction.label;"/>

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

@ -21,3 +21,234 @@
* Alec Flett <alecf@netscape.com>
*/
var gTotalSearchTerms=0;
var gSearchRowContainer;
var gSearchTermContainer;
var gSearchRemovedTerms = new Array;
var gSearchScope;
var nsIMsgSearchTerm = Components.interfaces.nsIMsgSearchTerm;
function initializeSearchWidgets() {
gSearchBooleanRadiogroup = document.getElementById("booleanAndGroup");
gSearchRowContainer = document.getElementById("searchTermList");
gSearchTermContainer = document.getElementById("searchterms");
}
function initializeBooleanWidgets() {
var booleanAnd = true;
// get the boolean value from the first term
var firstTerm = gSearchTermContainer.firstChild;
if (firstTerm)
booleanAnd = firstTerm.booleanAnd;
// target radio items have data="and" or data="or"
targetValue = "or";
if (booleanAnd) targetValue = "and";
targetElement = gSearchBooleanRadiogroup.getElementsByAttribute("data", targetValue)[0];
gSearchBooleanRadiogroup.selectedItem = targetElement;
}
function initializeSearchRows(scope, searchTerms)
{
gTotalSearchTerms = searchTerms.Count();
for (var i=0; i<gTotalSearchTerms; i++) {
var searchTerm = searchTerms.QueryElementAt(i, nsIMsgSearchTerm);
createSearchRow(i, scope, searchTerm);
}
initializeBooleanWidgets();
}
function onMore(event)
{
createSearchRow(gTotalSearchTerms++, gSearchScope, null);
}
function onLess(event)
{
removeSearchRow(--gTotalSearchTerms);
}
// set scope on all visible searhattribute tags
function setSearchScope(scope) {
gSearchScope = scope;
var searchTermElements = gSearchTermContainer.childNodes;
if (!searchTermElements) return;
for (var i=0; i<searchTermElements.length; i++) {
searchTermElements[i].searchattribute.searchScope = scope;
}
}
function booleanChanged(event) {
// when boolean changes, we have to update all the attributes on the
// filter terms
var newBoolValue =
(event.target.getAttribute("data") == "and") ? true : false;
searchTermElements = gSearchTermContainer.childNodes;
if (!searchTermElements) return;
for (var i=0; i<searchTermElements.length; i++) {
var searchTerm = searchTermElements[i];
searchTerm.booleanAnd = newBoolValue;
}
dump("Boolean is now " + event.target.data + "\n");
}
function createSearchRow(index, scope, searchTerm)
{
var searchAttr = document.createElement("searchattribute");
var searchOp = document.createElement("searchoperator");
var searchVal = document.createElement("searchvalue");
// now set up ids:
searchAttr.id = "searchAttr" + index;
searchOp.id = "searchOp" + index;
searchVal.id = "searchVal" + index;
searchAttr.setAttribute("for", searchOp.id + "," + searchVal.id);
var rowdata = new Array(null, searchAttr,
null, searchOp,
null, searchVal,
null);
var searchrow = constructRow(rowdata);
searchrow.id = "searchRow" + index;
// should this be done with XBL or just straight JS?
// probably straight JS but I don't know how that's done.
var searchTermElement = document.createElement("searchterm");
searchTermElement.id = "searchTerm" + index;
gSearchTermContainer.appendChild(searchTermElement);
searchTermElement = document.getElementById(searchTermElement.id);
searchTermElement.searchattribute = searchAttr;
searchTermElement.searchoperator = searchOp;
searchTermElement.searchvalue = searchVal;
// and/or string handling:
// this is scary - basically we want to take every other
// treecell, (note the i+=2) which will be a text label,
// and set the searchTermElement's
// booleanNodes to that
var stringNodes = new Array;
var treecells = searchrow.firstChild.childNodes;
var j=0;
for (var i=0; i<treecells.length; i+=2) {
stringNodes[j++] = treecells[i];
}
searchTermElement.booleanNodes = stringNodes;
gSearchRowContainer.appendChild(searchrow);
searchTermElement.searchScope = scope;
if (searchTerm)
searchTermElement.searchTerm = searchTerm;
else
searchTermElement.booleanAnd = getBooleanAnd();
}
// creates a <treerow> using the array treeCellChildren as
// the children of each treecell
function constructRow(treeCellChildren)
{
var treeitem = document.createElement("treeitem");
var row = document.createElement("treerow");
for (var i = 0; i<treeCellChildren.length; i++) {
var treecell = document.createElement("treecell");
// it's ok to have empty cells
if (treeCellChildren[i]) {
treecell.setAttribute("allowevents", "true");
treeCellChildren[i].setAttribute("flex", "1");
treecell.appendChild(treeCellChildren[i]);
}
row.appendChild(treecell);
}
treeitem.appendChild(row);
return treeitem;
}
function removeSearchRow(index)
{
dump("removing search term " + index + "\n");
var searchTermElement = document.getElementById("searchTerm" + index);
if (!searchTermElement) {
dump("removeSearchRow: couldn't find search term " + index + "\n");
return;
}
// need to remove row from tree, so walk upwards from the
// searchattribute to find the first <treeitem>
var treeItemRow = searchTermElement.searchattribute;
while (treeItemRow) {
if (treeItemRow.tagName == "treeitem") break;
treeItemRow = treeItemRow.parentNode;
}
if (!treeItemRow) {
dump("Error: couldn't find parent treeitem!\n");
return;
}
if (searchTermElement.searchTerm) {
dump("That was a real row! queuing " + searchTermElement.searchTerm + " for disposal\n");
gSearchRemovedTerms[gSearchRemovedTerms.length] = searchTermElement.searchTerm;
} else {
dump("That wasn't real. ignoring \n");
}
treeItemRow.parentNode.removeChild(treeItemRow);
searchTermElement.parentNode.removeChild(searchTermElement);
}
function getBooleanAnd()
{
if (gSearchBooleanRadiogroup.selectedItem)
return (booleanAndElement.selectedItem.getAttribute("data") == "and") ? true : false;
// default to false
return false;
}
function saveSearchTerms(searchTerms, termOwner)
{
var searchTermElements =
gSearchTermContainer.childNodes;
for (var i = 0; i<searchTermElements.length; i++) {
try {
dump("Saving search element " + i + "\n");
var searchTerm = searchTermElements[i].searchTerm;
if (searchTerm)
searchTermElements[i].save();
else {
// need to create a new searchTerm, and somehow save it to that
dump("Need to create searchterm " + i + "\n");
searchTerm = termOwner.createTerm();
searchTermElements[i].saveTo(searchTerm);
termOwner.appendTerm(searchTerm);
}
} catch (ex) {
dump("** Error: " + ex + "\n");
}
}
// now remove the queued elements
for (var i=0; i<gSearchRemovedTerms.length; i++) {
// this is so nasty, we have to iterate through
// because GetIndexOf is acting funny
var searchTermSupports =
gSearchRemovedTerms[i].QueryInterface(Components.interfaces.nsISupports);
searchTerms.RemoveElement(searchTermSupports);
}
}

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

@ -22,7 +22,68 @@
Alec Flett <alecf@netscape.com>
-->
<!DOCTYPE window SYSTEM "chrome://messenger/locale/searchTermOverlay.dtd" >
<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script src="chrome://messenger/content/searchTermOverlay.js"/>
<titledbox orient="vertical" id="searchTermListBox">
<title>
<text value="&conditions.label;"/>
</title>
<text value="&conditionDesc.label;"/>
<radiogroup id="booleanAndGroup" oncommand="booleanChanged(event);">
<radio group="booleanAndGroup" data="and" value="&matchAll.label;"/>
<radio group="booleanAndGroup" data="or" value="&matchAny.label;"/>
</radiogroup>
<spring class="spacer"/>
<box style="min-height:200px">
<searchterms id="searchterms"/>
<tree class="inset" flex="1" id="searchTermTree">
<treecol width="1*"/>
<treecol width="4*"/>
<treecol width="0*"/>
<treecol width="4*"/>
<treecol width="0*"/>
<treecol width="4*"/>
<treecol width="0*"/>
<treechildren id="searchTermList">
<!-- this is what the treerows will look like:
<treeitem id="searchListItem">
<treerow>
<treecell id="preSearchAttr"/>
<treecell allowevents="true">
<searchattribute id="searchAttr" for="searchOp,searchValue" flex="1"/>
</treecell>
<treecell id="preSearchOp"/>
<treecell allowevents="true">
<searchoperator id="searchOp" flex="1"/>
</treecell>
<treecell id="preSearchValue"/>
<treecell allowevents="true" >
<searchvalue id="searchValue" flex="1"/>
</treecell>
<treecell id="postSearchValue"/>
</treerow>
</treeitem>
<treeitem>
<treerow>
<treecell value="the.."/>
<treecell value="contains.."/>
<treecell value="text here"/>
</treerow>
</treeitem>
-->
</treechildren>
</tree>
</box>
<box>
<button value="&more.label;" onclick="onMore(event);"/>
<button value="&less.label;" onclick="onLess(event);"/>
</box>
</titledbox>
</overlay>

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

@ -13,9 +13,6 @@
<!ENTITY body.label "body">
<!ENTITY contains.label "contains">
<!ENTITY nocontains.label "doesn't contain">
<!ENTITY conditionDesc.label "When new messages arrive in my Inbox, watch for messages that:">
<!ENTITY matchAll.label "Match ALL of the following conditions">
<!ENTITY matchAny.label "Match at least ONE of the following conditions">
<!ENTITY filterAction.label "Action">
<!ENTITY moveToFolder.label "Move To Folder">
<!ENTITY changePriority.label "Change Priority">
@ -23,7 +20,4 @@
<!ENTITY markRead.label "Mark read">
<!ENTITY ignoreThread.label "Ignore thread">
<!ENTITY watchThread.label "Watch thread">
<!ENTITY more.label "More">
<!ENTITY less.label "Fewer">
<!ENTITY filterName.label "Filter Name:">
<!ENTITY conditions.label "Conditions">

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

@ -5,3 +5,4 @@ SearchOptions.dtd
search-attributes.properties
search-operators.properties
search.properties
searchTermOverlay.dtd

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

@ -37,6 +37,7 @@ CHROME_L10N = \
search-attributes.properties \
search-operators.properties \
search.properties \
searchTermOverlay.xul \
$(NULL)
include $(topsrcdir)/config/rules.mk

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

@ -32,6 +32,7 @@ CHROME_L10N = \
.\search-attributes.properties \
.\search-operators.properties \
.\search.properties \
.\searchTermOverlay.dtd \
$(NULL)
include <$(DEPTH)\config\rules.mak>

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

@ -0,0 +1,6 @@
<!ENTITY more.label "More">
<!ENTITY less.label "Fewer">
<!ENTITY conditions.label "Conditions">
<!ENTITY conditionDesc.label "When new messages arrive in my Inbox, watch for messages that:">
<!ENTITY matchAll.label "Match ALL of the following conditions">
<!ENTITY matchAny.label "Match at least ONE of the following conditions">