Move debug output logging to the Help menu
Adds a submenu for quickly generating and submitting debug output, with a button to copy the Debug ID to the clipboard and a one-click option to restart with logging enabled. Debug output can also now be viewed in real-time using the new debug output viewer window (previously available only via a command-line flag). The locale switcher has moved to the top of the Advanced prefpane (where Debug Output Logging used to go) in a Miscellaneous section, and there's a new "Advanced Configuration" section (mirroring Thunderbird) at the bottom for "Config Editor". Closes #1108
This commit is contained in:
parent
e3947e7b45
commit
c2bb4ac10b
8 changed files with 240 additions and 240 deletions
|
@ -30,7 +30,6 @@ Zotero_Preferences.Advanced = {
|
|||
|
||||
|
||||
init: function () {
|
||||
Zotero_Preferences.Debug_Output.init();
|
||||
Zotero_Preferences.Keys.init();
|
||||
|
||||
// Show Memory Info button if the Error Console menu option is enabled
|
||||
|
@ -782,202 +781,6 @@ Zotero_Preferences.Attachment_Base_Directory = {
|
|||
};
|
||||
|
||||
|
||||
Zotero_Preferences.Debug_Output = {
|
||||
_timer: null,
|
||||
|
||||
init: function () {
|
||||
var storing = Zotero.Debug.storing;
|
||||
this._updateButton();
|
||||
this.updateLines();
|
||||
if (storing) {
|
||||
this._initTimer();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
toggleStore: function () {
|
||||
this.setStore(!Zotero.Debug.storing);
|
||||
},
|
||||
|
||||
|
||||
setStore: function (set) {
|
||||
Zotero.Debug.setStore(set);
|
||||
if (set) {
|
||||
this._initTimer();
|
||||
}
|
||||
else {
|
||||
if (this._timerID) {
|
||||
this._timer.cancel();
|
||||
this._timerID = null;
|
||||
}
|
||||
}
|
||||
this._updateButton();
|
||||
this.updateLines();
|
||||
},
|
||||
|
||||
|
||||
view: function () {
|
||||
Zotero_Preferences.openInViewer("zotero://debug/");
|
||||
},
|
||||
|
||||
|
||||
submit: Zotero.Promise.coroutine(function* () {
|
||||
document.getElementById('debug-output-submit').disabled = true;
|
||||
var pm = document.getElementById('debug-output-submit-progress');
|
||||
pm.hidden = false;
|
||||
|
||||
Components.utils.import("resource://zotero/config.js");
|
||||
|
||||
var url = ZOTERO_CONFIG.REPOSITORY_URL + "report?debug=1";
|
||||
var output = yield Zotero.Debug.get(
|
||||
Zotero.Prefs.get('debug.store.submitSize'),
|
||||
Zotero.Prefs.get('debug.store.submitLineLength')
|
||||
);
|
||||
Zotero_Preferences.Debug_Output.setStore(false);
|
||||
|
||||
var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
|
||||
.getService(Components.interfaces.nsIPromptService);
|
||||
try {
|
||||
var xmlhttp = yield Zotero.HTTP.request(
|
||||
"POST",
|
||||
url,
|
||||
{
|
||||
compressBody: true,
|
||||
body: output,
|
||||
logBodyLength: 30,
|
||||
timeout: 30000,
|
||||
requestObserver: function (req) {
|
||||
// Don't fail during tests, with fake XHR
|
||||
if (!req.channel) {
|
||||
return;
|
||||
}
|
||||
req.channel.notificationCallbacks = {
|
||||
onProgress: function (request, context, progress, progressMax) {
|
||||
pm.mode = 'determined';
|
||||
if (!pm.value || progress > pm.value) {
|
||||
pm.value = progress;
|
||||
}
|
||||
if (!pm.max || progressMax > pm.max) {
|
||||
pm.max = progressMax;
|
||||
}
|
||||
},
|
||||
|
||||
// nsIInterfaceRequestor
|
||||
getInterface: function (iid) {
|
||||
try {
|
||||
return this.QueryInterface(iid);
|
||||
}
|
||||
catch (e) {
|
||||
throw Components.results.NS_NOINTERFACE;
|
||||
}
|
||||
},
|
||||
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Components.interfaces.nsISupports) ||
|
||||
iid.equals(Components.interfaces.nsIInterfaceRequestor) ||
|
||||
iid.equals(Components.interfaces.nsIProgressEventSink)) {
|
||||
return this;
|
||||
}
|
||||
throw Components.results.NS_NOINTERFACE;
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
catch (e) {
|
||||
Zotero.logError(e);
|
||||
let title = Zotero.getString('general.error');
|
||||
let msg;
|
||||
if (e instanceof Zotero.HTTP.UnexpectedStatusException) {
|
||||
msg = Zotero.getString('general.invalidResponseServer');
|
||||
}
|
||||
else if (e instanceof Zotero.HTTP.BrowserOfflineException) {
|
||||
msg = Zotero.getString('general.browserIsOffline', Zotero.appName);
|
||||
}
|
||||
else {
|
||||
msg = Zotero.getString('zotero.preferences.advanced.debug.error');
|
||||
}
|
||||
ps.alert(null, title, msg);
|
||||
return false;
|
||||
}
|
||||
|
||||
document.getElementById('debug-output-submit').disabled = false;
|
||||
document.getElementById('debug-output-submit-progress').hidden = true;
|
||||
|
||||
Zotero.debug(xmlhttp.responseText);
|
||||
|
||||
var reported = xmlhttp.responseXML.getElementsByTagName('reported');
|
||||
if (reported.length != 1) {
|
||||
ps.alert(
|
||||
null,
|
||||
Zotero.getString('general.error'),
|
||||
Zotero.getString('general.serverError')
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
var reportID = reported[0].getAttribute('reportID');
|
||||
ps.alert(
|
||||
null,
|
||||
Zotero.getString('zotero.preferences.advanced.debug.title'),
|
||||
Zotero.getString('zotero.preferences.advanced.debug.sent', reportID)
|
||||
);
|
||||
|
||||
return true;
|
||||
}),
|
||||
|
||||
|
||||
clear: function () {
|
||||
Zotero.Debug.clear();
|
||||
this.updateLines();
|
||||
},
|
||||
|
||||
|
||||
updateLines: function () {
|
||||
var enabled = Zotero.Debug.storing;
|
||||
var lines = Zotero.Debug.count();
|
||||
document.getElementById('debug-output-lines').value = lines;
|
||||
var empty = lines == 0;
|
||||
document.getElementById('debug-output-view').disabled = !enabled && empty;
|
||||
document.getElementById('debug-output-clear').disabled = empty;
|
||||
document.getElementById('debug-output-submit').disabled = empty;
|
||||
},
|
||||
|
||||
|
||||
_initTimer: function () {
|
||||
this._timer = Components.classes["@mozilla.org/timer;1"].
|
||||
createInstance(Components.interfaces.nsITimer);
|
||||
this._timer.initWithCallback({
|
||||
notify: function() {
|
||||
Zotero_Preferences.Debug_Output.updateLines();
|
||||
}
|
||||
}, 10000, Components.interfaces.nsITimer.TYPE_REPEATING_SLACK);
|
||||
},
|
||||
|
||||
|
||||
_updateButton: function () {
|
||||
var storing = Zotero.Debug.storing
|
||||
|
||||
var button = document.getElementById('debug-output-enable');
|
||||
if (storing) {
|
||||
button.label = Zotero.getString('general.disable');
|
||||
}
|
||||
else {
|
||||
button.label = Zotero.getString('general.enable');
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
onUnload: function () {
|
||||
if (this._timer) {
|
||||
this._timer.cancel();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Zotero_Preferences.Keys = {
|
||||
init: function () {
|
||||
var rows = document.getElementById('zotero-prefpane-advanced-keys-tab').getElementsByTagName('row');
|
||||
|
|
|
@ -71,26 +71,15 @@
|
|||
|
||||
<tabpanels id="zotero-prefpane-advanced-tabpanels">
|
||||
<tabpanel id="zotero-prefpane-advanced-general-tab" orient="vertical">
|
||||
<groupbox>
|
||||
<caption label="&zotero.preferences.debugOutputLogging;"/>
|
||||
|
||||
<!-- This doesn't wrap without an explicit width -->
|
||||
<vbox>
|
||||
<description width="45em">&zotero.preferences.debugOutputLogging.message;</description>
|
||||
</vbox>
|
||||
<groupbox id="zotero-prefpane-advanced-miscellaneous">
|
||||
<caption label="&zotero.preferences.miscellaneous;"/>
|
||||
|
||||
<hbox align="center">
|
||||
<button id="debug-output-enable" oncommand="Zotero_Preferences.Debug_Output.toggleStore()"/>
|
||||
<label id="debug-output-lines" style="margin-right: 0"/>
|
||||
<label value="&zotero.preferences.debugOutputLogging.linesLogged;"/>
|
||||
<checkbox preference="pref-debug-output-enableAfterRestart" label="&zotero.preferences.debugOutputLogging.enableAfterRestart;" style="margin-left: 1.5em"/>
|
||||
</hbox>
|
||||
|
||||
<hbox align="center">
|
||||
<button id="debug-output-view" label="&zotero.preferences.debugOutputLogging.viewOutput;" oncommand="Zotero_Preferences.Debug_Output.view()"/>
|
||||
<button id="debug-output-clear" label="&zotero.preferences.debugOutputLogging.clearOutput;" oncommand="Zotero_Preferences.Debug_Output.clear()"/>
|
||||
<button id="debug-output-submit" label="&zotero.preferences.debugOutputLogging.submitToServer;" oncommand="Zotero_Preferences.Debug_Output.submit()"/>
|
||||
<progressmeter id="debug-output-submit-progress" mode="undetermined" hidden="true"/>
|
||||
<label value="&zotero.bibliography.locale.label;"/>
|
||||
<menulist id="locale-menu"
|
||||
oncommand="Zotero_Preferences.Advanced.onLocaleChange()">
|
||||
<menupopup/>
|
||||
</menulist>
|
||||
</hbox>
|
||||
</groupbox>
|
||||
|
||||
|
@ -131,18 +120,8 @@
|
|||
</hbox>
|
||||
</groupbox>
|
||||
|
||||
<groupbox id="zotero-prefpane-advanced-miscellaneous">
|
||||
<caption label="&zotero.preferences.miscellaneous;"/>
|
||||
|
||||
<hbox align="center">
|
||||
<label value="&zotero.bibliography.locale.label;"/>
|
||||
<menulist id="locale-menu"
|
||||
oncommand="Zotero_Preferences.Advanced.onLocaleChange()">
|
||||
<menupopup/>
|
||||
</menulist>
|
||||
</hbox>
|
||||
|
||||
<separator/>
|
||||
<groupbox id="zotero-prefpane-advanced-advancedConfiguration">
|
||||
<caption label="&zotero.preferences.advanced.advancedConfiguration;"/>
|
||||
|
||||
<hbox id="zotero-prefpane-advanced-openbuttons" align="center" style="display: block">
|
||||
<button id="config-editor"
|
||||
|
|
|
@ -52,6 +52,8 @@ const ZoteroStandalone = new function() {
|
|||
document.getElementById('menu_errorConsole').hidden = false;
|
||||
}
|
||||
|
||||
ZoteroStandalone.DebugOutput.init();
|
||||
|
||||
Zotero.hideZoteroPaneOverlays();
|
||||
ZoteroPane.init();
|
||||
ZoteroPane.makeVisible();
|
||||
|
@ -197,6 +199,189 @@ const ZoteroStandalone = new function() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
ZoteroStandalone.DebugOutput = {
|
||||
_timer: null,
|
||||
|
||||
init: function () {
|
||||
var storing = Zotero.Debug.storing;
|
||||
this._showMenu();
|
||||
this.update();
|
||||
},
|
||||
|
||||
|
||||
toggleStore: function () {
|
||||
Zotero.Debug.setStore(!Zotero.Debug.storing);
|
||||
},
|
||||
|
||||
|
||||
update: function () {
|
||||
var enabled = Zotero.Debug.storing;
|
||||
var lines = Zotero.Debug.count();
|
||||
var empty = lines == 0;
|
||||
|
||||
// Show "Submit" when enabled, but leave disabled until there's output
|
||||
var menuitem = document.getElementById('debug-output-submit');
|
||||
menuitem.hidden = !enabled && empty;
|
||||
menuitem.disabled = empty;
|
||||
|
||||
// Toggle between "Enable" and "Disable"
|
||||
menuitem = document.getElementById('debug-output-enable-disable');
|
||||
menuitem.label = Zotero.getString('general.' + (enabled ? 'disable' : 'enable'));
|
||||
|
||||
// Update line count
|
||||
var str = Zotero.getString('zotero.debugOutputLogging.linesLogged', lines, lines);
|
||||
document.getElementById('debug-output-status').label = str;
|
||||
|
||||
// Enable "Clear" when there's output
|
||||
document.getElementById('debug-output-clear').disabled = empty;
|
||||
},
|
||||
|
||||
|
||||
submit: function () {
|
||||
// 'Zotero' isn't defined yet when this function is created, so do it inline
|
||||
return Zotero.Promise.coroutine(function* () {
|
||||
Components.utils.import("resource://zotero/config.js");
|
||||
|
||||
var url = ZOTERO_CONFIG.REPOSITORY_URL + "report?debug=1";
|
||||
var output = yield Zotero.Debug.get(
|
||||
Zotero.Prefs.get('debug.store.submitSize'),
|
||||
Zotero.Prefs.get('debug.store.submitLineLength')
|
||||
);
|
||||
Zotero.Debug.setStore(false);
|
||||
|
||||
var ps = Services.prompt;
|
||||
try {
|
||||
var xmlhttp = yield Zotero.HTTP.request(
|
||||
"POST",
|
||||
url,
|
||||
{
|
||||
compressBody: true,
|
||||
body: output,
|
||||
logBodyLength: 30,
|
||||
timeout: 15000,
|
||||
requestObserver: function (req) {
|
||||
// Don't fail during tests, with fake XHR
|
||||
if (!req.channel) {
|
||||
return;
|
||||
}
|
||||
req.channel.notificationCallbacks = {
|
||||
onProgress: function (request, context, progress, progressMax) {},
|
||||
|
||||
// nsIInterfaceRequestor
|
||||
getInterface: function (iid) {
|
||||
try {
|
||||
return this.QueryInterface(iid);
|
||||
}
|
||||
catch (e) {
|
||||
throw Components.results.NS_NOINTERFACE;
|
||||
}
|
||||
},
|
||||
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Components.interfaces.nsISupports) ||
|
||||
iid.equals(Components.interfaces.nsIInterfaceRequestor) ||
|
||||
iid.equals(Components.interfaces.nsIProgressEventSink)) {
|
||||
return this;
|
||||
}
|
||||
throw Components.results.NS_NOINTERFACE;
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
catch (e) {
|
||||
Zotero.logError(e);
|
||||
let title = Zotero.getString('general.error');
|
||||
let msg;
|
||||
if (e instanceof Zotero.HTTP.UnexpectedStatusException) {
|
||||
msg = Zotero.getString('general.invalidResponseServer');
|
||||
}
|
||||
else if (e instanceof Zotero.HTTP.BrowserOfflineException) {
|
||||
msg = Zotero.getString('general.browserIsOffline', Zotero.appName);
|
||||
}
|
||||
else {
|
||||
msg = Zotero.getString('zotero.debugOutputLogging.dialog.error');
|
||||
}
|
||||
ps.alert(null, title, msg);
|
||||
return false;
|
||||
}
|
||||
|
||||
Zotero.debug(xmlhttp.responseText);
|
||||
|
||||
var reported = xmlhttp.responseXML.getElementsByTagName('reported');
|
||||
if (reported.length != 1) {
|
||||
ps.alert(
|
||||
null,
|
||||
Zotero.getString('general.error'),
|
||||
Zotero.getString('general.serverError')
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
var reportID = reported[0].getAttribute('reportID');
|
||||
|
||||
var buttonFlags = ps.BUTTON_POS_0 * ps.BUTTON_TITLE_IS_STRING
|
||||
+ ps.BUTTON_POS_1 * ps.BUTTON_TITLE_CANCEL;
|
||||
var index = ps.confirmEx(
|
||||
null,
|
||||
Zotero.getString('zotero.debugOutputLogging.dialog.title'),
|
||||
Zotero.getString('zotero.debugOutputLogging.dialog.sent', [ZOTERO_CONFIG.DOMAIN_NAME, reportID]),
|
||||
buttonFlags,
|
||||
Zotero.getString('general.copyToClipboard'),
|
||||
null, null, null, {}
|
||||
);
|
||||
if (index == 0) {
|
||||
const helper = Components.classes["@mozilla.org/widget/clipboardhelper;1"]
|
||||
.getService(Components.interfaces.nsIClipboardHelper);
|
||||
helper.copyString("D" + reportID);
|
||||
}
|
||||
|
||||
Zotero.Debug.clear();
|
||||
return true;
|
||||
}.bind(this))();
|
||||
},
|
||||
|
||||
|
||||
view: function () {
|
||||
Zotero.openInViewer("chrome://zotero/content/debugViewer.html", function (doc) {
|
||||
var submitted = false;
|
||||
doc.querySelector('#submit-button').addEventListener('click', function (event) {
|
||||
submitted = true;
|
||||
});
|
||||
doc.querySelector('#clear-button').addEventListener('click', function (event) {
|
||||
Zotero.Debug.clear();
|
||||
});
|
||||
// If output has been submitted, disable logging when window is closed
|
||||
doc.defaultView.addEventListener('unload', function (event) {
|
||||
if (submitted) {
|
||||
Zotero.Debug.setStore(false);
|
||||
Zotero.Debug.clear();
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
clear: function () {
|
||||
Zotero.Debug.clear();
|
||||
},
|
||||
|
||||
|
||||
restartEnabled: function () {
|
||||
Zotero.Prefs.set('debug.store', true);
|
||||
Zotero.Utilities.Internal.quit(true);
|
||||
},
|
||||
|
||||
|
||||
_showMenu: function () {
|
||||
document.getElementById('debug-output-menu').hidden = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** Taken from browser.js **/
|
||||
function toJavaScriptConsole() {
|
||||
toOpenWindowByType("global:console", "chrome://global/content/console.xul");
|
||||
|
|
|
@ -207,6 +207,34 @@
|
|||
accesskey="&helpReportErrors.accesskey;"
|
||||
label="&helpReportErrors.label;"
|
||||
command="cmd_zotero_reportErrors"/>
|
||||
<menu id="debug-output-menu"
|
||||
accesskey="&debugOutputLogging.accesskey;"
|
||||
label="&debugOutputLogging.label;"
|
||||
hidden="true">
|
||||
<menupopup id="debug-output-popup"
|
||||
onpopupshowing="ZoteroStandalone.DebugOutput.update()">
|
||||
<menuitem id="debug-output-submit"
|
||||
label="&debugOutputLogging.submit;"
|
||||
oncommand="ZoteroStandalone.DebugOutput.submit()"
|
||||
hidden="true"/>
|
||||
<menuitem id="debug-output-enable-disable"
|
||||
oncommand="ZoteroStandalone.DebugOutput.toggleStore()"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="debug-output-status" disabled="true"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="debug-output-view"
|
||||
label="&debugOutputLogging.view;"
|
||||
oncommand="ZoteroStandalone.DebugOutput.view()"/>
|
||||
<menuitem id="debug-output-clear"
|
||||
label="&debugOutputLogging.clear;"
|
||||
oncommand="ZoteroStandalone.DebugOutput.clear()"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="debug-output-restart-enabled"
|
||||
label="&debugOutputLogging.restartWithLoggingEnabled;"
|
||||
oncommand="ZoteroStandalone.DebugOutput.restartEnabled()"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
<menuseparator/>
|
||||
<menuitem id="checkForUpdates"
|
||||
accesskey="&helpCheckForUpdates.accesskey;"
|
||||
label="&helpCheckForUpdates.label;"
|
||||
|
|
|
@ -38,7 +38,7 @@ Zotero.Debug = new function () {
|
|||
* Debug logging can be set in several different ways:
|
||||
*
|
||||
* - via the debug.log pref in the client or connector
|
||||
* - by enabling debug output logging in the Advanced prefs in the client
|
||||
* - by enabling debug output logging from the Help menu
|
||||
* - by passing -ZoteroDebug or -ZoteroDebugText on the command line
|
||||
*
|
||||
* In the client, debug.log and -ZoteroDebugText enable logging via the terminal, while -ZoteroDebug
|
||||
|
@ -231,13 +231,14 @@ Zotero.Debug = new function () {
|
|||
|
||||
|
||||
this.getConsoleViewerOutput = function () {
|
||||
var queue = _consoleViewerQueue;
|
||||
var queue = _output.concat(_consoleViewerQueue);
|
||||
_consoleViewerQueue = [];
|
||||
return queue;
|
||||
}
|
||||
|
||||
|
||||
this.addConsoleViewerListener = function (listener) {
|
||||
this.enabled = _consoleViewer = true;
|
||||
_consoleViewerListener = listener;
|
||||
};
|
||||
|
||||
|
|
|
@ -175,6 +175,8 @@
|
|||
<!ENTITY zotero.preferences.advanced.filesAndFolders "Files and Folders">
|
||||
<!ENTITY zotero.preferences.advanced.keys "Shortcuts">
|
||||
|
||||
<!ENTITY zotero.preferences.advanced.advancedConfiguration "Advanced Configuration">
|
||||
|
||||
<!ENTITY zotero.preferences.prefpane.locate "Locate">
|
||||
<!ENTITY zotero.preferences.locate.locateEngineManager "Article Lookup Engine Manager">
|
||||
<!ENTITY zotero.preferences.locate.description "Description">
|
||||
|
@ -206,12 +208,4 @@
|
|||
<!ENTITY zotero.preferences.dbMaintenance.resetTranslators "Reset Translators…">
|
||||
<!ENTITY zotero.preferences.dbMaintenance.resetStyles "Reset Styles…">
|
||||
|
||||
<!ENTITY zotero.preferences.debugOutputLogging "Debug Output Logging">
|
||||
<!ENTITY zotero.preferences.debugOutputLogging.message "Debug output can help Zotero developers diagnose problems in Zotero. Debug logging will slow down Zotero, so you should generally leave it disabled unless a Zotero developer requests debug output.">
|
||||
<!ENTITY zotero.preferences.debugOutputLogging.linesLogged "lines logged">
|
||||
<!ENTITY zotero.preferences.debugOutputLogging.enableAfterRestart "Enable after restart">
|
||||
<!ENTITY zotero.preferences.debugOutputLogging.viewOutput "View Output">
|
||||
<!ENTITY zotero.preferences.debugOutputLogging.clearOutput "Clear Output">
|
||||
<!ENTITY zotero.preferences.debugOutputLogging.submitToServer "Submit to Zotero Server">
|
||||
|
||||
<!ENTITY zotero.preferences.configEditor "Config Editor">
|
||||
|
|
|
@ -75,5 +75,13 @@
|
|||
|
||||
<!ENTITY helpReportErrors.label "Report Errors…">
|
||||
<!ENTITY helpReportErrors.accesskey "R">
|
||||
|
||||
<!ENTITY debugOutputLogging.label "Debug Output Logging">
|
||||
<!ENTITY debugOutputLogging.accesskey "L">
|
||||
<!ENTITY debugOutputLogging.submit "Submit Output">
|
||||
<!ENTITY debugOutputLogging.view "View Output">
|
||||
<!ENTITY debugOutputLogging.clear "Clear Output">
|
||||
<!ENTITY debugOutputLogging.restartWithLoggingEnabled "Restart with Logging Enabled">
|
||||
|
||||
<!ENTITY helpCheckForUpdates.label "Check for Updates…">
|
||||
<!ENTITY helpCheckForUpdates.accesskey "U">
|
||||
|
|
|
@ -62,6 +62,7 @@ general.tryAgain = Try Again
|
|||
general.tryLater = Try Later
|
||||
general.showDirectory = Show Directory
|
||||
general.continue = Continue
|
||||
general.copyToClipboard = Copy to Clipboard
|
||||
|
||||
general.operationInProgress = A Zotero operation is currently in progress.
|
||||
general.operationInProgress.waitUntilFinished = Please wait until it has finished.
|
||||
|
@ -672,9 +673,10 @@ zotero.preferences.advanced.migrateDataDir.directoryWillBeMoved = Your %1
|
|||
zotero.preferences.advanced.migrateDataDir.appMustBeRestarted = %S must be restarted to complete the migration.
|
||||
zotero.preferences.advanced.migrateDataDir.manualMigration = You can also quit %1$S and move your existing data directory to %2$S manually, which may be faster for larger data directories. %3$S will automatically detect the new location.
|
||||
|
||||
zotero.preferences.advanced.debug.title = Debug Output Submitted
|
||||
zotero.preferences.advanced.debug.sent = Debug output has been sent to the Zotero server.\n\nThe Debug ID is D%S.
|
||||
zotero.preferences.advanced.debug.error = An error occurred sending debug output.
|
||||
zotero.debugOutputLogging.linesLogged = %1$S line logged;%1$S lines logged
|
||||
zotero.debugOutputLogging.dialog.title = Debug Output Submitted
|
||||
zotero.debugOutputLogging.dialog.sent = Debug output has been sent to %S.\n\nThe Debug ID is D%S.
|
||||
zotero.debugOutputLogging.dialog.error = An error occurred sending debug output.
|
||||
|
||||
dragAndDrop.existingFiles = The following files already existed in the destination directory and were not copied:
|
||||
dragAndDrop.filesNotFound = The following files were not found and could not be copied:
|
||||
|
|
Loading…
Reference in a new issue