fix 497279 r=bienvenu, issues with view | thread |threads with unread

This commit is contained in:
Andrew Sutherland 2009-07-02 11:00:54 -07:00
Родитель a42a4132e2
Коммит 4438778442
4 изменённых файлов: 98 добавлений и 7 удалений

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

@ -409,9 +409,9 @@ var DefaultController =
case "cmd_previousFlaggedMsg":
return IsViewNavigationItemEnabled();
case "cmd_viewAllMsgs":
case "cmd_viewUnreadMsgs":
case "cmd_viewIgnoredThreads":
return gDBView;
case "cmd_viewUnreadMsgs":
case "cmd_viewThreadsWithUnread":
case "cmd_viewWatchedThreadsWithUnread":
return !gFolderDisplay.view.isVirtual;

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

@ -83,7 +83,7 @@ var FolderNotificationHelper = {
* search results wrappers.
*/
_curiousWrappers: [],
/**
* Initialize our listeners. We currently don't bother cleaning these up
* because we are a singleton and if anyone imports us, they probably want
@ -166,7 +166,7 @@ var FolderNotificationHelper = {
noteCuriosity: function FolderNotificationHelper_noteCuriosity(aViewWrapper) {
this._curiousWrappers.push(aViewWrapper);
},
/**
* Removal helper for use by removeNotifications.
*
@ -938,6 +938,17 @@ DBViewWrapper.prototype = {
this._ensureValidSort();
}
// See if the last-used view was one of the special views. If so, put us in
// that special view mode. We intentionally do this after restoring the
// view flags because _setSpecialView enforces threading.
// The nsMsgDBView is the one who persists this information for us. In this
// case the nsMsgThreadedDBView superclass of the special views triggers it
// when opened.
let viewType = dbFolderInfo.viewType;
if ((viewType == nsMsgViewType.eShowThreadsWithUnread) ||
(viewType == nsMsgViewType.eShowWatchedThreadsWithUnread))
this._setSpecialView(viewType);
// - retrieve virtual folder configuration
if (aFolder.flags & nsMsgFolderFlags.Virtual) {
let virtFolder = VirtualFolderHelper.wrapVirtualFolder(aFolder);
@ -1092,7 +1103,7 @@ DBViewWrapper.prototype = {
this.folderLoading = false;
// If _underlyingFolders is null, DBViewWrapper_open probably got
// an exception trying to open the db, but after reparsing the local
// folder, we should have a db, so set up the view based on info
// folder, we should have a db, so set up the view based on info
// from the db.
if (this._underlyingFolders == null) {
this._prepareToLoadView(aFolder.msgDatabase, aFolder);
@ -1268,7 +1279,8 @@ DBViewWrapper.prototype = {
* - Single-folder threaded/unthreaded can handle a change to/from unthreaded/
* threaded, so set it.
* - Single-folder can _not_ handle a change between grouped and not-grouped,
* so re-generate the view.
* so re-generate the view. Nor can it handle a change involving
* kUnreadOnly.
*/
set _viewFlags DBViewWrapper_set__viewFlags(aViewFlags) {
if (this._viewUpdateDepth || !this.dbView)
@ -1278,7 +1290,8 @@ DBViewWrapper.prototype = {
let changedFlags = oldFlags ^ aViewFlags;
if ((this.isVirtual && this.isMultiFolder) ||
(this.isSingleFolder &&
!(changedFlags & nsMsgViewFlagsType.kGroupBySort))) {
!(changedFlags & (nsMsgViewFlagsType.kGroupBySort |
nsMsgViewFlagsType.kUnreadOnly)))) {
this.dbView.viewFlags = aViewFlags;
// ugh, and the single folder case needs us to re-apply his sort...
if (this.isSingleFolder)
@ -1709,13 +1722,24 @@ DBViewWrapper.prototype = {
* view (or other search) for unread messages. There also exist special
* views for showing messages with unread threads which is different and
* has serious limitations because of its nature.
* Setting anything to this value clears any active special view because the
* actual UI use case (the "View... Threads..." menu) uses this setter
* intentionally as a mutually exclusive UI choice from the special views.
*/
set showUnreadOnly(aShowUnreadOnly) {
if (this.showUnreadOnly != aShowUnreadOnly) {
if (this._specialView || (this.showUnreadOnly != aShowUnreadOnly)) {
let viewRebuildRequired = (this._specialView != null);
this._specialView = null;
if (viewRebuildRequired)
this.beginViewUpdate();
if (aShowUnreadOnly)
this._viewFlags |= nsMsgViewFlagsType.kUnreadOnly;
else
this._viewFlags &= ~nsMsgViewFlagsType.kUnreadOnly;
if (viewRebuildRequired)
this.endViewUpdate();
}
},
@ -1744,6 +1768,9 @@ DBViewWrapper.prototype = {
// all special views imply a threaded view
this.showThreaded = true;
this._specialView = aViewEnum;
// We clear the search for paranoia/correctness reasons. However, the UI
// layer is currently responsible for making sure these are already zeroed
// out.
this.search.clear();
this.endViewUpdate();
},

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

@ -29,6 +29,49 @@ function test_threading_grouping_mutual_exclusion () {
"view should be grouped by sort");
}
/**
* Verify that flipping between the "View... Threads..." menu cases supported by
* |showUnreadOnly| / |specialViewThreadsWithUnread| /
* |specialViewThreadsWithUnread| has them all be properly mutually exclusive.
*/
function test_threads_special_views_mutual_exclusion() {
let viewWrapper = make_view_wrapper();
let folder = make_empty_folder();
yield async_view_open(viewWrapper, folder);
// enter an update that will never conclude. this is fine.
viewWrapper.beginViewUpdate();
// turn on the special view, make sure we think it took
viewWrapper.specialViewThreadsWithUnread = true;
do_check_true(viewWrapper.specialViewThreadsWithUnread);
do_check_false(viewWrapper.specialViewWatchedThreadsWithUnread);
// hit showUnreadOnly which should already be false, so this makes sure that
// just writing to it forces the special view off.
viewWrapper.showUnreadOnly = false;
do_check_false(viewWrapper.showUnreadOnly);
do_check_false(viewWrapper.specialViewThreadsWithUnread);
do_check_false(viewWrapper.specialViewWatchedThreadsWithUnread);
// turn on the other special view
viewWrapper.specialViewWatchedThreadsWithUnread = true;
do_check_false(viewWrapper.specialViewThreadsWithUnread);
do_check_true(viewWrapper.specialViewWatchedThreadsWithUnread);
// turn on show unread only mode, make sure special view is cleared
viewWrapper.showUnreadOnly = true;
do_check_true(viewWrapper.showUnreadOnly);
do_check_false(viewWrapper.specialViewThreadsWithUnread);
do_check_false(viewWrapper.specialViewWatchedThreadsWithUnread);
// turn off show unread only mode just to make sure the transition happens
viewWrapper.showUnreadOnly = false;
do_check_false(viewWrapper.showUnreadOnly);
do_check_false(viewWrapper.specialViewThreadsWithUnread);
do_check_false(viewWrapper.specialViewWatchedThreadsWithUnread);
}
/**
* Do a quick test of primary sorting to make sure we're actually changing the
* sort order. (However, we are not responsible for verifying correctness of
@ -204,6 +247,7 @@ function test_view_update_depth_logic() {
var tests = [
test_threading_grouping_mutual_exclusion,
test_threads_special_views_mutual_exclusion,
test_sort_primary,
test_sort_secondary_explicit,
test_sort_secondary_implicit,

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

@ -679,6 +679,25 @@ function test_real_folder_special_views_threads_with_unread() {
verify_messages_in_view([setThreadOne, setThreadTwo], viewWrapper);
}
/**
* Make sure that we restore special views from their persisted state when
* opening the view.
*/
function test_real_folder_special_views_persist() {
let viewWrapper = make_view_wrapper();
let folder = make_empty_folder();
yield async_view_open(viewWrapper, folder);
viewWrapper.beginViewUpdate();
viewWrapper.specialViewThreadsWithUnread = true;
yield async_view_end_update(viewWrapper);
viewWrapper.close();
yield async_view_open(viewWrapper, folder);
assert_true(viewWrapper.specialViewThreadsWithUnread,
"We should be in threads-with-unread special view mode.");
}
var tests = [
test_real_folder_load,
test_real_folder_update,
@ -711,6 +730,7 @@ var tests = [
test_real_folder_mail_view_and_quick_search,
// - special views
test_real_folder_special_views_threads_with_unread,
test_real_folder_special_views_persist,
// (we cannot test the watched threads with unread case in local folders)
];