Addresses #1146, Check for duplicate items functionality
Ben's duplicate detection code, with the integration reworked a bit Very rough, so currently requires creation of a boolean extensions.zotero.debugShowDuplicates pref to view the Actions menu option
This commit is contained in:
parent
18c1287dd5
commit
0746824c0f
5 changed files with 120 additions and 2 deletions
|
@ -225,6 +225,10 @@ var ZoteroPane = new function()
|
|||
sep.nextSibling.nextSibling.nextSibling.hidden = false;
|
||||
sep.nextSibling.nextSibling.nextSibling.nextSibling.hidden = false;
|
||||
}
|
||||
|
||||
if (Zotero.Prefs.get('debugShowDuplicates')) {
|
||||
document.getElementById('zotero-tb-actions-showDuplicates').hidden = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -796,6 +800,7 @@ var ZoteroPane = new function()
|
|||
var itemgroup = this.collectionsView._getItemAtRow(this.collectionsView.selection.currentIndex);
|
||||
itemgroup.setSearch('');
|
||||
itemgroup.setTags(getTagSelection());
|
||||
itemgroup.showDuplicates = false;
|
||||
|
||||
try {
|
||||
Zotero.UnresponsiveScriptIndicator.disable();
|
||||
|
@ -825,6 +830,23 @@ var ZoteroPane = new function()
|
|||
}
|
||||
|
||||
|
||||
|
||||
this.showDuplicates = function () {
|
||||
if (this.collectionsView.selection.count == 1 && this.collectionsView.selection.currentIndex != -1) {
|
||||
var itemGroup = this.collectionsView._getItemAtRow(this.collectionsView.selection.currentIndex);
|
||||
itemGroup.showDuplicates = true;
|
||||
|
||||
try {
|
||||
Zotero.UnresponsiveScriptIndicator.disable();
|
||||
this.itemsView.refresh();
|
||||
}
|
||||
finally {
|
||||
Zotero.UnresponsiveScriptIndicator.enable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function itemSelected()
|
||||
{
|
||||
if (!Zotero.stateCheck()) {
|
||||
|
@ -998,7 +1020,7 @@ var ZoteroPane = new function()
|
|||
if (this.itemsView._itemGroup.isCollection()) {
|
||||
var noPrompt = true;
|
||||
}
|
||||
// Do nothing in search view
|
||||
// Do nothing in search and share views
|
||||
else if (this.itemsView._itemGroup.isSearch() ||
|
||||
this.itemsView._itemGroup.isShare()) {
|
||||
return;
|
||||
|
|
|
@ -128,6 +128,8 @@
|
|||
label="Search for Shared Libraries" oncommand="Zotero.Zeroconf.findInstances()"/>
|
||||
<menuseparator id="zotero-tb-actions-plugins-separator"/>
|
||||
<menuitem id="zotero-tb-actions-timeline" label="&zotero.toolbar.timeline.label;" oncommand="Zotero_Timeline_Interface.loadTimeline()"/>
|
||||
<!-- TODO: localize <menuitem id="zotero-tb-actions-duplicate" label="&zotero.toolbar.duplicate.label;" oncommand="ZoteroPane.showDuplicates()"/>-->
|
||||
<menuitem id="zotero-tb-actions-showDuplicates" label="Show Duplicates" oncommand="ZoteroPane.showDuplicates()" hidden="true"/>
|
||||
<menuseparator id="zotero-tb-actions-sync-separator"/>
|
||||
<menuitem hidden="true" label="Sync Debugging" disabled="true"/>
|
||||
<menuitem hidden="true" label=" Clear Server Data" oncommand="Zotero.Sync.Server.clear()"/>
|
||||
|
|
|
@ -37,6 +37,7 @@ Zotero.CollectionTreeView = function()
|
|||
this.itemToSelect = null;
|
||||
this._highlightedRows = {};
|
||||
this._unregisterID = Zotero.Notifier.registerObserver(this, ['collection', 'search', 'share']);
|
||||
this.showDuplicates = false;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1095,7 +1096,16 @@ Zotero.ItemGroup.prototype.getChildItems = function()
|
|||
|
||||
var s = this.getSearchObject();
|
||||
try {
|
||||
var ids = s.search();
|
||||
var ids;
|
||||
if (this.showDuplicates) {
|
||||
var duplicates = new Zotero.Duplicate;
|
||||
var tmpTable = s.search(true);
|
||||
ids = duplicates.getIDs(tmpTable);
|
||||
Zotero.DB.query("DROP TABLE " + tmpTable);
|
||||
}
|
||||
else {
|
||||
ids = s.search();
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
Zotero.DB.rollbackAllTransactions();
|
||||
|
|
83
chrome/content/zotero/xpcom/duplicate.js
Normal file
83
chrome/content/zotero/xpcom/duplicate.js
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
***** BEGIN LICENSE BLOCK *****
|
||||
|
||||
Copyright (c) 2006 Center for History and New Media
|
||||
George Mason University, Fairfax, Virginia, USA
|
||||
http://chnm.gmu.edu
|
||||
|
||||
Licensed under the Educational Community License, Version 1.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.opensource.org/licenses/ecl1.php
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
***** END LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
Zotero.Duplicate = function(duplicateID) {
|
||||
this._id = duplicateID ? duplicateID : null;
|
||||
this._itemIDs = [];
|
||||
}
|
||||
|
||||
Zotero.Duplicate.prototype.__defineGetter__('id', function () { return this._id; });
|
||||
|
||||
Zotero.Duplicate.prototype.getIDs = function(idsTable) {
|
||||
if (!idsTable) {
|
||||
return;
|
||||
}
|
||||
|
||||
var minLen = 5, percentLen = 1./3, checkLen, i, j;
|
||||
|
||||
var sql = "SELECT itemID, value AS val "
|
||||
+ "FROM " + idsTable + " NATURAL JOIN itemData "
|
||||
+ "NATURAL JOIN itemDataValues "
|
||||
+ "WHERE fieldID BETWEEN 110 AND 113 AND "
|
||||
+ "itemID NOT IN (SELECT itemID FROM itemAttachments) "
|
||||
+ "ORDER BY val";
|
||||
|
||||
var results = Zotero.DB.query(sql);
|
||||
|
||||
var resultsLen = results.length;
|
||||
this._itemIDs = [];
|
||||
|
||||
for (i = 0; i < resultsLen; i++) {
|
||||
results[i].len = results[i].val.length;
|
||||
}
|
||||
|
||||
for (i = 0; i < resultsLen; i++) {
|
||||
// title must be at least minLen long to be a duplicate
|
||||
if (results[i].len < minLen) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (j = i + 1; j < resultsLen; j++) {
|
||||
// duplicates must match the first checkLen characters
|
||||
// checkLen = percentLen * the length of the longer title
|
||||
checkLen = (results[i].len >= results[j].len) ?
|
||||
parseInt(percentLen * results[i].len) : parseInt(percentLen * results[j].len);
|
||||
checkLen = (checkLen > results[i].len) ? results[i].len : checkLen;
|
||||
checkLen = (checkLen > results[j].len) ? results[j].len : checkLen;
|
||||
checkLen = (checkLen < minLen) ? minLen : checkLen;
|
||||
|
||||
if (results[i].val.substr(0, checkLen) == results[j].val.substr(0, checkLen)) {
|
||||
// include results[i] when a duplicate is first found
|
||||
if (j == i + 1) {
|
||||
this._itemIDs.push(results[i].itemID);
|
||||
}
|
||||
this._itemIDs.push(results[j].itemID);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
i = j - 1;
|
||||
}
|
||||
|
||||
return this._itemIDs;
|
||||
}
|
|
@ -67,6 +67,7 @@
|
|||
<!ENTITY zotero.toolbar.import.label "Import...">
|
||||
<!ENTITY zotero.toolbar.export.label "Export Library...">
|
||||
<!ENTITY zotero.toolbar.timeline.label "Create Timeline">
|
||||
<!ENTITY zotero.toolbar.duplicate.label "Show Duplicates">
|
||||
<!ENTITY zotero.toolbar.preferences.label "Preferences...">
|
||||
<!ENTITY zotero.toolbar.documentation.label "Documentation">
|
||||
<!ENTITY zotero.toolbar.about.label "About Zotero">
|
||||
|
|
Loading…
Reference in a new issue