[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