[Pkg-owncloud-commits] [owncloud-client] 21/498: Settings: New UI that intergate the selective sync within the account settings

Sandro Knauß hefee-guest at moszumanska.debian.org
Tue Aug 11 14:48:29 UTC 2015


This is an automated email from the git hooks/post-receive script.

hefee-guest pushed a commit to branch master
in repository owncloud-client.

commit 426d2338d9106b3d3d28211890838af0f143c80b
Author: Olivier Goffart <ogoffart at woboq.com>
Date:   Fri Mar 27 11:46:03 2015 +0100

    Settings: New UI that intergate the selective sync within the account settings
---
 src/gui/accountsettings.cpp     | 256 ++++++++-------------
 src/gui/accountsettings.h       |  17 +-
 src/gui/accountsettings.ui      | 221 +++++++++---------
 src/gui/folderstatusmodel.cpp   | 485 +++++++++++++++++++++++++++++++++++++++-
 src/gui/folderstatusmodel.h     |  66 +++++-
 src/gui/generalsettings.cpp     |  26 +++
 src/gui/generalsettings.h       |   7 +-
 src/gui/generalsettings.ui      |  67 +++++-
 src/gui/selectivesyncdialog.cpp |   2 -
 9 files changed, 859 insertions(+), 288 deletions(-)

diff --git a/src/gui/accountsettings.cpp b/src/gui/accountsettings.cpp
index f46cf80..5eab1b0 100644
--- a/src/gui/accountsettings.cpp
+++ b/src/gui/accountsettings.cpp
@@ -21,13 +21,10 @@
 #include "folderstatusmodel.h"
 #include "utility.h"
 #include "application.h"
-#include "owncloudsetupwizard.h"
 #include "configfile.h"
-#include "ignorelisteditor.h"
 #include "account.h"
 #include "accountstate.h"
 #include "quotainfo.h"
-#include "selectivesyncdialog.h"
 #include "creds/abstractcredentials.h"
 
 #include <math.h>
@@ -37,9 +34,13 @@
 #include <QListWidgetItem>
 #include <QMessageBox>
 #include <QAction>
+#include <QVBoxLayout>
+#include <QTreeView>
 #include <QKeySequence>
 #include <QIcon>
 #include <QVariant>
+#include <qstringlistmodel.h>
+#include <qpropertyanimation.h>
 
 #include "account.h"
 
@@ -64,10 +65,12 @@ AccountSettings::AccountSettings(QWidget *parent) :
     ui->setupUi(this);
 
     _model = new FolderStatusModel;
+    _model->setAccount(_accountState->account());
     _model->setParent(this);
     FolderStatusDelegate *delegate = new FolderStatusDelegate;
     delegate->setParent(this);
 
+    ui->_folderList->header()->hide();
     ui->_folderList->setItemDelegate( delegate );
     ui->_folderList->setModel( _model );
 #if defined(Q_OS_MAC)
@@ -75,12 +78,13 @@ AccountSettings::AccountSettings(QWidget *parent) :
 #else
     ui->_folderList->setMinimumWidth( 300 );
 #endif
-    ui->_folderList->setEditTriggers( QAbstractItemView::NoEditTriggers );
+    connect(ui->_folderList, SIGNAL(customContextMenuRequested(QPoint)),
+            this, SLOT(slotCustomContextMenuRequested(QPoint)));
 
-    ui->_buttonRemove->setEnabled(false);
-    ui->_buttonEnable->setEnabled(false);
-    ui->_buttonSelectiveSync->setEnabled(false);
-    ui->_buttonAdd->setEnabled(true);
+    connect(ui->_folderList, SIGNAL(expanded(QModelIndex)) , this, SLOT(refreshSelectiveSyncStatus()));
+    connect(ui->_folderList, SIGNAL(collapsed(QModelIndex)) , this, SLOT(refreshSelectiveSyncStatus()));
+    connect(_model, SIGNAL(dirtyChanged()), this, SLOT(refreshSelectiveSyncStatus()));
+    ui->selectiveSyncStatus->hide();
 
     QAction *resetFolderAction = new QAction(this);
     resetFolderAction->setShortcut(QKeySequence(Qt::Key_F5));
@@ -92,35 +96,59 @@ AccountSettings::AccountSettings(QWidget *parent) :
     connect(syncNowAction, SIGNAL(triggered()), SLOT(slotSyncCurrentFolderNow()));
     addAction(syncNowAction);
 
-    connect(ui->_buttonRemove, SIGNAL(clicked()), this, SLOT(slotRemoveCurrentFolder()));
-    connect(ui->_buttonEnable, SIGNAL(clicked()), this, SLOT(slotEnableCurrentFolder()));
-    connect(ui->_buttonAdd,    SIGNAL(clicked()), this, SLOT(slotAddFolder()));
-    connect(ui->_buttonSelectiveSync, SIGNAL(clicked()), this, SLOT(slotSelectiveSync()));
-    connect(ui->modifyAccountButton, SIGNAL(clicked()), SLOT(slotOpenAccountWizard()));
-    connect(ui->ignoredFilesButton, SIGNAL(clicked()), SLOT(slotIgnoreFilesEditor()));;
-
     connect(ui->_folderList, SIGNAL(clicked(QModelIndex)), SLOT(slotFolderActivated(QModelIndex)));
     connect(ui->_folderList, SIGNAL(doubleClicked(QModelIndex)),SLOT(slotDoubleClicked(QModelIndex)));
 
+    connect(ui->selectiveSyncApply, SIGNAL(clicked()), _model, SLOT(slotApplySelectiveSync()));
+    connect(ui->selectiveSyncCancel, SIGNAL(clicked()), _model, SLOT(resetFolders()));
+    connect(FolderMan::instance(), SIGNAL(folderListLoaded(Folder::Map)), _model, SLOT(resetFolders()));
+    connect(this, SIGNAL(folderChanged()), _model, SLOT(resetFolders()));
+
+
     QColor color = palette().highlight().color();
     ui->quotaProgressBar->setStyleSheet(QString::fromLatin1(progressBarStyleC).arg(color.name()));
     ui->connectLabel->setWordWrap(true);
     ui->connectLabel->setOpenExternalLinks(true);
-    ui->quotaLabel->setWordWrap(true);
+    QFont smallFont = ui->quotaInfoLabel->font();
+    smallFont.setPointSize(smallFont.pointSize() * 0.8);
+    ui->quotaInfoLabel->setFont(smallFont);
+
+    _quotaLabel = new QLabel(ui->quotaProgressBar);
+    (new QVBoxLayout(ui->quotaProgressBar))->addWidget(_quotaLabel);
 
     ui->connectLabel->setText(tr("No account configured."));
-    ui->_buttonAdd->setEnabled(false);
 
     connect(AccountStateManager::instance(), SIGNAL(accountStateAdded(AccountState*)),
             this, SLOT(slotAccountStateChanged(AccountState*)));
     slotAccountStateChanged(AccountStateManager::instance()->accountState());
+}
 
-    FolderMan *folderMan = FolderMan::instance();
-    connect(folderMan, SIGNAL(folderListLoaded(Folder::Map)),
-            this, SLOT(setFolderList(Folder::Map)));
-    setFolderList(FolderMan::instance()->map());
+void AccountSettings::slotCustomContextMenuRequested(const QPoint &pos)
+{
+    QTreeView *tv = ui->_folderList;
+    QModelIndex index = tv->indexAt(pos);
+    if (!index.isValid()) {
+        return;
+    }
+
+    QString alias = _model->data( index, FolderStatusDelegate::FolderAliasRole ).toString();
+    if (alias.isEmpty()) {
+        return;
+    }
+
+    tv->setCurrentIndex(index);
+    bool folderPaused = _model->data( index, FolderStatusDelegate::FolderSyncPaused).toBool();
+
+    QMenu *menu = new QMenu(tv);
+    menu->setAttribute(Qt::WA_DeleteOnClose);
+    connect(menu->addAction(tr("Remove folder")), SIGNAL(triggered(bool)),
+            this, SLOT(slotRemoveCurrentFolder()));
+    connect(menu->addAction(folderPaused ? tr("Resume") : tr("Pause")), SIGNAL(triggered(bool)),
+            this, SLOT(slotEnableCurrentFolder()));
+    menu->exec(tv->mapToGlobal(pos));
 }
 
+
 void AccountSettings::slotAccountStateChanged(AccountState *newAccountState)
 {
     if (_accountState) {
@@ -140,40 +168,16 @@ void AccountSettings::slotAccountStateChanged(AccountState *newAccountState)
                 this, SLOT(slotUpdateQuota(qint64,qint64)));
         slotUpdateQuota(quotaInfo->lastQuotaTotalBytes(), quotaInfo->lastQuotaUsedBytes());
     }
-
 }
 
 void AccountSettings::slotFolderActivated( const QModelIndex& indx )
 {
-  bool isValid = indx.isValid();
-
-  bool haveFolders = ui->_folderList->model()->rowCount() > 0;
-
-  ui->_buttonRemove->setEnabled(isValid);
-  if( Theme::instance()->singleSyncFolder() ) {
-      // only one folder synced folder allowed.
-      ui->_buttonAdd->setVisible(!haveFolders);
-  } else {
-      ui->_buttonAdd->setVisible(true);
-  }
-  bool isConnected = _accountState && _accountState->isConnected();
-  ui->_buttonAdd->setEnabled(isConnected);
-  ui->_buttonEnable->setEnabled( isValid );
-  ui->_buttonSelectiveSync->setEnabled(isConnected && isValid);
-
-  if ( isValid ) {
-    bool folderPaused = _model->data( indx, FolderStatusDelegate::FolderSyncPaused).toBool();
-    if ( !folderPaused) {
-      ui->_buttonEnable->setText( tr( "Pause" ) );
-    } else {
-      ui->_buttonEnable->setText( tr( "Resume" ) );
+    if (indx.data(FolderStatusDelegate::AddButton).toBool()) {
+        slotAddFolder();
+        return;
     }
-    ui->_buttonEnable->setEnabled(isConnected);
-  }
 }
 
-
-
 void AccountSettings::slotAddFolder()
 {
     FolderMan *folderMan = FolderMan::instance();
@@ -204,13 +208,11 @@ void AccountSettings::slotFolderWizardAccepted()
         return;
 
     Folder *f = folderMan->setupFolderFromConfigFile( alias );
-    slotAddFolder( f );
     folderMan->setSyncEnabled(true);
     if( f ) {
         folderMan->slotScheduleAllFolders();
         emit folderChanged();
     }
-    slotButtonsSetEnabled();
 }
 
 void AccountSettings::slotFolderWizardRejected()
@@ -221,32 +223,6 @@ void AccountSettings::slotFolderWizardRejected()
     folderMan->slotScheduleAllFolders();
 }
 
-void AccountSettings::slotOpenAccountWizard()
-{
-    if (QSystemTrayIcon::isSystemTrayAvailable()) {
-        topLevelWidget()->close();
-    }
-    OwncloudSetupWizard::runWizard(qApp, SLOT(slotownCloudWizardDone(int)), 0);
-}
-
-void AccountSettings::slotAddFolder( Folder *folder )
-{
-    if( ! folder || folder->alias().isEmpty() ) return;
-
-    QStandardItem *item = new QStandardItem();
-    folderToModelItem( item, folder, _accountState && _accountState->isConnectedOrMaintenance());
-    _model->appendRow( item );
-    // in order to update the enabled state of the "Sync now" button
-    connect(folder, SIGNAL(syncStateChange()), this, SLOT(slotFolderSyncStateChange()), Qt::UniqueConnection);
-}
-
-void AccountSettings::slotButtonsSetEnabled()
-{
-    QModelIndex selected = ui->_folderList->currentIndex();
-
-    slotFolderActivated(selected);
-}
-
 void AccountSettings::setGeneralErrors( const QStringList& errors )
 {
     _generalErrors = errors;
@@ -339,24 +315,12 @@ void AccountSettings::slotRemoveCurrentFolder()
             if( ret == QMessageBox::No ) {
                 return;
             }
-            /* Remove the selected item from the timer hash. */
-            QStandardItem *item = NULL;
-            if( selected.isValid() )
-                item = _model->itemFromIndex(selected);
-
-            if( selected.isValid() && item && _hideProgressTimers.contains(item) ) {
-                QTimer *t = _hideProgressTimers[item];
-                t->stop();
-                _hideProgressTimers.remove(item);
-                delete(t);
-            }
 
             FolderMan *folderMan = FolderMan::instance();
             folderMan->slotRemoveFolder( alias );
             _model->removeRow(row);
 
             // single folder fix to show add-button and hide remove-button
-            slotButtonsSetEnabled();
 
             emit folderChanged();
         }
@@ -368,6 +332,8 @@ void AccountSettings::slotResetCurrentFolder()
     QModelIndex selected = ui->_folderList->selectionModel()->currentIndex();
     if( selected.isValid() ) {
         QString alias = _model->data( selected, FolderStatusDelegate::FolderAliasRole ).toString();
+        if (alias.isEmpty())
+            return;
         int ret = QMessageBox::question( 0, tr("Confirm Folder Reset"),
                                          tr("<p>Do you really want to reset folder <i>%1</i> and rebuild your client database?</p>"
                                             "<p><b>Note:</b> This function is designed for maintenance purposes only. "
@@ -385,23 +351,11 @@ void AccountSettings::slotResetCurrentFolder()
     }
 }
 
-void AccountSettings::slotSelectiveSync()
-{
-    QModelIndex selected = ui->_folderList->selectionModel()->currentIndex();
-    if( selected.isValid() ) {
-        QString alias = _model->data( selected, FolderStatusDelegate::FolderAliasRole ).toString();
-        FolderMan *folderMan = FolderMan::instance();
-        Folder *f = folderMan->folder(alias);
-        if (f) {
-            (new SelectiveSyncDialog(AccountManager::instance()->account(), f, this))->open();
-        }
-    }
-}
-
 void AccountSettings::slotDoubleClicked( const QModelIndex& indx )
 {
     if( ! indx.isValid() ) return;
     QString alias = _model->data( indx, FolderStatusDelegate::FolderAliasRole ).toString();
+    if (alias.isEmpty()) return;
 
     emit openFolderAlias( alias );
 }
@@ -421,28 +375,7 @@ void AccountSettings::showConnectionLabel( const QString& message, const QString
         ui->connectLabel->setToolTip(QString());
         ui->connectLabel->setStyleSheet(errStyle);
     }
-}
-
-void AccountSettings::setFolderList( const Folder::Map &folders )
-{
-    _model->clear();
-
-    foreach(QTimer *t, _hideProgressTimers) {
-        t->stop();
-        delete t;
-    }
-    _hideProgressTimers.clear();
-
-    foreach( Folder *f, folders ) {
-        slotAddFolder( f );
-    }
-
-    QModelIndex idx = _model->index(0, 0);
-    if (idx.isValid()) {
-        ui->_folderList->setCurrentIndex(idx);
-    }
-    slotButtonsSetEnabled();
-
+    ui->accountStatus->setVisible(!message.isEmpty());
 }
 
 void AccountSettings::slotEnableCurrentFolder()
@@ -503,8 +436,6 @@ void AccountSettings::slotEnableCurrentFolder()
         if( currentlyPaused ) _wasDisabledBefore = true;
 
         slotUpdateFolderState (f);
-        // set the button text accordingly.
-        slotFolderActivated( selected );
     }
 }
 
@@ -525,7 +456,7 @@ void AccountSettings::slotUpdateFolderState( Folder *folder )
     int row = 0;
 
     if( ! folder ) return;
-
+#if 0
     item = _model->item( row );
 
     while( item ) {
@@ -541,6 +472,7 @@ void AccountSettings::slotUpdateFolderState( Folder *folder )
     } else {
         // the dialog is not visible.
     }
+#endif
 }
 
 void AccountSettings::slotOpenOC()
@@ -551,24 +483,7 @@ void AccountSettings::slotOpenOC()
 
 QStandardItem* AccountSettings::itemForFolder(const QString& folder)
 {
-    QStandardItem *item = NULL;
-
-    if( folder.isEmpty() ) {
-        return item;
-    }
-
-    int row = 0;
-
-    item = _model->item( row );
-
-    while( item ) {
-        if( item->data( FolderStatusDelegate::FolderAliasRole ) == folder ) {
-            // its the item to update!
-            break;
-        }
-        item = _model->item( ++row );
-    }
-    return item;
+    return nullptr;
 }
 
 QString AccountSettings::shortenFilename( const QString& folder, const QString& file ) const
@@ -593,6 +508,7 @@ QString AccountSettings::shortenFilename( const QString& folder, const QString&
 
 void AccountSettings::slotSetProgress(const QString& folder, const Progress::Info &progress )
 {
+#if 0
     if (!isVisible()) {
         return; // for https://github.com/owncloud/client/issues/2648#issuecomment-71377909
     }
@@ -686,10 +602,12 @@ void AccountSettings::slotSetProgress(const QString& folder, const Progress::Inf
     }
     overallPercent = qBound(0, overallPercent, 100);
     item->setData( overallPercent, FolderStatusDelegate::SyncProgressOverallPercent);
+#endif
 }
 
 void AccountSettings::slotHideProgress()
 {
+#if 0
     QTimer *send_timer = qobject_cast<QTimer*>(this->sender());
     QHash<QStandardItem*, QTimer*>::const_iterator i = _hideProgressTimers.constBegin();
     while (i != _hideProgressTimers.constEnd()) {
@@ -717,11 +635,12 @@ void AccountSettings::slotHideProgress()
     }
 
     send_timer->deleteLater();
+#endif
 }
 
 void AccountSettings::slotFolderSyncStateChange()
 {
-    slotButtonsSetEnabled();
+#if 0
     Folder* folder = qobject_cast<Folder *>(sender());
     if (!folder) return;
 
@@ -745,12 +664,14 @@ void AccountSettings::slotFolderSyncStateChange()
         }
         timer->start(5000);
     }
+#endif
 }
 
 
 void AccountSettings::slotUpdateQuota(qint64 total, qint64 used)
 {
     if( total > 0 ) {
+        ui->storageGroupBox->setVisible(true);
         ui->quotaProgressBar->setVisible(true);
         ui->quotaInfoLabel->setVisible(true);
         ui->quotaProgressBar->setEnabled(true);
@@ -763,22 +684,12 @@ void AccountSettings::slotUpdateQuota(qint64 total, qint64 used)
         QString totalStr = Utility::octetsToString(total);
         double percent = used/(double)total*100;
         QString percentStr = Utility::compactFormatDouble(percent, 1);
-        ui->quotaLabel->setText(tr("%1 (%3%) of %2 server space in use.").arg(usedStr, totalStr, percentStr));
+        _quotaLabel->setText(tr("%1 (%3%) of %2 server space in use.").arg(usedStr, totalStr, percentStr));
     } else {
-        ui->quotaProgressBar->setVisible(false);
+        ui->storageGroupBox->setVisible(false);
         ui->quotaInfoLabel->setVisible(false);
-        ui->quotaLabel->setText(tr("Currently there is no storage usage information available."));
-    }
-}
-
-void AccountSettings::slotIgnoreFilesEditor()
-{
-    if (_ignoreEditor.isNull()) {
-        _ignoreEditor = new IgnoreListEditor(this);
-        _ignoreEditor->setAttribute( Qt::WA_DeleteOnClose, true );
-        _ignoreEditor->open();
-    } else {
-        ownCloudGui::raiseDialog(_ignoreEditor);
+        ui->quotaProgressBar->setMaximum(0);
+        _quotaLabel->setText(tr("Currently there is no storage usage information available."));
     }
 }
 
@@ -789,7 +700,6 @@ void AccountSettings::slotAccountStateChanged(int state)
         AccountPtr account = _accountState->account();
         QUrl safeUrl(account->url());
         safeUrl.setPassword(QString()); // Remove the password from the URL to avoid showing it in the UI
-        slotButtonsSetEnabled();
         FolderMan *folderMan = FolderMan::instance();
         foreach (Folder *folder, folderMan->map().values()) {
             slotUpdateFolderState(folder);
@@ -815,7 +725,6 @@ void AccountSettings::slotAccountStateChanged(int state)
     } else {
         // ownCloud is not yet configured.
         showConnectionLabel( tr("No %1 connection configured.").arg(Theme::instance()->appNameGUI()) );
-        ui->_buttonAdd->setEnabled( false);
     }
 }
 
@@ -824,4 +733,29 @@ AccountSettings::~AccountSettings()
     delete ui;
 }
 
+void AccountSettings::refreshSelectiveSyncStatus()
+{
+    ui->selectiveSyncApply->setEnabled(_model->isDirty());
+    ui->selectiveSyncCancel->setEnabled(_model->isDirty());
+    bool shouldBeVisible = _model->isDirty();
+    for (int i = 0; !shouldBeVisible && i < _model->rowCount(); ++i) {
+        if (ui->_folderList->isExpanded(_model->index(i)))
+            shouldBeVisible = true;
+    }
+    bool wasVisible = ui->selectiveSyncApply->isVisible();
+    if (wasVisible != shouldBeVisible) {
+        QSize hint = ui->selectiveSyncStatus->sizeHint();
+        if (shouldBeVisible) {
+            ui->selectiveSyncStatus->setMaximumHeight(0);
+            ui->selectiveSyncStatus->setVisible(true);
+        }
+        auto anim = new QPropertyAnimation(ui->selectiveSyncStatus, "maximumHeight", ui->selectiveSyncStatus);
+        anim->setEndValue(shouldBeVisible ? hint.height() : 0);
+        anim->start(QAbstractAnimation::DeleteWhenStopped);
+        if (!shouldBeVisible) {
+            connect(anim, SIGNAL(finished()), ui->selectiveSyncStatus, SLOT(hide()));
+        }
+    }
+}
+
 } // namespace OCC
diff --git a/src/gui/accountsettings.h b/src/gui/accountsettings.h
index 94110a9..da0132b 100644
--- a/src/gui/accountsettings.h
+++ b/src/gui/accountsettings.h
@@ -29,6 +29,7 @@ class QModelIndex;
 class QStandardItem;
 class QNetworkReply;
 class QListWidgetItem;
+class QLabel;
 
 namespace OCC {
 
@@ -37,9 +38,10 @@ class AccountSettings;
 }
 
 class FolderMan;
-class IgnoreListEditor;
+
 class Account;
 class AccountState;
+class FolderStatusModel;
 
 class AccountSettings : public QWidget
 {
@@ -62,27 +64,22 @@ public slots:
     void slotUpdateFolderState( Folder* );
     void slotDoubleClicked( const QModelIndex& );
     void slotSetProgress(const QString& folder, const Progress::Info& progress);
-    void slotButtonsSetEnabled();
 
     void slotUpdateQuota( qint64,qint64 );
-    void slotIgnoreFilesEditor();
     void slotAccountStateChanged(int state);
 
     void setGeneralErrors( const QStringList& errors );
-    void setFolderList( const Folder::Map& );
 
 protected slots:
     void slotAddFolder();
-    void slotAddFolder( Folder* );
     void slotEnableCurrentFolder();
     void slotSyncCurrentFolderNow();
     void slotRemoveCurrentFolder();
     void slotResetCurrentFolder();
     void slotFolderWizardAccepted();
     void slotFolderWizardRejected();
-    void slotOpenAccountWizard();
     void slotHideProgress();
-    void slotSelectiveSync();
+    void refreshSelectiveSyncStatus();
 
 private:
     QString shortenFilename( const QString& folder, const QString& file ) const;
@@ -91,16 +88,18 @@ private:
     void showConnectionLabel( const QString& message, const QString& tooltip = QString() );
 
     Ui::AccountSettings *ui;
-    QPointer<IgnoreListEditor> _ignoreEditor;
-    QStandardItemModel *_model;
+
+    FolderStatusModel *_model;
     QUrl   _OCUrl;
     QHash<QStandardItem*, QTimer*> _hideProgressTimers;
     QStringList _generalErrors;
     bool _wasDisabledBefore;
     AccountState *_accountState;
+    QLabel *_quotaLabel;
 private slots:
     void slotFolderSyncStateChange();
     void slotAccountStateChanged(AccountState*);
+    void slotCustomContextMenuRequested(const QPoint&);
 };
 
 } // namespace OCC
diff --git a/src/gui/accountsettings.ui b/src/gui/accountsettings.ui
index 82ea9e2..e2adf85 100644
--- a/src/gui/accountsettings.ui
+++ b/src/gui/accountsettings.ui
@@ -6,101 +6,71 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>615</width>
-    <height>422</height>
+    <width>469</width>
+    <height>652</height>
    </rect>
   </property>
   <property name="windowTitle">
    <string>Form</string>
   </property>
-  <layout class="QGridLayout" name="gridLayout_2">
-   <item row="0" column="0" colspan="2">
-    <widget class="QGroupBox" name="syncStatusGroupBox">
-     <property name="title">
-      <string>Account to Synchronize</string>
-     </property>
-     <layout class="QGridLayout" name="gridLayout">
-      <item row="0" column="0" colspan="2">
-       <layout class="QHBoxLayout" name="horizontalLayout">
-        <item>
-         <widget class="SslButton" name="sslButton">
-          <property name="sizePolicy">
-           <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
-            <horstretch>0</horstretch>
-            <verstretch>0</verstretch>
-           </sizepolicy>
-          </property>
-          <property name="text">
-           <string/>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QLabel" name="connectLabel">
-          <property name="text">
-           <string>Connected with <server> as <user></string>
-          </property>
-         </widget>
-        </item>
-       </layout>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QWidget" name="accountStatus" native="true">
+     <layout class="QHBoxLayout" name="horizontalLayout">
+      <item>
+       <widget class="SslButton" name="sslButton">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="text">
+         <string/>
+        </property>
+       </widget>
       </item>
-      <item row="1" column="0">
-       <widget class="QListView" name="_folderList"/>
+      <item>
+       <widget class="QLabel" name="connectLabel">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="text">
+         <string>Connected with <server> as <user></string>
+        </property>
+       </widget>
       </item>
-      <item row="1" column="1">
-       <layout class="QVBoxLayout" name="verticalLayout_2">
-        <item>
-         <widget class="QPushButton" name="_buttonAdd">
-          <property name="text">
-           <string>Add Folder...</string>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QPushButton" name="_buttonEnable">
-          <property name="text">
-           <string>Pause</string>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QPushButton" name="_buttonRemove">
-          <property name="text">
-           <string>Remove</string>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QPushButton" name="_buttonSelectiveSync">
-          <property name="text">
-           <string>Choose What to Sync</string>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <spacer name="verticalSpacer_3">
-          <property name="orientation">
-           <enum>Qt::Vertical</enum>
-          </property>
-          <property name="sizeHint" stdset="0">
-           <size>
-            <width>20</width>
-            <height>40</height>
-           </size>
-          </property>
-         </spacer>
-        </item>
-       </layout>
+      <item>
+       <widget class="QPushButton" name="pushButton">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="text">
+         <string>Delete</string>
+        </property>
+       </widget>
       </item>
      </layout>
     </widget>
    </item>
-   <item row="1" column="0">
+   <item>
     <widget class="QGroupBox" name="storageGroupBox">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
      <property name="title">
       <string>Storage Usage</string>
      </property>
-     <layout class="QVBoxLayout" name="verticalLayout">
+     <layout class="QVBoxLayout" name="verticalLayout_2">
       <item>
        <widget class="QProgressBar" name="quotaProgressBar">
         <property name="enabled">
@@ -118,16 +88,15 @@
        </widget>
       </item>
       <item>
-       <widget class="QLabel" name="quotaLabel">
-        <property name="text">
-         <string>Retrieving usage information...</string>
-        </property>
-       </widget>
-      </item>
-      <item>
        <widget class="QLabel" name="quotaInfoLabel">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
         <property name="text">
-         <string><b>Note:</b> Some folders, including network mounted or shared folders, might have different limits.</string>
+         <string>Some folders, including network mounted or shared folders, might have different limits.</string>
         </property>
         <property name="wordWrap">
          <bool>true</bool>
@@ -137,26 +106,76 @@
      </layout>
     </widget>
    </item>
-   <item row="1" column="1">
-    <widget class="QGroupBox" name="maintenanceGroupBox">
-     <property name="title">
-      <string>Account Maintenance</string>
+   <item>
+    <widget class="QTreeView" name="_folderList">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding">
+       <horstretch>0</horstretch>
+       <verstretch>5</verstretch>
+      </sizepolicy>
      </property>
-     <layout class="QVBoxLayout" name="verticalLayout_3">
-      <item>
-       <widget class="QPushButton" name="ignoredFilesButton">
-        <property name="enabled">
-         <bool>true</bool>
+     <property name="contextMenuPolicy">
+      <enum>Qt::CustomContextMenu</enum>
+     </property>
+     <property name="editTriggers">
+      <set>QAbstractItemView::NoEditTriggers</set>
+     </property>
+     <property name="animated">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QWidget" name="selectiveSyncStatus" native="true">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="MinimumExpanding" vsizetype="Maximum">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <layout class="QGridLayout" name="gridLayout_2">
+      <property name="sizeConstraint">
+       <enum>QLayout::SetNoConstraint</enum>
+      </property>
+      <item row="1" column="1">
+       <widget class="QPushButton" name="selectiveSyncCancel">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
         </property>
         <property name="text">
-         <string>Edit Ignored Files</string>
+         <string>Cancel</string>
         </property>
        </widget>
       </item>
-      <item>
-       <widget class="QPushButton" name="modifyAccountButton">
+      <item row="0" column="1">
+       <widget class="QPushButton" name="selectiveSyncApply">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Minimum" vsizetype="Maximum">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
         <property name="text">
-         <string>Modify Account</string>
+         <string>Apply</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="0" rowspan="2">
+       <widget class="QLabel" name="label">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="MinimumExpanding" vsizetype="Maximum">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="text">
+         <string>Unchecked folders will be <b>removed</b> from your local file system and will not be synchronized to this computer anymore</string>
+        </property>
+        <property name="wordWrap">
+         <bool>true</bool>
         </property>
        </widget>
       </item>
diff --git a/src/gui/folderstatusmodel.cpp b/src/gui/folderstatusmodel.cpp
index d86edd7..04a0e6a 100644
--- a/src/gui/folderstatusmodel.cpp
+++ b/src/gui/folderstatusmodel.cpp
@@ -13,7 +13,10 @@
  */
 
 #include "folderstatusmodel.h"
+#include "folderman.h"
 #include "utility.h"
+#include <theme.h>
+#include <account.h>
 
 #include <QtCore>
 #include <QtGui>
@@ -21,17 +24,42 @@
 #include <QtWidgets>
 #endif
 
+Q_DECLARE_METATYPE(QPersistentModelIndex)
+
 namespace OCC {
 
-FolderStatusModel::FolderStatusModel()
-    :QStandardItemModel()
+static const char propertyParentIndexC[] = "oc_parentIndex";
+
+FolderStatusModel::FolderStatusModel(QObject *parent)
+    :QAbstractItemModel(parent)
 {
+}
+
+FolderStatusModel::~FolderStatusModel()
+{ }
+
 
+void FolderStatusModel::setAccount(const AccountPtr& account)
+{
+    beginResetModel();
+    _dirty = false;
+    _folders.clear();
+    _account = account;
+    endResetModel();
 }
 
-Qt::ItemFlags FolderStatusModel::flags ( const QModelIndex&  ) const
+
+Qt::ItemFlags FolderStatusModel::flags ( const QModelIndex &index  ) const
 {
-    return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
+    switch (classify(index)) {
+        case AddButton:
+            return Qt::ItemIsEnabled;
+        case RootFolder:
+            return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
+        case SubFolder:
+            return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable;
+    }
+    return 0;
 }
 
 QVariant FolderStatusModel::data(const QModelIndex &index, int role) const
@@ -41,10 +69,433 @@ QVariant FolderStatusModel::data(const QModelIndex &index, int role) const
 
     if (role == Qt::EditRole)
         return QVariant();
-    else
-        return QStandardItemModel::data(index,role);
+
+    switch(classify(index)) {
+    case AddButton:
+        if (role == FolderStatusDelegate::AddButton)
+            return QVariant(true);
+        return QVariant();
+    case SubFolder:
+    {
+        const auto &x = static_cast<SubFolderInfo *>(index.internalPointer())->_subs[index.row()];
+        switch (role) {
+        case Qt::ToolTipRole:
+        case Qt::DisplayRole:
+            return x._name;
+        case Qt::CheckStateRole:
+            return x._checked;
+        case Qt::DecorationRole:
+            return QFileIconProvider().icon(QFileIconProvider::Folder);
+        }
+    }
+        return QVariant();
+    case RootFolder:
+        break;
+    }
+
+    auto folderList = FolderMan::instance()->map().values();
+    auto f = folderList.at(index.row());
+    if (!f)
+        return QVariant();
+
+    bool accountConnected = true; // FIXME
+
+    switch (role) {
+    case FolderStatusDelegate::FolderPathRole         : return  f->nativePath();
+    case FolderStatusDelegate::FolderSecondPathRole   : return  f->remotePath();
+    case FolderStatusDelegate::FolderAliasRole        : return  f->alias();
+    case FolderStatusDelegate::FolderSyncPaused       : return  f->syncPaused();
+    case FolderStatusDelegate::FolderAccountConnected : return  accountConnected;
+    case Qt::ToolTipRole:
+        return Theme::instance()->statusHeaderText(f->syncResult().status());
+    case FolderStatusDelegate::FolderStatusIconRole:
+        if ( accountConnected ) {
+            auto theme = Theme::instance();
+            auto status = f->syncResult().status();
+            if( f->syncPaused() ) {
+                return theme->folderDisabledIcon( );
+            } else {
+                if( status == SyncResult::SyncPrepare ) {
+                    return theme->syncStateIcon(SyncResult::SyncRunning);
+                } else if( status == SyncResult::Undefined ) {
+                    return theme->syncStateIcon( SyncResult::SyncRunning);
+                } else {
+                    // kepp the previous icon for the prepare phase.
+                    if( status == SyncResult::Problem) {
+                        return theme->syncStateIcon( SyncResult::Success);
+                    } else {
+                        return theme->syncStateIcon( status );
+                    }
+                }
+            }
+        } else {
+            return Theme::instance()->folderOfflineIcon();
+        }
+    }
+    return QVariant();
+}
+
+bool FolderStatusModel::setData(const QModelIndex& index, const QVariant& value, int role)
+{
+    if(role == Qt::CheckStateRole) {
+        auto info = infoForIndex(index);
+        Qt::CheckState checked = static_cast<Qt::CheckState>(value.toInt());
+
+        if (info && info->_checked != checked) {
+            info->_checked = checked;
+            if (checked == Qt::Checked) {
+                // If we are checked, check that we may need to check the parent as well if
+                // all the sibilings are also checked
+                QModelIndex parent = index.parent();
+                auto parentInfo = infoForIndex(parent);
+                if (parentInfo && parentInfo->_checked != Qt::Checked) {
+                    bool hasUnchecked = false;
+                    foreach(const auto &sub, parentInfo->_subs) {
+                        if (sub._checked != Qt::Checked) {
+                            hasUnchecked = true;
+                            break;
+                        }
+                    }
+                    if (!hasUnchecked) {
+                        setData(parent, Qt::Checked, Qt::CheckStateRole);
+                    } else if (parentInfo->_checked == Qt::Unchecked) {
+                        setData(parent, Qt::PartiallyChecked, Qt::CheckStateRole);
+                    }
+                }
+                // also check all the children
+                for (int i = 0; i < info->_subs.count(); ++i) {
+                    if (info->_subs[i]._checked != Qt::Checked) {
+                        setData(index.child(i, 0), Qt::Checked, Qt::CheckStateRole);
+                    }
+                }
+            }
+
+            if (checked == Qt::Unchecked) {
+                QModelIndex parent = index.parent();
+                auto parentInfo = infoForIndex(parent);
+                if (parentInfo && parentInfo->_checked == Qt::Checked) {
+                    setData(parent, Qt::PartiallyChecked, Qt::CheckStateRole);
+                }
+
+                // Uncheck all the children
+                for (int i = 0; i < info->_subs.count(); ++i) {
+                    if (info->_subs[i]._checked != Qt::Unchecked) {
+                        setData(index.child(i, 0), Qt::Unchecked, Qt::CheckStateRole);
+                    }
+                }
+            }
+
+            if (checked == Qt::PartiallyChecked) {
+                QModelIndex parent = index.parent();
+                auto parentInfo = infoForIndex(parent);
+                if (parentInfo && parentInfo->_checked != Qt::PartiallyChecked) {
+                    setData(parent, Qt::PartiallyChecked, Qt::CheckStateRole);
+                }
+            }
+
+        }
+        _dirty = true;
+        emit dirtyChanged();
+        dataChanged(index, index, QVector<int>() << role);
+        return true;
+    }
+    return QAbstractItemModel::setData(index, value, role);
+}
+
+
+int FolderStatusModel::columnCount(const QModelIndex&) const
+{
+    return 1;
+}
+
+int FolderStatusModel::rowCount(const QModelIndex& parent) const
+{
+    if (!parent.isValid()) {
+        return FolderMan::instance()->map().count() + 1;
+    }
+
+    auto info = infoForIndex(parent);
+    if (!info)
+        return 0;
+    return info->_subs.count();
+}
+
+FolderStatusModel::ItemType FolderStatusModel::classify(const QModelIndex& index) const
+{
+    if (index.internalPointer()) {
+        return SubFolder;
+    }
+    //FIXME:
+    auto folderList = FolderMan::instance()->map(); //.values();
+    if (index.row() < folderList.count()) {
+        return RootFolder;
+    }
+    return AddButton;
 }
 
+FolderStatusModel::SubFolderInfo* FolderStatusModel::infoForIndex(const QModelIndex& index) const
+{
+    if (!index.isValid())
+        return 0;
+    if (auto parentInfo = index.internalPointer()) {
+        return &static_cast<SubFolderInfo*>(parentInfo)->_subs[index.row()];
+    } else {
+        auto folders = FolderMan::instance()->map(); // FIXME
+        if (index.row() >= folders.count()) {
+            // AddButton
+            return 0;
+        }
+        if (_folders.size() <=  index.row()) {
+            _folders.resize(index.row() + 1);
+        }
+        auto info = &_folders[index.row()];
+        if (info->_pathIdx.isEmpty()) {
+            info->_pathIdx << index.row();
+            info->_name = folders.values().at(index.row())->alias();
+            info->_path = "/";
+            info->_folder = folders.values().at(index.row());
+        }
+        return info;
+    }
+}
+
+
+QModelIndex FolderStatusModel::index(int row, int column, const QModelIndex& parent) const
+{
+    if (!parent.isValid()) {
+        return createIndex(row, column, nullptr);
+    }
+    switch(classify(parent)) {
+        case AddButton: return QModelIndex();
+        case RootFolder:
+            if (_folders.count() <= parent.row())
+                return QModelIndex(); // should not happen
+            return createIndex(row, column, const_cast<SubFolderInfo *>(&_folders[parent.row()]));
+        case SubFolder:
+            //return QModelIndex();
+            if (static_cast<SubFolderInfo*>(parent.internalPointer())->_subs.count() <= parent.row())
+                return QModelIndex(); // should not happen
+            if (static_cast<SubFolderInfo*>(parent.internalPointer())->_subs.at(parent.row())._subs.count() <= row)
+                return QModelIndex(); // should not happen
+            return createIndex(row, column, &static_cast<SubFolderInfo*>(parent.internalPointer())->_subs[parent.row()]);
+    }
+    return QModelIndex();
+}
+
+QModelIndex FolderStatusModel::parent(const QModelIndex& child) const
+{
+    if (!child.isValid()) {
+        return QModelIndex();
+    }
+    switch(classify(child)) {
+        case RootFolder:
+        case AddButton:
+            return QModelIndex();
+        case SubFolder:
+            break;
+    }
+    auto pathIdx = static_cast<SubFolderInfo*>(child.internalPointer())->_subs[child.row()]._pathIdx;
+    int i = 1;
+    Q_ASSERT(pathIdx.at(0) < _folders.count());
+    if (pathIdx.count() == 2) {
+        return createIndex(pathIdx.at(0), 0, nullptr);
+    }
+
+    const SubFolderInfo *info = &_folders[pathIdx.at(0)];
+    while (i < pathIdx.count() - 2) {
+        Q_ASSERT(pathIdx.at(i) < info->_subs.count());
+        info = &info->_subs[pathIdx.at(i)];
+        ++i;
+    }
+    return createIndex(pathIdx.at(i), 0, const_cast<SubFolderInfo *>(info));
+}
+
+bool FolderStatusModel::hasChildren(const QModelIndex& parent) const
+{
+    if (!parent.isValid())
+        return true;
+
+    auto info = infoForIndex(parent);
+    if (!info)
+        return false;
+
+    if (!info->_fetched)
+        return true;
+
+    if (info->_subs.isEmpty())
+        return false;
+
+    return true;
+}
+
+
+bool FolderStatusModel::canFetchMore(const QModelIndex& parent) const
+{
+    auto info = infoForIndex(parent);
+    if (!info || info->_fetched || info->_fetching)
+        return false;
+    return true;
+}
+
+
+void FolderStatusModel::fetchMore(const QModelIndex& parent)
+{
+    auto info = infoForIndex(parent);
+    if (!info || info->_fetched || info->_fetching)
+        return;
+
+    info->_fetching = true;
+    LsColJob *job = new LsColJob(_account, info->_folder->remotePath() + "/" + info->_path, this);
+    job->setProperties(QList<QByteArray>() << "resourcetype" << "quota-used-bytes");
+    connect(job, SIGNAL(directoryListingSubfolders(QStringList)),
+            SLOT(slotUpdateDirectories(QStringList)));
+    job->start();
+    job->setProperty(propertyParentIndexC , QVariant::fromValue<QPersistentModelIndex>(parent));
+}
+
+void FolderStatusModel::slotUpdateDirectories(const QStringList &list_)
+{
+    auto job = qobject_cast<LsColJob *>(sender());
+    Q_ASSERT(job);
+    QModelIndex idx = qvariant_cast<QPersistentModelIndex>(job->property(propertyParentIndexC));
+    if (!idx.isValid()) {
+        return;
+    }
+    auto parentInfo = infoForIndex(idx);
+
+    auto list = list_;
+    list.removeFirst(); // remove the parent item
+
+    beginInsertRows(idx, 0, list.count());
+
+    QUrl url = parentInfo->_folder->remoteUrl();
+    QString pathToRemove = url.path();
+    if (!pathToRemove.endsWith('/'))
+        pathToRemove += '/';
+
+    parentInfo->_fetched = true;
+    parentInfo->_fetching = false;
+
+    int i = 0;
+    foreach (QString path, list) {
+        SubFolderInfo newInfo;
+        newInfo._folder = parentInfo->_folder;
+        newInfo._pathIdx = parentInfo->_pathIdx;
+        newInfo._pathIdx << i++;
+        auto size = job ? job->_sizes.value(path) : 0;
+        newInfo._size = size;
+        path.remove(pathToRemove);
+        newInfo._path = path;
+        newInfo._name = path.split('/', QString::SkipEmptyParts).last();
+
+        if (path.isEmpty())
+            continue;
+
+        if (parentInfo->_checked == Qt::Unchecked) {
+            newInfo._checked = Qt::Unchecked;
+        } else {
+            auto *f = FolderMan::instance()->map().values().at(parentInfo->_pathIdx.first());
+            foreach(const QString &str , f->selectiveSyncBlackList()) {
+                if (str == path || str == QLatin1String("/")) {
+                    newInfo._checked = Qt::Unchecked;
+                    break;
+                } else if (str.startsWith(path)) {
+                    newInfo._checked = Qt::PartiallyChecked;
+                }
+            }
+        }
+        parentInfo->_subs.append(newInfo);
+    }
+
+    endInsertRows();
+}
+
+/*void SelectiveSyncTreeView::slotLscolFinishedWithError(QNetworkReply *r)
+{
+    if (r->error() == QNetworkReply::ContentNotFoundError) {
+        _loading->setText(tr("No subfolders currently on the server."));
+    } else {
+        _loading->setText(tr("An error occured while loading the list of sub folders."));
+    }
+    _loading->resize(_loading->sizeHint()); // because it's not in a layout
+}*/
+
+QStringList FolderStatusModel::createBlackList(FolderStatusModel::SubFolderInfo *root,
+                                               const QStringList &oldBlackList) const
+{
+    if (!root) return QStringList();
+
+    switch(root->_checked) {
+        case Qt::Unchecked:
+            return QStringList(root->_path);
+        case  Qt::Checked:
+            return QStringList();
+        case Qt::PartiallyChecked:
+            break;
+    }
+
+    QStringList result;
+    if (root->_fetched) {
+        for (int i = 0; i < root->_subs.count(); ++i) {
+            result += createBlackList(&root->_subs[i], oldBlackList);
+        }
+    } else {
+        // We did not load from the server so we re-use the one from the old black list
+        QString path = root->_path;
+        foreach (const QString & it, oldBlackList) {
+            if (it.startsWith(path))
+                result += it;
+        }
+    }
+    return result;
+}
+
+void FolderStatusModel::slotApplySelectiveSync()
+{
+    if (!_dirty)
+        return;
+    auto folderList = FolderMan::instance()->map().values(); //FIXME
+
+    for (int i = 0; i < folderList.count(); ++i) {
+        if (i >= _folders.count()) break;
+        if (!_folders[i]._fetched) continue;
+        auto folder = folderList.at(i);
+
+        auto oldBlackList = folder->selectiveSyncBlackList();
+        QStringList blackList = createBlackList(&_folders[i], oldBlackList);
+        folder->setSelectiveSyncBlackList(blackList);
+
+        // FIXME: Use ConfigFile
+        QSettings settings(folder->configFile(), QSettings::IniFormat);
+        settings.beginGroup(FolderMan::escapeAlias(folder->alias()));
+        settings.setValue("blackList", blackList);
+        FolderMan *folderMan = FolderMan::instance();
+        auto blackListSet = blackList.toSet();
+        auto oldBlackListSet = oldBlackList.toSet();
+        auto changes = (oldBlackListSet - blackListSet) + (blackListSet - oldBlackListSet);
+        if (!changes.isEmpty()) {
+            if (folder->isBusy()) {
+                folder->slotTerminateSync();
+            }
+            //The part that changed should not be read from the DB on next sync because there might be new folders
+            // (the ones that are no longer in the blacklist)
+            foreach(const auto &it, changes) {
+                folder->journalDb()->avoidReadFromDbOnNextSync(it);
+            }
+            folderMan->slotScheduleSync(folder->alias());
+        }
+    }
+
+    resetFolders();
+}
+
+
+void FolderStatusModel::resetFolders()
+{
+    setAccount(_account);
+}
+
+
 // ====================================================================================
 
 FolderStatusDelegate::FolderStatusDelegate()
@@ -62,6 +513,12 @@ FolderStatusDelegate::~FolderStatusDelegate()
 QSize FolderStatusDelegate::sizeHint(const QStyleOptionViewItem & option ,
                                    const QModelIndex & index) const
 {
+
+    if (static_cast<const FolderStatusModel *>(index.model())->classify(index) != FolderStatusModel::RootFolder) {
+        return QStyledItemDelegate::sizeHint(option, index);
+    }
+
+
   Q_UNUSED(option)
   QFont aliasFont = option.font;
   QFont font = option.font;
@@ -101,8 +558,17 @@ QSize FolderStatusDelegate::sizeHint(const QStyleOptionViewItem & option ,
 void FolderStatusDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
                                  const QModelIndex &index) const
 {
+  if (qvariant_cast<bool>(index.data(AddButton))) {
+      painter->drawText(option.rect, "[+ Add Folder]");
+      return;
+  }
+
+
   QStyledItemDelegate::paint(painter,option,index);
 
+  if (static_cast<const FolderStatusModel *>(index.model())->classify(index) != FolderStatusModel::RootFolder) {
+      return;
+  }
   painter->save();
 
   QFont aliasFont = option.font;
@@ -141,7 +607,7 @@ void FolderStatusDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
   QRect iconRect = option.rect;
   QRect aliasRect = option.rect;
 
-  iconRect.setLeft( aliasMargin );
+  iconRect.setLeft( option.rect.left() + aliasMargin );
   iconRect.setTop( iconRect.top() + aliasMargin ); // (iconRect.height()-iconsize.height())/2);
 
   // alias box
@@ -313,11 +779,14 @@ void FolderStatusDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
 
       painter->restore();
   }
+
   painter->restore();
 }
 
-bool FolderStatusDelegate::editorEvent ( QEvent * /*event*/, QAbstractItemModel * /*model*/, const QStyleOptionViewItem & /*option*/, const QModelIndex & /*index*/ )
+bool FolderStatusDelegate::editorEvent ( QEvent * event, QAbstractItemModel * model,
+                                         const QStyleOptionViewItem & option, const QModelIndex & index )
 {
+    return QStyledItemDelegate::editorEvent(event, model, option, index);
     return false;
 }
 
diff --git a/src/gui/folderstatusmodel.h b/src/gui/folderstatusmodel.h
index b1cbf2b..2e1709b 100644
--- a/src/gui/folderstatusmodel.h
+++ b/src/gui/folderstatusmodel.h
@@ -17,16 +17,72 @@
 
 #include <QStyledItemDelegate>
 #include <QStandardItemModel>
+#include <accountfwd.h>
+
+#ifndef Q_DECL_OVERRIDE
+#define Q_DECL_OVERRIDE
+#endif
 
 namespace OCC {
 
-class FolderStatusModel : public QStandardItemModel
+class Folder;
+
+class FolderStatusModel : public QAbstractItemModel
 {
+    Q_OBJECT
 public:
-    FolderStatusModel();
-    virtual Qt::ItemFlags flags( const QModelIndex& ) const Q_DECL_OVERRIDE;
+    FolderStatusModel(QObject * parent = 0);
+    ~FolderStatusModel();
+    void setAccount(const OCC::AccountPtr& account);
+
+    Qt::ItemFlags flags( const QModelIndex& ) const Q_DECL_OVERRIDE;
     QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE;
+    bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) Q_DECL_OVERRIDE;
+    int columnCount(const QModelIndex& parent = QModelIndex()) const Q_DECL_OVERRIDE;
+    int rowCount(const QModelIndex& parent = QModelIndex()) const Q_DECL_OVERRIDE;
+    QModelIndex index(int row, int column = 0, const QModelIndex& parent = QModelIndex()) const Q_DECL_OVERRIDE;
+    QModelIndex parent(const QModelIndex& child) const Q_DECL_OVERRIDE;
+    bool canFetchMore(const QModelIndex& parent) const Q_DECL_OVERRIDE;
+    void fetchMore(const QModelIndex& parent) Q_DECL_OVERRIDE;
+    bool hasChildren(const QModelIndex& parent = QModelIndex()) const Q_DECL_OVERRIDE;
+
+
+    struct SubFolderInfo {
+//        QWeakPointer<SubFolderInfo> parent;
+        QString _name;
+        QString _path;
+        QVector<int> _pathIdx;
+        int _size = 0;
+        bool _fetched = false; // If we did the LSCOL for this folder already
+        bool _fetching = false;
+        QVector<SubFolderInfo> _subs;
+        Qt::CheckState _checked = Qt::Checked;
+        Folder *_folder;
+    };
+
+    mutable QVector<SubFolderInfo> _folders;
 
+    enum ItemType { RootFolder, SubFolder, AddButton, SelectiveSyncText };
+    ItemType classify(const QModelIndex &index) const;
+    SubFolderInfo *infoForIndex(const QModelIndex &index) const;
+
+    bool isDirty() { return _dirty; }
+
+public slots:
+    void slotApplySelectiveSync();
+    void resetFolders();
+
+private slots:
+    void slotUpdateDirectories(const QStringList &);
+
+private:
+    QStringList createBlackList(OCC::FolderStatusModel::SubFolderInfo* root,
+                                const QStringList& oldBlackList) const;
+    AccountPtr _account;
+    bool _dirty = false;
+
+signals:
+    void dirtyChanged();
 };
 
 class FolderStatusDelegate : public QStyledItemDelegate
@@ -51,7 +107,9 @@ class FolderStatusDelegate : public QStyledItemDelegate
                     SyncProgressItemString,
                     AddProgressSpace,
                     WarningCount,
-                    SyncRunning
+                    SyncRunning,
+
+                    AddButton
                   };
     void paint( QPainter*, const QStyleOptionViewItem&, const QModelIndex& ) const Q_DECL_OVERRIDE;
     QSize sizeHint( const QStyleOptionViewItem&, const QModelIndex& ) const Q_DECL_OVERRIDE;
diff --git a/src/gui/generalsettings.cpp b/src/gui/generalsettings.cpp
index 2c63770..5ee97fe 100644
--- a/src/gui/generalsettings.cpp
+++ b/src/gui/generalsettings.cpp
@@ -19,9 +19,12 @@
 #include "application.h"
 #include "utility.h"
 #include "configfile.h"
+#include "owncloudsetupwizard.h"
+
 
 #include "updater/updater.h"
 #include "updater/ocupdater.h"
+#include "ignorelisteditor.h"
 
 #include "config.h"
 
@@ -68,6 +71,9 @@ GeneralSettings::GeneralSettings(QWidget *parent) :
     QString themeDir = QString::fromLatin1(":/client/theme/%1/")
             .arg(Theme::instance()->systrayIconFlavor(true));
     _ui->monoIconsCheckBox->setVisible(QDir(themeDir).exists());
+
+    connect(_ui->ignoredFilesButton, SIGNAL(clicked()), SLOT(slotIgnoreFilesEditor()));
+    connect(_ui->addAccountButton, SIGNAL(clicked()), SLOT(slotOpenAccountWizard()));
 }
 
 GeneralSettings::~GeneralSettings()
@@ -119,4 +125,24 @@ void GeneralSettings::slotToggleOptionalDesktopNotifications(bool enable)
     cfgFile.setOptionalDesktopNotifications(enable);
 }
 
+void GeneralSettings::slotIgnoreFilesEditor()
+{
+    if (_ignoreEditor.isNull()) {
+        _ignoreEditor = new IgnoreListEditor(this);
+        _ignoreEditor->setAttribute( Qt::WA_DeleteOnClose, true );
+        _ignoreEditor->open();
+    } else {
+        ownCloudGui::raiseDialog(_ignoreEditor);
+    }
+}
+
+void GeneralSettings::slotOpenAccountWizard()
+{
+    if (QSystemTrayIcon::isSystemTrayAvailable()) {
+        topLevelWidget()->close();
+    }
+    OwncloudSetupWizard::runWizard(qApp, SLOT(slotownCloudWizardDone(int)), 0);
+}
+
+
 } // namespace OCC
diff --git a/src/gui/generalsettings.h b/src/gui/generalsettings.h
index bf3961c..6c0c4aa 100644
--- a/src/gui/generalsettings.h
+++ b/src/gui/generalsettings.h
@@ -15,9 +15,10 @@
 #define MIRALL_GENERALSETTINGS_H
 
 #include <QWidget>
-
+#include <QPointer>
 
 namespace OCC {
+class IgnoreListEditor;
 
 namespace Ui {
 class GeneralSettings;
@@ -36,11 +37,15 @@ private slots:
     void slotToggleLaunchOnStartup(bool);
     void slotToggleOptionalDesktopNotifications(bool);
     void slotUpdateInfo();
+    void slotIgnoreFilesEditor();
+    void slotOpenAccountWizard();
+
 
 private:
     void loadMiscSettings();
 
     Ui::GeneralSettings *_ui;
+    QPointer<IgnoreListEditor> _ignoreEditor;
 };
 
 
diff --git a/src/gui/generalsettings.ui b/src/gui/generalsettings.ui
index ed2a47f..443e8de 100644
--- a/src/gui/generalsettings.ui
+++ b/src/gui/generalsettings.ui
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>468</width>
-    <height>249</height>
+    <width>599</width>
+    <height>429</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -41,13 +41,76 @@
         </property>
        </widget>
       </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QGroupBox" name="groupBox">
+     <property name="title">
+      <string>Advanced</string>
+     </property>
+     <layout class="QGridLayout" name="gridLayout">
       <item row="1" column="1">
+       <layout class="QHBoxLayout" name="horizontalLayout_4">
+        <item>
+         <widget class="QPushButton" name="ignoredFilesButton">
+          <property name="text">
+           <string>Edit Ignored Files</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer name="horizontalSpacer_4">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
+      </item>
+      <item row="2" column="1">
        <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>Show crash reporter</string>
         </property>
        </widget>
       </item>
+      <item row="1" column="2">
+       <layout class="QHBoxLayout" name="horizontalLayout_2">
+        <item>
+         <widget class="QPushButton" name="addAccountButton">
+          <property name="text">
+           <string>Add an Account</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer name="horizontalSpacer_2">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
+      </item>
      </layout>
     </widget>
    </item>
diff --git a/src/gui/selectivesyncdialog.cpp b/src/gui/selectivesyncdialog.cpp
index 7034847..7dc4b2f 100644
--- a/src/gui/selectivesyncdialog.cpp
+++ b/src/gui/selectivesyncdialog.cpp
@@ -410,7 +410,5 @@ qint64 SelectiveSyncDialog::estimatedSize()
 }
 
 
-
-
 }
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-owncloud/owncloud-client.git



More information about the Pkg-owncloud-commits mailing list