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:
Adomas Venčkauskas 2015-11-04 19:30:25 +00:00
parent bd1092e519
commit b75cc8f9d0
7 changed files with 92 additions and 84 deletions

View file

@ -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 {

View file

@ -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 == '') {

View file

@ -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>

View file

@ -1024,4 +1024,9 @@ Zotero.File = new function(){
throw e; throw e;
} }
this.isDropboxDirectory = function(path) {
return path.toLowerCase().indexOf('dropbox') != -1;
}
} }

View file

@ -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
*/ */

View file

@ -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

View file

@ -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);