Don't hang UI when importing files
- File import now uses a translucent overlay over Zotero pane with a progress meter that doesn't hang - New method Zotero.wait(timeout) to allow synchronous code to wait for events on main thread to be processed until timeout is reached - Wait status can be tested with Zotero.waiting property - Zotero.showZoteroPaneProgressBar(msg, determinate) locks Zotero and creates overlay with progress meter - Code that might trigger via timers or external UI should check Zotero.lock Lock checks so far: - Translator save icon and RIS/Refer import display error if triggered while locked - Browser content context menu options are now in a Zotero submenu and are disabled when Zotero is locked - Sync, repository, and DB backup timers check for lock and bail - If a new window is opened, Zotero pane can't be opened and display an error message until lock is released Probably need to check lock in word processor integration code and advanced search window Also: - New method Zotero.sleep(ms) (currently unused) to allow synchronous code to sleep and allow events on main thread to be processed
This commit is contained in:
parent
045e2b0830
commit
96345a3aa8
12 changed files with 282 additions and 100 deletions
|
@ -120,6 +120,17 @@ var Zotero_Browser = new function() {
|
|||
* @return void
|
||||
*/
|
||||
function scrapeThisPage(libraryID, collectionID) {
|
||||
if (Zotero.locked) {
|
||||
Zotero_Browser.progress.changeHeadline(Zotero.getString("ingester.scrapeError"));
|
||||
// TODO: localize
|
||||
var desc = "A Zotero operation is currently in progress. Please wait until it finishes and try again.";
|
||||
Zotero_Browser.progress.addDescription(desc);
|
||||
Zotero_Browser.progress.show();
|
||||
Zotero_Browser.progress.startCloseTimer(8000);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Zotero.stateCheck()) {
|
||||
Zotero_Browser.progress.changeHeadline(Zotero.getString("ingester.scrapeError"));
|
||||
var desc = Zotero.getString("ingester.scrapeError.transactionInProgress.previousError")
|
||||
|
|
|
@ -80,10 +80,9 @@ Zotero_File_Exporter.prototype.save = function() {
|
|||
translation.setHandler("done", this._exportDone);
|
||||
Zotero.UnresponsiveScriptIndicator.disable();
|
||||
Zotero_File_Interface.Progress.show(
|
||||
Zotero.getString("fileInterface.itemsExported"),
|
||||
function() {
|
||||
translation.translate();
|
||||
});
|
||||
Zotero.getString("fileInterface.itemsExported")
|
||||
);
|
||||
translation.translate()
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -269,13 +268,10 @@ var Zotero_File_Interface = new function() {
|
|||
|
||||
// show progress indicator
|
||||
Zotero_File_Interface.Progress.show(
|
||||
Zotero.getString("fileInterface.itemsImported"),
|
||||
function() {
|
||||
Zotero.DB.beginTransaction();
|
||||
|
||||
// translate
|
||||
translation.translate();
|
||||
});
|
||||
Zotero.getString("fileInterface.itemsImported")
|
||||
);
|
||||
Zotero.DB.beginTransaction();
|
||||
translation.translate();
|
||||
} else {
|
||||
var prompt = Components.classes["@mozilla.org/network/default-prompt;1"]
|
||||
.getService(Components.interfaces.nsIPrompt);
|
||||
|
@ -569,50 +565,14 @@ var Zotero_File_Interface = new function() {
|
|||
|
||||
// Handles the display of a progress indicator
|
||||
Zotero_File_Interface.Progress = new function() {
|
||||
var _windowLoaded = false;
|
||||
var _windowLoading = false;
|
||||
var _progressWindow;
|
||||
// keep track of all of these things in case they're called before we're
|
||||
// done loading the progress window
|
||||
var _loadHeadline, _loadNumber, _outOf, _callback;
|
||||
|
||||
this.show = show;
|
||||
this.close = close;
|
||||
|
||||
function show(headline, callback) {
|
||||
if(_windowLoading || _windowLoaded) { // already loading or loaded
|
||||
_progressWindow.focus();
|
||||
return false;
|
||||
}
|
||||
_windowLoading = true;
|
||||
|
||||
_loadHeadline = headline;
|
||||
_loadNumber = 0;
|
||||
_outOf = 0;
|
||||
_callback = callback;
|
||||
|
||||
_progressWindow = window.openDialog("chrome://zotero/content/fileProgress.xul", "", "chrome,resizable=no,close=no,dependent,dialog,centerscreen");
|
||||
_progressWindow.addEventListener("pageshow", _onWindowLoaded, false);
|
||||
|
||||
return true;
|
||||
function show(headline) {
|
||||
Zotero.showZoteroPaneProgressBar(headline)
|
||||
}
|
||||
|
||||
function close() {
|
||||
_windowLoaded = false;
|
||||
try {
|
||||
_progressWindow.close();
|
||||
} catch(ex) {}
|
||||
}
|
||||
|
||||
function _onWindowLoaded() {
|
||||
_windowLoading = false;
|
||||
_windowLoaded = true;
|
||||
|
||||
// do things we delayed because the winodw was loading
|
||||
_progressWindow.document.getElementById("progress-label").value = _loadHeadline;
|
||||
|
||||
if(_callback) {
|
||||
window.setTimeout(_callback, 1500);
|
||||
}
|
||||
Zotero.hideZoteroPaneOverlay();
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
<?xml version="1.0" ?>
|
||||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||
<!DOCTYPE window SYSTEM "chrome://zotero/locale/zotero.dtd">
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="&zotero.progress.title;" width="300" height="30"
|
||||
id="zotero-progress">
|
||||
<vbox style="padding:10px">
|
||||
<hbox align="stretch">
|
||||
<label id="progress-label" flex="1" />
|
||||
<label id="progress-items" style="text-align:right;width:20px" />
|
||||
</hbox>
|
||||
<progressmeter id="progress-indicator" mode="undetermined" />
|
||||
</vbox>
|
||||
</window>
|
|
@ -27,6 +27,7 @@ var ZoteroPane = new function()
|
|||
{
|
||||
this.collectionsView = false;
|
||||
this.itemsView = false;
|
||||
this.__defineGetter__('loaded', function () _loaded);
|
||||
|
||||
//Privileged methods
|
||||
this.onLoad = onLoad;
|
||||
|
@ -85,6 +86,7 @@ var ZoteroPane = new function()
|
|||
const COLLECTIONS_HEIGHT = 32; // minimum height of the collections pane and toolbar
|
||||
|
||||
var self = this;
|
||||
var _loaded = false;
|
||||
var titlebarcolorState, toolbarCollapseState, titleState;
|
||||
|
||||
// Also needs to be changed in collectionTreeView.js
|
||||
|
@ -99,6 +101,11 @@ var ZoteroPane = new function()
|
|||
return;
|
||||
}
|
||||
|
||||
if (Zotero.locked) {
|
||||
return;
|
||||
}
|
||||
_loaded = true;
|
||||
|
||||
if(Zotero.Prefs.get("zoteroPaneOnTop"))
|
||||
{
|
||||
var oldPane = document.getElementById('zotero-pane');
|
||||
|
@ -245,7 +252,7 @@ var ZoteroPane = new function()
|
|||
*/
|
||||
function onUnload()
|
||||
{
|
||||
if (!Zotero || !Zotero.initialized) {
|
||||
if (!Zotero || !Zotero.initialized || !_loaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -262,7 +269,19 @@ var ZoteroPane = new function()
|
|||
*/
|
||||
function toggleDisplay()
|
||||
{
|
||||
var zoteroPane = document.getElementById('zotero-pane');
|
||||
if (!ZoteroPane.loaded) {
|
||||
if (Zotero.locked) {
|
||||
var pr = Components.classes["@mozilla.org/network/default-prompt;1"]
|
||||
.getService(Components.interfaces.nsIPrompt);
|
||||
// TODO: localize
|
||||
var msg = "Another Zotero operation is currently in progress.\n\nPlease wait until it has finished.";
|
||||
pr.alert("", msg);
|
||||
return;
|
||||
}
|
||||
ZoteroPane.onLoad();
|
||||
}
|
||||
|
||||
var zoteroPane = document.getElementById('zotero-pane-stack');
|
||||
var zoteroSplitter = document.getElementById('zotero-splitter')
|
||||
|
||||
if (zoteroPane.getAttribute('hidden') == 'true') {
|
||||
|
@ -383,7 +402,7 @@ var ZoteroPane = new function()
|
|||
|
||||
|
||||
function isShowing() {
|
||||
var zoteroPane = document.getElementById('zotero-pane');
|
||||
var zoteroPane = document.getElementById('zotero-pane-stack');
|
||||
return zoteroPane.getAttribute('hidden') != 'true' &&
|
||||
zoteroPane.getAttribute('collapsed') != 'true';
|
||||
}
|
||||
|
@ -391,21 +410,21 @@ var ZoteroPane = new function()
|
|||
|
||||
function fullScreen(set)
|
||||
{
|
||||
var zPane = document.getElementById('zotero-pane');
|
||||
var zoteroPane = document.getElementById('zotero-pane-stack');
|
||||
|
||||
if (set != undefined) {
|
||||
var makeFullScreen = !!set;
|
||||
}
|
||||
else {
|
||||
var makeFullScreen = zPane.getAttribute('fullscreenmode') != 'true';
|
||||
var makeFullScreen = zoteroPane.getAttribute('fullscreenmode') != 'true';
|
||||
}
|
||||
|
||||
// Turn Z-pane flex on to stretch to window in full-screen, but off otherwise so persist works
|
||||
zPane.setAttribute('flex', makeFullScreen ? "1" : "0");
|
||||
zoteroPane.setAttribute('flex', makeFullScreen ? "1" : "0");
|
||||
document.getElementById('content').setAttribute('collapsed', makeFullScreen);
|
||||
document.getElementById('zotero-splitter').setAttribute('hidden', makeFullScreen);
|
||||
|
||||
zPane.setAttribute('fullscreenmode', makeFullScreen);
|
||||
zoteroPane.setAttribute('fullscreenmode', makeFullScreen);
|
||||
_setFullWindowMode(makeFullScreen);
|
||||
}
|
||||
|
||||
|
@ -468,6 +487,11 @@ var ZoteroPane = new function()
|
|||
Zotero.debug(e);
|
||||
}
|
||||
|
||||
if (Zotero.locked) {
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
if (from == 'zotero-pane') {
|
||||
// Highlight collections containing selected items
|
||||
//
|
||||
|
@ -497,7 +521,7 @@ var ZoteroPane = new function()
|
|||
}
|
||||
|
||||
// Ignore keystrokes if Zotero pane is closed
|
||||
var zoteroPane = document.getElementById('zotero-pane');
|
||||
var zoteroPane = document.getElementById('zotero-pane-stack');
|
||||
if (zoteroPane.getAttribute('hidden') == 'true' ||
|
||||
zoteroPane.getAttribute('collapsed') == 'true') {
|
||||
return;
|
||||
|
@ -783,7 +807,6 @@ var ZoteroPane = new function()
|
|||
|
||||
|
||||
function toggleTagSelector(){
|
||||
var zoteroPane = document.getElementById('zotero-pane');
|
||||
var tagSelector = document.getElementById('zotero-tag-selector');
|
||||
|
||||
var showing = tagSelector.getAttribute('collapsed') == 'true';
|
||||
|
@ -805,7 +828,7 @@ var ZoteroPane = new function()
|
|||
|
||||
function updateTagSelectorSize() {
|
||||
//Zotero.debug('Updating tag selector size');
|
||||
var zoteroPane = document.getElementById('zotero-pane');
|
||||
var zoteroPane = document.getElementById('zotero-pane-stack');
|
||||
var splitter = document.getElementById('zotero-tags-splitter');
|
||||
var tagSelector = document.getElementById('zotero-tag-selector');
|
||||
|
||||
|
@ -966,7 +989,6 @@ 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);
|
||||
|
@ -2225,8 +2247,11 @@ var ZoteroPane = new function()
|
|||
}
|
||||
}
|
||||
|
||||
var separator = document.getElementById("zotero-context-separator");
|
||||
separator.hidden = !showing;
|
||||
// If Zotero is locked, disable menu items
|
||||
var menu = document.getElementById('zotero-content-area-context-menu');
|
||||
for each(var menuitem in menu.firstChild.childNodes) {
|
||||
menuitem.disabled = Zotero.locked;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -53,20 +53,23 @@
|
|||
</toolbarpalette>
|
||||
|
||||
<popup id="contentAreaContextMenu">
|
||||
<menuseparator id="zotero-context-separator" hidden="true"/>
|
||||
<menuitem id="zotero-context-add-to-current-note" class="menu-iconic"
|
||||
label="&zotero.contextMenu.addTextToCurrentNote;" hidden="true"
|
||||
oncommand="var str = event.currentTarget.ownerDocument.popupNode.ownerDocument.defaultView.getSelection().toString(); ZoteroPane.addTextToNote(str)"/>
|
||||
<menuitem id="zotero-context-add-to-new-note" class="menu-iconic"
|
||||
label="&zotero.contextMenu.addTextToNewNote;" hidden="true"
|
||||
oncommand="var str = event.currentTarget.ownerDocument.popupNode.ownerDocument.defaultView.getSelection().toString(); var itemID = ZoteroPane.addItemFromPage(); ZoteroPane.newNote(false, itemID, str)"/>
|
||||
<!-- TODO: localize and remove zotero.contextMenu.saveLinkAsItem/saveImageAsSnapshot -->
|
||||
<menuitem id="zotero-context-save-link-as-item" class="menu-iconic"
|
||||
label="Save Link as Zotero Item" hidden="true"
|
||||
oncommand="ZoteroPane.addItemFromURL(window.gContextMenu.linkURL, 'temporaryPDFHack')"/>
|
||||
<menuitem id="zotero-context-save-image-as-item" class="menu-iconic"
|
||||
label="Save Image as Zotero Item" hidden="true"
|
||||
oncommand="ZoteroPane.addItemFromURL(window.gContextMenu.onImage ? (window.gContextMenu.mediaURL ? window.gContextMenu.mediaURL : window.gContextMenu.imageURL) : window.gContextMenu.bgImageURL, 'artwork')"/>
|
||||
<menu id="zotero-content-area-context-menu" label="Zotero">
|
||||
<menupopup>
|
||||
<menuitem id="zotero-context-add-to-current-note" class="menu-iconic"
|
||||
label="&zotero.contextMenu.addTextToCurrentNote;" hidden="true"
|
||||
oncommand="var str = event.currentTarget.ownerDocument.popupNode.ownerDocument.defaultView.getSelection().toString(); ZoteroPane.addTextToNote(str)"/>
|
||||
<menuitem id="zotero-context-add-to-new-note" class="menu-iconic"
|
||||
label="&zotero.contextMenu.addTextToNewNote;" hidden="true"
|
||||
oncommand="var str = event.currentTarget.ownerDocument.popupNode.ownerDocument.defaultView.getSelection().toString(); var itemID = ZoteroPane.addItemFromPage(); ZoteroPane.newNote(false, itemID, str)"/>
|
||||
<!-- TODO: localize and remove zotero.contextMenu.saveLinkAsItem/saveImageAsSnapshot -->
|
||||
<menuitem id="zotero-context-save-link-as-item" class="menu-iconic"
|
||||
label="Save Link as Zotero Item" hidden="true"
|
||||
oncommand="ZoteroPane.addItemFromURL(window.gContextMenu.linkURL, 'temporaryPDFHack')"/>
|
||||
<menuitem id="zotero-context-save-image-as-item" class="menu-iconic"
|
||||
label="Save Image as Zotero Item" hidden="true"
|
||||
oncommand="ZoteroPane.addItemFromURL(window.gContextMenu.onImage ? (window.gContextMenu.mediaURL ? window.gContextMenu.mediaURL : window.gContextMenu.imageURL) : window.gContextMenu.bgImageURL, 'artwork')"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</popup>
|
||||
|
||||
<vbox id="appcontent">
|
||||
|
@ -74,7 +77,15 @@
|
|||
<!-- onmouseup shouldn't be necessary but seems to help prevent tag selector from sometimes going off the screen -->
|
||||
<splitter id="zotero-splitter" resizebefore="closest" resizeafter="closest" hidden="true"
|
||||
onmouseup="ZoteroPane.updateTagSelectorSize()"/>
|
||||
<hbox id="zotero-pane" persist="savedHeight" hidden="true"
|
||||
|
||||
<stack id="zotero-pane-stack" persist="savedHeight" hidden="true">
|
||||
|
||||
<!-- Barrier to prevent tabbing into Zotero pane when busy -->
|
||||
<box id="zotero-pane-tab-catcher-top" hidden="true" align="center" pack="center" style="opacity: 0">
|
||||
<checkbox/>
|
||||
</box>
|
||||
|
||||
<hbox id="zotero-pane"
|
||||
onkeydown="ZoteroPane.handleKeyDown(event, this.id)"
|
||||
onkeyup="ZoteroPane.handleKeyUp(event, this.id)"
|
||||
chromedir="&locale.dir;">
|
||||
|
@ -402,6 +413,28 @@
|
|||
</vbox>
|
||||
</hbox>
|
||||
|
||||
<!-- Barrier to prevent tabbing into Zotero pane when busy -->
|
||||
<box id="zotero-pane-tab-catcher-bottom" hidden="true" align="center" pack="center" style="opacity: 0">
|
||||
<checkbox/>
|
||||
</box>
|
||||
|
||||
<stack id="zotero-pane-overlay" flex="1" hidden="true">
|
||||
<box style="background: black; opacity: .3" flex="1"/>
|
||||
|
||||
<deck id="zotero-pane-overlay-deck" flex="1">
|
||||
<box id="zotero-pane-progress" flex="1" align="center" pack="center">
|
||||
<box style="background: white; -moz-border-radius: 1px; -moz-box-shadow: gray 4px 6px 4px;" width="300" height="30">
|
||||
<vbox style="padding:10px" flex="1">
|
||||
<label id="zotero-pane-progress-label"/>
|
||||
<progressmeter id="zotero-pane-progressmeter" mode="undetermined"/>
|
||||
</vbox>
|
||||
</box>
|
||||
</box>
|
||||
</deck>
|
||||
</stack>
|
||||
|
||||
</stack>
|
||||
|
||||
<!-- Annotation Toolbar -->
|
||||
<toolbar id="zotero-annotate-tb" crop="end" insertbefore="content" hidden="true">
|
||||
<toolbarbutton id="zotero-annotate-tb-add" tooltiptext="&zotero.annotate.toolbar.add.label;" oncommand="Zotero_Browser.toggleMode(this.id);"/>
|
||||
|
|
|
@ -217,6 +217,11 @@ Zotero.DBConnection.prototype.columnQuery = function (sql,params) {
|
|||
* [1,"hello",3] or [{'int':2},{'string':'foobar'}]
|
||||
*/
|
||||
Zotero.DBConnection.prototype.getStatement = function (sql, params, checkParams) {
|
||||
// TODO: limit to Zotero.DB, not all Zotero.DBConnections?
|
||||
if (Zotero.waiting) {
|
||||
throw ("Cannot access database layer during active Zotero.wait()");
|
||||
}
|
||||
|
||||
var db = this._getDBConnection();
|
||||
|
||||
// First, determine the type of query using first word
|
||||
|
@ -414,6 +419,11 @@ Zotero.DBConnection.prototype.getLastErrorString = function () {
|
|||
|
||||
|
||||
Zotero.DBConnection.prototype.beginTransaction = function () {
|
||||
// TODO: limit to Zotero.DB, not all Zotero.DBConnections?
|
||||
if (Zotero.waiting) {
|
||||
throw ("Cannot access database layer during active Zotero.wait()");
|
||||
}
|
||||
|
||||
var db = this._getDBConnection();
|
||||
|
||||
if (db.transactionInProgress) {
|
||||
|
@ -792,6 +802,11 @@ Zotero.DBConnection.prototype.backupDatabase = function (suffix) {
|
|||
}
|
||||
}
|
||||
|
||||
if (Zotero.locked) {
|
||||
this._debug("Zotero is locked -- skipping backup of DB '" + this._dbName + "'", 2);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.transactionInProgress()) {
|
||||
this._debug("Transaction in progress--skipping backup of DB '" + this._dbName + "'", 2);
|
||||
return false;
|
||||
|
|
|
@ -22,14 +22,24 @@
|
|||
|
||||
Zotero.Ingester = new function() {
|
||||
this.importHandler = function(string, uri) {
|
||||
var frontWindow = Components.classes["@mozilla.org/embedcomp/window-watcher;1"].
|
||||
getService(Components.interfaces.nsIWindowWatcher).activeWindow;
|
||||
|
||||
if (Zotero.locked) {
|
||||
frontWindow.Zotero_Browser.progress.changeHeadline(Zotero.getString("ingester.scrapeError"));
|
||||
// TODO: localize
|
||||
var desc = "A Zotero operation is currently in progress. Please wait until it finishes and try again.";
|
||||
frontWindow.Zotero_Browser.progress.addDescription(desc);
|
||||
frontWindow.Zotero_Browser.progress.show();
|
||||
frontWindow.Zotero_Browser.progress.startCloseTimer(8000);
|
||||
return;
|
||||
}
|
||||
|
||||
// attempt to import through Zotero.Translate
|
||||
var translation = new Zotero.Translate("import");
|
||||
translation.setLocation(uri);
|
||||
translation.setString(string);
|
||||
|
||||
var frontWindow = Components.classes["@mozilla.org/embedcomp/window-watcher;1"].
|
||||
getService(Components.interfaces.nsIWindowWatcher).activeWindow;
|
||||
|
||||
frontWindow.Zotero_Browser.progress.show();
|
||||
var libraryID = null;
|
||||
var collection = null;
|
||||
|
|
|
@ -544,6 +544,12 @@ Zotero.Schema = new function(){
|
|||
}
|
||||
}
|
||||
|
||||
if (Zotero.locked) {
|
||||
Zotero.debug('Zotero is locked -- delaying repository check', 4);
|
||||
_setRepositoryTimer(600);
|
||||
return false;
|
||||
}
|
||||
|
||||
// If transaction already in progress, delay by ten minutes
|
||||
if (Zotero.DB.transactionInProgress()){
|
||||
Zotero.debug('Transaction in progress -- delaying repository check', 4)
|
||||
|
|
|
@ -550,6 +550,11 @@ Zotero.Sync.Runner = new function () {
|
|||
return;
|
||||
}
|
||||
|
||||
if (Zotero.locked) {
|
||||
Zotero.debug('Zotero is locked -- skipping auto-sync', 4);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Zotero.Sync.Storage.syncInProgress) {
|
||||
Zotero.debug('Storage sync already in progress -- skipping auto-sync', 4);
|
||||
return;
|
||||
|
|
|
@ -1680,6 +1680,9 @@ Zotero.Translate.prototype._itemDone = function(item, attachedTo) {
|
|||
}
|
||||
|
||||
delete item;
|
||||
|
||||
// Allow progress meter to update
|
||||
Zotero.wait(50);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -119,6 +119,18 @@ var Zotero = new function(){
|
|||
return key;
|
||||
};
|
||||
|
||||
/**
|
||||
* @property {Boolean} waiting Whether Zotero is waiting for other
|
||||
* main thread events to be processed
|
||||
*/
|
||||
this.__defineGetter__('waiting', function () _waiting);
|
||||
|
||||
/**
|
||||
* @property {Boolean} locked Whether all Zotero panes are locked
|
||||
* with an overlay
|
||||
*/
|
||||
this.__defineGetter__('locked', function () _locked);
|
||||
|
||||
|
||||
var _startupError;
|
||||
var _startupErrorHandler;
|
||||
|
@ -129,6 +141,8 @@ var Zotero = new function(){
|
|||
var _debugLastTime;
|
||||
var _localizedStringBundle;
|
||||
var _localUserKey;
|
||||
var _waiting;
|
||||
var _locked;
|
||||
|
||||
/*
|
||||
* Initialize the extension
|
||||
|
@ -380,6 +394,10 @@ var Zotero = new function(){
|
|||
* Check if a DB transaction is open and, if so, disable Zotero
|
||||
*/
|
||||
function stateCheck() {
|
||||
if (Zotero.locked) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Zotero.DB.transactionInProgress()) {
|
||||
this.initialized = false;
|
||||
this.skipLoading = true;
|
||||
|
@ -1033,6 +1051,117 @@ var Zotero = new function(){
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sleep for a given amount of time, allowing other events on main thread to be processed
|
||||
*
|
||||
* @param {Integer} wait Milliseconds to wait
|
||||
*/
|
||||
this.sleep = function (ms) {
|
||||
var tm = Components.classes["@mozilla.org/thread-manager;1"].getService();
|
||||
var endTime = Date.now() + ms;
|
||||
var mainThread = tm.mainThread;
|
||||
do {
|
||||
mainThread.processNextEvent(false);
|
||||
} while (Date.now() < endTime);
|
||||
|
||||
return;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Allow other events (e.g., UI updates) on main thread to be processed if necessary
|
||||
*
|
||||
* @param {Integer} timeout Maximum number of milliseconds to wait
|
||||
*/
|
||||
this.wait = function (timeout) {
|
||||
var tm = Components.classes["@mozilla.org/thread-manager;1"].getService();
|
||||
var endTime = Date.now() + timeout;
|
||||
var mainThread = tm.mainThread;
|
||||
var cycles = 0;
|
||||
|
||||
_waiting = true;
|
||||
|
||||
do {
|
||||
mainThread.processNextEvent(false);
|
||||
cycles++;
|
||||
} while (mainThread.hasPendingEvents() && Date.now() < endTime);
|
||||
|
||||
_waiting = false;
|
||||
|
||||
//Zotero.debug("Waited " + cycles + " cycles");
|
||||
return cycles;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Show Zotero pane overlay and progress bar in all windows
|
||||
*
|
||||
* @param {String} msg
|
||||
* @param {Boolean} [determinate=false]
|
||||
* @return {Element[]} Array of XUL <progressmeter> elements
|
||||
*/
|
||||
this.showZoteroPaneProgressBar = function (msg, determinate) {
|
||||
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
|
||||
.getService(Components.interfaces.nsIWindowMediator);
|
||||
var enumerator = wm.getEnumerator("navigator:browser");
|
||||
var progressMeters = [];
|
||||
while (enumerator.hasMoreElements()) {
|
||||
var win = enumerator.getNext();
|
||||
|
||||
win.document.getElementById('zotero-pane-progress-label').value = msg;
|
||||
var progressMeter = win.document.getElementById('zotero-pane-progressmeter')
|
||||
if (determinate) {
|
||||
progressMeter.mode = 'determined';
|
||||
progressMeter.value = 0;
|
||||
progressMeter.max = 100;
|
||||
}
|
||||
else {
|
||||
progressMeter.mode = 'undetermined';
|
||||
}
|
||||
|
||||
_showWindowZoteroPaneOverlay(win);
|
||||
win.document.getElementById('zotero-pane-overlay-deck').selectedIndex = 0;
|
||||
|
||||
progressMeters.push(progressMeter);
|
||||
}
|
||||
_locked = true;
|
||||
return progressMeters;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Hide Zotero pane overlay in all windows
|
||||
*/
|
||||
this.hideZoteroPaneOverlay = function () {
|
||||
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
|
||||
.getService(Components.interfaces.nsIWindowMediator);
|
||||
var enumerator = wm.getEnumerator("navigator:browser");
|
||||
while (enumerator.hasMoreElements()) {
|
||||
var win = enumerator.getNext();
|
||||
_hideWindowZoteroPaneOverlay(win);
|
||||
}
|
||||
_locked = false;
|
||||
}
|
||||
|
||||
|
||||
function _showWindowZoteroPaneOverlay(win) {
|
||||
win.document.getElementById('zotero-collections-tree').disabled = true;
|
||||
win.document.getElementById('zotero-items-tree').disabled = true;
|
||||
win.document.getElementById('zotero-pane-tab-catcher-top').hidden = false;
|
||||
win.document.getElementById('zotero-pane-tab-catcher-bottom').hidden = false;
|
||||
win.document.getElementById('zotero-pane-overlay').hidden = false;
|
||||
}
|
||||
|
||||
|
||||
function _hideWindowZoteroPaneOverlay(win) {
|
||||
win.document.getElementById('zotero-collections-tree').disabled = false;
|
||||
win.document.getElementById('zotero-items-tree').disabled = false;
|
||||
win.document.getElementById('zotero-pane-tab-catcher-top').hidden = true;
|
||||
win.document.getElementById('zotero-pane-tab-catcher-bottom').hidden = true;
|
||||
win.document.getElementById('zotero-pane-overlay').hidden = true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Clear entries that no longer exist from various tables
|
||||
*/
|
||||
|
|
|
@ -24,13 +24,13 @@
|
|||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* these are hacks do display a window separator in full screen mode on OS X */
|
||||
window #zotero-pane[fullscreenmode="true"][platform="mac"]
|
||||
/* these are hacks to display a window separator in full screen mode on OS X */
|
||||
window #zotero-pane-stack[fullscreenmode="true"][platform="mac"]
|
||||
{
|
||||
border-top: 1px solid #A3A3A3;
|
||||
}
|
||||
|
||||
window[active="true"] #zotero-pane[fullscreenmode="true"][platform="mac"]
|
||||
window[active="true"] #zotero-pane-stack[fullscreenmode="true"][platform="mac"]
|
||||
{
|
||||
border-top: 1px solid black;
|
||||
}
|
||||
|
@ -266,7 +266,7 @@ window[active="true"] #zotero-pane[fullscreenmode="true"][platform="mac"]
|
|||
list-style-image: url('chrome://zotero/skin/toolbar-fullscreen-top.png');
|
||||
}
|
||||
|
||||
#zotero-pane[fullscreenmode="true"] #zotero-tb-fullscreen
|
||||
#zotero-pane-stack[fullscreenmode="true"] #zotero-tb-fullscreen
|
||||
{
|
||||
background: #666666;
|
||||
-moz-border-radius: 6px;
|
||||
|
|
Loading…
Add table
Reference in a new issue