commit 3025123cb82d9733e32a47829c686a7e60a5912a
parent 563cfb4fd40cb8a90999a49c4086c21022b9ccd9
Author: Dan Stillman <dstillman@zotero.org>
Date: Thu, 12 Nov 2015 15:45:00 -0500
Merge pull request #867 from adomasven/feature/dropbox-alert
Detect when data directory is in Dropbox
Diffstat:
7 files changed, 92 insertions(+), 84 deletions(-)
diff --git a/chrome/content/zotero/overlay.js b/chrome/content/zotero/overlay.js
@@ -210,6 +210,10 @@ var ZoteroOverlay = new function()
// Make visible
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
document.getElementById('zotero-tags-splitter').collapsed = false;
} else {
diff --git a/chrome/content/zotero/preferences/preferences_advanced.js b/chrome/content/zotero/preferences/preferences_advanced.js
@@ -198,59 +198,32 @@ Zotero_Preferences.Advanced = {
onDataDirUpdate: function (event) {
var radiogroup = document.getElementById('dataDir');
- var path = document.getElementById('dataDirPath');
var useDataDir = Zotero.Prefs.get('useDataDir');
+ var newUseDataDir = radiogroup.selectedIndex == 1;
- // If triggered from the Choose button, don't show the dialog, since
- // Zotero.chooseZoteroDirectory() (called below due to the radio button
- // change) shows its own
- if (event.originalTarget && event.originalTarget.tagName == 'button') {
- return true;
+ if (newUseDataDir == useDataDir && !useDataDir) {
+ return;
}
-
- // If changing from default to custom
- if (!useDataDir) {
- event.stopPropagation();
- var file = Zotero.chooseZoteroDirectory(true, false, function () {
- Zotero_Preferences.openURL('http://zotero.org/support/zotero_data');
- });
- radiogroup.selectedIndex = file ? 1 : 0;
- 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) {
+
+ // This call shows a filepicker if needed,
+ // forces a restart if required
+ // and does nothing if cancel was pressed
+ Zotero.chooseZoteroDirectory(true, !newUseDataDir, function () {
Zotero_Preferences.openURL('http://zotero.org/support/zotero_data');
- }
-
+ });
+ useDataDir = Zotero.Prefs.get('useDataDir');
radiogroup.selectedIndex = useDataDir ? 1 : 0;
+
return useDataDir;
},
+ chooseDataDir: function(event) {
+ document.getElementById('dataDir').selectedIndex = 1;
+ //this.onDataDirUpdate(event);
+ },
+
+
getDataDirPath: function () {
var desc = Zotero.Prefs.get('dataDir');
if (desc == '') {
diff --git a/chrome/content/zotero/preferences/preferences_advanced.xul b/chrome/content/zotero/preferences/preferences_advanced.xul
@@ -181,10 +181,7 @@
onsyncfrompreference="return Zotero_Preferences.Advanced.getDataDirPath();"
readonly="true" flex="1"/>
<button label="&zotero.preferences.dataDir.choose;"
- oncommand="var file = Zotero.chooseZoteroDirectory(true);
- if (!file) {
- event.stopPropagation();
- }"/>
+ oncommand="return Zotero_Preferences.Advanced.chooseDataDir(event)"/>
</hbox>
</radiogroup>
diff --git a/chrome/content/zotero/xpcom/file.js b/chrome/content/zotero/xpcom/file.js
@@ -1024,4 +1024,9 @@ Zotero.File = new function(){
throw e;
}
+
+
+ this.isDropboxDirectory = function(path) {
+ return path.toLowerCase().indexOf('dropbox') != -1;
+ }
}
diff --git a/chrome/content/zotero/xpcom/zotero.js b/chrome/content/zotero/xpcom/zotero.js
@@ -381,7 +381,9 @@ Components.utils.import("resource://gre/modules/osfile.jsm");
return false;
}
}
-
+ if(Zotero.isStandalone) {
+ Zotero.checkForUnsafeDataDirectory(dataDir.path);
+ }
// Register shutdown handler to call Zotero.shutdown()
var _shutdownObserver = {observe:function() { Zotero.shutdown().done() }};
Services.obs.addObserver(_shutdownObserver, "quit-application", false);
@@ -1066,56 +1068,50 @@ Components.utils.import("resource://gre/modules/osfile.jsm");
var fp = Components.classes["@mozilla.org/filepicker;1"]
.createInstance(nsIFilePicker);
fp.init(win, Zotero.getString('dataDir.selectDir'), nsIFilePicker.modeGetFolder);
+ fp.displayDirectory = Zotero.getZoteroDirectory();
fp.appendFilters(nsIFilePicker.filterAll);
if (fp.show() == nsIFilePicker.returnOK) {
var file = fp.file;
-
- if (file.directoryEntries.hasMoreElements()) {
- var dbfile = file.clone();
+ let dialogText = '';
+ let dialogTitle = '';
+
+ // In dropbox folder
+ 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');
// Warn if non-empty and no zotero.sqlite
if (!dbfile.exists()) {
- var buttonFlags = ps.STD_YES_NO_BUTTONS;
- if (moreInfoCallback) {
- 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;
- }
+ dialogTitle = Zotero.getString('dataDir.selectedDirNonEmpty.title');
+ dialogText = Zotero.getString('dataDir.selectedDirNonEmpty.text');
}
}
+ // Directory empty
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) {
buttonFlags += ps.BUTTON_POS_2 * ps.BUTTON_TITLE_IS_STRING;
}
- var index = ps.confirmEx(null,
- Zotero.getString('dataDir.selectedDirEmpty.title'),
- Zotero.getString('dataDir.selectedDirEmpty.text', Zotero.appName) + '\n\n'
- + Zotero.getString('dataDir.selectedDirEmpty.useNewDir'),
+ let index = ps.confirmEx(null,
+ dialogTitle,
+ dialogText,
buttonFlags,
null,
null,
moreInfoCallback ? Zotero.getString('general.moreInformation') : null,
null, {});
-
+
// Not OK -- return to file picker
if (index == 1) {
continue;
@@ -1127,8 +1123,7 @@ Components.utils.import("resource://gre/modules/osfile.jsm");
return false;
}
}
-
-
+
// Set new data directory
Zotero.Prefs.set('dataDir', file.persistentDescriptor);
Zotero.Prefs.set('lastDataDir', file.path);
@@ -1156,12 +1151,41 @@ Components.utils.import("resource://gre/modules/osfile.jsm");
forceQuitNow ? null : Zotero.getString('general.restartLater'),
null, null, {});
- if (index == 0) {
+ if (forceQuitNow || index == 0) {
Services.startup.quit(Components.interfaces.nsIAppStartup.eAttemptQuit);
}
return useProfileDir ? true : file;
}
+
+
+ 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);
+ }
+ }
+ }
/**
diff --git a/chrome/locale/en-US/zotero/zotero.properties b/chrome/locale/en-US/zotero/zotero.properties
@@ -112,6 +112,10 @@ dataDir.notFound = The Zotero data directory could not be found.
dataDir.previousDir = Previous directory:
dataDir.useProfileDir = Use %S profile 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.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
diff --git a/defaults/preferences/zotero.js b/defaults/preferences/zotero.js
@@ -11,6 +11,7 @@ pref("extensions.zotero.baseAttachmentPath", '');
pref("extensions.zotero.useDataDir", false);
pref("extensions.zotero.dataDir", '');
pref("extensions.zotero.lastDataDir", '');
+pref("extensions.zotero.warnOnUnsafeDataDir", true);
pref("extensions.zotero.debug.log",false);
pref("extensions.zotero.debug.stackTrace", false);
pref("extensions.zotero.debug.store",false);