Wizard: Add options to ask confirmation for external storage
authorOlivier Goffart <ogoffart@woboq.com>
Tue, 24 Jan 2017 09:16:10 +0000 (10:16 +0100)
committerMarkus Goetz <markus@woboq.com>
Fri, 27 Jan 2017 14:59:59 +0000 (15:59 +0100)
Added two checkboxes in the Account Wizard in the advanced page to change the first options.
Also added a checkbox in the general settings to ask for confirmation for external storages.

Theme options allow to hide the checkboxes in the wizard.

As described in issue #5340

14 files changed:
src/gui/accountsettings.cpp
src/gui/folder.cpp
src/gui/generalsettings.cpp
src/gui/generalsettings.ui
src/gui/wizard/owncloudadvancedsetuppage.cpp
src/gui/wizard/owncloudadvancedsetuppage.ui
src/libsync/configfile.cpp
src/libsync/configfile.h
src/libsync/discoveryphase.cpp
src/libsync/discoveryphase.h
src/libsync/syncengine.cpp
src/libsync/syncengine.h
src/libsync/theme.cpp
src/libsync/theme.h

index cceba75bae97be674f39c807b05486fe045f93f9..0fb32cfbf946a505d7681b079b1b2bf251e4fa02 100644 (file)
@@ -675,8 +675,13 @@ void AccountSettings::refreshSelectiveSyncStatus()
         ui->selectiveSyncButtons->setVisible(true);
         ui->bigFolderUi->setVisible(false);
     } else {
-        QString wholeMsg = tr("There are new folders that were not synchronized because they are too big: ") + msg;
-        ui->selectiveSyncNotification->setText(wholeMsg);
+        ConfigFile cfg;
+        QString info =
+            !cfg.confirmExternalStorage() ? tr("There are folders that were not synchronized because they are too big: ") :
+            !cfg.newBigFolderSizeLimit().first ? tr("There are folders that were not synchronized because they are external storages: ") :
+            tr("There are folders that were not synchronized because they are too big or external storages: ");
+
+        ui->selectiveSyncNotification->setText(info + msg);
         ui->selectiveSyncButtons->setVisible(false);
         ui->bigFolderUi->setVisible(true);
         shouldBeVisible = true;
index 24ed2cc1c6adae3fb3b5d89de5ab864c7044ebfa..6079edb28bc6abf2dc0bfdabc658558eef95b4e4 100644 (file)
@@ -748,10 +748,12 @@ void Folder::startSync(const QStringList &pathList)
 
     setDirtyNetworkLimits();
 
+    SyncOptions opt;
     ConfigFile cfgFile;
     auto newFolderLimit = cfgFile.newBigFolderSizeLimit();
-    quint64 limit = newFolderLimit.first ? newFolderLimit.second * 1000 * 1000 : -1; // convert from MB to B
-    _engine->setNewBigFolderSizeLimit(limit);
+    opt._newBigFolderSizeLimit = newFolderLimit.first ? newFolderLimit.second * 1000LL * 1000LL : -1; // convert from MB to B
+    opt._confirmExternalStorage = cfgFile.confirmExternalStorage();
+    _engine->setSyncOptions(opt);
 
     _engine->setIgnoreHiddenFiles(_definition.ignoreHiddenFiles);
 
index d6eae4116b2621ebc7d62fba9d15078d9fd33b49..25a3c2828457ca12f4ddb16994764045c484a267 100644 (file)
@@ -106,6 +106,8 @@ void GeneralSettings::loadMiscSettings()
     auto newFolderLimit = cfgFile.newBigFolderSizeLimit();
     _ui->newFolderLimitCheckBox->setChecked(newFolderLimit.first);
     _ui->newFolderLimitSpinBox->setValue(newFolderLimit.second);
+    _ui->newExternalStorage->setChecked(cfgFile.confirmExternalStorage());
+    _ui->monoIconsCheckBox->setChecked(cfgFile.monoIcons());
 }
 
 void GeneralSettings::slotUpdateInfo()
@@ -138,6 +140,7 @@ void GeneralSettings::saveMiscSettings()
 
     cfgFile.setNewBigFolderSizeLimit(_ui->newFolderLimitCheckBox->isChecked(),
                                         _ui->newFolderLimitSpinBox->value());
+    cfgFile.setConfirmExternalStorage(_ui->newExternalStorage->isChecked());
 }
 
 void GeneralSettings::slotToggleLaunchOnStartup(bool enable)
index 4bc4b995883b62eb0534712265722b50248bc325..06b7aa0343f0e06533af154ab0412f9087e6529c 100644 (file)
@@ -6,7 +6,7 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>706</width>
+    <width>785</width>
     <height>523</height>
    </rect>
   </property>
       <string>Advanced</string>
      </property>
      <layout class="QGridLayout" name="gridLayout">
-      <item row="0" column="0">
-       <widget class="QPushButton" name="ignoredFilesButton">
-        <property name="text">
-         <string>Edit &amp;Ignored Files</string>
-        </property>
-       </widget>
-      </item>
       <item row="0" column="1" colspan="2">
        <spacer name="horizontalSpacer_4">
         <property name="orientation">
         </property>
        </spacer>
       </item>
+      <item row="3" column="0" colspan="2">
+       <widget class="QCheckBox" name="crashreporterCheckBox">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="text">
+         <string>S&amp;how crash reporter</string>
+        </property>
+       </widget>
+      </item>
       <item row="1" column="0" colspan="3">
        <layout class="QHBoxLayout" name="horizontalLayout_3">
         <item>
          <widget class="QCheckBox" name="newFolderLimitCheckBox">
           <property name="text">
-           <string>Ask &amp;confirmation before downloading folders larger than</string>
+           <string>Ask for confirmation before synchronizing folders larger than</string>
           </property>
           <property name="checked">
            <bool>true</bool>
         <item>
          <widget class="QLabel" name="label">
           <property name="text">
-           <string>MB</string>
+           <string extracomment="Trailing part of &quot;Ask confirmation before syncing folder larger than&quot; ">MB</string>
           </property>
          </widget>
         </item>
         </item>
        </layout>
       </item>
-      <item row="2" column="0" colspan="2">
-       <widget class="QCheckBox" name="crashreporterCheckBox">
-        <property name="sizePolicy">
-         <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
-          <horstretch>0</horstretch>
-          <verstretch>0</verstretch>
-         </sizepolicy>
-        </property>
-        <property name="text">
-         <string>S&amp;how crash reporter</string>
-        </property>
-       </widget>
-      </item>
-      <item row="2" column="2">
+      <item row="3" column="2">
        <layout class="QHBoxLayout" name="horizontalLayout_5">
         <item>
          <spacer name="horizontalSpacer_5">
         </item>
        </layout>
       </item>
+      <item row="0" column="0">
+       <widget class="QPushButton" name="ignoredFilesButton">
+        <property name="text">
+         <string>Edit &amp;Ignored Files</string>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="0" colspan="3">
+       <widget class="QCheckBox" name="newExternalStorage">
+        <property name="text">
+         <string>Ask for confirmation before synchronizing external storages</string>
+        </property>
+       </widget>
+      </item>
      </layout>
     </widget>
    </item>
index c0a03815139c30bb0d4de16a016f2ce358592c81..ae6d6d81f91e2659b3f40a33badd42484f9ce1a4 100644 (file)
@@ -68,6 +68,15 @@ OwncloudAdvancedSetupPage::OwncloudAdvancedSetupPage()
     _ui.lServerIcon->setPixmap(appIcon.pixmap(48));
     _ui.lLocalIcon->setText(QString());
     _ui.lLocalIcon->setPixmap(QPixmap(Theme::hidpiFileName(":/client/resources/folder-sync.png")));
+
+    if (theme->wizardHideExternalStorageConfirmationCheckbox()) {
+        _ui.confCheckBoxExternal->hide();
+    }
+    if (theme->wizardHideFolderSizeLimitCheckbox()) {
+        _ui.confCheckBoxSize->hide();
+        _ui.confSpinBox->hide();
+        _ui.confTraillingSizeLabel->hide();
+    }
 }
 
 void OwncloudAdvancedSetupPage::setupCustomization()
@@ -118,6 +127,12 @@ void OwncloudAdvancedSetupPage::initializePage()
         _selectiveSyncBlacklist = QStringList("/");
         QTimer::singleShot(0, this, SLOT(slotSelectiveSyncClicked()));
     }
+
+    ConfigFile cfgFile;
+    auto newFolderLimit = cfgFile.newBigFolderSizeLimit();
+    _ui.confCheckBoxSize->setChecked(newFolderLimit.first);
+    _ui.confSpinBox->setValue(newFolderLimit.second);
+    _ui.confCheckBoxExternal->setChecked(cfgFile.confirmExternalStorage());
 }
 
 // Called if the user changes the user- or url field. Adjust the texts and
@@ -208,6 +223,13 @@ bool OwncloudAdvancedSetupPage::validatePage()
         startSpinner();
         emit completeChanged();
 
+        if (_ui.rSyncEverything->isChecked()) {
+            ConfigFile cfgFile;
+            cfgFile.setNewBigFolderSizeLimit(_ui.confCheckBoxSize->isChecked(),
+                                                _ui.confSpinBox->value());
+            cfgFile.setConfirmExternalStorage(_ui.confCheckBoxExternal->isChecked());
+        }
+
         emit createLocalAndRemoteFolders(localFolder(), _remoteFolder);
         return false;
     } else {
index 74ec741eaf385fb9334cd70ebdcb2a3a27dece6c..bd3aa2c30a4dfcf3510c0f1cf124bd17b3c55155 100644 (file)
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>917</width>
-    <height>493</height>
+    <width>1099</width>
+    <height>636</height>
    </rect>
   </property>
   <property name="sizePolicy">
        <layout class="QVBoxLayout" name="verticalLayout">
         <item>
          <layout class="QHBoxLayout" name="horizontalLayout_2">
-          <property name="spacing">
-           <number>0</number>
-          </property>
           <item>
            <widget class="QRadioButton" name="rSyncEverything">
             <property name="text">
           </item>
          </layout>
         </item>
+        <item>
+         <layout class="QGridLayout" name="gridLayout_2">
+          <item row="0" column="0">
+           <spacer name="horizontalSpacer_4">
+            <property name="orientation">
+             <enum>Qt::Horizontal</enum>
+            </property>
+            <property name="sizeType">
+             <enum>QSizePolicy::Minimum</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>40</width>
+              <height>20</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+          <item row="0" column="1">
+           <layout class="QHBoxLayout" name="horizontalLayout_3">
+            <item>
+             <widget class="QCheckBox" name="confCheckBoxSize">
+              <property name="text">
+               <string>Ask for confirmation before synchroni&amp;zing folders larger than</string>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QSpinBox" name="confSpinBox">
+              <property name="maximum">
+               <number>1000000000</number>
+              </property>
+              <property name="value">
+               <number>500</number>
+              </property>
+             </widget>
+            </item>
+            <item>
+             <widget class="QLabel" name="confTraillingSizeLabel">
+              <property name="text">
+               <string extracomment="Trailing part of &quot;Ask confirmation before syncing folder larger than&quot; ">MB</string>
+              </property>
+             </widget>
+            </item>
+           </layout>
+          </item>
+          <item row="1" column="1">
+           <widget class="QCheckBox" name="confCheckBoxExternal">
+            <property name="text">
+             <string>Ask for confirmation before synchronizing e&amp;xternal storages</string>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </item>
         <item>
          <layout class="QHBoxLayout" name="horizontalLayout">
           <item>
   </layout>
  </widget>
  <resources/>
- <connections/>
+ <connections>
+  <connection>
+   <sender>rSyncEverything</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>confCheckBoxSize</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>217</x>
+     <y>78</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>298</x>
+     <y>126</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>rSyncEverything</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>confSpinBox</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>311</x>
+     <y>83</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>952</x>
+     <y>134</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>rSyncEverything</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>confTraillingSizeLabel</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>277</x>
+     <y>76</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>1076</x>
+     <y>136</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>rSyncEverything</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>confCheckBoxExternal</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>181</x>
+     <y>78</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>382</x>
+     <y>174</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
 </ui>
index 4c8a30bf6f9525d7331ecb234d3901aa2c70d20d..8982b33b395c97d02cb7be4c7facd84965e3c501 100644 (file)
@@ -67,6 +67,7 @@ static const char downloadLimitC[]    = "BWLimit/downloadLimit";
 
 static const char newBigFolderSizeLimitC[] = "newBigFolderSizeLimit";
 static const char useNewBigFolderSizeLimitC[] = "useNewBigFolderSizeLimit";
+static const char confirmExternalStorageC[] = "confirmExternalStorage";
 
 static const char maxLogLinesC[] = "Logging/maxLogLines";
 
@@ -596,6 +597,16 @@ void ConfigFile::setNewBigFolderSizeLimit(bool isChecked, quint64 mbytes)
     setValue(useNewBigFolderSizeLimitC, isChecked);
 }
 
+bool ConfigFile::confirmExternalStorage() const
+{
+    return getValue(confirmExternalStorageC, QString(), true).toBool();
+}
+
+void ConfigFile::setConfirmExternalStorage(bool isChecked)
+{
+    setValue(confirmExternalStorageC, isChecked);
+}
+
 bool ConfigFile::promptDeleteFiles() const
 {
     QSettings settings(configFile(), QSettings::IniFormat);
index cd95f1a0bce50cfbe130f4e00b67f5bff1a7c3a9..0fe3b3cd06394633c0fe94e7b40a218e29f9d6b7 100644 (file)
@@ -105,6 +105,8 @@ public:
     /** [checked, size in MB] **/
     QPair<bool, quint64> newBigFolderSizeLimit() const;
     void setNewBigFolderSizeLimit(bool isChecked, quint64 mbytes);
+    bool confirmExternalStorage() const;
+    void setConfirmExternalStorage(bool);
 
     static bool setConfDir(const QString &value);
 
index b629b426ed9a9eadabf84ace8a32bc54335bf3d4..5e3a6bbdbd87b2a70e46ef2bc82b9632a62483dc 100644 (file)
@@ -86,20 +86,29 @@ int DiscoveryJob::isInSelectiveSyncBlackListCallback(void *data, const char *pat
 
 bool DiscoveryJob::checkSelectiveSyncNewFolder(const QString& path, const char *remotePerm)
 {
-    // If this path or the parent is in the white list, then we do not block this file
-    if (findPathInList(_selectiveSyncWhiteList, path)) {
-        return false;
-    }
 
-    if (Theme::instance()->dontSyncMountedStorageByDefault()) {
-        // 'M' in the permission means that it is unselected by default. (issue #5331)
-        if (std::strchr(remotePerm, 'M')) {
-            emit newBigFolder(path);
-            return true;
+    if (_syncOptions._confirmExternalStorage && std::strchr(remotePerm, 'M')) {
+        // 'M' in the permission means external storage.
+
+        // Only allow it if the white list contains exactly this path (not parents)
+        // We want to ask confirmation for external storage even if the parents where selected
+        if (_selectiveSyncWhiteList.contains(path + QLatin1Char('/'))) {
+            return false;
         }
+
+        // FIXME! if the parent folder has 'M': return false
+
+        emit newBigFolder(path);
+        return true;
+    }
+
+   // If this path or the parent is in the white list, then we do not block this file
+    if (findPathInList(_selectiveSyncWhiteList, path)) {
+        return false;
     }
 
-    if (_newBigFolderSizeLimit < 0) {
+    auto limit = _syncOptions._newBigFolderSizeLimit;
+    if (limit < 0) {
         // no limit, everything is allowed;
         return false;
     }
@@ -113,7 +122,6 @@ bool DiscoveryJob::checkSelectiveSyncNewFolder(const QString& path, const char *
         _vioWaitCondition.wait(&_vioMutex);
     }
 
-    auto limit = _newBigFolderSizeLimit;
     if (result >= limit) {
         // we tell the UI there is a new folder
         emit newBigFolder(path);
index 701581c06dfd46418add2165c11230e05b037693..7c352c2f181573647207703b50323976e3d260e2 100644 (file)
@@ -34,6 +34,15 @@ class Account;
  * if the files are new, or changed.
  */
 
+struct SyncOptions {
+    /** Maximum size (in Bytes) a folder can have without asking for confirmation.
+     * -1 means infinite */
+    qint64 _newBigFolderSizeLimit = -1;
+    /** If a confirmation should be asked for external storages */
+    bool _confirmExternalStorage = false;
+};
+
+
 /**
  * @brief The FileStatPointer class
  * @ingroup libsync
@@ -197,7 +206,7 @@ class DiscoveryJob : public QObject {
 
 public:
     explicit DiscoveryJob(CSYNC *ctx, QObject* parent = 0)
-            : QObject(parent), _csync_ctx(ctx), _newBigFolderSizeLimit(-1) {
+            : QObject(parent), _csync_ctx(ctx) {
         // We need to forward the log property as csync uses thread local
         // and updates run in another thread
         _log_callback = csync_get_log_callback();
@@ -207,7 +216,7 @@ public:
 
     QStringList _selectiveSyncBlackList;
     QStringList _selectiveSyncWhiteList;
-    qint64 _newBigFolderSizeLimit;
+    SyncOptions _syncOptions;
     Q_INVOKABLE void start();
 signals:
     void finished(int result);
index a4e2fceabcd26ccab05c16a5eae7d1b524bfaaa7..b6c347fe3d60cbe31e1d40875eea1f4c16f9f754 100644 (file)
@@ -71,7 +71,6 @@ SyncEngine::SyncEngine(AccountPtr account, const QString& localPath,
   , _backInTimeFiles(0)
   , _uploadLimit(0)
   , _downloadLimit(0)
-  , _newBigFolderSizeLimit(-1)
   , _checksum_hook(journal)
   , _anotherSyncNeeded(NoFollowUpSync)
 {
@@ -830,7 +829,7 @@ void SyncEngine::startSync()
         return;
     }
 
-    discoveryJob->_newBigFolderSizeLimit = _newBigFolderSizeLimit;
+    discoveryJob->_syncOptions = _syncOptions;
     discoveryJob->moveToThread(&_thread);
     connect(discoveryJob, SIGNAL(finished(int)), this, SLOT(slotDiscoveryJobFinished(int)));
     connect(discoveryJob, SIGNAL(folderDiscovered(bool,QString)),
index d29c433b1606a3f2a8b5aa468c244546e84cab31..927c7ad5bf2a3f050c4f2aa69b446212f368a59f 100644 (file)
@@ -78,10 +78,7 @@ public:
 
     bool isSyncRunning() const { return _syncRunning; }
 
-    /* Set the maximum size a folder can have without asking for confirmation
-     * -1 means infinite
-     */
-    void setNewBigFolderSizeLimit(qint64 limit) { _newBigFolderSizeLimit = limit; }
+    void setSyncOptions(const SyncOptions &options) { _syncOptions = options; }
     bool ignoreHiddenFiles() const { return _csync_ctx->ignore_hidden_files; }
     void setIgnoreHiddenFiles(bool ignore) { _csync_ctx->ignore_hidden_files = ignore; }
 
@@ -257,8 +254,7 @@ private:
 
     int _uploadLimit;
     int _downloadLimit;
-    /* maximum size a folder can have without asking for confirmation: -1 means infinite */
-    qint64 _newBigFolderSizeLimit;
+    SyncOptions _syncOptions;
 
     // hash containing the permissions on the remote directory
     QHash<QString, QByteArray> _remotePerms;
index 3a0c0b3edbbc8ce286eafd89364fc570d7180506..54612b545e63e18cb15e35d1e32a11940847a3f0 100644 (file)
@@ -275,6 +275,15 @@ qint64 Theme::newBigFolderSizeLimit() const
     return 500;
 }
 
+bool Theme::wizardHideExternalStorageConfirmationCheckbox() const
+{
+    return false;
+}
+
+bool Theme::wizardHideFolderSizeLimitCheckbox() const
+{
+    return false;
+}
 
 QString Theme::gitSHA1() const
 {
@@ -479,9 +488,5 @@ QString Theme::quotaBaseFolder() const
     return QLatin1String("/");
 }
 
-bool Theme::dontSyncMountedStorageByDefault() const
-{
-    return false;
-}
 
 } // end namespace client
index 4e6130fd6daf3e46e51785214373f4bc56ebc454..a3632fb7096730c2771c34308e029df1e676e82d 100644 (file)
@@ -219,6 +219,17 @@ public:
      **/
     virtual qint64 newBigFolderSizeLimit() const;
 
+    /**
+     * Hide the checkbox that says "Ask for confirmation before synchronizing folders larger than X MB"
+     * in the account wizard
+     */
+    virtual bool wizardHideFolderSizeLimitCheckbox() const;
+    /**
+     * Hide the checkbox that says "Ask for confirmation before synchronizing external storages"
+     * in the account wizard
+     */
+    virtual bool wizardHideExternalStorageConfirmationCheckbox() const;
+
     /**
      * Alternative path on the server that provides access to the webdav capabilities
      *
@@ -302,11 +313,6 @@ public:
      */
     virtual QString quotaBaseFolder() const;
 
-    /**
-     * By default, mounted storage will not be sync'ed (i.e, they will be disabled in the
-     * selective sync
-     */
-    virtual bool dontSyncMountedStorageByDefault() const;
 
 protected:
 #ifndef TOKEN_AUTH_ONLY