Bug 332047 - Should select correct items (after delete, insert, paste, drop). patch from Marco Bonardo <mak77@supereva.it>, r=me.

This commit is contained in:
mozilla.mano@sent.com 2008-02-06 13:05:23 -08:00
Родитель 842a00613e
Коммит c03bd4e43f
9 изменённых файлов: 126 добавлений и 86 удалений

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

@ -784,8 +784,6 @@ PlacesController.prototype = {
if (!ip)
throw Cr.NS_ERROR_NOT_AVAILABLE;
this._view.saveSelection(this._view.SAVE_SELECTION_INSERT);
var performed = false;
if (aType == "bookmark")
performed = PlacesUtils.showAddBookmarkUI(null, null, null, ip);
@ -794,8 +792,12 @@ PlacesController.prototype = {
else // folder
performed = PlacesUtils.showAddFolderUI(null, ip);
if (performed)
this._view.restoreSelection();
if (performed) {
// select the new item
var insertedNodeId = PlacesUtils.bookmarks
.getIdForItemAt(ip.itemId, ip.index);
this._view.selectItems([insertedNodeId], ip.itemId);
}
},
@ -808,9 +810,14 @@ PlacesController.prototype = {
if (!ip)
throw Cr.NS_ERROR_NOT_AVAILABLE;
this._view.saveSelection(this._view.SAVE_SELECTION_INSERT);
if (PlacesUtils.showAddFolderUI(null, ip))
this._view.restoreSelection();
var performed = false;
performed = PlacesUtils.showAddFolderUI(null, ip);
if (performed) {
// select the new item
var insertedNodeId = PlacesUtils.bookmarks
.getIdForItemAt(ip.itemId, ip.index);
this._view.selectItems([insertedNodeId]);
}
},
/**
@ -822,6 +829,10 @@ PlacesController.prototype = {
throw Cr.NS_ERROR_NOT_AVAILABLE;
var txn = PlacesUtils.ptm.createSeparator(ip.itemId, ip.index);
PlacesUtils.ptm.doTransaction(txn);
// select the new item
var insertedNodeId = PlacesUtils.bookmarks
.getIdForItemAt(ip.itemId, ip.index);
this._view.selectItems([insertedNodeId]);
},
/**
@ -1201,6 +1212,14 @@ PlacesController.prototype = {
PlacesUtils.TYPE_UNICODE]);
var txn = PlacesUtils.ptm.aggregateTransactions("Paste", transactions);
PlacesUtils.ptm.doTransaction(txn);
// select the pasted items, they should be consecutive
var insertedNodeIds = [];
for (var i = 0; i < transactions.length; ++i)
insertedNodeIds.push(PlacesUtils.bookmarks
.getIdForItemAt(ip.itemId, ip.index + i));
if (insertedNodeIds.length > 0)
this._view.selectItems(insertedNodeIds);
}
};

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

@ -542,16 +542,6 @@
]]></body>
</method>
<method name="saveSelection">
<parameter name="mode"/>
<body><![CDATA[
]]></body>
</method>
<method name="restoreSelection">
<body><![CDATA[
]]></body>
</method>
<property name="selType" readonly="true" onget="return 'single';"/>
<method name="buildContextMenu">

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

@ -929,16 +929,6 @@
]]></body>
</method>
<method name="saveSelection">
<parameter name="mode"/>
<body><![CDATA[
]]></body>
</method>
<method name="restoreSelection">
<body><![CDATA[
]]></body>
</method>
<property name="selType" onget="return 'single';"/>
<method name="buildContextMenu">

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

@ -745,54 +745,6 @@
]]></body>
</method>
<field name="_nextSelection">[]</field>
<field name="SAVE_SELECTION_RELOAD">0</field>
<field name="SAVE_SELECTION_INSERT">1</field>
<method name="saveSelection">
<parameter name="mode"/>
<body><![CDATA[
// mode can be one of any of the SAVE_SELECTION field values,
// specifying how selection is to be saved.
var s = this.view.selection;
var rc = s.getRangeCount();
switch (mode) {
case this.SAVE_SELECTION_INSERT:
var min = { }, max = { };
s.getRangeAt(rc - 1, min, max);
this._nextSelection = [{ min: max.value, max: max.value }];
break;
case this.SAVE_SELECTION_RELOAD:
this._nextSelection = [];
for (var i = 0; i < rc; ++i) {
var min = { }, max = { };
s.getRangeAt(i, range.min, range.max);
this._nextSelection.push({ min: range.min, max: range.max });
}
break;
}
]]></body>
</method>
<method name="restoreSelection">
<body><![CDATA[
var allowedMaxIndex = this.view.rowCount - 1;
for (var i = 0; i < this._nextSelection.length; ++i) {
var range = this._nextSelection[i];
// make sure the index is not over the end of the view
// this fixes bug 376581
if (range.max > allowedMaxIndex)
range.max = allowedMaxIndex;
if (range.min > allowedMaxIndex)
range.min = allowedMaxIndex;
if (range.min > -1 && range.max > -1)
this.view.selection.rangedSelect(range.min, range.max, true);
}
]]></body>
</method>
<method name="buildContextMenu">
<parameter name="aPopup"/>
<body><![CDATA[

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

@ -742,8 +742,16 @@ PlacesTreeView.prototype = {
this._fixViewIndexOnRemove(aItem, aParent);
// restore selection if the item was exclusively selected
if (selectNext && this._visibleElements.length > oldViewIndex)
selection.rangedSelect(oldViewIndex, oldViewIndex, true);
if (!selectNext)
return;
// restore selection
if (this._visibleElements.length > oldViewIndex)
selection.rangedSelect(oldViewIndex, oldViewIndex, true);
else if (this._visibleElements.length > 0) {
// if we removed the last child, we select the new last child if exists
selection.rangedSelect(this._visibleElements.length - 1,
this._visibleElements.length - 1, true);
}
},
/**

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

@ -165,7 +165,7 @@ interface nsINavBookmarkObserver : nsISupports
* folders. A URI in history can be contained in one or more such folders.
*/
[scriptable, uuid(617fe3a9-5c5b-4854-aae6-23a66ddf1c25)]
[scriptable, uuid(3b6ff5c5-0ab4-4aab-b1be-d569763a6ce0)]
interface nsINavBookmarksService : nsISupports
{
/**
@ -213,7 +213,7 @@ interface nsINavBookmarksService : nsISupports
* @param aURI
* The URI to insert
* @param aIndex
* The index to insert at, or -1 to append
* The index to insert at, or DEFAULT_INDEX to append
* @param aTitle
* The title for the new bookmark
* @returns The ID of the newly-created bookmark
@ -235,7 +235,7 @@ interface nsINavBookmarksService : nsISupports
* @param aName
* The name of the new folder
* @param aIndex
* The index to insert at, or -1 to append
* The index to insert at, or DEFAULT_INDEX to append
* @returns the ID of the newly-inserted folder
*/
long long createFolder(in long long aParentFolder, in AUTF8String name,
@ -252,7 +252,7 @@ interface nsINavBookmarksService : nsISupports
* The contract id of the service which is to manipulate this
* container.
* @param aIndex
* The index to insert at, or -1 to append
* The index to insert at, or DEFAULT_INDEX to append
*
* @returns the ID of the newly-inserted folder
*/
@ -299,7 +299,7 @@ interface nsINavBookmarksService : nsISupports
* @param aNewParent
* The id of the new parent
* @param aIndex
* The index under aNewParent, or -1 to append
* The index under aNewParent, or DEFAULT_INDEX to append
*/
void moveItem(in long long aFolder, in long long newParent, in long aIndex);
@ -320,7 +320,7 @@ interface nsINavBookmarksService : nsISupports
* @param aFolder
* Parent folder of the separator
* @param aIndex
* The separator's index under folder, or -1 to append
* The separator's index under folder, or DEFAULT_INDEX to append
* @returns the id of the new separator
*/
long long insertSeparator(in long long aFolder, in long aIndex);
@ -334,6 +334,17 @@ interface nsINavBookmarksService : nsISupports
*/
void removeChildAt(in long long aFolder, in long aIndex);
/**
* Get the itemId given the containing folder and the index.
* @param aFolder
* The direct parent folder of the item
* @param aIndex
* The index of the item within aFolder, DEFAULT_INDEX for the last item
* @returns the id of the found item
* @throws if the item does not exist
*/
long long getIdForItemAt(in long long aFolder, in long aIndex);
/**
* Get a globally unique identifier for an item, meant to be used in
* sync scenarios. Even if their contents are exactly the same

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

@ -1271,6 +1271,64 @@ nsNavBookmarks::InsertSeparator(PRInt64 aParent, PRInt32 aIndex,
return NS_OK;
}
nsresult
nsNavBookmarks::GetLastChildId(PRInt64 aFolder, PRInt64* aItemId)
{
mozIStorageConnection *dbConn = DBConn();
nsCOMPtr<mozIStorageStatement> statement;
nsresult rv = dbConn->CreateStatement(NS_LITERAL_CSTRING(
"SELECT id FROM moz_bookmarks WHERE parent = ?1 "
"ORDER BY position DESC LIMIT 1"), getter_AddRefs(statement));
NS_ENSURE_SUCCESS(rv, rv);
rv = statement->BindInt64Parameter(0, aFolder);
NS_ENSURE_SUCCESS(rv, rv);
PRBool hasMore;
rv = statement->ExecuteStep(&hasMore);
NS_ENSURE_SUCCESS(rv, rv);
if (!hasMore) {
// Item doesn't exist
return NS_ERROR_INVALID_ARG;
}
*aItemId = statement->AsInt64(0);
return NS_OK;
}
NS_IMETHODIMP
nsNavBookmarks::GetIdForItemAt(PRInt64 aFolder, PRInt32 aIndex, PRInt64* aItemId)
{
nsresult rv;
if (aIndex == nsINavBookmarksService::DEFAULT_INDEX) {
// we want the last item within aFolder
return GetLastChildId(aFolder, aItemId);
} else {
mozIStorageConnection *dbConn = DBConn();
{
// get the item in aFolder with position aIndex
mozStorageStatementScoper scope(mDBGetChildAt);
rv = mDBGetChildAt->BindInt64Parameter(0, aFolder);
NS_ENSURE_SUCCESS(rv, rv);
rv = mDBGetChildAt->BindInt32Parameter(1, aIndex);
NS_ENSURE_SUCCESS(rv, rv);
PRBool hasMore;
rv = mDBGetChildAt->ExecuteStep(&hasMore);
NS_ENSURE_SUCCESS(rv, rv);
if (!hasMore) {
// Item doesn't exist
return NS_ERROR_INVALID_ARG;
}
// actually found an item
*aItemId = mDBGetChildAt->AsInt64(0);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsNavBookmarks::RemoveChildAt(PRInt64 aParent, PRInt32 aIndex)
{

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

@ -122,6 +122,8 @@ private:
PRInt32 FolderCount(PRInt64 aFolder);
nsresult GetFolderType(PRInt64 aFolder, nsACString &aType);
nsresult GetLastChildId(PRInt64 aFolder, PRInt64* aItemId);
// remove me when there is better query initialization
nsNavHistory* History() { return nsNavHistory::GetHistoryService(); }

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

@ -292,6 +292,9 @@ function run_test() {
bmsvc.setItemTitle(newId6, "Google Sites");
do_check_eq(observer._itemChangedProperty, "title");
// test getIdForItemAt
do_check_eq(bmsvc.getIdForItemAt(testRoot, 0), workFolder);
// move folder, appending, to different folder
var oldParentCC = getChildCount(testRoot);
bmsvc.moveItem(workFolder, homeFolder, bmsvc.DEFAULT_INDEX);
@ -305,9 +308,16 @@ function run_test() {
do_check_eq(bmsvc.getItemIndex(workFolder), 1);
do_check_eq(bmsvc.getFolderIdForItem(workFolder), homeFolder);
// try to get index of the folder from it's ex-parent
// XXX expose getItemAtIndex(folder, idx) to test that the item was *removed* from the old parent?
// XXX or expose FolderCount, and check that the old parent has one less kids?
// try to get index of the item from within the old parent folder
// check that it has been really removed from there
do_check_neq(bmsvc.getIdForItemAt(testRoot, 0), workFolder);
// check the last item from within the old parent folder
do_check_neq(bmsvc.getIdForItemAt(testRoot, -1), workFolder);
// check the index of the item within the new parent folder
do_check_eq(bmsvc.getIdForItemAt(homeFolder, 1), workFolder);
// try to get index of the last item within the new parent folder
do_check_eq(bmsvc.getIdForItemAt(homeFolder, -1), workFolder);
// XXX expose FolderCount, and check that the old parent has one less child?
do_check_eq(getChildCount(testRoot), oldParentCC-1);
// XXX move folder, specified index, to different folder