Closes #437, Detect when data directory is in Dropbox
Display a warning when choosing data directory Or on opening Zotero Pane for existing users with data dir in dropbox Also: Fix a bug where it won't use custom path if "Choose..." button is pressed instead of radio button. Change filepicker to show current data directory on display
This commit is contained in:
parent
bd1092e519
commit
b75cc8f9d0
7 changed files with 92 additions and 84 deletions
|
@ -210,6 +210,10 @@ var ZoteroOverlay = new function()
|
||||||
// Make visible
|
// Make visible
|
||||||
ZoteroPane.makeVisible();
|
ZoteroPane.makeVisible();
|
||||||
|
|
||||||
|
// Warn about unsafe data directory on first display
|
||||||
|
let dataDir = Zotero.getZoteroDirectory();
|
||||||
|
Zotero.checkForUnsafeDataDirectory(dataDir.path);
|
||||||
|
|
||||||
// Make sure tags splitter isn't missing for people upgrading from <2.0b7
|
// Make sure tags splitter isn't missing for people upgrading from <2.0b7
|
||||||
document.getElementById('zotero-tags-splitter').collapsed = false;
|
document.getElementById('zotero-tags-splitter').collapsed = false;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -198,59 +198,32 @@ Zotero_Preferences.Advanced = {
|
||||||
|
|
||||||
onDataDirUpdate: function (event) {
|
onDataDirUpdate: function (event) {
|
||||||
var radiogroup = document.getElementById('dataDir');
|
var radiogroup = document.getElementById('dataDir');
|
||||||
var path = document.getElementById('dataDirPath');
|
|
||||||
var useDataDir = Zotero.Prefs.get('useDataDir');
|
var useDataDir = Zotero.Prefs.get('useDataDir');
|
||||||
|
var newUseDataDir = radiogroup.selectedIndex == 1;
|
||||||
|
|
||||||
// If triggered from the Choose button, don't show the dialog, since
|
if (newUseDataDir == useDataDir && !useDataDir) {
|
||||||
// Zotero.chooseZoteroDirectory() (called below due to the radio button
|
return;
|
||||||
// change) shows its own
|
|
||||||
if (event.originalTarget && event.originalTarget.tagName == 'button') {
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If changing from default to custom
|
// This call shows a filepicker if needed,
|
||||||
if (!useDataDir) {
|
// forces a restart if required
|
||||||
event.stopPropagation();
|
// and does nothing if cancel was pressed
|
||||||
var file = Zotero.chooseZoteroDirectory(true, false, function () {
|
Zotero.chooseZoteroDirectory(true, !newUseDataDir, function () {
|
||||||
Zotero_Preferences.openURL('http://zotero.org/support/zotero_data');
|
Zotero_Preferences.openURL('http://zotero.org/support/zotero_data');
|
||||||
});
|
});
|
||||||
radiogroup.selectedIndex = file ? 1 : 0;
|
useDataDir = Zotero.Prefs.get('useDataDir');
|
||||||
return !!file;
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
+ ps.BUTTON_POS_2 * ps.BUTTON_TITLE_IS_STRING;
|
|
||||||
var app = Zotero.appName;
|
|
||||||
var index = ps.confirmEx(window,
|
|
||||||
Zotero.getString('general.restartRequired'),
|
|
||||||
Zotero.getString('general.restartRequiredForChange', app) + '\n\n'
|
|
||||||
+ Zotero.getString('dataDir.moveFilesToNewLocation', app),
|
|
||||||
buttonFlags,
|
|
||||||
Zotero.getString('general.quitApp', app),
|
|
||||||
null,
|
|
||||||
Zotero.getString('general.moreInformation'),
|
|
||||||
null, {});
|
|
||||||
|
|
||||||
if (index == 0) {
|
|
||||||
useDataDir = !!radiogroup.selectedIndex;
|
|
||||||
// quit() is asynchronous, but set this here just in case
|
|
||||||
Zotero.Prefs.set('useDataDir', useDataDir);
|
|
||||||
var appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"]
|
|
||||||
.getService(Components.interfaces.nsIAppStartup);
|
|
||||||
appStartup.quit(Components.interfaces.nsIAppStartup.eAttemptQuit);
|
|
||||||
}
|
|
||||||
else if (index == 2) {
|
|
||||||
Zotero_Preferences.openURL('http://zotero.org/support/zotero_data');
|
|
||||||
}
|
|
||||||
|
|
||||||
radiogroup.selectedIndex = useDataDir ? 1 : 0;
|
radiogroup.selectedIndex = useDataDir ? 1 : 0;
|
||||||
|
|
||||||
return useDataDir;
|
return useDataDir;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
chooseDataDir: function(event) {
|
||||||
|
document.getElementById('dataDir').selectedIndex = 1;
|
||||||
|
//this.onDataDirUpdate(event);
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
getDataDirPath: function () {
|
getDataDirPath: function () {
|
||||||
var desc = Zotero.Prefs.get('dataDir');
|
var desc = Zotero.Prefs.get('dataDir');
|
||||||
if (desc == '') {
|
if (desc == '') {
|
||||||
|
|
|
@ -181,10 +181,7 @@
|
||||||
onsyncfrompreference="return Zotero_Preferences.Advanced.getDataDirPath();"
|
onsyncfrompreference="return Zotero_Preferences.Advanced.getDataDirPath();"
|
||||||
readonly="true" flex="1"/>
|
readonly="true" flex="1"/>
|
||||||
<button label="&zotero.preferences.dataDir.choose;"
|
<button label="&zotero.preferences.dataDir.choose;"
|
||||||
oncommand="var file = Zotero.chooseZoteroDirectory(true);
|
oncommand="return Zotero_Preferences.Advanced.chooseDataDir(event)"/>
|
||||||
if (!file) {
|
|
||||||
event.stopPropagation();
|
|
||||||
}"/>
|
|
||||||
</hbox>
|
</hbox>
|
||||||
</radiogroup>
|
</radiogroup>
|
||||||
|
|
||||||
|
|
|
@ -1024,4 +1024,9 @@ Zotero.File = new function(){
|
||||||
|
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.isDropboxDirectory = function(path) {
|
||||||
|
return path.toLowerCase().indexOf('dropbox') != -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -381,7 +381,9 @@ Components.utils.import("resource://gre/modules/osfile.jsm");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(Zotero.isStandalone) {
|
||||||
|
Zotero.checkForUnsafeDataDirectory(dataDir.path);
|
||||||
|
}
|
||||||
// Register shutdown handler to call Zotero.shutdown()
|
// Register shutdown handler to call Zotero.shutdown()
|
||||||
var _shutdownObserver = {observe:function() { Zotero.shutdown().done() }};
|
var _shutdownObserver = {observe:function() { Zotero.shutdown().done() }};
|
||||||
Services.obs.addObserver(_shutdownObserver, "quit-application", false);
|
Services.obs.addObserver(_shutdownObserver, "quit-application", false);
|
||||||
|
@ -1066,50 +1068,44 @@ Components.utils.import("resource://gre/modules/osfile.jsm");
|
||||||
var fp = Components.classes["@mozilla.org/filepicker;1"]
|
var fp = Components.classes["@mozilla.org/filepicker;1"]
|
||||||
.createInstance(nsIFilePicker);
|
.createInstance(nsIFilePicker);
|
||||||
fp.init(win, Zotero.getString('dataDir.selectDir'), nsIFilePicker.modeGetFolder);
|
fp.init(win, Zotero.getString('dataDir.selectDir'), nsIFilePicker.modeGetFolder);
|
||||||
|
fp.displayDirectory = Zotero.getZoteroDirectory();
|
||||||
fp.appendFilters(nsIFilePicker.filterAll);
|
fp.appendFilters(nsIFilePicker.filterAll);
|
||||||
if (fp.show() == nsIFilePicker.returnOK) {
|
if (fp.show() == nsIFilePicker.returnOK) {
|
||||||
var file = fp.file;
|
var file = fp.file;
|
||||||
|
let dialogText = '';
|
||||||
|
let dialogTitle = '';
|
||||||
|
|
||||||
if (file.directoryEntries.hasMoreElements()) {
|
// In dropbox folder
|
||||||
var dbfile = file.clone();
|
if (Zotero.File.isDropboxDirectory(file.path)) {
|
||||||
|
dialogTitle = Zotero.getString('general.warning');
|
||||||
|
dialogText = Zotero.getString('dataDir.unsafeLocation.selected.dropbox') + "\n\n"
|
||||||
|
+ Zotero.getString('dataDir.unsafeLocation.selected.useAnyway');
|
||||||
|
}
|
||||||
|
else if (file.directoryEntries.hasMoreElements()) {
|
||||||
|
let dbfile = file.clone();
|
||||||
dbfile.append('zotero.sqlite');
|
dbfile.append('zotero.sqlite');
|
||||||
|
|
||||||
// Warn if non-empty and no zotero.sqlite
|
// Warn if non-empty and no zotero.sqlite
|
||||||
if (!dbfile.exists()) {
|
if (!dbfile.exists()) {
|
||||||
var buttonFlags = ps.STD_YES_NO_BUTTONS;
|
dialogTitle = Zotero.getString('dataDir.selectedDirNonEmpty.title');
|
||||||
if (moreInfoCallback) {
|
dialogText = Zotero.getString('dataDir.selectedDirNonEmpty.text');
|
||||||
buttonFlags += ps.BUTTON_POS_2 * ps.BUTTON_TITLE_IS_STRING;
|
|
||||||
}
|
|
||||||
var index = ps.confirmEx(null,
|
|
||||||
Zotero.getString('dataDir.selectedDirNonEmpty.title'),
|
|
||||||
Zotero.getString('dataDir.selectedDirNonEmpty.text'),
|
|
||||||
buttonFlags,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
moreInfoCallback ? Zotero.getString('general.help') : null,
|
|
||||||
null, {});
|
|
||||||
|
|
||||||
// Not OK -- return to file picker
|
|
||||||
if (index == 1) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (index == 2) {
|
|
||||||
setTimeout(function () {
|
|
||||||
moreInfoCallback();
|
|
||||||
}, 1);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Directory empty
|
||||||
else {
|
else {
|
||||||
var buttonFlags = ps.STD_YES_NO_BUTTONS;
|
dialogTitle = Zotero.getString('dataDir.selectedDirEmpty.title');
|
||||||
|
dialogText = Zotero.getString('dataDir.selectedDirEmpty.text', Zotero.appName) + '\n\n'
|
||||||
|
+ Zotero.getString('dataDir.selectedDirEmpty.useNewDir');
|
||||||
|
}
|
||||||
|
// Warning dialog to be displayed
|
||||||
|
if(dialogText !== '') {
|
||||||
|
let buttonFlags = ps.STD_YES_NO_BUTTONS;
|
||||||
if (moreInfoCallback) {
|
if (moreInfoCallback) {
|
||||||
buttonFlags += ps.BUTTON_POS_2 * ps.BUTTON_TITLE_IS_STRING;
|
buttonFlags += ps.BUTTON_POS_2 * ps.BUTTON_TITLE_IS_STRING;
|
||||||
}
|
}
|
||||||
var index = ps.confirmEx(null,
|
let index = ps.confirmEx(null,
|
||||||
Zotero.getString('dataDir.selectedDirEmpty.title'),
|
dialogTitle,
|
||||||
Zotero.getString('dataDir.selectedDirEmpty.text', Zotero.appName) + '\n\n'
|
dialogText,
|
||||||
+ Zotero.getString('dataDir.selectedDirEmpty.useNewDir'),
|
|
||||||
buttonFlags,
|
buttonFlags,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
|
@ -1128,7 +1124,6 @@ Components.utils.import("resource://gre/modules/osfile.jsm");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Set new data directory
|
// Set new data directory
|
||||||
Zotero.Prefs.set('dataDir', file.persistentDescriptor);
|
Zotero.Prefs.set('dataDir', file.persistentDescriptor);
|
||||||
Zotero.Prefs.set('lastDataDir', file.path);
|
Zotero.Prefs.set('lastDataDir', file.path);
|
||||||
|
@ -1156,7 +1151,7 @@ Components.utils.import("resource://gre/modules/osfile.jsm");
|
||||||
forceQuitNow ? null : Zotero.getString('general.restartLater'),
|
forceQuitNow ? null : Zotero.getString('general.restartLater'),
|
||||||
null, null, {});
|
null, null, {});
|
||||||
|
|
||||||
if (index == 0) {
|
if (forceQuitNow || index == 0) {
|
||||||
Services.startup.quit(Components.interfaces.nsIAppStartup.eAttemptQuit);
|
Services.startup.quit(Components.interfaces.nsIAppStartup.eAttemptQuit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1164,6 +1159,35 @@ Components.utils.import("resource://gre/modules/osfile.jsm");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.warnOnUnsafeDataDir = true;
|
||||||
|
this.checkForUnsafeDataDirectory = function (path) {
|
||||||
|
if (this.warnOnUnsafeDataDir && Zotero.File.isDropboxDirectory(path)
|
||||||
|
&& Zotero.Prefs.get('warnOnUnsafeDataDir')) {
|
||||||
|
|
||||||
|
this.warnOnUnsafeDataDir = false;
|
||||||
|
let check = {value: false};
|
||||||
|
let index = Services.prompt.confirmEx(
|
||||||
|
null,
|
||||||
|
Zotero.getString('general.warning'),
|
||||||
|
Zotero.getString('dataDir.unsafeLocation.existing.dropbox') + "\n\n"
|
||||||
|
+ Zotero.getString('dataDir.unsafeLocation.existing.chooseDifferent'),
|
||||||
|
Services.prompt.STD_YES_NO_BUTTONS,
|
||||||
|
null, null, null,
|
||||||
|
Zotero.getString('general.dontShowWarningAgain'),
|
||||||
|
check
|
||||||
|
);
|
||||||
|
|
||||||
|
// Yes - display dialog.
|
||||||
|
if (index == 0) {
|
||||||
|
Zotero.chooseZoteroDirectory(true);
|
||||||
|
}
|
||||||
|
if (check.value) {
|
||||||
|
Zotero.Prefs.set('warnOnUnsafeDataDir', false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Launch a file, the best way we can
|
* Launch a file, the best way we can
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -112,6 +112,10 @@ dataDir.notFound = The Zotero data directory could not be found.
|
||||||
dataDir.previousDir = Previous directory:
|
dataDir.previousDir = Previous directory:
|
||||||
dataDir.useProfileDir = Use %S profile directory
|
dataDir.useProfileDir = Use %S profile directory
|
||||||
dataDir.selectDir = Select a Zotero data directory
|
dataDir.selectDir = Select a Zotero data directory
|
||||||
|
dataDir.unsafeLocation.selected.dropbox = Choosing a data directory within Dropbox may corrupt your database.
|
||||||
|
dataDir.unsafeLocation.selected.useAnyway = Use this directory anyway?
|
||||||
|
dataDir.unsafeLocation.existing.dropbox = Your Zotero data directory is within Dropbox, which may lead to data corruption.
|
||||||
|
dataDir.unsafeLocation.existing.chooseDifferent = Would you like to choose a different location now?
|
||||||
dataDir.selectedDirNonEmpty.title = Directory Not Empty
|
dataDir.selectedDirNonEmpty.title = Directory Not Empty
|
||||||
dataDir.selectedDirNonEmpty.text = The directory you selected is not empty and does not appear to be a Zotero data directory.\n\nCreate Zotero files in this directory anyway?
|
dataDir.selectedDirNonEmpty.text = The directory you selected is not empty and does not appear to be a Zotero data directory.\n\nCreate Zotero files in this directory anyway?
|
||||||
dataDir.selectedDirEmpty.title = Directory Empty
|
dataDir.selectedDirEmpty.title = Directory Empty
|
||||||
|
|
|
@ -11,6 +11,7 @@ pref("extensions.zotero.baseAttachmentPath", '');
|
||||||
pref("extensions.zotero.useDataDir", false);
|
pref("extensions.zotero.useDataDir", false);
|
||||||
pref("extensions.zotero.dataDir", '');
|
pref("extensions.zotero.dataDir", '');
|
||||||
pref("extensions.zotero.lastDataDir", '');
|
pref("extensions.zotero.lastDataDir", '');
|
||||||
|
pref("extensions.zotero.warnOnUnsafeDataDir", true);
|
||||||
pref("extensions.zotero.debug.log",false);
|
pref("extensions.zotero.debug.log",false);
|
||||||
pref("extensions.zotero.debug.stackTrace", false);
|
pref("extensions.zotero.debug.stackTrace", false);
|
||||||
pref("extensions.zotero.debug.store",false);
|
pref("extensions.zotero.debug.store",false);
|
||||||
|
|
Loading…
Reference in a new issue