- Adds file conflict resolution -- not particularly attractive at the moment, and no Apply to All button, but possibly functional
- Fixes file syncing after editing a file locally - Fixes a few storage bugs that could result in eternal spinning, invalid percentages, and other unpleasantries - Made the attachment display box more flexible, including a filename field that we may or may not want to keep in the main view
This commit is contained in:
parent
a1277ccaa9
commit
bd070f7b63
6 changed files with 396 additions and 55 deletions
|
@ -41,6 +41,7 @@
|
|||
<field name="displayGoButtons">false</field>
|
||||
<field name="clickableLink">false</field>
|
||||
<field name="displayButton">false</field>
|
||||
<field name="displayNote">false</field>
|
||||
|
||||
<field name="buttonCaption"/>
|
||||
<field name="clickHandler"/>
|
||||
|
@ -52,31 +53,52 @@
|
|||
<![CDATA[
|
||||
this.editable = false;
|
||||
this.displayGoButtons = false;
|
||||
this.displayURL = false;
|
||||
this.displayFileName = false;
|
||||
this.clickableLink = false;
|
||||
this.displayIndexed = false;
|
||||
this.displayAccessed = false;
|
||||
this.displayPages = false;
|
||||
this.displayDateModified = false;
|
||||
this.displayIndexed = false;
|
||||
this.displayNote = false;
|
||||
|
||||
switch (val) {
|
||||
case 'view':
|
||||
this.displayGoButtons = true;
|
||||
this.displayURL = true;
|
||||
this.displayFileName = true;
|
||||
this.clickableLink = true;
|
||||
this.displayIndexed = true;
|
||||
this.displayAccessed = true;
|
||||
this.displayPages = true;
|
||||
this.displayIndexed = true;
|
||||
this.displayNote = true;
|
||||
break;
|
||||
|
||||
case 'edit':
|
||||
this.editable = true;
|
||||
this.displayGoButtons = true;
|
||||
this.displayURL = true;
|
||||
this.displayFileName = true;
|
||||
this.clickableLink = true;
|
||||
this.displayIndexed = true;
|
||||
this.displayAccessed = true;
|
||||
this.displayPages = true;
|
||||
this.displayIndexed = true;
|
||||
this.displayNote = true;
|
||||
break;
|
||||
|
||||
case 'merge':
|
||||
this.displayURL = true;
|
||||
this.displayFileName = true;
|
||||
this.displayAccessed = true;
|
||||
this.displayNote = true;
|
||||
this.displayButton = true;
|
||||
break;
|
||||
|
||||
case 'mergeedit':
|
||||
this.displayURL = true;
|
||||
this.displayFileName = true;
|
||||
this.displayAccessed = true;
|
||||
this.displayNote = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -114,9 +136,11 @@
|
|||
var goButtons = this._id('go-buttons');
|
||||
var viewButton = this._id('view');
|
||||
var showButton = this._id('show');
|
||||
var fileNameRow = this._id('fileNameRow');
|
||||
var urlField = this._id('url');
|
||||
var accessed = this._id('accessed');
|
||||
var pagesRow = this._id('pages');
|
||||
var dateModifiedRow = this._id('dateModified');
|
||||
var indexBox = this._id('index-box');
|
||||
var selectButton = this._id('select-button');
|
||||
|
||||
|
@ -180,9 +204,10 @@
|
|||
var str = Zotero.getString('pane.item.attachments.view.link');
|
||||
}
|
||||
|
||||
showButton.setAttribute('hidden', !isImportedURL);
|
||||
showButton.hidden = !isImportedURL;
|
||||
|
||||
// URL
|
||||
if (this.displayURL) {
|
||||
var urlSpec = this.item.getField('url');
|
||||
urlField.setAttribute('value', urlSpec);
|
||||
urlField.setAttribute('hidden', false);
|
||||
|
@ -195,21 +220,58 @@
|
|||
else {
|
||||
urlField.className = '';
|
||||
}
|
||||
urlField.hidden = false;
|
||||
}
|
||||
else {
|
||||
urlField.hidden = true;
|
||||
}
|
||||
|
||||
// Access date
|
||||
accessed.setAttribute('value',
|
||||
Zotero.getString('itemFields.accessDate') + ': '
|
||||
+ Zotero.Date.sqlToDate(this.item.getField('accessDate'), true).toLocaleString());
|
||||
accessed.setAttribute('hidden', false);
|
||||
if (this.displayAccessed) {
|
||||
accessed.value = Zotero.localeJoin([
|
||||
Zotero.getString('itemFields.accessDate'),
|
||||
': ',
|
||||
Zotero.Date.sqlToDate(
|
||||
this.item.getField('accessDate'), true
|
||||
).toLocaleString()
|
||||
], '');
|
||||
accessed.hidden = false;
|
||||
}
|
||||
else {
|
||||
accessed.hidden = true;
|
||||
}
|
||||
}
|
||||
// Metadata for files
|
||||
else {
|
||||
var str = Zotero.getString('pane.item.attachments.view.file');
|
||||
showButton.setAttribute('hidden', false);
|
||||
urlField.setAttribute('hidden', true);
|
||||
accessed.setAttribute('hidden', true);
|
||||
showButton.hidden = false;
|
||||
urlField.hidden = true;
|
||||
accessed.hidden = true;
|
||||
}
|
||||
|
||||
if (this.item.attachmentLinkMode
|
||||
!= Zotero.Attachments.LINK_MODE_LINKED_URL
|
||||
&& this.displayFileName) {
|
||||
// TODO: localize
|
||||
var file = this.item.getFile(false, true);
|
||||
var fileName = file.leafName;
|
||||
if (fileName) {
|
||||
fileNameRow.value = Zotero.localeJoin([
|
||||
'Filename', // TODO: localize
|
||||
': ', // TODO: probably needs to be in localized string
|
||||
fileName
|
||||
], '');
|
||||
fileNameRow.hidden = false;
|
||||
}
|
||||
else {
|
||||
fileNameRow.hidden = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
fileNameRow.hidden = true;
|
||||
}
|
||||
|
||||
|
||||
viewButton.setAttribute('label', str);
|
||||
|
||||
// Page count
|
||||
|
@ -217,16 +279,35 @@
|
|||
var pages = Zotero.Fulltext.getPages(this.item.id);
|
||||
var pages = pages ? pages.total : null;
|
||||
if (pages) {
|
||||
var str = Zotero.getString('itemFields.pages') + ': ' + pages;
|
||||
pagesRow.setAttribute('value', str);
|
||||
pagesRow.setAttribute('hidden', false);
|
||||
var str = Zotero.localeJoin([
|
||||
Zotero.getString('itemFields.pages'),
|
||||
': ',
|
||||
pages
|
||||
], '');
|
||||
pagesRow.value = str;
|
||||
pagesRow.hidden = false;
|
||||
}
|
||||
else {
|
||||
pagesRow.setAttribute('hidden', true);
|
||||
pagesRow.hidden = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
pagesRow.setAttribute('hidden', true);
|
||||
pagesRow.hidden = true;
|
||||
}
|
||||
|
||||
if (this.displayDateModified) {
|
||||
var str = Zotero.localeJoin([
|
||||
Zotero.getString('itemFields.dateModified'),
|
||||
': ',
|
||||
Zotero.Date.sqlToDate(
|
||||
this.item.getField('dateModified'), true
|
||||
).toLocaleString()
|
||||
], '');
|
||||
dateModifiedRow.value = str;
|
||||
dateModifiedRow.hidden = false;
|
||||
}
|
||||
else {
|
||||
dateModifiedRow.hidden = true;
|
||||
}
|
||||
|
||||
// Full-text index information
|
||||
|
@ -240,6 +321,9 @@
|
|||
|
||||
// Note editor
|
||||
var noteEditor = this._id('note-editor');
|
||||
if (this.displayNote) {
|
||||
noteEditor.hidden = false;
|
||||
|
||||
// Don't make note editable (at least for now)
|
||||
if (this.mode == 'merge' || this.mode == 'mergeedit') {
|
||||
noteEditor.mode = 'merge';
|
||||
|
@ -250,6 +334,11 @@
|
|||
}
|
||||
noteEditor.parent = null;
|
||||
noteEditor.item = this.item;
|
||||
}
|
||||
else {
|
||||
noteEditor.hidden = true;
|
||||
}
|
||||
|
||||
|
||||
if (this.displayButton) {
|
||||
selectButton.label = this.buttonCaption;
|
||||
|
@ -412,9 +501,10 @@
|
|||
<button id="show" label="&zotero.item.attachment.file.show;" flex="1"/>
|
||||
</hbox>
|
||||
<label id="url" crop="end"/>
|
||||
|
||||
<label id="fileNameRow"/>
|
||||
<label id="accessed"/>
|
||||
<label id="pages"/>
|
||||
<label id="dateModified"/>
|
||||
|
||||
<hbox id="index-box">
|
||||
<label id="index-status"/>
|
||||
|
|
|
@ -134,6 +134,7 @@
|
|||
|
||||
if (this._leftpane.ref != 'deleted'
|
||||
&& this._rightpane.ref != 'deleted') {
|
||||
|
||||
var dm1 = this._leftpane.ref.getField('dateModified');
|
||||
if (dm1) {
|
||||
dm1 = Zotero.Date.sqlToDate(dm1);
|
||||
|
@ -318,6 +319,10 @@
|
|||
elementName = 'zoteronoteeditor';
|
||||
break;
|
||||
|
||||
case 'storagefile':
|
||||
elementName = 'zoterostoragefilebox';
|
||||
break;
|
||||
|
||||
default:
|
||||
throw ("Object type '" + this.type
|
||||
+ "' not supported in <zoteromergepane>.ref");
|
||||
|
@ -349,6 +354,7 @@
|
|||
switch (this.type) {
|
||||
case 'attachment':
|
||||
case 'note':
|
||||
case 'storagefile':
|
||||
objbox.buttonCaption = 'Choose this version';
|
||||
break;
|
||||
}
|
||||
|
|
67
chrome/content/zotero/bindings/storagefilebox.xml
Normal file
67
chrome/content/zotero/bindings/storagefilebox.xml
Normal file
|
@ -0,0 +1,67 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
***** 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 *****
|
||||
-->
|
||||
|
||||
<!DOCTYPE bindings SYSTEM "chrome://zotero/locale/zotero.dtd">
|
||||
|
||||
<bindings xmlns="http://www.mozilla.org/xbl"
|
||||
xmlns:xbl="http://www.mozilla.org/xbl"
|
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<binding id="storage-file-box"
|
||||
extends="chrome://zotero/content/bindings/attachmentbox.xml#attachment-box">
|
||||
|
||||
<implementation>
|
||||
<property name="mode" onget="return this._mode;">
|
||||
<setter>
|
||||
<![CDATA[
|
||||
this.editable = false;
|
||||
this.displayGoButtons = false;
|
||||
this.clickableLink = false;
|
||||
this.displayIndexed = false;
|
||||
this.displayPages = false;
|
||||
this.displayNote = false;
|
||||
|
||||
switch (val) {
|
||||
case 'merge':
|
||||
this.displayFileName = true;
|
||||
this.displayButton = true;
|
||||
this.displayDateModified = true;
|
||||
break;
|
||||
|
||||
case 'mergeedit':
|
||||
this.displayFileName = true;
|
||||
this.displayDateModified = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw ("Invalid mode '" + val + "' in storagefilebox.xml");
|
||||
}
|
||||
|
||||
this._mode = val;
|
||||
document.getAnonymousNodes(this)[0].setAttribute('mode', val);
|
||||
]]>
|
||||
</setter>
|
||||
</property>
|
||||
</implementation>
|
||||
</binding>
|
||||
</bindings>
|
|
@ -42,6 +42,7 @@ var Zotero_Merge_Window = new function () {
|
|||
|
||||
switch (_mergeGroup.type) {
|
||||
case 'item':
|
||||
case 'storagefile':
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -127,6 +128,8 @@ var Zotero_Merge_Window = new function () {
|
|||
}
|
||||
}
|
||||
catch (e) {
|
||||
Zotero.debug(e);
|
||||
|
||||
var prompt = Components.classes["@mozilla.org/network/default-prompt;1"]
|
||||
.createInstance(Components.interfaces.nsIPrompt);
|
||||
prompt.alert(Zotero.getString('general.error'), e);
|
||||
|
|
|
@ -5,6 +5,8 @@ Zotero.Sync.Storage = new function () {
|
|||
this.SYNC_STATE_TO_UPLOAD = 0;
|
||||
this.SYNC_STATE_TO_DOWNLOAD = 1;
|
||||
this.SYNC_STATE_IN_SYNC = 2;
|
||||
this.SYNC_STATE_FORCE_UPLOAD = 3;
|
||||
this.SYNC_STATE_FORCE_DOWNLOAD = 4;
|
||||
|
||||
this.SUCCESS = 1;
|
||||
this.ERROR_NO_URL = -1;
|
||||
|
@ -22,7 +24,6 @@ Zotero.Sync.Storage = new function () {
|
|||
this.ERROR_NOT_ALLOWED = -14;
|
||||
this.ERROR_UNKNOWN = -15;
|
||||
|
||||
|
||||
//
|
||||
// Public properties
|
||||
//
|
||||
|
@ -242,7 +243,6 @@ Zotero.Sync.Storage = new function () {
|
|||
}
|
||||
|
||||
Zotero.debug("Beginning storage sync");
|
||||
Zotero.Sync.Runner.setSyncIcon('animate');
|
||||
_syncInProgress = true;
|
||||
_changesMade = false;
|
||||
|
||||
|
@ -297,6 +297,8 @@ Zotero.Sync.Storage = new function () {
|
|||
case this.SYNC_STATE_TO_UPLOAD:
|
||||
case this.SYNC_STATE_TO_DOWNLOAD:
|
||||
case this.SYNC_STATE_IN_SYNC:
|
||||
case this.SYNC_STATE_FORCE_UPLOAD:
|
||||
case this.SYNC_STATE_FORCE_DOWNLOAD:
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -608,6 +610,10 @@ Zotero.Sync.Storage = new function () {
|
|||
* @return {Boolean}
|
||||
*/
|
||||
this.downloadFiles = function () {
|
||||
if (!_syncInProgress) {
|
||||
_syncInProgress = true;
|
||||
}
|
||||
|
||||
// Check for active operations?
|
||||
var queue = Zotero.Sync.Storage.QueueManager.get('download');
|
||||
if (queue.isRunning()) {
|
||||
|
@ -624,7 +630,9 @@ Zotero.Sync.Storage = new function () {
|
|||
|
||||
for each(var itemID in downloadFileIDs) {
|
||||
var item = Zotero.Items.get(itemID);
|
||||
if (this.isFileModified(itemID)) {
|
||||
if (Zotero.Sync.Storage.getSyncState(itemID) !=
|
||||
Zotero.Sync.Storage.SYNC_STATE_FORCE_DOWNLOAD
|
||||
&& this.isFileModified(itemID)) {
|
||||
Zotero.debug("File for attachment " + itemID + " has been modified");
|
||||
this.setSyncState(itemID, this.SYNC_STATE_TO_UPLOAD);
|
||||
continue;
|
||||
|
@ -671,6 +679,24 @@ Zotero.Sync.Storage = new function () {
|
|||
|
||||
try {
|
||||
var syncModTime = Zotero.Date.toUnixTimestamp(mdate);
|
||||
|
||||
// Skip download if local file exists and matches mod time
|
||||
var file = item.getFile();
|
||||
if (file && file.exists()
|
||||
&& syncModTime == Math.round(file.lastModifiedTime / 1000)) {
|
||||
Zotero.debug("Stored file mod time matches remote file -- skipping download");
|
||||
|
||||
Zotero.DB.beginTransaction();
|
||||
var syncState = Zotero.Sync.Storage.getSyncState(item.id);
|
||||
var updateItem = syncState != 1;
|
||||
Zotero.Sync.Storage.setSyncedModificationTime(item.id, syncModTime, true);
|
||||
Zotero.Sync.Storage.setSyncState(item.id, Zotero.Sync.Storage.SYNC_STATE_IN_SYNC);
|
||||
Zotero.DB.commitTransaction();
|
||||
_changesMade = true;
|
||||
request.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
var uri = _getItemURI(item);
|
||||
var destFile = Zotero.getTempDirectory();
|
||||
destFile.append(item.key + '.zip.tmp');
|
||||
|
@ -715,6 +741,10 @@ Zotero.Sync.Storage = new function () {
|
|||
* @return {Boolean}
|
||||
*/
|
||||
this.uploadFiles = function () {
|
||||
if (!_syncInProgress) {
|
||||
_syncInProgress = true;
|
||||
}
|
||||
|
||||
// Check for active operations?
|
||||
var queue = Zotero.Sync.Storage.QueueManager.get('upload');
|
||||
if (queue.isRunning()) {
|
||||
|
@ -946,9 +976,24 @@ Zotero.Sync.Storage = new function () {
|
|||
}
|
||||
|
||||
|
||||
this.resetAllSyncStates = function () {
|
||||
this.resetAllSyncStates = function (syncState) {
|
||||
if (!syncState) {
|
||||
syncState = this.SYNC_STATE_TO_UPLOAD;
|
||||
}
|
||||
|
||||
switch (syncState) {
|
||||
case this.SYNC_STATE_TO_UPLOAD:
|
||||
case this.SYNC_STATE_TO_DOWNLOAD:
|
||||
case this.SYNC_STATE_IN_SYNC:
|
||||
break;
|
||||
|
||||
default:
|
||||
throw ("Invalid sync state '" + syncState + "' in "
|
||||
+ "Zotero.Sync.Storage.resetAllSyncStates()");
|
||||
}
|
||||
|
||||
var sql = "UPDATE itemAttachments SET syncState=?";
|
||||
Zotero.DB.query(sql, [this.SYNC_STATE_TO_UPLOAD]);
|
||||
Zotero.DB.query(sql, [syncState]);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1217,19 +1262,29 @@ Zotero.Sync.Storage = new function () {
|
|||
|
||||
try {
|
||||
// Check for conflict
|
||||
if (Zotero.Sync.Storage.getSyncState(item.id)
|
||||
!= Zotero.Sync.Storage.SYNC_STATE_FORCE_UPLOAD) {
|
||||
if (mdate) {
|
||||
var file = item.getFile();
|
||||
var mtime = Zotero.Date.toUnixTimestamp(mdate);
|
||||
var smtime = Zotero.Sync.Storage.getSyncedModificationTime(item.id);
|
||||
if (mtime != smtime) {
|
||||
request.error("Conflict! Last known mod time does not match remote time!"
|
||||
var localData = { modTime: smtime };
|
||||
var remoteData = { modTime: mtime };
|
||||
Zotero.Sync.Storage.QueueManager.addConflict(
|
||||
request.name, localData, remoteData
|
||||
);
|
||||
Zotero.debug("File conflict -- last known mod time "
|
||||
+ "does not match remote time"
|
||||
+ " (" + mtime + " != " + smtime + ")");
|
||||
request.finish();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Zotero.debug("Remote file not found for item " + item.id);
|
||||
}
|
||||
}
|
||||
|
||||
var file = Zotero.getTempDirectory();
|
||||
file.append(item.key + '.zip');
|
||||
|
@ -1364,8 +1419,13 @@ Zotero.Sync.Storage = new function () {
|
|||
* @return {Number[]} Array of attachment itemIDs
|
||||
*/
|
||||
function _getFilesToDownload() {
|
||||
var sql = "SELECT itemID FROM itemAttachments WHERE syncState=?";
|
||||
return Zotero.DB.columnQuery(sql, Zotero.Sync.Storage.SYNC_STATE_TO_DOWNLOAD);
|
||||
var sql = "SELECT itemID FROM itemAttachments WHERE syncState IN (?,?)";
|
||||
return Zotero.DB.columnQuery(sql,
|
||||
[
|
||||
Zotero.Sync.Storage.SYNC_STATE_TO_DOWNLOAD,
|
||||
Zotero.Sync.Storage.SYNC_STATE_FORCE_DOWNLOAD
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1376,11 +1436,12 @@ Zotero.Sync.Storage = new function () {
|
|||
* @return {Number[]} Array of attachment itemIDs
|
||||
*/
|
||||
function _getFilesToUpload() {
|
||||
var sql = "SELECT itemID FROM itemAttachments WHERE syncState=? "
|
||||
var sql = "SELECT itemID FROM itemAttachments WHERE syncState IN (?,?) "
|
||||
+ "AND linkMode IN (?,?)";
|
||||
return Zotero.DB.columnQuery(sql,
|
||||
[
|
||||
Zotero.Sync.Storage.SYNC_STATE_TO_UPLOAD,
|
||||
Zotero.Sync.Storage.SYNC_STATE_FORCE_UPLOAD,
|
||||
Zotero.Attachments.LINK_MODE_IMPORTED_FILE,
|
||||
Zotero.Attachments.LINK_MODE_IMPORTED_URL
|
||||
]
|
||||
|
@ -1890,6 +1951,13 @@ Zotero.Sync.Storage = new function () {
|
|||
Zotero.debug("Storage sync is complete");
|
||||
_syncInProgress = false;
|
||||
|
||||
if (!cancelled && this.resyncOnFinish) {
|
||||
Zotero.debug("Force-resyncing items in conflict");
|
||||
this.resyncOnFinish = false;
|
||||
this.sync();
|
||||
return;
|
||||
}
|
||||
|
||||
if (cancelled || !_changesMade) {
|
||||
if (!_changesMade) {
|
||||
Zotero.debug("No changes made during storage sync");
|
||||
|
@ -1991,6 +2059,7 @@ Zotero.Sync.Storage = new function () {
|
|||
|
||||
Zotero.Sync.Storage.QueueManager = new function () {
|
||||
var _queues = {};
|
||||
var _conflicts = [];
|
||||
|
||||
|
||||
/**
|
||||
|
@ -2028,6 +2097,7 @@ Zotero.Sync.Storage.QueueManager = new function () {
|
|||
for each(var queue in _queues) {
|
||||
queue.stop();
|
||||
}
|
||||
_conflicts = [];
|
||||
}
|
||||
|
||||
|
||||
|
@ -2035,6 +2105,14 @@ Zotero.Sync.Storage.QueueManager = new function () {
|
|||
* Tell the storage system that we're finished
|
||||
*/
|
||||
this.finish = function () {
|
||||
if (_conflicts.length) {
|
||||
var data = _reconcileConflicts();
|
||||
if (data) {
|
||||
_processMergeData(data);
|
||||
}
|
||||
_conflicts = [];
|
||||
}
|
||||
|
||||
Zotero.Sync.Storage.finish(this._cancelled);
|
||||
this._cancelled = false;
|
||||
}
|
||||
|
@ -2075,8 +2153,10 @@ Zotero.Sync.Storage.QueueManager = new function () {
|
|||
//Zotero.debug("Total percentage is " + percentage);
|
||||
|
||||
// Remaining KB
|
||||
var downloadStatus = _getQueueStatus(_queues.download);
|
||||
var uploadStatus = _getQueueStatus(_queues.upload);
|
||||
var downloadStatus = _queues.download ?
|
||||
_getQueueStatus(_queues.download) : 0;
|
||||
var uploadStatus = _queues.upload ?
|
||||
_getQueueStatus(_queues.upload) : 0;
|
||||
|
||||
this.updateProgressMeters(
|
||||
activeRequests, percentage, downloadStatus, uploadStatus
|
||||
|
@ -2124,6 +2204,15 @@ Zotero.Sync.Storage.QueueManager = new function () {
|
|||
}
|
||||
|
||||
|
||||
this.addConflict = function (requestName, localData, remoteData) {
|
||||
_conflicts.push({
|
||||
name: requestName,
|
||||
localData: localData,
|
||||
remoteData: remoteData
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a status string for a queue
|
||||
*
|
||||
|
@ -2155,6 +2244,77 @@ Zotero.Sync.Storage.QueueManager = new function () {
|
|||
var status = Zotero.localeJoin([kbRemaining, '(' + filesRemaining + ')']);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
function _reconcileConflicts() {
|
||||
var objectPairs = [];
|
||||
for each(var conflict in _conflicts) {
|
||||
var item = Zotero.Items.getByKey(conflict.name);
|
||||
var item1 = item.clone();
|
||||
item1.setField('dateModified',
|
||||
Zotero.Date.dateToSQL(new Date(conflict.localData.modTime * 1000), true));
|
||||
var item2 = item.clone();
|
||||
item2.setField('dateModified',
|
||||
Zotero.Date.dateToSQL(new Date(conflict.remoteData.modTime * 1000), true));
|
||||
objectPairs.push([item1, item2]);
|
||||
}
|
||||
|
||||
var io = {
|
||||
dataIn: {
|
||||
type: 'storagefile',
|
||||
captions: [
|
||||
// TODO: localize
|
||||
'Local File',
|
||||
'Remote File',
|
||||
'Saved File'
|
||||
],
|
||||
objects: objectPairs
|
||||
}
|
||||
};
|
||||
|
||||
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
|
||||
.getService(Components.interfaces.nsIWindowMediator);
|
||||
var lastWin = wm.getMostRecentWindow("navigator:browser");
|
||||
lastWin.openDialog('chrome://zotero/content/merge.xul', '', 'chrome,modal,centerscreen', io);
|
||||
|
||||
if (!io.dataOut) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Since we're only putting cloned items into the merge window,
|
||||
// we have to manually set the ids
|
||||
for (var i=0; i<_conflicts.length; i++) {
|
||||
io.dataOut[i].id = Zotero.Items.getByKey(_conflicts[i].name).id;
|
||||
}
|
||||
|
||||
return io.dataOut;
|
||||
}
|
||||
|
||||
|
||||
function _processMergeData(data) {
|
||||
if (!data.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Zotero.Sync.Storage.resyncOnFinish = true;
|
||||
|
||||
for each(var mergeItem in data) {
|
||||
var itemID = mergeItem.id;
|
||||
var dateModified = mergeItem.ref.getField('dateModified');
|
||||
// Local
|
||||
if (dateModified == mergeItem.left.getField('dateModified')) {
|
||||
Zotero.Sync.Storage.setSyncState(
|
||||
itemID, Zotero.Sync.Storage.SYNC_STATE_FORCE_UPLOAD
|
||||
);
|
||||
}
|
||||
// Remote
|
||||
else {
|
||||
Zotero.Sync.Storage.setSyncState(
|
||||
itemID, Zotero.Sync.Storage.SYNC_STATE_FORCE_DOWNLOAD
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -2229,6 +2389,10 @@ Zotero.Sync.Storage.Queue = function (name) {
|
|||
return remaining;
|
||||
});
|
||||
this.__defineGetter__('percentage', function () {
|
||||
if (this.totalRequests == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
var completedRequests = 0;
|
||||
for each(var request in this._requests) {
|
||||
completedRequests += request.percentage / 100;
|
||||
|
@ -2374,8 +2538,14 @@ Zotero.Sync.Storage.Queue.prototype.stop = function () {
|
|||
Zotero.debug(this.Name + " queue is already finished");
|
||||
return;
|
||||
}
|
||||
this._stopping = true;
|
||||
|
||||
// If no requests, finish manually
|
||||
if (this.activeRequests == 0) {
|
||||
this._finishedRequests = this._finishedRequests;
|
||||
return;
|
||||
}
|
||||
|
||||
this._stopping = true;
|
||||
for each(var request in this._requests) {
|
||||
if (!request.isFinished()) {
|
||||
request.stop();
|
||||
|
@ -2461,6 +2631,7 @@ Zotero.Sync.Storage.Request.prototype.__defineGetter__('percentage', function ()
|
|||
if (this.progressMax == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
var percentage = Math.round((this.progress / this.progressMax) * 100);
|
||||
if (percentage < this._percentage) {
|
||||
Zotero.debug(percentage + " is less than last percentage of "
|
||||
|
|
|
@ -73,6 +73,10 @@ zoteroattachmentbox
|
|||
-moz-binding: url('chrome://zotero/content/bindings/attachmentbox.xml#attachment-box');
|
||||
}
|
||||
|
||||
zoterostoragefilebox
|
||||
{
|
||||
-moz-binding: url('chrome://zotero/content/bindings/storagefilebox.xml#storage-file-box');
|
||||
}
|
||||
|
||||
zoteronoteeditor
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue