2013-03-20 08:47:52 +00:00
|
|
|
|
/*
|
|
|
|
|
***** BEGIN LICENSE BLOCK *****
|
|
|
|
|
|
|
|
|
|
Copyright © 2006–2013 Center for History and New Media
|
|
|
|
|
George Mason University, Fairfax, Virginia, USA
|
|
|
|
|
http://zotero.org
|
|
|
|
|
|
|
|
|
|
This file is part of Zotero.
|
|
|
|
|
|
|
|
|
|
Zotero is free software: you can redistribute it and/or modify
|
|
|
|
|
it under the terms of the GNU Affero General Public License as published by
|
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
|
|
Zotero is distributed in the hope that it will be useful,
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
GNU Affero General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Affero General Public License
|
|
|
|
|
along with Zotero. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
|
|
***** END LICENSE BLOCK *****
|
|
|
|
|
*/
|
|
|
|
|
|
2017-07-21 09:30:49 +00:00
|
|
|
|
Components.utils.import("resource://gre/modules/Services.jsm");
|
2021-04-14 07:15:44 +00:00
|
|
|
|
import FilePicker from 'zotero/modules/filePicker';
|
2013-03-20 08:47:52 +00:00
|
|
|
|
|
|
|
|
|
Zotero_Preferences.Advanced = {
|
2021-08-13 10:05:18 +00:00
|
|
|
|
DEFAULT_OPENURL_RESOLVER: 'https://www.worldcat.org/registry/gateway',
|
2013-03-20 08:47:52 +00:00
|
|
|
|
|
2021-08-13 10:05:18 +00:00
|
|
|
|
_openURLResolvers: null,
|
2013-03-20 08:47:52 +00:00
|
|
|
|
|
|
|
|
|
init: function () {
|
2015-03-05 14:33:20 +00:00
|
|
|
|
Zotero_Preferences.Keys.init();
|
2016-11-01 06:14:25 +00:00
|
|
|
|
|
2019-08-02 06:56:26 +00:00
|
|
|
|
// Show Memory Info button
|
|
|
|
|
if (Zotero.Prefs.get('debug.memoryInfo')) {
|
2017-07-21 11:47:32 +00:00
|
|
|
|
document.getElementById('memory-info').hidden = false;
|
|
|
|
|
}
|
2020-12-21 10:20:17 +00:00
|
|
|
|
|
|
|
|
|
// This might not work for checkboxes if we later need to create them
|
|
|
|
|
// with html
|
|
|
|
|
var inputs = document.querySelectorAll('input[data-preference]');
|
|
|
|
|
for (let input of inputs) {
|
|
|
|
|
let preferenceName = input.dataset.preference;
|
|
|
|
|
input.addEventListener('change', function () {
|
|
|
|
|
let value = input.value;
|
|
|
|
|
Zotero.Prefs.set(preferenceName, value);
|
|
|
|
|
});
|
|
|
|
|
input.value = Zotero.Prefs.get(preferenceName);
|
|
|
|
|
}
|
2017-07-21 11:47:32 +00:00
|
|
|
|
|
2021-08-13 10:05:18 +00:00
|
|
|
|
// Set OpenURL resolver drop-down to last-known name
|
|
|
|
|
if (Zotero.Prefs.get('openURL.resolver')) {
|
|
|
|
|
let name = Zotero.Prefs.get('openURL.name');
|
|
|
|
|
if (name) {
|
|
|
|
|
document.getElementById('openurl-primary-popup').firstChild.setAttribute('label', name);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-01 06:14:25 +00:00
|
|
|
|
this.onDataDirLoad();
|
2017-07-21 09:30:49 +00:00
|
|
|
|
this.refreshLocale();
|
2013-03-20 08:47:52 +00:00
|
|
|
|
},
|
|
|
|
|
|
Data directory migration
This adds a new button to the Advanced prefs to migrate the data directory to
$HOME/Zotero. The button only appears if the data directory is set to the
default location within a profile directory (including the other program from
the one running, even though that's technically stored as a custom data
directory).
On Mac/Linux, directories within the data directory are moved with /bin/mv. On
Windows, or if that fails, they're copied recursively using OS.File.move()
(which annoyingly doesn't reliably support directory moving). The former should
be instantaneous on most systems (unless the data directory or 'storage' were
on a different filesystem from $HOME).
If the database fails to transfer, migration fails and the data directory
setting remains on the old directory. If the database transfers but other files
fail, the data directory setting is updated. In both cases, the user is
encouraged to migrate remaining files manually with a button that reveals the
directories and quits the program.
This isn't yet tested on Linux or Windows, and migration isn't yet suggested
automatically.
Adds Zotero.File.reveal(), Zotero.File.directoryIsEmpty(), and
Zotero.File.moveDirectory().
2016-11-12 19:20:34 +00:00
|
|
|
|
|
2018-03-07 09:20:26 +00:00
|
|
|
|
updateTranslators: Zotero.Promise.coroutine(function* () {
|
|
|
|
|
var updated = yield Zotero.Schema.updateFromRepository(Zotero.Schema.REPO_UPDATE_MANUAL);
|
|
|
|
|
var button = document.getElementById('updateButton');
|
|
|
|
|
if (button) {
|
|
|
|
|
if (updated===-1) {
|
|
|
|
|
var label = Zotero.getString('zotero.preferences.update.upToDate');
|
|
|
|
|
}
|
|
|
|
|
else if (updated) {
|
|
|
|
|
var label = Zotero.getString('zotero.preferences.update.updated');
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
var label = Zotero.getString('zotero.preferences.update.error');
|
|
|
|
|
}
|
|
|
|
|
button.setAttribute('label', label);
|
|
|
|
|
|
|
|
|
|
if (updated && Zotero_Preferences.Cite) {
|
|
|
|
|
yield Zotero_Preferences.Cite.refreshStylesList();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}),
|
|
|
|
|
|
|
|
|
|
|
Data directory migration
This adds a new button to the Advanced prefs to migrate the data directory to
$HOME/Zotero. The button only appears if the data directory is set to the
default location within a profile directory (including the other program from
the one running, even though that's technically stored as a custom data
directory).
On Mac/Linux, directories within the data directory are moved with /bin/mv. On
Windows, or if that fails, they're copied recursively using OS.File.move()
(which annoyingly doesn't reliably support directory moving). The former should
be instantaneous on most systems (unless the data directory or 'storage' were
on a different filesystem from $HOME).
If the database fails to transfer, migration fails and the data directory
setting remains on the old directory. If the database transfers but other files
fail, the data directory setting is updated. In both cases, the user is
encouraged to migrate remaining files manually with a button that reveals the
directories and quits the program.
This isn't yet tested on Linux or Windows, and migration isn't yet suggested
automatically.
Adds Zotero.File.reveal(), Zotero.File.directoryIsEmpty(), and
Zotero.File.moveDirectory().
2016-11-12 19:20:34 +00:00
|
|
|
|
migrateDataDirectory: Zotero.Promise.coroutine(function* () {
|
2016-11-27 03:41:26 +00:00
|
|
|
|
var currentDir = Zotero.DataDirectory.dir;
|
|
|
|
|
var defaultDir = Zotero.DataDirectory.defaultDir;
|
Data directory migration
This adds a new button to the Advanced prefs to migrate the data directory to
$HOME/Zotero. The button only appears if the data directory is set to the
default location within a profile directory (including the other program from
the one running, even though that's technically stored as a custom data
directory).
On Mac/Linux, directories within the data directory are moved with /bin/mv. On
Windows, or if that fails, they're copied recursively using OS.File.move()
(which annoyingly doesn't reliably support directory moving). The former should
be instantaneous on most systems (unless the data directory or 'storage' were
on a different filesystem from $HOME).
If the database fails to transfer, migration fails and the data directory
setting remains on the old directory. If the database transfers but other files
fail, the data directory setting is updated. In both cases, the user is
encouraged to migrate remaining files manually with a button that reveals the
directories and quits the program.
This isn't yet tested on Linux or Windows, and migration isn't yet suggested
automatically.
Adds Zotero.File.reveal(), Zotero.File.directoryIsEmpty(), and
Zotero.File.moveDirectory().
2016-11-12 19:20:34 +00:00
|
|
|
|
if (currentDir == defaultDir) {
|
|
|
|
|
Zotero.debug("Already using default directory");
|
|
|
|
|
return;
|
2013-03-20 08:47:52 +00:00
|
|
|
|
}
|
Data directory migration
This adds a new button to the Advanced prefs to migrate the data directory to
$HOME/Zotero. The button only appears if the data directory is set to the
default location within a profile directory (including the other program from
the one running, even though that's technically stored as a custom data
directory).
On Mac/Linux, directories within the data directory are moved with /bin/mv. On
Windows, or if that fails, they're copied recursively using OS.File.move()
(which annoyingly doesn't reliably support directory moving). The former should
be instantaneous on most systems (unless the data directory or 'storage' were
on a different filesystem from $HOME).
If the database fails to transfer, migration fails and the data directory
setting remains on the old directory. If the database transfers but other files
fail, the data directory setting is updated. In both cases, the user is
encouraged to migrate remaining files manually with a button that reveals the
directories and quits the program.
This isn't yet tested on Linux or Windows, and migration isn't yet suggested
automatically.
Adds Zotero.File.reveal(), Zotero.File.directoryIsEmpty(), and
Zotero.File.moveDirectory().
2016-11-12 19:20:34 +00:00
|
|
|
|
|
|
|
|
|
Components.utils.import("resource://zotero/config.js")
|
|
|
|
|
var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
|
|
|
|
|
.getService(Components.interfaces.nsIPromptService);
|
2016-12-14 07:12:48 +00:00
|
|
|
|
|
2017-07-24 12:38:25 +00:00
|
|
|
|
// If there's a migration marker, point data directory back to the current location and remove
|
|
|
|
|
// it to trigger the migration again
|
|
|
|
|
var marker = OS.Path.join(defaultDir, Zotero.DataDirectory.MIGRATION_MARKER);
|
|
|
|
|
if (yield OS.File.exists(marker)) {
|
|
|
|
|
Zotero.Prefs.clear('dataDir');
|
|
|
|
|
Zotero.Prefs.clear('useDataDir');
|
|
|
|
|
yield OS.File.remove(marker);
|
|
|
|
|
try {
|
|
|
|
|
yield OS.File.remove(OS.Path.join(defaultDir, '.DS_Store'));
|
|
|
|
|
}
|
|
|
|
|
catch (e) {}
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-14 07:12:48 +00:00
|
|
|
|
// ~/Zotero exists and is non-empty
|
|
|
|
|
if ((yield OS.File.exists(defaultDir)) && !(yield Zotero.File.directoryIsEmpty(defaultDir))) {
|
|
|
|
|
let buttonFlags = (ps.BUTTON_POS_0) * (ps.BUTTON_TITLE_IS_STRING)
|
|
|
|
|
+ (ps.BUTTON_POS_1) * (ps.BUTTON_TITLE_CANCEL);
|
|
|
|
|
let index = ps.confirmEx(
|
|
|
|
|
window,
|
|
|
|
|
Zotero.getString('general.error'),
|
|
|
|
|
Zotero.getString('zotero.preferences.advanced.migrateDataDir.directoryExists1', defaultDir)
|
|
|
|
|
+ "\n\n"
|
|
|
|
|
+ Zotero.getString('zotero.preferences.advanced.migrateDataDir.directoryExists2'),
|
|
|
|
|
buttonFlags,
|
|
|
|
|
Zotero.getString('general.showDirectory'),
|
|
|
|
|
null, null, null, {}
|
|
|
|
|
);
|
|
|
|
|
if (index == 0) {
|
|
|
|
|
yield Zotero.File.reveal(
|
|
|
|
|
// Windows opens the directory, which might be confusing here, so open parent instead
|
|
|
|
|
Zotero.isWin ? OS.Path.dirname(defaultDir) : defaultDir
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var additionalText = '';
|
|
|
|
|
if (Zotero.isWin) {
|
|
|
|
|
try {
|
|
|
|
|
let numItems = yield Zotero.DB.valueQueryAsync(
|
|
|
|
|
"SELECT COUNT(*) FROM itemAttachments WHERE linkMode IN (?, ?)",
|
|
|
|
|
[Zotero.Attachments.LINK_MODE_IMPORTED_FILE, Zotero.Attachments.LINK_MODE_IMPORTED_URL]
|
|
|
|
|
);
|
|
|
|
|
if (numItems > 100) {
|
|
|
|
|
additionalText = '\n\n' + Zotero.getString(
|
|
|
|
|
'zotero.preferences.advanced.migrateDataDir.manualMigration',
|
|
|
|
|
[Zotero.appName, defaultDir, ZOTERO_CONFIG.CLIENT_NAME]
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (e) {
|
|
|
|
|
Zotero.logError(e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Prompt to restart
|
Data directory migration
This adds a new button to the Advanced prefs to migrate the data directory to
$HOME/Zotero. The button only appears if the data directory is set to the
default location within a profile directory (including the other program from
the one running, even though that's technically stored as a custom data
directory).
On Mac/Linux, directories within the data directory are moved with /bin/mv. On
Windows, or if that fails, they're copied recursively using OS.File.move()
(which annoyingly doesn't reliably support directory moving). The former should
be instantaneous on most systems (unless the data directory or 'storage' were
on a different filesystem from $HOME).
If the database fails to transfer, migration fails and the data directory
setting remains on the old directory. If the database transfers but other files
fail, the data directory setting is updated. In both cases, the user is
encouraged to migrate remaining files manually with a button that reveals the
directories and quits the program.
This isn't yet tested on Linux or Windows, and migration isn't yet suggested
automatically.
Adds Zotero.File.reveal(), Zotero.File.directoryIsEmpty(), and
Zotero.File.moveDirectory().
2016-11-12 19:20:34 +00:00
|
|
|
|
var buttonFlags = (ps.BUTTON_POS_0) * (ps.BUTTON_TITLE_IS_STRING)
|
|
|
|
|
+ (ps.BUTTON_POS_1) * (ps.BUTTON_TITLE_CANCEL);
|
|
|
|
|
var index = ps.confirmEx(window,
|
|
|
|
|
Zotero.getString('zotero.preferences.advanced.migrateDataDir.title'),
|
|
|
|
|
Zotero.getString(
|
|
|
|
|
'zotero.preferences.advanced.migrateDataDir.directoryWillBeMoved',
|
|
|
|
|
[ZOTERO_CONFIG.CLIENT_NAME, defaultDir]
|
|
|
|
|
) + '\n\n'
|
|
|
|
|
+ Zotero.getString(
|
|
|
|
|
'zotero.preferences.advanced.migrateDataDir.appMustBeRestarted', Zotero.appName
|
2016-12-14 07:12:48 +00:00
|
|
|
|
) + additionalText,
|
Data directory migration
This adds a new button to the Advanced prefs to migrate the data directory to
$HOME/Zotero. The button only appears if the data directory is set to the
default location within a profile directory (including the other program from
the one running, even though that's technically stored as a custom data
directory).
On Mac/Linux, directories within the data directory are moved with /bin/mv. On
Windows, or if that fails, they're copied recursively using OS.File.move()
(which annoyingly doesn't reliably support directory moving). The former should
be instantaneous on most systems (unless the data directory or 'storage' were
on a different filesystem from $HOME).
If the database fails to transfer, migration fails and the data directory
setting remains on the old directory. If the database transfers but other files
fail, the data directory setting is updated. In both cases, the user is
encouraged to migrate remaining files manually with a button that reveals the
directories and quits the program.
This isn't yet tested on Linux or Windows, and migration isn't yet suggested
automatically.
Adds Zotero.File.reveal(), Zotero.File.directoryIsEmpty(), and
Zotero.File.moveDirectory().
2016-11-12 19:20:34 +00:00
|
|
|
|
buttonFlags,
|
2016-12-14 07:12:48 +00:00
|
|
|
|
Zotero.getString('general.continue'),
|
Data directory migration
This adds a new button to the Advanced prefs to migrate the data directory to
$HOME/Zotero. The button only appears if the data directory is set to the
default location within a profile directory (including the other program from
the one running, even though that's technically stored as a custom data
directory).
On Mac/Linux, directories within the data directory are moved with /bin/mv. On
Windows, or if that fails, they're copied recursively using OS.File.move()
(which annoyingly doesn't reliably support directory moving). The former should
be instantaneous on most systems (unless the data directory or 'storage' were
on a different filesystem from $HOME).
If the database fails to transfer, migration fails and the data directory
setting remains on the old directory. If the database transfers but other files
fail, the data directory setting is updated. In both cases, the user is
encouraged to migrate remaining files manually with a button that reveals the
directories and quits the program.
This isn't yet tested on Linux or Windows, and migration isn't yet suggested
automatically.
Adds Zotero.File.reveal(), Zotero.File.directoryIsEmpty(), and
Zotero.File.moveDirectory().
2016-11-12 19:20:34 +00:00
|
|
|
|
null, null, null, {}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (index == 0) {
|
2016-11-27 03:41:26 +00:00
|
|
|
|
yield Zotero.DataDirectory.markForMigration(currentDir);
|
Data directory migration
This adds a new button to the Advanced prefs to migrate the data directory to
$HOME/Zotero. The button only appears if the data directory is set to the
default location within a profile directory (including the other program from
the one running, even though that's technically stored as a custom data
directory).
On Mac/Linux, directories within the data directory are moved with /bin/mv. On
Windows, or if that fails, they're copied recursively using OS.File.move()
(which annoyingly doesn't reliably support directory moving). The former should
be instantaneous on most systems (unless the data directory or 'storage' were
on a different filesystem from $HOME).
If the database fails to transfer, migration fails and the data directory
setting remains on the old directory. If the database transfers but other files
fail, the data directory setting is updated. In both cases, the user is
encouraged to migrate remaining files manually with a button that reveals the
directories and quits the program.
This isn't yet tested on Linux or Windows, and migration isn't yet suggested
automatically.
Adds Zotero.File.reveal(), Zotero.File.directoryIsEmpty(), and
Zotero.File.moveDirectory().
2016-11-12 19:20:34 +00:00
|
|
|
|
Zotero.Utilities.Internal.quitZotero(true);
|
2013-03-20 08:47:52 +00:00
|
|
|
|
}
|
Data directory migration
This adds a new button to the Advanced prefs to migrate the data directory to
$HOME/Zotero. The button only appears if the data directory is set to the
default location within a profile directory (including the other program from
the one running, even though that's technically stored as a custom data
directory).
On Mac/Linux, directories within the data directory are moved with /bin/mv. On
Windows, or if that fails, they're copied recursively using OS.File.move()
(which annoyingly doesn't reliably support directory moving). The former should
be instantaneous on most systems (unless the data directory or 'storage' were
on a different filesystem from $HOME).
If the database fails to transfer, migration fails and the data directory
setting remains on the old directory. If the database transfers but other files
fail, the data directory setting is updated. In both cases, the user is
encouraged to migrate remaining files manually with a button that reveals the
directories and quits the program.
This isn't yet tested on Linux or Windows, and migration isn't yet suggested
automatically.
Adds Zotero.File.reveal(), Zotero.File.directoryIsEmpty(), and
Zotero.File.moveDirectory().
2016-11-12 19:20:34 +00:00
|
|
|
|
}),
|
2013-03-20 08:47:52 +00:00
|
|
|
|
|
|
|
|
|
|
2017-12-15 04:49:08 +00:00
|
|
|
|
runIntegrityCheck: async function (button) {
|
|
|
|
|
button.disabled = true;
|
2013-03-20 08:47:52 +00:00
|
|
|
|
|
2017-12-15 04:49:08 +00:00
|
|
|
|
try {
|
|
|
|
|
let ps = Services.prompt;
|
|
|
|
|
|
|
|
|
|
var ok = await Zotero.DB.integrityCheck();
|
|
|
|
|
if (ok) {
|
|
|
|
|
ok = await Zotero.Schema.integrityCheck();
|
|
|
|
|
if (!ok) {
|
|
|
|
|
var buttonFlags = (ps.BUTTON_POS_0) * (ps.BUTTON_TITLE_IS_STRING)
|
|
|
|
|
+ (ps.BUTTON_POS_1) * (ps.BUTTON_TITLE_CANCEL);
|
|
|
|
|
var index = ps.confirmEx(window,
|
|
|
|
|
Zotero.getString('general.failed'),
|
|
|
|
|
Zotero.getString('db.integrityCheck.failed') + "\n\n" +
|
|
|
|
|
Zotero.getString('db.integrityCheck.repairAttempt') + " " +
|
|
|
|
|
Zotero.getString('db.integrityCheck.appRestartNeeded', Zotero.appName),
|
2013-03-20 08:47:52 +00:00
|
|
|
|
buttonFlags,
|
2017-12-15 04:49:08 +00:00
|
|
|
|
Zotero.getString('db.integrityCheck.fixAndRestart', Zotero.appName),
|
2013-03-20 08:47:52 +00:00
|
|
|
|
null, null, null, {}
|
|
|
|
|
);
|
|
|
|
|
|
2017-12-15 04:49:08 +00:00
|
|
|
|
if (index == 0) {
|
|
|
|
|
// Safety first
|
|
|
|
|
await Zotero.DB.backupDatabase();
|
|
|
|
|
|
|
|
|
|
// Fix the errors
|
|
|
|
|
await Zotero.Schema.integrityCheck(true);
|
|
|
|
|
|
|
|
|
|
// And run the check again
|
|
|
|
|
ok = await Zotero.Schema.integrityCheck();
|
|
|
|
|
var buttonFlags = (ps.BUTTON_POS_0) * (ps.BUTTON_TITLE_IS_STRING);
|
|
|
|
|
if (ok) {
|
|
|
|
|
var str = 'success';
|
|
|
|
|
var msg = Zotero.getString('db.integrityCheck.errorsFixed');
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
var str = 'failed';
|
|
|
|
|
var msg = Zotero.getString('db.integrityCheck.errorsNotFixed')
|
|
|
|
|
+ "\n\n" + Zotero.getString('db.integrityCheck.reportInForums');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ps.confirmEx(window,
|
|
|
|
|
Zotero.getString('general.' + str),
|
|
|
|
|
msg,
|
|
|
|
|
buttonFlags,
|
|
|
|
|
Zotero.getString('general.restartApp', Zotero.appName),
|
|
|
|
|
null, null, null, {}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
var appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"]
|
|
|
|
|
.getService(Components.interfaces.nsIAppStartup);
|
|
|
|
|
appStartup.quit(Components.interfaces.nsIAppStartup.eAttemptQuit
|
|
|
|
|
| Components.interfaces.nsIAppStartup.eRestart);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return;
|
2013-03-20 08:47:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-12-15 04:49:08 +00:00
|
|
|
|
try {
|
|
|
|
|
await Zotero.DB.vacuum();
|
|
|
|
|
}
|
|
|
|
|
catch (e) {
|
|
|
|
|
Zotero.logError(e);
|
|
|
|
|
ok = false;
|
|
|
|
|
}
|
2013-03-20 08:47:52 +00:00
|
|
|
|
}
|
2017-12-15 04:49:08 +00:00
|
|
|
|
var str = ok ? 'passed' : 'failed';
|
2017-05-30 01:25:23 +00:00
|
|
|
|
|
2017-12-15 04:49:08 +00:00
|
|
|
|
ps.alert(window,
|
|
|
|
|
Zotero.getString('general.' + str),
|
|
|
|
|
Zotero.getString('db.integrityCheck.' + str)
|
|
|
|
|
+ (!ok ? "\n\n" + Zotero.getString('db.integrityCheck.dbRepairTool') : ''));
|
2013-03-20 08:47:52 +00:00
|
|
|
|
}
|
2017-12-15 04:49:08 +00:00
|
|
|
|
finally {
|
|
|
|
|
button.disabled = false;
|
|
|
|
|
}
|
|
|
|
|
},
|
2013-03-20 08:47:52 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
resetTranslatorsAndStyles: function () {
|
|
|
|
|
var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
|
|
|
|
|
.getService(Components.interfaces.nsIPromptService);
|
|
|
|
|
|
|
|
|
|
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('general.warning'),
|
|
|
|
|
Zotero.getString('zotero.preferences.advanced.resetTranslatorsAndStyles.changesLost'),
|
|
|
|
|
buttonFlags,
|
|
|
|
|
Zotero.getString('zotero.preferences.advanced.resetTranslatorsAndStyles'),
|
|
|
|
|
null, null, null, {});
|
|
|
|
|
|
|
|
|
|
if (index == 0) {
|
2013-08-16 03:21:57 +00:00
|
|
|
|
Zotero.Schema.resetTranslatorsAndStyles()
|
|
|
|
|
.then(function () {
|
2013-05-10 18:49:29 +00:00
|
|
|
|
if (Zotero_Preferences.Export) {
|
|
|
|
|
Zotero_Preferences.Export.populateQuickCopyList();
|
|
|
|
|
}
|
2015-03-22 06:06:40 +00:00
|
|
|
|
});
|
2013-03-20 08:47:52 +00:00
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
2017-06-19 04:43:24 +00:00
|
|
|
|
resetTranslators: async function () {
|
2013-03-20 08:47:52 +00:00
|
|
|
|
var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
|
|
|
|
|
.getService(Components.interfaces.nsIPromptService);
|
|
|
|
|
|
|
|
|
|
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('general.warning'),
|
|
|
|
|
Zotero.getString('zotero.preferences.advanced.resetTranslators.changesLost'),
|
|
|
|
|
buttonFlags,
|
|
|
|
|
Zotero.getString('zotero.preferences.advanced.resetTranslators'),
|
|
|
|
|
null, null, null, {});
|
|
|
|
|
|
|
|
|
|
if (index == 0) {
|
2017-06-19 04:43:24 +00:00
|
|
|
|
let button = document.getElementById('reset-translators-button');
|
|
|
|
|
button.disabled = true;
|
|
|
|
|
try {
|
|
|
|
|
await Zotero.Schema.resetTranslators();
|
2013-05-10 18:51:41 +00:00
|
|
|
|
if (Zotero_Preferences.Export) {
|
|
|
|
|
Zotero_Preferences.Export.populateQuickCopyList();
|
|
|
|
|
}
|
2017-06-19 04:43:24 +00:00
|
|
|
|
}
|
|
|
|
|
finally {
|
|
|
|
|
button.disabled = false;
|
|
|
|
|
}
|
2013-03-20 08:47:52 +00:00
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
2017-06-19 04:43:24 +00:00
|
|
|
|
resetStyles: async function () {
|
2013-03-20 08:47:52 +00:00
|
|
|
|
var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
|
|
|
|
|
.getService(Components.interfaces.nsIPromptService);
|
|
|
|
|
|
|
|
|
|
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('general.warning'),
|
|
|
|
|
Zotero.getString('zotero.preferences.advanced.resetStyles.changesLost'),
|
|
|
|
|
buttonFlags,
|
|
|
|
|
Zotero.getString('zotero.preferences.advanced.resetStyles'),
|
|
|
|
|
null, null, null, {});
|
|
|
|
|
|
|
|
|
|
if (index == 0) {
|
2017-06-19 04:43:24 +00:00
|
|
|
|
let button = document.getElementById('reset-styles-button');
|
|
|
|
|
button.disabled = true;
|
|
|
|
|
try {
|
|
|
|
|
await Zotero.Schema.resetStyles()
|
2013-05-10 18:49:29 +00:00
|
|
|
|
if (Zotero_Preferences.Export) {
|
|
|
|
|
Zotero_Preferences.Export.populateQuickCopyList();
|
|
|
|
|
}
|
2017-06-19 04:43:24 +00:00
|
|
|
|
}
|
|
|
|
|
finally {
|
|
|
|
|
button.disabled = false;
|
|
|
|
|
}
|
2013-03-20 08:47:52 +00:00
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
onDataDirLoad: function () {
|
|
|
|
|
var useDataDir = Zotero.Prefs.get('useDataDir');
|
2016-11-01 06:14:25 +00:00
|
|
|
|
var dataDir = Zotero.Prefs.get('lastDataDir') || Zotero.Prefs.get('dataDir');
|
2016-11-27 03:41:26 +00:00
|
|
|
|
var currentDir = Zotero.DataDirectory.dir;
|
|
|
|
|
var defaultDataDir = Zotero.DataDirectory.defaultDir;
|
2016-11-01 06:14:25 +00:00
|
|
|
|
|
2017-09-11 07:49:06 +00:00
|
|
|
|
if (Zotero.forceDataDir) {
|
|
|
|
|
document.getElementById('command-line-data-dir-path').textContent = currentDir;
|
|
|
|
|
document.getElementById('command-line-data-dir').hidden = false;
|
|
|
|
|
document.getElementById('data-dir').hidden = true;
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-01 06:14:25 +00:00
|
|
|
|
// Change "Use profile directory" label to home directory location unless using profile dir
|
Data directory migration
This adds a new button to the Advanced prefs to migrate the data directory to
$HOME/Zotero. The button only appears if the data directory is set to the
default location within a profile directory (including the other program from
the one running, even though that's technically stored as a custom data
directory).
On Mac/Linux, directories within the data directory are moved with /bin/mv. On
Windows, or if that fails, they're copied recursively using OS.File.move()
(which annoyingly doesn't reliably support directory moving). The former should
be instantaneous on most systems (unless the data directory or 'storage' were
on a different filesystem from $HOME).
If the database fails to transfer, migration fails and the data directory
setting remains on the old directory. If the database transfers but other files
fail, the data directory setting is updated. In both cases, the user is
encouraged to migrate remaining files manually with a button that reveals the
directories and quits the program.
This isn't yet tested on Linux or Windows, and migration isn't yet suggested
automatically.
Adds Zotero.File.reveal(), Zotero.File.directoryIsEmpty(), and
Zotero.File.moveDirectory().
2016-11-12 19:20:34 +00:00
|
|
|
|
if (useDataDir || currentDir == defaultDataDir) {
|
|
|
|
|
document.getElementById('default-data-dir').setAttribute(
|
2016-11-27 03:41:26 +00:00
|
|
|
|
'label', Zotero.getString('dataDir.default', Zotero.DataDirectory.defaultDir)
|
2016-11-01 06:14:25 +00:00
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Don't show custom data dir as in-use if set to the default
|
|
|
|
|
if (dataDir == defaultDataDir) {
|
|
|
|
|
useDataDir = false;
|
|
|
|
|
}
|
|
|
|
|
|
Data directory migration
This adds a new button to the Advanced prefs to migrate the data directory to
$HOME/Zotero. The button only appears if the data directory is set to the
default location within a profile directory (including the other program from
the one running, even though that's technically stored as a custom data
directory).
On Mac/Linux, directories within the data directory are moved with /bin/mv. On
Windows, or if that fails, they're copied recursively using OS.File.move()
(which annoyingly doesn't reliably support directory moving). The former should
be instantaneous on most systems (unless the data directory or 'storage' were
on a different filesystem from $HOME).
If the database fails to transfer, migration fails and the data directory
setting remains on the old directory. If the database transfers but other files
fail, the data directory setting is updated. In both cases, the user is
encouraged to migrate remaining files manually with a button that reveals the
directories and quits the program.
This isn't yet tested on Linux or Windows, and migration isn't yet suggested
automatically.
Adds Zotero.File.reveal(), Zotero.File.directoryIsEmpty(), and
Zotero.File.moveDirectory().
2016-11-12 19:20:34 +00:00
|
|
|
|
document.getElementById('data-dir-path').setAttribute('disabled', !useDataDir);
|
|
|
|
|
document.getElementById('migrate-data-dir').setAttribute(
|
2016-11-27 03:41:26 +00:00
|
|
|
|
'hidden', !Zotero.DataDirectory.canMigrate()
|
Data directory migration
This adds a new button to the Advanced prefs to migrate the data directory to
$HOME/Zotero. The button only appears if the data directory is set to the
default location within a profile directory (including the other program from
the one running, even though that's technically stored as a custom data
directory).
On Mac/Linux, directories within the data directory are moved with /bin/mv. On
Windows, or if that fails, they're copied recursively using OS.File.move()
(which annoyingly doesn't reliably support directory moving). The former should
be instantaneous on most systems (unless the data directory or 'storage' were
on a different filesystem from $HOME).
If the database fails to transfer, migration fails and the data directory
setting remains on the old directory. If the database transfers but other files
fail, the data directory setting is updated. In both cases, the user is
encouraged to migrate remaining files manually with a button that reveals the
directories and quits the program.
This isn't yet tested on Linux or Windows, and migration isn't yet suggested
automatically.
Adds Zotero.File.reveal(), Zotero.File.directoryIsEmpty(), and
Zotero.File.moveDirectory().
2016-11-12 19:20:34 +00:00
|
|
|
|
);
|
2016-11-01 06:14:25 +00:00
|
|
|
|
|
|
|
|
|
return useDataDir;
|
2013-03-20 08:47:52 +00:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
2016-12-04 19:18:43 +00:00
|
|
|
|
onDataDirUpdate: Zotero.Promise.coroutine(function* (event, forceNew) {
|
Data directory migration
This adds a new button to the Advanced prefs to migrate the data directory to
$HOME/Zotero. The button only appears if the data directory is set to the
default location within a profile directory (including the other program from
the one running, even though that's technically stored as a custom data
directory).
On Mac/Linux, directories within the data directory are moved with /bin/mv. On
Windows, or if that fails, they're copied recursively using OS.File.move()
(which annoyingly doesn't reliably support directory moving). The former should
be instantaneous on most systems (unless the data directory or 'storage' were
on a different filesystem from $HOME).
If the database fails to transfer, migration fails and the data directory
setting remains on the old directory. If the database transfers but other files
fail, the data directory setting is updated. In both cases, the user is
encouraged to migrate remaining files manually with a button that reveals the
directories and quits the program.
This isn't yet tested on Linux or Windows, and migration isn't yet suggested
automatically.
Adds Zotero.File.reveal(), Zotero.File.directoryIsEmpty(), and
Zotero.File.moveDirectory().
2016-11-12 19:20:34 +00:00
|
|
|
|
var radiogroup = document.getElementById('data-dir');
|
2015-11-04 19:30:25 +00:00
|
|
|
|
var newUseDataDir = radiogroup.selectedIndex == 1;
|
2013-03-20 08:47:52 +00:00
|
|
|
|
|
2016-12-04 19:18:43 +00:00
|
|
|
|
if (!forceNew && newUseDataDir && !this._usingDefaultDataDir()) {
|
2015-11-04 19:30:25 +00:00
|
|
|
|
return;
|
2013-03-20 18:55:50 +00:00
|
|
|
|
}
|
2016-11-01 06:14:25 +00:00
|
|
|
|
|
|
|
|
|
// This call shows a filepicker if needed, forces a restart if required, and does nothing if
|
|
|
|
|
// cancel was pressed or value hasn't changed
|
2016-11-27 03:41:26 +00:00
|
|
|
|
yield Zotero.DataDirectory.choose(
|
|
|
|
|
true,
|
|
|
|
|
!newUseDataDir,
|
2020-05-15 23:24:45 +00:00
|
|
|
|
() => Zotero_Preferences.openURL('https://www.zotero.org/support/zotero_data')
|
2016-11-27 03:41:26 +00:00
|
|
|
|
);
|
2016-11-01 06:14:25 +00:00
|
|
|
|
radiogroup.selectedIndex = this._usingDefaultDataDir() ? 0 : 1;
|
2016-11-27 03:41:26 +00:00
|
|
|
|
}),
|
2013-03-20 08:47:52 +00:00
|
|
|
|
|
|
|
|
|
|
2015-11-04 19:30:25 +00:00
|
|
|
|
chooseDataDir: function(event) {
|
Data directory migration
This adds a new button to the Advanced prefs to migrate the data directory to
$HOME/Zotero. The button only appears if the data directory is set to the
default location within a profile directory (including the other program from
the one running, even though that's technically stored as a custom data
directory).
On Mac/Linux, directories within the data directory are moved with /bin/mv. On
Windows, or if that fails, they're copied recursively using OS.File.move()
(which annoyingly doesn't reliably support directory moving). The former should
be instantaneous on most systems (unless the data directory or 'storage' were
on a different filesystem from $HOME).
If the database fails to transfer, migration fails and the data directory
setting remains on the old directory. If the database transfers but other files
fail, the data directory setting is updated. In both cases, the user is
encouraged to migrate remaining files manually with a button that reveals the
directories and quits the program.
This isn't yet tested on Linux or Windows, and migration isn't yet suggested
automatically.
Adds Zotero.File.reveal(), Zotero.File.directoryIsEmpty(), and
Zotero.File.moveDirectory().
2016-11-12 19:20:34 +00:00
|
|
|
|
document.getElementById('data-dir').selectedIndex = 1;
|
2016-12-04 19:18:43 +00:00
|
|
|
|
this.onDataDirUpdate(event, true);
|
2015-11-04 19:30:25 +00:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
2013-03-20 08:47:52 +00:00
|
|
|
|
getDataDirPath: function () {
|
2016-10-31 08:05:45 +00:00
|
|
|
|
// TEMP: lastDataDir can be removed once old persistent descriptors have been
|
|
|
|
|
// converted, which they are in getZoteroDirectory() in 5.0
|
2016-11-01 06:14:25 +00:00
|
|
|
|
var prefValue = Zotero.Prefs.get('lastDataDir') || Zotero.Prefs.get('dataDir');
|
|
|
|
|
|
|
|
|
|
// Don't show path if the default
|
2016-11-27 03:41:26 +00:00
|
|
|
|
if (prefValue == Zotero.DataDirectory.defaultDir) {
|
2016-11-01 06:14:25 +00:00
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return prefValue || '';
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_usingDefaultDataDir: function () {
|
|
|
|
|
// Legacy profile directory location
|
|
|
|
|
if (!Zotero.Prefs.get('useDataDir')) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var dataDir = Zotero.Prefs.get('lastDataDir') || Zotero.Prefs.get('dataDir');
|
|
|
|
|
// Default home directory location
|
2016-11-27 03:41:26 +00:00
|
|
|
|
if (dataDir == Zotero.DataDirectory.defaultDir) {
|
2016-11-01 06:14:25 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
2013-03-20 08:47:52 +00:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
2021-08-13 10:05:18 +00:00
|
|
|
|
handleOpenURLPopupShowing: async function (event) {
|
|
|
|
|
if (event.target.id != 'openurl-primary-popup') {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (!this._openURLResolvers) {
|
|
|
|
|
let menupopup = document.getElementById('openurl-primary-popup');
|
|
|
|
|
menupopup.firstChild.setAttribute('label', Zotero.getString('general.loading'));
|
|
|
|
|
try {
|
|
|
|
|
this._openURLResolvers = await Zotero.Utilities.Internal.OpenURL.getResolvers();
|
|
|
|
|
}
|
|
|
|
|
catch (e) {
|
|
|
|
|
Zotero.logError(e);
|
|
|
|
|
menupopup.firstChild.setAttribute('label', "Error loading resolvers");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
this.updateOpenURLResolversMenu();
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
updateOpenURLResolversMenu: function () {
|
|
|
|
|
if (!this._openURLResolvers) {
|
|
|
|
|
Zotero.debug("Resolvers not loaded -- not updating menu");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var currentResolver = Zotero.Prefs.get('openURL.resolver');
|
|
|
|
|
|
|
|
|
|
var openURLMenu = document.getElementById('openurl-menu');
|
|
|
|
|
var menupopup = openURLMenu.firstChild;
|
|
|
|
|
menupopup.innerHTML = '';
|
|
|
|
|
|
|
|
|
|
var defaultMenuItem = document.createElement('menuitem');
|
|
|
|
|
defaultMenuItem.setAttribute('label', Zotero.getString('general.default'));
|
|
|
|
|
defaultMenuItem.setAttribute('value', this.DEFAULT_OPENURL_RESOLVER);
|
|
|
|
|
defaultMenuItem.setAttribute('type', 'checkbox');
|
|
|
|
|
menupopup.appendChild(defaultMenuItem);
|
2013-03-20 08:47:52 +00:00
|
|
|
|
|
2021-08-13 10:05:18 +00:00
|
|
|
|
var customMenuItem = document.createElement('menuitem');
|
|
|
|
|
customMenuItem.setAttribute('label', Zotero.getString('general.custom'));
|
|
|
|
|
customMenuItem.setAttribute('value', 'custom');
|
|
|
|
|
customMenuItem.setAttribute('type', 'checkbox');
|
|
|
|
|
menupopup.appendChild(customMenuItem);
|
|
|
|
|
|
|
|
|
|
menupopup.appendChild(document.createElement('menuseparator'));
|
|
|
|
|
|
|
|
|
|
var selectedName;
|
|
|
|
|
var lastContinent;
|
|
|
|
|
var lastCountry;
|
|
|
|
|
var currentContinentPopup;
|
|
|
|
|
var currentMenuPopup;
|
2016-05-03 21:51:12 +00:00
|
|
|
|
for (let r of this._openURLResolvers) {
|
2021-08-13 10:05:18 +00:00
|
|
|
|
// Create submenus for continents
|
|
|
|
|
if (r.continent != lastContinent) {
|
|
|
|
|
let menu = document.createElement('menu');
|
|
|
|
|
menu.setAttribute('label', r.continent);
|
|
|
|
|
openURLMenu.firstChild.appendChild(menu);
|
|
|
|
|
|
|
|
|
|
currentContinentPopup = currentMenuPopup = document.createElement('menupopup');
|
|
|
|
|
menu.appendChild(currentContinentPopup);
|
|
|
|
|
lastContinent = r.continent;
|
|
|
|
|
}
|
|
|
|
|
if (r.country != lastCountry) {
|
|
|
|
|
// If there's a country, create a submenu for it
|
|
|
|
|
if (r.country) {
|
|
|
|
|
let menu = document.createElement('menu');
|
|
|
|
|
menu.setAttribute('label', r.country);
|
|
|
|
|
currentContinentPopup.appendChild(menu);
|
|
|
|
|
|
|
|
|
|
let menupopup = document.createElement('menupopup');
|
|
|
|
|
menu.appendChild(menupopup);
|
|
|
|
|
currentMenuPopup = menupopup;
|
|
|
|
|
}
|
|
|
|
|
// Otherwise use the continent popup
|
|
|
|
|
else {
|
|
|
|
|
currentMenuPopup = currentContinentPopup;
|
|
|
|
|
}
|
|
|
|
|
lastCountry = r.country;
|
|
|
|
|
}
|
|
|
|
|
let menuitem = document.createElement('menuitem');
|
|
|
|
|
menuitem.setAttribute('label', r.name);
|
|
|
|
|
menuitem.setAttribute('value', r.url);
|
|
|
|
|
menuitem.setAttribute('type', 'checkbox');
|
|
|
|
|
currentMenuPopup.appendChild(menuitem);
|
|
|
|
|
var checked = r.url == Zotero.Prefs.get('openURL.resolver');
|
|
|
|
|
menuitem.setAttribute('checked', checked);
|
|
|
|
|
if (checked) {
|
|
|
|
|
selectedName = r.name;
|
2013-03-20 08:47:52 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-13 10:05:18 +00:00
|
|
|
|
// Default
|
|
|
|
|
if (currentResolver == this.DEFAULT_OPENURL_RESOLVER) {
|
|
|
|
|
openURLMenu.setAttribute('label', Zotero.getString('general.default'));
|
|
|
|
|
defaultMenuItem.setAttribute('checked', true);
|
|
|
|
|
Zotero.Prefs.clear('openURL.name');
|
|
|
|
|
}
|
|
|
|
|
else if (selectedName) {
|
|
|
|
|
openURLMenu.setAttribute('label', selectedName);
|
|
|
|
|
// If we found a match, update stored name
|
|
|
|
|
Zotero.Prefs.set('openURL.name', selectedName);
|
|
|
|
|
}
|
|
|
|
|
// Custom
|
|
|
|
|
else {
|
|
|
|
|
openURLMenu.setAttribute('label', Zotero.getString('general.custom'));
|
|
|
|
|
customMenuItem.setAttribute('checked', true);
|
|
|
|
|
Zotero.Prefs.clear('openURL.name');
|
2013-03-20 08:47:52 +00:00
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
2021-08-13 10:05:18 +00:00
|
|
|
|
handleOpenURLSelected: function (event) {
|
|
|
|
|
event.stopPropagation();
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
|
|
|
|
|
if (event.target.localName != 'menuitem') {
|
|
|
|
|
Zotero.debug("Ignoring click on " + event.target.localName);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var openURLMenu = document.getElementById('openurl-menu');
|
|
|
|
|
|
2013-03-20 08:47:52 +00:00
|
|
|
|
var openURLServerField = document.getElementById('openURLServerField');
|
|
|
|
|
var openURLVersionMenu = document.getElementById('openURLVersionMenu');
|
|
|
|
|
|
2021-08-13 10:05:18 +00:00
|
|
|
|
// Default
|
|
|
|
|
if (event.target.value == this.DEFAULT_OPENURL_RESOLVER) {
|
|
|
|
|
Zotero.Prefs.clear('openURL.name');
|
|
|
|
|
Zotero.Prefs.clear('openURL.resolver');
|
|
|
|
|
Zotero.Prefs.clear('openURL.version');
|
|
|
|
|
openURLServerField.value = this.DEFAULT_OPENURL_RESOLVER;
|
|
|
|
|
}
|
|
|
|
|
// If "Custom" selected, clear URL field
|
|
|
|
|
else if (event.target.value == "custom") {
|
|
|
|
|
Zotero.Prefs.clear('openURL.name');
|
|
|
|
|
Zotero.Prefs.set('openURL.resolver', '');
|
|
|
|
|
Zotero.Prefs.clear('openURL.version');
|
|
|
|
|
openURLServerField.value = '';
|
2013-03-20 08:47:52 +00:00
|
|
|
|
openURLServerField.focus();
|
|
|
|
|
}
|
2021-08-13 10:05:18 +00:00
|
|
|
|
else {
|
|
|
|
|
Zotero.Prefs.set('openURL.name', openURLServerField.value = event.target.label);
|
|
|
|
|
Zotero.Prefs.set('openURL.resolver', openURLServerField.value = event.target.value);
|
|
|
|
|
Zotero.Prefs.set('openURL.version', openURLVersionMenu.value = "1.0");
|
2013-03-20 08:47:52 +00:00
|
|
|
|
}
|
2021-08-13 10:05:18 +00:00
|
|
|
|
|
|
|
|
|
openURLMenu.firstChild.hidePopup();
|
|
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
this.updateOpenURLResolversMenu();
|
|
|
|
|
});
|
2013-03-20 08:47:52 +00:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
onOpenURLCustomized: function () {
|
2021-08-13 10:05:18 +00:00
|
|
|
|
setTimeout(() => {
|
|
|
|
|
this.updateOpenURLResolversMenu();
|
|
|
|
|
});
|
2017-07-21 09:30:49 +00:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_getAutomaticLocaleMenuLabel: function () {
|
|
|
|
|
return Zotero.getString(
|
|
|
|
|
'zotero.preferences.locale.automaticWithLocale',
|
|
|
|
|
Zotero.Locale.availableLocales[Zotero.locale] || Zotero.locale
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
refreshLocale: function () {
|
|
|
|
|
var autoLocaleName, currentValue;
|
|
|
|
|
|
|
|
|
|
// If matching OS, get the name of the current locale
|
2019-10-27 07:08:16 +00:00
|
|
|
|
if (Zotero.Prefs.get('intl.locale.requested', true) === '') {
|
2017-07-21 09:30:49 +00:00
|
|
|
|
autoLocaleName = this._getAutomaticLocaleMenuLabel();
|
|
|
|
|
currentValue = 'automatic';
|
|
|
|
|
}
|
|
|
|
|
// Otherwise get the name of the locale specified in the pref
|
|
|
|
|
else {
|
|
|
|
|
autoLocaleName = Zotero.getString('zotero.preferences.locale.automatic');
|
2019-10-26 05:27:14 +00:00
|
|
|
|
currentValue = Zotero.locale;
|
2017-07-21 09:30:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Populate menu
|
|
|
|
|
var menu = document.getElementById('locale-menu');
|
|
|
|
|
var menupopup = menu.firstChild;
|
|
|
|
|
menupopup.textContent = '';
|
|
|
|
|
// Show "Automatic (English)", "Automatic (Français)", etc.
|
|
|
|
|
menu.appendItem(autoLocaleName, 'automatic');
|
|
|
|
|
menu.menupopup.appendChild(document.createElement('menuseparator'));
|
|
|
|
|
// Add all available locales
|
|
|
|
|
for (let locale in Zotero.Locale.availableLocales) {
|
|
|
|
|
menu.appendItem(Zotero.Locale.availableLocales[locale], locale);
|
|
|
|
|
}
|
|
|
|
|
menu.value = currentValue;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
onLocaleChange: function () {
|
2019-10-23 23:02:50 +00:00
|
|
|
|
var requestedLocale = Services.locale.getRequestedLocale();
|
2017-07-21 09:30:49 +00:00
|
|
|
|
var menu = document.getElementById('locale-menu');
|
|
|
|
|
if (menu.value == 'automatic') {
|
|
|
|
|
// Changed if not already set to automatic (unless we have the automatic locale name,
|
|
|
|
|
// meaning we just switched away to the same manual locale and back to automatic)
|
2019-10-23 23:02:50 +00:00
|
|
|
|
var changed = requestedLocale && menu.label != this._getAutomaticLocaleMenuLabel();
|
2019-10-27 07:08:16 +00:00
|
|
|
|
Services.locale.setRequestedLocales(null);
|
2017-07-21 09:30:49 +00:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
// Changed if moving to a locale other than the current one
|
|
|
|
|
var changed = Zotero.locale != menu.value
|
2019-10-23 23:02:50 +00:00
|
|
|
|
Services.locale.setRequestedLocales([menu.value]);
|
2017-07-21 09:30:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!changed) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var ps = Services.prompt;
|
|
|
|
|
var buttonFlags = ps.BUTTON_POS_0 * ps.BUTTON_TITLE_IS_STRING
|
|
|
|
|
+ ps.BUTTON_POS_1 * ps.BUTTON_TITLE_IS_STRING;
|
|
|
|
|
var index = ps.confirmEx(null,
|
|
|
|
|
Zotero.getString('general.restartRequired'),
|
|
|
|
|
Zotero.getString('general.restartRequiredForChange', Zotero.appName),
|
|
|
|
|
buttonFlags,
|
|
|
|
|
Zotero.getString('general.restartNow'),
|
|
|
|
|
Zotero.getString('general.restartLater'),
|
|
|
|
|
null, null, {});
|
|
|
|
|
|
|
|
|
|
if (index == 0) {
|
|
|
|
|
Zotero.Utilities.Internal.quitZotero(true);
|
|
|
|
|
}
|
2013-03-20 08:47:52 +00:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Zotero_Preferences.Attachment_Base_Directory = {
|
2015-09-29 08:05:13 +00:00
|
|
|
|
getPath: function () {
|
|
|
|
|
var oldPath = Zotero.Prefs.get('baseAttachmentPath');
|
|
|
|
|
if (oldPath) {
|
2013-03-20 08:47:52 +00:00
|
|
|
|
try {
|
2015-09-29 08:05:13 +00:00
|
|
|
|
return OS.Path.normalize(oldPath);
|
2013-03-20 08:47:52 +00:00
|
|
|
|
}
|
|
|
|
|
catch (e) {
|
2015-09-29 08:05:13 +00:00
|
|
|
|
Zotero.logError(e);
|
|
|
|
|
return false;
|
2013-03-20 08:47:52 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2015-09-29 08:05:13 +00:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
2019-08-24 08:25:51 +00:00
|
|
|
|
choosePath: async function () {
|
2015-09-29 08:05:13 +00:00
|
|
|
|
var oldPath = this.getPath();
|
2013-03-20 08:47:52 +00:00
|
|
|
|
|
|
|
|
|
//Prompt user to choose new base path
|
2019-08-24 08:25:51 +00:00
|
|
|
|
var fp = new FilePicker();
|
2015-09-29 08:05:13 +00:00
|
|
|
|
if (oldPath) {
|
2019-08-24 08:25:51 +00:00
|
|
|
|
fp.displayDirectory = oldPath;
|
2015-09-29 08:05:13 +00:00
|
|
|
|
}
|
2019-08-24 08:25:51 +00:00
|
|
|
|
fp.init(window, Zotero.getString('attachmentBasePath.selectDir'), fp.modeGetFolder);
|
|
|
|
|
fp.appendFilters(fp.filterAll);
|
|
|
|
|
if (await fp.show() != fp.returnOK) {
|
2013-03-20 08:47:52 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
2019-08-24 08:25:51 +00:00
|
|
|
|
var newPath = fp.file;
|
2013-03-20 08:47:52 +00:00
|
|
|
|
|
2015-09-29 08:05:13 +00:00
|
|
|
|
if (oldPath && oldPath == newPath) {
|
2013-03-20 08:47:52 +00:00
|
|
|
|
Zotero.debug("Base directory hasn't changed");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-26 05:20:15 +00:00
|
|
|
|
try {
|
|
|
|
|
return await this.changePath(newPath);
|
|
|
|
|
}
|
|
|
|
|
catch (e) {
|
|
|
|
|
Zotero.logError(e);
|
|
|
|
|
Zotero.alert(null, Zotero.getString('general.error'), e.message);
|
|
|
|
|
}
|
2019-08-24 08:25:51 +00:00
|
|
|
|
},
|
2015-09-29 08:05:13 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
changePath: Zotero.Promise.coroutine(function* (basePath) {
|
2018-08-20 02:49:09 +00:00
|
|
|
|
Zotero.debug(`New base directory is ${basePath}`);
|
|
|
|
|
|
2020-04-26 05:20:15 +00:00
|
|
|
|
if (Zotero.File.directoryContains(Zotero.DataDirectory.dir, basePath)) {
|
|
|
|
|
throw new Error(
|
|
|
|
|
Zotero.getString(
|
|
|
|
|
'zotero.preferences.advanced.baseDirectory.withinDataDir',
|
|
|
|
|
Zotero.appName
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-20 08:47:52 +00:00
|
|
|
|
// Find all current attachments with relative attachment paths
|
2016-02-03 06:13:30 +00:00
|
|
|
|
var sql = "SELECT itemID FROM itemAttachments WHERE linkMode=? AND path LIKE ?";
|
|
|
|
|
var params = [
|
|
|
|
|
Zotero.Attachments.LINK_MODE_LINKED_FILE,
|
|
|
|
|
Zotero.Attachments.BASE_PATH_PLACEHOLDER + "%"
|
|
|
|
|
];
|
2015-09-29 08:05:13 +00:00
|
|
|
|
var oldRelativeAttachmentIDs = yield Zotero.DB.columnQueryAsync(sql, params);
|
2013-03-20 08:47:52 +00:00
|
|
|
|
|
|
|
|
|
//Find all attachments on the new base path
|
|
|
|
|
var sql = "SELECT itemID FROM itemAttachments WHERE linkMode=?";
|
|
|
|
|
var params = [Zotero.Attachments.LINK_MODE_LINKED_FILE];
|
2015-09-29 08:05:13 +00:00
|
|
|
|
var allAttachments = yield Zotero.DB.columnQueryAsync(sql, params);
|
2013-03-20 08:47:52 +00:00
|
|
|
|
var newAttachmentPaths = {};
|
|
|
|
|
var numNewAttachments = 0;
|
|
|
|
|
var numOldAttachments = 0;
|
|
|
|
|
for (let i=0; i<allAttachments.length; i++) {
|
|
|
|
|
let attachmentID = allAttachments[i];
|
2015-09-29 08:05:13 +00:00
|
|
|
|
let attachmentPath;
|
2013-04-19 05:18:59 +00:00
|
|
|
|
let relPath = false
|
2013-03-20 08:47:52 +00:00
|
|
|
|
|
|
|
|
|
try {
|
2015-09-29 08:05:13 +00:00
|
|
|
|
let attachment = yield Zotero.Items.getAsync(attachmentID);
|
2013-04-19 05:18:59 +00:00
|
|
|
|
// This will return FALSE for relative paths if base directory
|
|
|
|
|
// isn't currently set
|
2015-09-29 08:05:13 +00:00
|
|
|
|
attachmentPath = attachment.getFilePath();
|
2013-04-19 05:18:59 +00:00
|
|
|
|
// Get existing relative path
|
2015-09-29 08:05:13 +00:00
|
|
|
|
let storedPath = attachment.attachmentPath;
|
|
|
|
|
if (storedPath.startsWith(Zotero.Attachments.BASE_PATH_PLACEHOLDER)) {
|
|
|
|
|
relPath = storedPath.substr(Zotero.Attachments.BASE_PATH_PLACEHOLDER.length);
|
2013-04-19 05:18:59 +00:00
|
|
|
|
}
|
2013-03-20 08:47:52 +00:00
|
|
|
|
}
|
|
|
|
|
catch (e) {
|
|
|
|
|
// Don't deal with bad attachment paths. Just skip them.
|
2013-04-19 05:18:59 +00:00
|
|
|
|
Zotero.debug(e, 2);
|
2013-03-20 08:47:52 +00:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If a file with the same relative path exists within the new base directory,
|
|
|
|
|
// don't touch the attachment, since it will continue to work
|
2013-04-19 05:18:59 +00:00
|
|
|
|
if (relPath) {
|
2015-09-29 08:05:13 +00:00
|
|
|
|
if (yield OS.File.exists(OS.Path.join(basePath, relPath))) {
|
2013-03-20 08:47:52 +00:00
|
|
|
|
numNewAttachments++;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Files within the new base directory need to be updated to use
|
|
|
|
|
// relative paths (or, if the new base directory is an ancestor or
|
|
|
|
|
// descendant of the old one, new relative paths)
|
2015-09-29 08:05:13 +00:00
|
|
|
|
if (attachmentPath && Zotero.File.directoryContains(basePath, attachmentPath)) {
|
2018-08-20 02:49:09 +00:00
|
|
|
|
Zotero.debug(`Converting ${attachmentPath} to relative path`);
|
2015-09-29 08:05:13 +00:00
|
|
|
|
newAttachmentPaths[attachmentID] = relPath ? attachmentPath : null;
|
2013-03-20 08:47:52 +00:00
|
|
|
|
numNewAttachments++;
|
|
|
|
|
}
|
|
|
|
|
// Existing relative attachments not within the new base directory
|
|
|
|
|
// will be converted to absolute paths
|
2015-09-29 08:05:13 +00:00
|
|
|
|
else if (relPath && this.getPath()) {
|
2018-08-20 02:49:09 +00:00
|
|
|
|
Zotero.debug(`Converting ${relPath} to absolute path`);
|
2015-09-29 08:05:13 +00:00
|
|
|
|
newAttachmentPaths[attachmentID] = attachmentPath;
|
2013-03-20 08:47:52 +00:00
|
|
|
|
numOldAttachments++;
|
|
|
|
|
}
|
2018-08-20 02:49:09 +00:00
|
|
|
|
else {
|
|
|
|
|
Zotero.debug(`${attachmentPath} is not within the base directory`);
|
|
|
|
|
}
|
2013-03-20 08:47:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Confirm change of the base path
|
|
|
|
|
var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
|
|
|
|
|
.getService(Components.interfaces.nsIPromptService);
|
|
|
|
|
|
|
|
|
|
var chooseStrPrefix = 'attachmentBasePath.chooseNewPath.';
|
|
|
|
|
var clearStrPrefix = 'attachmentBasePath.clearBasePath.';
|
|
|
|
|
var title = Zotero.getString(chooseStrPrefix + 'title');
|
2013-04-02 17:47:19 +00:00
|
|
|
|
var msg1 = Zotero.getString(chooseStrPrefix + 'message') + "\n\n", msg2 = "", msg3 = "";
|
2013-03-20 08:47:52 +00:00
|
|
|
|
switch (numNewAttachments) {
|
|
|
|
|
case 0:
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
|
msg2 += Zotero.getString(chooseStrPrefix + 'existingAttachments.singular') + " ";
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
msg2 += Zotero.getString(chooseStrPrefix + 'existingAttachments.plural', numNewAttachments) + " ";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (numOldAttachments) {
|
|
|
|
|
case 0:
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
|
msg3 += Zotero.getString(clearStrPrefix + 'existingAttachments.singular');
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
msg3 += Zotero.getString(clearStrPrefix + 'existingAttachments.plural', numOldAttachments);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var buttonFlags = (ps.BUTTON_POS_0) * (ps.BUTTON_TITLE_IS_STRING)
|
|
|
|
|
+ (ps.BUTTON_POS_1) * (ps.BUTTON_TITLE_CANCEL);
|
|
|
|
|
var index = ps.confirmEx(
|
|
|
|
|
null,
|
|
|
|
|
title,
|
|
|
|
|
(msg1 + msg2 + msg3).trim(),
|
|
|
|
|
buttonFlags,
|
|
|
|
|
Zotero.getString(chooseStrPrefix + 'button'),
|
|
|
|
|
null,
|
|
|
|
|
null,
|
|
|
|
|
null,
|
|
|
|
|
{}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (index == 1) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-26 05:20:15 +00:00
|
|
|
|
// Set new base directory
|
2018-08-20 02:49:09 +00:00
|
|
|
|
Zotero.debug("Setting base directory to " + basePath);
|
2015-09-29 08:05:13 +00:00
|
|
|
|
Zotero.Prefs.set('baseAttachmentPath', basePath);
|
2013-03-20 08:47:52 +00:00
|
|
|
|
Zotero.Prefs.set('saveRelativeAttachmentPath', true);
|
|
|
|
|
// Resave all attachments on base path (so that their paths become relative)
|
|
|
|
|
// and all other relative attachments (so that their paths become absolute)
|
2015-09-29 08:05:13 +00:00
|
|
|
|
yield Zotero.Utilities.Internal.forEachChunkAsync(
|
|
|
|
|
Object.keys(newAttachmentPaths),
|
|
|
|
|
100,
|
|
|
|
|
function (chunk) {
|
|
|
|
|
return Zotero.DB.executeTransaction(function* () {
|
|
|
|
|
for (let id of chunk) {
|
|
|
|
|
let attachment = Zotero.Items.get(id);
|
|
|
|
|
if (newAttachmentPaths[id]) {
|
|
|
|
|
attachment.attachmentPath = newAttachmentPaths[id];
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
attachment.attachmentPath = attachment.getFilePath();
|
|
|
|
|
}
|
|
|
|
|
yield attachment.save({
|
|
|
|
|
skipDateModifiedUpdate: true
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
})
|
2013-03-20 08:47:52 +00:00
|
|
|
|
}
|
2015-09-29 08:05:13 +00:00
|
|
|
|
);
|
2013-03-20 08:47:52 +00:00
|
|
|
|
|
2015-09-29 08:05:13 +00:00
|
|
|
|
return true;
|
|
|
|
|
}),
|
2013-03-20 08:47:52 +00:00
|
|
|
|
|
|
|
|
|
|
2015-09-29 08:05:13 +00:00
|
|
|
|
clearPath: Zotero.Promise.coroutine(function* () {
|
2013-03-20 08:47:52 +00:00
|
|
|
|
// Find all current attachments with relative paths
|
2016-02-03 06:13:30 +00:00
|
|
|
|
var sql = "SELECT itemID FROM itemAttachments WHERE linkMode=? AND path LIKE ?";
|
|
|
|
|
var params = [
|
|
|
|
|
Zotero.Attachments.LINK_MODE_LINKED_FILE,
|
|
|
|
|
Zotero.Attachments.BASE_PATH_PLACEHOLDER + "%"
|
|
|
|
|
];
|
2015-09-29 08:05:13 +00:00
|
|
|
|
var relativeAttachmentIDs = yield Zotero.DB.columnQueryAsync(sql, params);
|
2013-03-20 08:47:52 +00:00
|
|
|
|
|
|
|
|
|
// Prompt for confirmation
|
|
|
|
|
var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
|
|
|
|
|
.getService(Components.interfaces.nsIPromptService);
|
|
|
|
|
|
|
|
|
|
var strPrefix = 'attachmentBasePath.clearBasePath.';
|
|
|
|
|
var title = Zotero.getString(strPrefix + 'title');
|
|
|
|
|
var msg = Zotero.getString(strPrefix + 'message');
|
|
|
|
|
switch (relativeAttachmentIDs.length) {
|
|
|
|
|
case 0:
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
|
msg += "\n\n" + Zotero.getString(strPrefix + 'existingAttachments.singular');
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
msg += "\n\n" + Zotero.getString(strPrefix + 'existingAttachments.plural',
|
|
|
|
|
relativeAttachmentIDs.length);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var buttonFlags = (ps.BUTTON_POS_0) * (ps.BUTTON_TITLE_IS_STRING)
|
|
|
|
|
+ (ps.BUTTON_POS_1) * (ps.BUTTON_TITLE_CANCEL);
|
|
|
|
|
var index = ps.confirmEx(
|
|
|
|
|
window,
|
|
|
|
|
title,
|
|
|
|
|
msg,
|
|
|
|
|
buttonFlags,
|
|
|
|
|
Zotero.getString(strPrefix + 'button'),
|
|
|
|
|
null,
|
|
|
|
|
null,
|
|
|
|
|
null,
|
|
|
|
|
{}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (index == 1) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Disable relative path saving and then resave all relative
|
|
|
|
|
// attachments so that their absolute paths are stored
|
|
|
|
|
Zotero.debug('Clearing base directory');
|
|
|
|
|
Zotero.Prefs.set('saveRelativeAttachmentPath', false);
|
2015-09-29 08:05:13 +00:00
|
|
|
|
|
|
|
|
|
yield Zotero.Utilities.Internal.forEachChunkAsync(
|
|
|
|
|
relativeAttachmentIDs,
|
|
|
|
|
100,
|
|
|
|
|
function (chunk) {
|
|
|
|
|
return Zotero.DB.executeTransaction(function* () {
|
|
|
|
|
for (let id of chunk) {
|
|
|
|
|
let attachment = yield Zotero.Items.getAsync(id);
|
|
|
|
|
attachment.attachmentPath = attachment.getFilePath();
|
|
|
|
|
yield attachment.save({
|
|
|
|
|
skipDateModifiedUpdate: true
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}.bind(this));
|
|
|
|
|
}.bind(this)
|
|
|
|
|
);
|
|
|
|
|
|
2013-03-20 08:47:52 +00:00
|
|
|
|
Zotero.Prefs.set('baseAttachmentPath', '');
|
2015-09-29 08:05:13 +00:00
|
|
|
|
}),
|
2013-03-20 08:47:52 +00:00
|
|
|
|
|
|
|
|
|
|
2015-09-29 08:05:13 +00:00
|
|
|
|
updateUI: Zotero.Promise.coroutine(function* () {
|
2013-03-20 08:47:52 +00:00
|
|
|
|
var filefield = document.getElementById('baseAttachmentPath');
|
2015-09-29 08:05:13 +00:00
|
|
|
|
var path = Zotero.Prefs.get('baseAttachmentPath');
|
|
|
|
|
Components.utils.import("resource://gre/modules/osfile.jsm");
|
|
|
|
|
if (yield OS.File.exists(path)) {
|
|
|
|
|
filefield.file = Zotero.File.pathToFile(path);
|
|
|
|
|
filefield.label = path;
|
2013-03-20 08:47:52 +00:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
filefield.label = '';
|
|
|
|
|
}
|
2015-09-29 08:05:13 +00:00
|
|
|
|
document.getElementById('resetBasePath').disabled = !path;
|
|
|
|
|
})
|
2013-03-20 08:47:52 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2015-03-05 14:33:20 +00:00
|
|
|
|
Zotero_Preferences.Keys = {
|
|
|
|
|
init: function () {
|
|
|
|
|
var rows = document.getElementById('zotero-prefpane-advanced-keys-tab').getElementsByTagName('row');
|
|
|
|
|
for (var i=0; i<rows.length; i++) {
|
|
|
|
|
// Display the appropriate modifier keys for the platform
|
2016-02-11 10:37:20 +00:00
|
|
|
|
let label = rows[i].firstChild.nextSibling;
|
2016-02-11 11:02:38 +00:00
|
|
|
|
if (label.className == 'modifier') {
|
2016-02-11 10:37:20 +00:00
|
|
|
|
label.value = Zotero.isMac ? Zotero.getString('general.keys.cmdShift') : Zotero.getString('general.keys.ctrlShift');
|
|
|
|
|
}
|
2015-03-05 14:33:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var textboxes = document.getElementById('zotero-keys-rows').getElementsByTagName('textbox');
|
|
|
|
|
for (let i=0; i<textboxes.length; i++) {
|
|
|
|
|
let textbox = textboxes[i];
|
|
|
|
|
textbox.value = textbox.value.toUpperCase();
|
|
|
|
|
// .value takes care of the initial value, and this takes care of direct pref changes
|
|
|
|
|
// while the window is open
|
|
|
|
|
textbox.setAttribute('onsyncfrompreference', 'return Zotero_Preferences.Keys.capitalizePref(this.id)');
|
|
|
|
|
textbox.setAttribute('oninput', 'this.value = this.value.toUpperCase()');
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
capitalizePref: function (id) {
|
|
|
|
|
var elem = document.getElementById(id);
|
|
|
|
|
var pref = document.getElementById(elem.getAttribute('preference'));
|
|
|
|
|
if (pref.value) {
|
|
|
|
|
return pref.value.toUpperCase();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|