зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
842a00613e
Коммит
c03bd4e43f
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче