315940 - more D&D fixes. makes sure the right elements are selected post drop, fix js errors and save selection. NPOB

This commit is contained in:
beng%bengoodger.com 2005-12-01 23:58:02 +00:00
Родитель 571c2d267c
Коммит 17846e8ef2
3 изменённых файлов: 153 добавлений и 62 удалений

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

@ -87,13 +87,33 @@ function STACK(args) {
* The folderId of the parent container
* @param index
* The index within the container where we should insert
* @param orientation
* The orientation of the insertion. NOTE: the adjustments to the
* insertion point to accommodate the orientation should be done by
* the person who constructs the IP, not the user. The orientation
* is provided for informational purposes only!
* @constructor
*/
function InsertionPoint(folderId, index) {
function InsertionPoint(folderId, index, orientation) {
this.folderId = folderId;
this.index = index;
this.orientation = orientation;
}
/**
* Initialization Configuration for a View
*/
function ViewConfig(dropTypes, dropOnTypes, filterOptions, firstDropIndex) {
this.dropTypes = dropTypes;
this.dropOnTypes = dropOnTypes;
this.filterOptions = filterOptions;
this.firstDropIndex = firstDropIndex;
}
ViewConfig.GENERIC_DROP_TYPES = [TYPE_X_MOZ_PLACE_CONTAINER, TYPE_X_MOZ_PLACE,
TYPE_X_MOZ_URL];
ViewConfig.GENERIC_FILTER_OPTIONS = Ci.nsINavHistoryQuery.INCLUDE_ITEMS +
Ci.nsINavHistoryQuery.INCLUDE_QUERIES;
/**
* The Master Places Controller
*/
@ -123,6 +143,45 @@ var PlacesController = {
}
return this.__hist;
},
/**
* Generates a HistoryResult for the contents of a folder.
* @param folderId
* The folder to open
* @param filterOptions
* Options regarding the type of items to be returned. See
* documentation in nsINavHistoryQuery for the |itemTypes| property.
* @returns A HistoryResult containing the contents of the folder.
*/
getFolderContents: function PC_getFolderContents(folderId, filterOptions) {
var query = this._hist.getNewQuery();
query.setFolders([folderId], 1);
query.itemTypes = filterOptions;
var options = this._hist.getNewQueryOptions();
options.setGroupingMode([Ci.nsINavHistoryQueryOptions.GROUP_BY_FOLDER], 1);
return this._hist.executeQuery(query, options);
},
/**
* Get the pivot node for a given insertion point in a container populated
* with the specified filter options.
* @param insertionPoint
* The point at which content is to be inserted
* @param filterOptions
* Filter options for the view/container. See documentation in
* nsINavHistoryQuery for the |itemTypes| property.
* @returns A HistoryResultNode at which content is to be inserted.
*/
getInsertionNode:
function PC_getInsertionNode(insertionPoint, filterOptions) {
var result = this.getFolderContents(insertionPoint.folderId, filterOptions);
var index = insertionPoint.index - 1;
if (insertionPoint.index == 0)
index = 0;
else if (insertionPoint.index == -1)
index = result.childCount - 1;
return index > -1 ? result.getChild(index) : null;
},
_activeView: null,
get activeView() {
@ -221,8 +280,6 @@ var PlacesController = {
* @returns true if the node is a Bookmark folder, false otherwise
*/
nodeIsFolder: function PC_nodeIsFolder(node) {
if (!node)
STACK(arguments);
return (node.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY &&
node.folderId > 0);
},
@ -1009,18 +1066,18 @@ var PlacesControllerDragHelper = {
* The AVI-implementing object that received the drop.
* @param insertionPoint
* The insertion point where the items should be dropped
* @param orientation
* The orientation of the drop
* @param visibleInsertCount
* The number of visible items to be inserted. This can be zero
* even when items are dropped because this is how many items will
* be _visible_ in the resulting tree.
*/
onDrop: function PCDH_onDrop(sourceView, targetView, insertionPoint,
orientation) {
visibleInsertCount) {
var session = this._getSession();
if (!session)
return;
var copy = session.dragAction & Ci.nsIDragService.DRAGDROP_ACTION_COPY;
var transactions = [];
var xferable = this._initTransferable(targetView, orientation);
var xferable = this._initTransferable(targetView,
insertionPoint.orientation);
var dropCount = session.numDropItems;
for (var i = 0; i < dropCount; ++i) {
session.getData(xferable, i);
@ -1048,8 +1105,9 @@ var PlacesControllerDragHelper = {
if (sourceView)
sourceView.willReloadView(RELOAD_ACTION_REMOVE, sourceView, null,
dropCount);
PlacesController.willReloadView(RELOAD_ACTION_INSERT, targetView,
insertionPoint, dropCount);
var action = visibleInsertCount == 0 ? RELOAD_ACTION_NOTHING
: RELOAD_ACTION_INSERT;
targetView.willReloadView(action, targetView, insertionPoint, dropCount);
}
var txn = new PlacesAggregateTransaction("DropItems", transactions);
PlacesController._hist.transactionManager.doTransaction(txn);

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

@ -94,6 +94,17 @@ var PlacesUIHook = {
},
};
function ViewConfig(dropTypes, dropOnTypes, filterOptions, firstDropIndex) {
this.dropTypes = dropTypes;
this.dropOnTypes = dropOnTypes;
this.filterOptions = filterOptions;
this.firstDropIndex = firstDropIndex;
}
ViewConfig.GENERIC_DROP_TYPES = [TYPE_X_MOZ_PLACE_CONTAINER, TYPE_X_MOZ_PLACE,
TYPE_X_MOZ_URL];
ViewConfig.GENERIC_FILTER_OPTIONS = [Ci.nsINavHistoryQuery.INCLUDE_ITEMS +
Ci.nsINavHistoryQuery.INCLUDE_QUERIES];
var PlacesPage = {
_content: null,
_places: null,
@ -105,17 +116,13 @@ var PlacesPage = {
this._places.controllers.appendController(PlacesController);
this._content.controllers.appendController(PlacesController);
this._places.supportedDropTypes = [TYPE_X_MOZ_PLACE_CONTAINER];
this._places.supportedDropOnTypes = [TYPE_X_MOZ_PLACE_CONTAINER,
TYPE_X_MOZ_PLACE, TYPE_X_MOZ_URL];
this._content.supportedDropTypes = [TYPE_X_MOZ_PLACE_CONTAINER,
TYPE_X_MOZ_PLACE, TYPE_X_MOZ_URL];
this._content.supportedDropOnTypes = this._content.supportedDropTypes;
this._places.filterOptions = [Ci.nsINavHistoryQuery.INCLUDE_QUERIES];
this._content.filterOptions = [Ci.nsINavHistoryQuery.INCLUDE_ITEMS +
Ci.nsINavHistoryQuery.INCLUDE_QUERIES];
this._places.firstDropIndex = 2;
this._content.firstDropIndex = 0;
this._places.init(new ViewConfig([TYPE_X_MOZ_PLACE_CONTAINER],
ViewConfig.GENERIC_DROP_TYPES,
Ci.nsINavHistoryQuery.INCLUDE_QUERIES,
ViewConfig.GENERIC_FILTER_OPTIONS, 2));
this._content.init(new ViewConfig(ViewConfig.GENERIC_DROP_TYPES,
ViewConfig.GENERIC_DROP_TYPES,
ViewConfig.GENERIC_FILTER_OPTIONS, 0));
// Hook the browser UI
PlacesUIHook.init(this._content);

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

@ -38,6 +38,16 @@
PlacesController.removeViewObserver(this);
]]></destructor>
<method name="init">
<parameter name="viewConfig"/>
<body><![CDATA[
this.supportedDropTypes = viewConfig.dropTypes;
this.supportedDropOnTypes = viewConfig.dropOnTypes;
this.filterOptions = viewConfig.filterOptions;
this.firstDropIndex = viewConfig.firstDropIndex;
]]></body>
</method>
<method name="_fireEvent">
<parameter name="name"/>
<body><![CDATA[
@ -202,14 +212,8 @@
var min = { }, max = { };
selection.getRangeAt(i, min, max);
try {
for (var j = min.value; j <= max.value; ++j)
nodes.push(result.nodeForTreeIndex(j));
}
catch (e) {
LOG("j = " + j + ", max.value = " + max.value);
STACK(arguments);
}
}
return nodes;
]]></body>
@ -265,7 +269,13 @@
var min = { }, max = { };
selection.getRangeAt(rc - 1, min, max);
return this._getInsertionPoint(max.value, 1);
const DROP_AFTER = Ci.nsINavHistoryResultViewObserver.DROP_AFTER;
const DROP_ON = Ci.nsINavHistoryResultViewObserver.DROP_ON;
var orientation = DROP_AFTER;
if (this.view.isContainer(max.value) &&
this.view.isContainerOpen(max.value))
orientation = DROP_ON;
return this._getInsertionPoint(max.value, 1, orientation);
]]></getter>
</property>
@ -299,7 +309,7 @@
index = orientation == NHRVO.DROP_BEFORE ? lsi - 1 : lsi;
}
}
return new InsertionPoint(container.folderId, index);
return new InsertionPoint(container.folderId, index, orientation);
]]></body>
</method>
@ -307,7 +317,7 @@
<property name="browserWindow" onget="return this._browserWindow"/>
<!-- AVI Method -->
<field name="firstDropIndex">null</field>
<field name="firstDropIndex">0</field>
<!-- AVI Method -->
<field name="supportedDropTypes">null</field>
@ -315,6 +325,12 @@
<!-- AVI Method -->
<field name="supportedDropOnTypes">null</field>
<!-- AVI Method -->
<field name="filterOptions">null</field>
<!-- AVI Method -->
<field name="dropOnFilterOptions">null</field>
<!-- AVI Method -->
<method name="selectAll">
<body><![CDATA[
@ -373,12 +389,21 @@
while (sourceView && sourceView.localName != "tree")
sourceView = sourceView.parentNode;
// Determine how many items will be visible in the target view after
// the drop operation completes. This can be zero if all items are
// dropped into a closed folder.
var visibleInsertCount = session.numDropItems;
if (orientation == Ci.nsINavHistoryResultViewObserver.DROP_ON &&
this._self.view.isContainer(index) &&
!this._self.view.isContainerOpen(index))
visibleInsertCount = 0;
// We are responsible for translating the |index| and |orientation|
// parameters into a container id and index within the container,
// since this information is specific to the tree view.
var ip = this._self._getInsertionPoint(index, orientation);
PlacesControllerDragHelper.onDrop(sourceView, this._self, ip,
orientation);
visibleInsertCount);
},
_states: { },
@ -470,6 +495,7 @@
if (view != this)
action = RELOAD_ACTION_NOTHING;
const NHRVO = Ci.nsINavHistoryResultViewObserver;
switch (action) {
case RELOAD_ACTION_NOTHING:
for (var i = 0; i < rc; ++i) {
@ -479,42 +505,42 @@
}
break;
case RELOAD_ACTION_MOVE:
// Drop before selection A
// Drop in selection B
// Drop after selection C
//
// Drop Point: Index Computation:
// Before Selection index
// Inside Selection
// After Selection index
// Insert index of insertion and number of rows to insert
var query = this._places.getNewQuery();
query.setFolders([insertionPoint.folderId], 1);
query.itemTypes = this.filterOptions;
var options = this._places.getNewQueryOptions();
options.setGroupingMode([Ci.nsINavHistoryQueryOptions.GROUP_BY_FOLDER], 1);
var result = this._places.executeQuery(query, options);
if (insertionPoint.index > -1) {
var node = result.getChild(insertionPoint.index - 1);
var index = this.getResult().treeIndexForNode(node);
if (insertionPoint.index == result.childCount)
++index;
}
else
index = this.getResult().childCount;
var filterOptions = this.filterOptions;
if (insertionPoint.orientation == NHRVO.DROP_ON)
filterOptions = ViewConfig.GENERIC_FILTER_OPTIONS;
var result = PlacesController.getFolderContents(insertionPoint.folderId,
filterOptions);
var node = null;
if (insertionPoint.index > -1)
node = result.getChild(insertionPoint.index - 1);
else
node = result.getChild(result.childCount - 1);
var index = this.getResult().treeIndexForNode(node);
var max = index + count - 1;
this._selection = [{ min: index, max: max }];
break;
case RELOAD_ACTION_INSERT:
// Insert index of insertion and number of rows to insert
var query = this._places.getNewQuery();
query.setFolders([insertionPoint.folderId], 1);
query.itemTypes = this.filterOptions;
var options = this._places.getNewQueryOptions();
options.setGroupingMode([Ci.nsINavHistoryQueryOptions.GROUP_BY_FOLDER], 1);
var result = this._places.executeQuery(query, options);
if (insertionPoint.index > -1) {
var node = result.getChild(insertionPoint.index - 1);
var index = this.getResult().treeIndexForNode(node);
if (insertionPoint.index == result.childCount)
++index;
}
var filterOptions = this.filterOptions;
if (insertionPoint.orientation == NHRVO.DROP_ON)
filterOptions = ViewConfig.GENERIC_FILTER_OPTIONS;
var node = PlacesController.getInsertionNode(insertionPoint,
filterOptions);
var index = this.getResult().treeIndexForNode(node);
if (insertionPoint.index == 0)
this._selection = [{ min: index, max: index + count - 1 }];
else
index = this.getResult().childCount;
var max = index + count - 1;
this._selection = [{ min: index, max: max }];
this._selection = [{ min: index + 1, max: index + count }];
break;
case RELOAD_ACTION_REMOVE:
min = { }, max = { };