1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-23 14:22:27 +01:00

[muttator] also search closed threads; new gj and gk key bindings

This commit is contained in:
Martin Stubenschrott
2008-05-06 13:31:53 +00:00
parent 2dc790a1e4
commit 5419d29a50
2 changed files with 123 additions and 32 deletions

View File

@@ -505,6 +505,10 @@ const liberator = (function () //{{{
if (window == ww.activeWindow && document.commandDispatcher.focusedElement && clearFocusedElement) if (window == ww.activeWindow && document.commandDispatcher.focusedElement && clearFocusedElement)
document.commandDispatcher.focusedElement.blur(); document.commandDispatcher.focusedElement.blur();
// TODO: make more generic
if (liberator.has("mail") && clearFocusedElement && gDBView)
gDBView.selection.select(gDBView.selection.currentIndex);
var elem = liberator.config.mainWidget || content; var elem = liberator.config.mainWidget || content;
if (elem != document.commandDispatcher.focusedElement) if (elem != document.commandDispatcher.focusedElement)
elem.focus(); elem.focus();

View File

@@ -129,6 +129,21 @@ liberator.Mail = function ()
return true; return true;
} }
function parentIndex(index)
{
var parent = index;
var tree = GetThreadTree();
while (true)
{
var tmp = tree.view.getParentIndex(parent);
if (tmp >= 0)
parent = tmp;
else
break;
}
return parent;
}
/////////////////////////////////////////////////////////////////////////////}}} /////////////////////////////////////////////////////////////////////////////}}}
////////////////////// OPTIONS ///////////////////////////////////////////////// ////////////////////// OPTIONS /////////////////////////////////////////////////
@@ -155,6 +170,19 @@ liberator.Mail = function ()
} }
}); });
/*liberator.options.add(["threads"],
"Use threading to group messages",
"boolean", true,
{
setter: function (value)
{
if (value)
MsgSortThreaded();
else
MsgSortUnthreaded();
}
});*/
/////////////////////////////////////////////////////////////////////////////}}} /////////////////////////////////////////////////////////////////////////////}}}
////////////////////// MAPPINGS //////////////////////////////////////////////// ////////////////////// MAPPINGS ////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////{{{ /////////////////////////////////////////////////////////////////////////////{{{
@@ -165,28 +193,42 @@ liberator.Mail = function ()
"Inspect (focus) message", "Inspect (focus) message",
function () { content.focus(); }); function () { content.focus(); });
liberator.mappings.add(modes, ["x"],
"Select thread",
function () { liberator.mail.selectThread(); });
liberator.mappings.add(modes, ["d", "<Del>"], liberator.mappings.add(modes, ["d", "<Del>"],
"Move mail to Trash folder", "Move mail to Trash folder",
function () { goDoCommand("cmd_delete"); }); function () { goDoCommand("cmd_delete"); });
liberator.mappings.add(modes, ["j", "<Right>"], liberator.mappings.add(modes, ["j", "<Right>"],
"Select next message", "Select next message",
function (count) { liberator.mail.selectMessage(function (msg) { return true; }, false, false, count); }, function (count) { liberator.mail.selectMessage(function (msg) { return true; }, false, false, false, count); },
{ flags: liberator.Mappings.flags.COUNT });
liberator.mappings.add(modes, ["gj"],
"Select next message, including closed threads",
function (count) { liberator.mail.selectMessage(function (msg) { return true; }, false, true, false, count); },
{ flags: liberator.Mappings.flags.COUNT }); { flags: liberator.Mappings.flags.COUNT });
liberator.mappings.add(modes, ["J", "<Tab>"], liberator.mappings.add(modes, ["J", "<Tab>"],
"Select next unread message", "Select next unread message",
function (count) { liberator.mail.selectMessage(function (msg) { return !msg.isRead; }, true, false, count); }, function (count) { liberator.mail.selectMessage(function (msg) { return !msg.isRead; }, true, true, false, count); },
{ flags: liberator.Mappings.flags.COUNT }); { flags: liberator.Mappings.flags.COUNT });
liberator.mappings.add(modes, ["k", "<Left>"], liberator.mappings.add(modes, ["k", "<Left>"],
"Select previous message", "Select previous message",
function (count) { liberator.mail.selectMessage(function (msg) { return true; }, false, true, count); }, function (count) { liberator.mail.selectMessage(function (msg) { return true; }, false, false, true, count); },
{ flags: liberator.Mappings.flags.COUNT });
liberator.mappings.add(modes, ["gk"],
"Select previous message",
function (count) { liberator.mail.selectMessage(function (msg) { return true; }, false, true, true, count); },
{ flags: liberator.Mappings.flags.COUNT }); { flags: liberator.Mappings.flags.COUNT });
liberator.mappings.add(modes, ["K"], liberator.mappings.add(modes, ["K"],
"Select previous unread message", "Select previous unread message",
function (count) { liberator.mail.selectMessage(function (msg) { return !msg.isRead; }, true, true, count); }, function (count) { liberator.mail.selectMessage(function (msg) { return !msg.isRead; }, true, true, true, count); },
{ flags: liberator.Mappings.flags.COUNT }); { flags: liberator.Mappings.flags.COUNT });
liberator.mappings.add(modes, ["r"], liberator.mappings.add(modes, ["r"],
@@ -214,12 +256,12 @@ liberator.Mail = function ()
liberator.mappings.add([liberator.modes.MESSAGE], ["<Left>"], liberator.mappings.add([liberator.modes.MESSAGE], ["<Left>"],
"Select previous message", "Select previous message",
function (count) { liberator.mail.selectMessage(function (msg) { return true; }, false, true, count); }, function (count) { liberator.mail.selectMessage(function (msg) { return true; }, false, false, true, count); },
{ flags: liberator.Mappings.flags.COUNT }); { flags: liberator.Mappings.flags.COUNT });
liberator.mappings.add([liberator.modes.MESSAGE], ["<Right>"], liberator.mappings.add([liberator.modes.MESSAGE], ["<Right>"],
"Select next message", "Select next message",
function (count) { liberator.mail.selectMessage(function (msg) { return true; }, false, false, count); }, function (count) { liberator.mail.selectMessage(function (msg) { return true; }, false, false, false, count); },
{ flags: liberator.Mappings.flags.COUNT }); { flags: liberator.Mappings.flags.COUNT });
@@ -271,22 +313,22 @@ liberator.Mail = function ()
liberator.mappings.add(modes, ["]s"], liberator.mappings.add(modes, ["]s"],
"Select next starred message", "Select next starred message",
function (count) { liberator.mail.selectMessage(function(msg) { return msg.isFlagged; }, true, false, count); }, function (count) { liberator.mail.selectMessage(function(msg) { return msg.isFlagged; }, true, true, false, count); },
{ flags: liberator.Mappings.flags.COUNT }); { flags: liberator.Mappings.flags.COUNT });
liberator.mappings.add(modes, ["[s"], liberator.mappings.add(modes, ["[s"],
"Select previous starred message", "Select previous starred message",
function (count) { liberator.mail.selectMessage(function(msg) { return msg.isFlagged; }, true, true, count); }, function (count) { liberator.mail.selectMessage(function(msg) { return msg.isFlagged; }, true, true, true, count); },
{ flags: liberator.Mappings.flags.COUNT }); { flags: liberator.Mappings.flags.COUNT });
liberator.mappings.add(modes, ["]a"], liberator.mappings.add(modes, ["]a"],
"Select next message with an attachment", "Select next message with an attachment",
function (count) { liberator.mail.selectMessage(function(msg) { return gDBView.db.HasAttachments(msg.messageKey); }, true, false, count); }, function (count) { liberator.mail.selectMessage(function(msg) { return gDBView.db.HasAttachments(msg.messageKey); }, true, true, false, count); },
{ flags: liberator.Mappings.flags.COUNT }); { flags: liberator.Mappings.flags.COUNT });
liberator.mappings.add(modes, ["[a"], liberator.mappings.add(modes, ["[a"],
"Select previous message with an attachment", "Select previous message with an attachment",
function (count) { liberator.mail.selectMessage(function(msg) { return gDBView.db.HasAttachments(msg.messageKey); }, true, true, count); }, function (count) { liberator.mail.selectMessage(function(msg) { return gDBView.db.HasAttachments(msg.messageKey); }, true, true, true, count); },
{ flags: liberator.Mappings.flags.COUNT }); { flags: liberator.Mappings.flags.COUNT });
@@ -545,16 +587,7 @@ liberator.Mail = function ()
var tree = GetThreadTree(); var tree = GetThreadTree();
if (tree) if (tree)
{ {
var parent = tree.currentIndex; var parent = parentIndex(tree.currentIndex);
while (true)
{
var tmp = tree.view.getParentIndex(parent);
if (tmp >= 0)
parent = tmp;
else
break;
}
if (tree.changeOpenState(parent, false)) if (tree.changeOpenState(parent, false))
{ {
tree.view.selection.select(parent); tree.view.selection.select(parent);
@@ -577,8 +610,24 @@ liberator.Mail = function ()
return false; return false;
}, },
selectMessage: function(validatorFunc, canWrap, reverse, count) /*
* general-purpose method to find messages
* @param validatorFunc(msg): return true/false whether msg should be selected or not
* @param canWrap: when true, wraps around folders
* @param openThreads: should we open closed threads?
* @param reverse: change direction of searching
*/
selectMessage: function(validatorFunc, canWrap, openThreads, reverse, count)
{ {
function closedThread(index)
{
if (!(gDBView.viewFlags & nsMsgViewFlagsType.kThreadedDisplay))
return false;
index = (typeof index == "number") ? index : gDBView.selection.currentIndex;
return !gDBView.isContainerOpen(index) && !gDBView.isContainerEmpty(index);
}
if (typeof validatorFunc != "function") if (typeof validatorFunc != "function")
return; return;
@@ -588,25 +637,50 @@ liberator.Mail = function ()
// first try to find in current folder // first try to find in current folder
if (gDBView) if (gDBView)
{ {
//var curIndex = for (var i = gDBView.selection.currentIndex + (reverse ? -1 : (openThreads && closedThread() ? 0 : 1));
// FIXME: doesn't work with collapsed threads reverse ? (i >= 0) : (i < gDBView.rowCount);
for (var i = gDBView.selection.currentIndex + (reverse ? -1 : 1); reverse ? i-- : i++)
(reverse ? ( i >= 0) : (i < gDBView.rowCount)); reverse ? i-- : i++)
{ {
var key = gDBView.getKeyAt(i); var key = gDBView.getKeyAt(i);
var msg = gDBView.db.GetMsgHdrForKey(key); var msg = gDBView.db.GetMsgHdrForKey(key);
if (validatorFunc(msg))
count--;
if (count == 0) // a closed thread
if (openThreads && closedThread(i))
{
var thread = gDBView.db.GetThreadContainingMsgHdr(msg);
var originalCount = count;
for (let j = (i == gDBView.selection.currentIndex && !reverse) ? 1 : (reverse ? thread.numChildren - 1 : 0);
reverse ? (j >= 0) : (j < thread.numChildren);
reverse ? j-- : j++)
{
msg = thread.getChildAt(j);
if (validatorFunc(msg) && --count == 0)
{
// this hack is needed to get the correct message, because getChildAt() does not
// necessarily return the messages in the order they are displayed
gDBView.selection.timedSelect(i, GetThreadTree()._selectDelay || 500);
GetThreadTree().treeBoxObject.ensureRowIsVisible(i);
if (j > 0)
{
GetThreadTree().changeOpenState(i, true);
this.selectMessage(validatorFunc, false, false, false, originalCount);
}
return;
}
}
}
else // simple non-threaded message
{
if (validatorFunc(msg) && --count == 0)
{ {
// gDBView.selectMsgByKey(key);
gDBView.selection.timedSelect(i, GetThreadTree()._selectDelay || 500); gDBView.selection.timedSelect(i, GetThreadTree()._selectDelay || 500);
GetThreadTree().treeBoxObject.ensureRowIsVisible(i); GetThreadTree().treeBoxObject.ensureRowIsVisible(i);
return; return;
} }
} }
} }
}
// then in other folders // then in other folders
if (canWrap) if (canWrap)
@@ -663,8 +737,21 @@ liberator.Mail = function ()
// TODO: finally for the "rest" of the current folder // TODO: finally for the "rest" of the current folder
liberator.beep(); liberator.beep();
},
// gDBView.doCommand(nsMsgViewCommandType.selectThread);
selectThread: function()
{
var tree = GetThreadTree();
var key = gDBView.getKeyAt(tree.currentIndex);
var msg = gDBView.db.GetMsgHdrForKey(key);
var thread = gDBView.db.GetThreadContainingMsgHdr(msg);
var parent = parentIndex(tree.currentIndex);
gDBView.selection.rangedSelect(parent + thread.numChildren -1, parent, false);
} }
}; };
//}}} //}}}
}; };