commit 4625b7081e11afae6c55b76cc0d933e2b593905d
parent 21ad09112ccede98b46147dc8e485063f85cfb2d
Author: Dan Stillman <dstillman@zotero.org>
Date: Thu, 26 Mar 2015 18:53:56 -0400
Add checkbox to use one side for all remaining conflicts
This should be rewritten in a way that allows it to be unit tested, but
it seems to work.
Diffstat:
5 files changed, 129 insertions(+), 49 deletions(-)
diff --git a/chrome/content/zotero/bindings/merge.xml b/chrome/content/zotero/bindings/merge.xml
@@ -124,6 +124,8 @@
<property name="rightpane" onget="return this._rightpane"/>
<property name="mergepane" onget="return this._mergepane"/>
+ <property name="onSelectionChange"/>
+
<field name="_leftpane"/>
<field name="_rightpane"/>
<field name="_mergepane"/>
@@ -397,6 +399,10 @@
else {
mergepane.ref = pane.original;
}
+
+ if (mergegroup.onSelectionChange) {
+ mergegroup.onSelectionChange();
+ }
]]>
</body>
</method>
diff --git a/chrome/content/zotero/merge.js b/chrome/content/zotero/merge.js
@@ -62,6 +62,7 @@ var Zotero_Merge_Window = new function () {
}
_mergeGroup.type = _io.dataIn.type;
+ _mergeGroup.onSelectionChange = _updateResolveAllCheckbox;
switch (_mergeGroup.type) {
case 'item':
@@ -78,6 +79,8 @@ var Zotero_Merge_Window = new function () {
_mergeGroup.rightCaption = _io.dataIn.captions[1];
_mergeGroup.mergeCaption = _io.dataIn.captions[2];
+ _resolveAllCheckbox = document.getElementById('resolve-all');
+
_numObjects = document.getElementById('zotero-merge-num-objects');
document.getElementById('zotero-merge-total-objects').value = _objects.length;
@@ -101,8 +104,15 @@ var Zotero_Merge_Window = new function () {
// Restore previously merged object into merge pane
_mergeGroup.merge = _merged[_pos].ref;
- _mergeGroup.leftpane.removeAttribute("selected");
- _mergeGroup.rightpane.removeAttribute("selected");
+ if (_merged[_pos].id == _mergeGroup.left.id) {
+ _mergeGroup.leftpane.setAttribute("selected", "true");
+ _mergeGroup.rightpane.removeAttribute("selected");
+ }
+ else {
+ _mergeGroup.leftpane.removeAttribute("selected");
+ _mergeGroup.rightpane.setAttribute("selected", "true");
+ }
+ _updateResolveAllCheckbox();
if (_mergeGroup.type == 'item') {
_updateChangedCreators();
@@ -125,7 +135,7 @@ var Zotero_Merge_Window = new function () {
function onNext() {
- if (_pos + 1 == _objects.length) {
+ if (_pos + 1 == _objects.length || _resolveAllCheckbox.checked) {
return true;
}
@@ -160,43 +170,17 @@ var Zotero_Merge_Window = new function () {
return;
}
+ _updateResolveAllCheckbox();
+
if (_mergeGroup.type == 'item') {
_updateChangedCreators();
}
- // On Windows the buttons don't move when one is hidden
- if ((_pos + 1) != _objects.length) {
- var nextButton = _wizard.getButton("next");
-
- if (Zotero.isMac) {
- nextButton.setAttribute("hidden", "false");
- _wizard.getButton("finish").setAttribute("hidden", "true");
- }
- else {
- var buttons = document.getAnonymousElementByAttribute(_wizard, "anonid", "Buttons");
- var deck = document.getAnonymousElementByAttribute(buttons, "anonid", "WizardButtonDeck");
- deck.selectedIndex = 1;
- }
-
- _setInstructionsString(nextButton.label);
+ if (_isLastConflict()) {
+ _showFinishButton();
}
- // Last object
else {
- var finishButton = _wizard.getButton("finish");
-
- if (Zotero.isMac) {
- _wizard.getButton("next").setAttribute("hidden", "true");
- finishButton.setAttribute("hidden", "false");
- }
- // Windows uses a deck to switch between the Next and Finish buttons
- // TODO: check Linux
- else {
- var buttons = document.getAnonymousElementByAttribute(_wizard, "anonid", "Buttons");
- var deck = document.getAnonymousElementByAttribute(buttons, "anonid", "WizardButtonDeck");
- deck.selectedIndex = 0;
- }
-
- _setInstructionsString(finishButton.label);
+ _showNextButton();
}
return false;
@@ -204,7 +188,20 @@ var Zotero_Merge_Window = new function () {
function onFinish() {
- _merged[_pos] = _getCurrentMergeObject();
+ // If using one side for all remaining, update merge object
+ if (!_isLastConflict() && _resolveAllCheckbox.checked) {
+ let useRemote = _mergeGroup.rightpane.getAttribute("selected") == "true";
+ for (let i = _pos; i < _objects.length; i++) {
+ _merged[i] = _getMergeObject(
+ _objects[i][useRemote ? 1 : 0],
+ _objects[i][0],
+ _objects[i][1]
+ );
+ }
+ }
+ else {
+ _merged[_pos] = _getCurrentMergeObject();
+ }
_io.dataOut = _merged;
return true;
@@ -216,21 +213,86 @@ var Zotero_Merge_Window = new function () {
}
- function _getCurrentMergeObject() {
- var id = _mergeGroup.merge == 'deleted' ?
- (_mergeGroup.left == 'deleted'
- ? _mergeGroup.right.id : _mergeGroup.left.id)
- : _mergeGroup.merge.id;
+ this.onResolveAllChange = function (resolveAll) {
+ if (resolveAll || _isLastConflict()) {
+ _showFinishButton();
+ }
+ else {
+ _showNextButton();
+ }
+ }
+
+ function _updateResolveAllCheckbox() {
+ if (_mergeGroup.rightpane.getAttribute("selected") == 'true') {
+ var label = 'sync.merge.resolveAllRemote';
+ }
+ else {
+ var label = 'sync.merge.resolveAllLocal';
+ }
+ _resolveAllCheckbox.label = Zotero.getString(label);
+ }
+
+
+ function _isLastConflict() {
+ return (_pos + 1) == _objects.length;
+ }
+
+
+ function _showNextButton() {
+ var nextButton = _wizard.getButton("next");
+
+ if (Zotero.isMac) {
+ nextButton.setAttribute("hidden", "false");
+ _wizard.getButton("finish").setAttribute("hidden", "true");
+ }
+ else {
+ var buttons = document.getAnonymousElementByAttribute(_wizard, "anonid", "Buttons");
+ var deck = document.getAnonymousElementByAttribute(buttons, "anonid", "WizardButtonDeck");
+ deck.selectedIndex = 1;
+ }
+
+ _setInstructionsString(nextButton.label);
+ }
+
+
+ function _showFinishButton() {
+ var finishButton = _wizard.getButton("finish");
+
+ if (Zotero.isMac) {
+ _wizard.getButton("next").setAttribute("hidden", "true");
+ finishButton.setAttribute("hidden", "false");
+ }
+ // Windows uses a deck to switch between the Next and Finish buttons
+ // TODO: check Linux
+ else {
+ var buttons = document.getAnonymousElementByAttribute(_wizard, "anonid", "Buttons");
+ var deck = document.getAnonymousElementByAttribute(buttons, "anonid", "WizardButtonDeck");
+ deck.selectedIndex = 0;
+ }
+
+ _setInstructionsString(finishButton.label);
+ }
+
+
+ function _getMergeObject(ref, left, right) {
+ var id = ref == 'deleted'
+ ? (left == 'deleted' ? right.id : left.id)
+ : ref.id;
return {
id: id,
- ref: _mergeGroup.merge,
- left: _mergeGroup.left,
- right: _mergeGroup.right
+ ref: ref,
+ left: left,
+ right: right
};
}
+ function _getCurrentMergeObject() {
+ return _getMergeObject(_mergeGroup.merge, _mergeGroup.left, _mergeGroup.right);
+ }
+
+
// Hack to support creator reconciliation via item view
function _updateChangedCreators() {
if (_mergeGroup.type != 'item') {
diff --git a/chrome/content/zotero/merge.xul b/chrome/content/zotero/merge.xul
@@ -48,10 +48,18 @@
<description id="zotero-merge-instructions"/>
<zoteromergegroup flex="1"/>
<separator class="thin"/>
- <hbox id="zotero-step-count">
- <label id="zotero-merge-num-objects"/>
- <label value="&zotero.merge.of;"/>
- <label id="zotero-merge-total-objects"/>
+ <hbox align="center">
+ <separator orient="vertical" flex="1"/>
+ <hbox>
+ <checkbox id="resolve-all"
+ oncommand="Zotero_Merge_Window.onResolveAllChange(this.checked)"/>
+ </hbox>
+ <separator orient="vertical"/>
+ <hbox id="zotero-step-count">
+ <label id="zotero-merge-num-objects"/>
+ <label value="&zotero.merge.of;"/>
+ <label id="zotero-merge-total-objects"/>
+ </hbox>
</hbox>
</wizardpage>
</wizard>
diff --git a/chrome/locale/en-US/zotero/zotero.properties b/chrome/locale/en-US/zotero/zotero.properties
@@ -770,6 +770,9 @@ sync.removeGroupsAndSync = Remove Groups and Sync
sync.localObject = Local Object
sync.remoteObject = Remote Object
sync.mergedObject = Merged Object
+sync.merge.resolveAllLocal = Use the local version for all remaining conflicts
+sync.merge.resolveAllRemote = Use the remote version for all remaining conflicts
+
sync.error.usernameNotSet = Username not set
sync.error.usernameNotSet.text = You must enter your zotero.org username and password in the Zotero preferences to sync with the Zotero server.
diff --git a/chrome/skin/default/zotero/merge.css b/chrome/skin/default/zotero/merge.css
@@ -40,8 +40,9 @@ wizard > deck {
padding: 0;
}
-#zotero-step-count {
- -moz-box-pack: end;
+
+#resolve-all {
+ font-size: 1.1em;
}
#zotero-step-count label:first-child {