mirror of
https://github.com/nextcloud/desktop.git
synced 2024-12-14 17:51:41 +03:00
Settings: New UI that intergate the selective sync within the account settings
This commit is contained in:
parent
dfd9d8725c
commit
426d2338d9
9 changed files with 864 additions and 293 deletions
|
@ -21,13 +21,10 @@
|
||||||
#include "folderstatusmodel.h"
|
#include "folderstatusmodel.h"
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
#include "application.h"
|
#include "application.h"
|
||||||
#include "owncloudsetupwizard.h"
|
|
||||||
#include "configfile.h"
|
#include "configfile.h"
|
||||||
#include "ignorelisteditor.h"
|
|
||||||
#include "account.h"
|
#include "account.h"
|
||||||
#include "accountstate.h"
|
#include "accountstate.h"
|
||||||
#include "quotainfo.h"
|
#include "quotainfo.h"
|
||||||
#include "selectivesyncdialog.h"
|
|
||||||
#include "creds/abstractcredentials.h"
|
#include "creds/abstractcredentials.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
@ -37,9 +34,13 @@
|
||||||
#include <QListWidgetItem>
|
#include <QListWidgetItem>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QTreeView>
|
||||||
#include <QKeySequence>
|
#include <QKeySequence>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
#include <qstringlistmodel.h>
|
||||||
|
#include <qpropertyanimation.h>
|
||||||
|
|
||||||
#include "account.h"
|
#include "account.h"
|
||||||
|
|
||||||
|
@ -64,10 +65,12 @@ AccountSettings::AccountSettings(QWidget *parent) :
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
_model = new FolderStatusModel;
|
_model = new FolderStatusModel;
|
||||||
|
_model->setAccount(_accountState->account());
|
||||||
_model->setParent(this);
|
_model->setParent(this);
|
||||||
FolderStatusDelegate *delegate = new FolderStatusDelegate;
|
FolderStatusDelegate *delegate = new FolderStatusDelegate;
|
||||||
delegate->setParent(this);
|
delegate->setParent(this);
|
||||||
|
|
||||||
|
ui->_folderList->header()->hide();
|
||||||
ui->_folderList->setItemDelegate( delegate );
|
ui->_folderList->setItemDelegate( delegate );
|
||||||
ui->_folderList->setModel( _model );
|
ui->_folderList->setModel( _model );
|
||||||
#if defined(Q_OS_MAC)
|
#if defined(Q_OS_MAC)
|
||||||
|
@ -75,12 +78,13 @@ AccountSettings::AccountSettings(QWidget *parent) :
|
||||||
#else
|
#else
|
||||||
ui->_folderList->setMinimumWidth( 300 );
|
ui->_folderList->setMinimumWidth( 300 );
|
||||||
#endif
|
#endif
|
||||||
ui->_folderList->setEditTriggers( QAbstractItemView::NoEditTriggers );
|
connect(ui->_folderList, SIGNAL(customContextMenuRequested(QPoint)),
|
||||||
|
this, SLOT(slotCustomContextMenuRequested(QPoint)));
|
||||||
|
|
||||||
ui->_buttonRemove->setEnabled(false);
|
connect(ui->_folderList, SIGNAL(expanded(QModelIndex)) , this, SLOT(refreshSelectiveSyncStatus()));
|
||||||
ui->_buttonEnable->setEnabled(false);
|
connect(ui->_folderList, SIGNAL(collapsed(QModelIndex)) , this, SLOT(refreshSelectiveSyncStatus()));
|
||||||
ui->_buttonSelectiveSync->setEnabled(false);
|
connect(_model, SIGNAL(dirtyChanged()), this, SLOT(refreshSelectiveSyncStatus()));
|
||||||
ui->_buttonAdd->setEnabled(true);
|
ui->selectiveSyncStatus->hide();
|
||||||
|
|
||||||
QAction *resetFolderAction = new QAction(this);
|
QAction *resetFolderAction = new QAction(this);
|
||||||
resetFolderAction->setShortcut(QKeySequence(Qt::Key_F5));
|
resetFolderAction->setShortcut(QKeySequence(Qt::Key_F5));
|
||||||
|
@ -92,35 +96,59 @@ AccountSettings::AccountSettings(QWidget *parent) :
|
||||||
connect(syncNowAction, SIGNAL(triggered()), SLOT(slotSyncCurrentFolderNow()));
|
connect(syncNowAction, SIGNAL(triggered()), SLOT(slotSyncCurrentFolderNow()));
|
||||||
addAction(syncNowAction);
|
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(clicked(QModelIndex)), SLOT(slotFolderActivated(QModelIndex)));
|
||||||
connect(ui->_folderList, SIGNAL(doubleClicked(QModelIndex)),SLOT(slotDoubleClicked(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();
|
QColor color = palette().highlight().color();
|
||||||
ui->quotaProgressBar->setStyleSheet(QString::fromLatin1(progressBarStyleC).arg(color.name()));
|
ui->quotaProgressBar->setStyleSheet(QString::fromLatin1(progressBarStyleC).arg(color.name()));
|
||||||
ui->connectLabel->setWordWrap(true);
|
ui->connectLabel->setWordWrap(true);
|
||||||
ui->connectLabel->setOpenExternalLinks(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->connectLabel->setText(tr("No account configured."));
|
||||||
ui->_buttonAdd->setEnabled(false);
|
|
||||||
|
|
||||||
connect(AccountStateManager::instance(), SIGNAL(accountStateAdded(AccountState*)),
|
connect(AccountStateManager::instance(), SIGNAL(accountStateAdded(AccountState*)),
|
||||||
this, SLOT(slotAccountStateChanged(AccountState*)));
|
this, SLOT(slotAccountStateChanged(AccountState*)));
|
||||||
slotAccountStateChanged(AccountStateManager::instance()->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)
|
void AccountSettings::slotAccountStateChanged(AccountState *newAccountState)
|
||||||
{
|
{
|
||||||
if (_accountState) {
|
if (_accountState) {
|
||||||
|
@ -140,40 +168,16 @@ void AccountSettings::slotAccountStateChanged(AccountState *newAccountState)
|
||||||
this, SLOT(slotUpdateQuota(qint64,qint64)));
|
this, SLOT(slotUpdateQuota(qint64,qint64)));
|
||||||
slotUpdateQuota(quotaInfo->lastQuotaTotalBytes(), quotaInfo->lastQuotaUsedBytes());
|
slotUpdateQuota(quotaInfo->lastQuotaTotalBytes(), quotaInfo->lastQuotaUsedBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AccountSettings::slotFolderActivated( const QModelIndex& indx )
|
void AccountSettings::slotFolderActivated( const QModelIndex& indx )
|
||||||
{
|
{
|
||||||
bool isValid = indx.isValid();
|
if (indx.data(FolderStatusDelegate::AddButton).toBool()) {
|
||||||
|
slotAddFolder();
|
||||||
bool haveFolders = ui->_folderList->model()->rowCount() > 0;
|
return;
|
||||||
|
|
||||||
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" ) );
|
|
||||||
}
|
|
||||||
ui->_buttonEnable->setEnabled(isConnected);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AccountSettings::slotAddFolder()
|
void AccountSettings::slotAddFolder()
|
||||||
{
|
{
|
||||||
FolderMan *folderMan = FolderMan::instance();
|
FolderMan *folderMan = FolderMan::instance();
|
||||||
|
@ -204,13 +208,11 @@ void AccountSettings::slotFolderWizardAccepted()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Folder *f = folderMan->setupFolderFromConfigFile( alias );
|
Folder *f = folderMan->setupFolderFromConfigFile( alias );
|
||||||
slotAddFolder( f );
|
|
||||||
folderMan->setSyncEnabled(true);
|
folderMan->setSyncEnabled(true);
|
||||||
if( f ) {
|
if( f ) {
|
||||||
folderMan->slotScheduleAllFolders();
|
folderMan->slotScheduleAllFolders();
|
||||||
emit folderChanged();
|
emit folderChanged();
|
||||||
}
|
}
|
||||||
slotButtonsSetEnabled();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AccountSettings::slotFolderWizardRejected()
|
void AccountSettings::slotFolderWizardRejected()
|
||||||
|
@ -221,32 +223,6 @@ void AccountSettings::slotFolderWizardRejected()
|
||||||
folderMan->slotScheduleAllFolders();
|
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 )
|
void AccountSettings::setGeneralErrors( const QStringList& errors )
|
||||||
{
|
{
|
||||||
_generalErrors = errors;
|
_generalErrors = errors;
|
||||||
|
@ -339,24 +315,12 @@ void AccountSettings::slotRemoveCurrentFolder()
|
||||||
if( ret == QMessageBox::No ) {
|
if( ret == QMessageBox::No ) {
|
||||||
return;
|
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 *folderMan = FolderMan::instance();
|
||||||
folderMan->slotRemoveFolder( alias );
|
folderMan->slotRemoveFolder( alias );
|
||||||
_model->removeRow(row);
|
_model->removeRow(row);
|
||||||
|
|
||||||
// single folder fix to show add-button and hide remove-button
|
// single folder fix to show add-button and hide remove-button
|
||||||
slotButtonsSetEnabled();
|
|
||||||
|
|
||||||
emit folderChanged();
|
emit folderChanged();
|
||||||
}
|
}
|
||||||
|
@ -368,6 +332,8 @@ void AccountSettings::slotResetCurrentFolder()
|
||||||
QModelIndex selected = ui->_folderList->selectionModel()->currentIndex();
|
QModelIndex selected = ui->_folderList->selectionModel()->currentIndex();
|
||||||
if( selected.isValid() ) {
|
if( selected.isValid() ) {
|
||||||
QString alias = _model->data( selected, FolderStatusDelegate::FolderAliasRole ).toString();
|
QString alias = _model->data( selected, FolderStatusDelegate::FolderAliasRole ).toString();
|
||||||
|
if (alias.isEmpty())
|
||||||
|
return;
|
||||||
int ret = QMessageBox::question( 0, tr("Confirm Folder Reset"),
|
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>"
|
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. "
|
"<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 )
|
void AccountSettings::slotDoubleClicked( const QModelIndex& indx )
|
||||||
{
|
{
|
||||||
if( ! indx.isValid() ) return;
|
if( ! indx.isValid() ) return;
|
||||||
QString alias = _model->data( indx, FolderStatusDelegate::FolderAliasRole ).toString();
|
QString alias = _model->data( indx, FolderStatusDelegate::FolderAliasRole ).toString();
|
||||||
|
if (alias.isEmpty()) return;
|
||||||
|
|
||||||
emit openFolderAlias( alias );
|
emit openFolderAlias( alias );
|
||||||
}
|
}
|
||||||
|
@ -421,28 +375,7 @@ void AccountSettings::showConnectionLabel( const QString& message, const QString
|
||||||
ui->connectLabel->setToolTip(QString());
|
ui->connectLabel->setToolTip(QString());
|
||||||
ui->connectLabel->setStyleSheet(errStyle);
|
ui->connectLabel->setStyleSheet(errStyle);
|
||||||
}
|
}
|
||||||
}
|
ui->accountStatus->setVisible(!message.isEmpty());
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AccountSettings::slotEnableCurrentFolder()
|
void AccountSettings::slotEnableCurrentFolder()
|
||||||
|
@ -503,8 +436,6 @@ void AccountSettings::slotEnableCurrentFolder()
|
||||||
if( currentlyPaused ) _wasDisabledBefore = true;
|
if( currentlyPaused ) _wasDisabledBefore = true;
|
||||||
|
|
||||||
slotUpdateFolderState (f);
|
slotUpdateFolderState (f);
|
||||||
// set the button text accordingly.
|
|
||||||
slotFolderActivated( selected );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -525,7 +456,7 @@ void AccountSettings::slotUpdateFolderState( Folder *folder )
|
||||||
int row = 0;
|
int row = 0;
|
||||||
|
|
||||||
if( ! folder ) return;
|
if( ! folder ) return;
|
||||||
|
#if 0
|
||||||
item = _model->item( row );
|
item = _model->item( row );
|
||||||
|
|
||||||
while( item ) {
|
while( item ) {
|
||||||
|
@ -541,6 +472,7 @@ void AccountSettings::slotUpdateFolderState( Folder *folder )
|
||||||
} else {
|
} else {
|
||||||
// the dialog is not visible.
|
// the dialog is not visible.
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void AccountSettings::slotOpenOC()
|
void AccountSettings::slotOpenOC()
|
||||||
|
@ -551,24 +483,7 @@ void AccountSettings::slotOpenOC()
|
||||||
|
|
||||||
QStandardItem* AccountSettings::itemForFolder(const QString& folder)
|
QStandardItem* AccountSettings::itemForFolder(const QString& folder)
|
||||||
{
|
{
|
||||||
QStandardItem *item = NULL;
|
return nullptr;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AccountSettings::shortenFilename( const QString& folder, const QString& file ) const
|
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 )
|
void AccountSettings::slotSetProgress(const QString& folder, const Progress::Info &progress )
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
if (!isVisible()) {
|
if (!isVisible()) {
|
||||||
return; // for https://github.com/owncloud/client/issues/2648#issuecomment-71377909
|
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);
|
overallPercent = qBound(0, overallPercent, 100);
|
||||||
item->setData( overallPercent, FolderStatusDelegate::SyncProgressOverallPercent);
|
item->setData( overallPercent, FolderStatusDelegate::SyncProgressOverallPercent);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void AccountSettings::slotHideProgress()
|
void AccountSettings::slotHideProgress()
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
QTimer *send_timer = qobject_cast<QTimer*>(this->sender());
|
QTimer *send_timer = qobject_cast<QTimer*>(this->sender());
|
||||||
QHash<QStandardItem*, QTimer*>::const_iterator i = _hideProgressTimers.constBegin();
|
QHash<QStandardItem*, QTimer*>::const_iterator i = _hideProgressTimers.constBegin();
|
||||||
while (i != _hideProgressTimers.constEnd()) {
|
while (i != _hideProgressTimers.constEnd()) {
|
||||||
|
@ -717,11 +635,12 @@ void AccountSettings::slotHideProgress()
|
||||||
}
|
}
|
||||||
|
|
||||||
send_timer->deleteLater();
|
send_timer->deleteLater();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void AccountSettings::slotFolderSyncStateChange()
|
void AccountSettings::slotFolderSyncStateChange()
|
||||||
{
|
{
|
||||||
slotButtonsSetEnabled();
|
#if 0
|
||||||
Folder* folder = qobject_cast<Folder *>(sender());
|
Folder* folder = qobject_cast<Folder *>(sender());
|
||||||
if (!folder) return;
|
if (!folder) return;
|
||||||
|
|
||||||
|
@ -745,12 +664,14 @@ void AccountSettings::slotFolderSyncStateChange()
|
||||||
}
|
}
|
||||||
timer->start(5000);
|
timer->start(5000);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void AccountSettings::slotUpdateQuota(qint64 total, qint64 used)
|
void AccountSettings::slotUpdateQuota(qint64 total, qint64 used)
|
||||||
{
|
{
|
||||||
if( total > 0 ) {
|
if( total > 0 ) {
|
||||||
|
ui->storageGroupBox->setVisible(true);
|
||||||
ui->quotaProgressBar->setVisible(true);
|
ui->quotaProgressBar->setVisible(true);
|
||||||
ui->quotaInfoLabel->setVisible(true);
|
ui->quotaInfoLabel->setVisible(true);
|
||||||
ui->quotaProgressBar->setEnabled(true);
|
ui->quotaProgressBar->setEnabled(true);
|
||||||
|
@ -763,22 +684,12 @@ void AccountSettings::slotUpdateQuota(qint64 total, qint64 used)
|
||||||
QString totalStr = Utility::octetsToString(total);
|
QString totalStr = Utility::octetsToString(total);
|
||||||
double percent = used/(double)total*100;
|
double percent = used/(double)total*100;
|
||||||
QString percentStr = Utility::compactFormatDouble(percent, 1);
|
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 {
|
} else {
|
||||||
ui->quotaProgressBar->setVisible(false);
|
ui->storageGroupBox->setVisible(false);
|
||||||
ui->quotaInfoLabel->setVisible(false);
|
ui->quotaInfoLabel->setVisible(false);
|
||||||
ui->quotaLabel->setText(tr("Currently there is no storage usage information available."));
|
ui->quotaProgressBar->setMaximum(0);
|
||||||
}
|
_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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -789,7 +700,6 @@ void AccountSettings::slotAccountStateChanged(int state)
|
||||||
AccountPtr account = _accountState->account();
|
AccountPtr account = _accountState->account();
|
||||||
QUrl safeUrl(account->url());
|
QUrl safeUrl(account->url());
|
||||||
safeUrl.setPassword(QString()); // Remove the password from the URL to avoid showing it in the UI
|
safeUrl.setPassword(QString()); // Remove the password from the URL to avoid showing it in the UI
|
||||||
slotButtonsSetEnabled();
|
|
||||||
FolderMan *folderMan = FolderMan::instance();
|
FolderMan *folderMan = FolderMan::instance();
|
||||||
foreach (Folder *folder, folderMan->map().values()) {
|
foreach (Folder *folder, folderMan->map().values()) {
|
||||||
slotUpdateFolderState(folder);
|
slotUpdateFolderState(folder);
|
||||||
|
@ -815,7 +725,6 @@ void AccountSettings::slotAccountStateChanged(int state)
|
||||||
} else {
|
} else {
|
||||||
// ownCloud is not yet configured.
|
// ownCloud is not yet configured.
|
||||||
showConnectionLabel( tr("No %1 connection configured.").arg(Theme::instance()->appNameGUI()) );
|
showConnectionLabel( tr("No %1 connection configured.").arg(Theme::instance()->appNameGUI()) );
|
||||||
ui->_buttonAdd->setEnabled( false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -824,4 +733,29 @@ AccountSettings::~AccountSettings()
|
||||||
delete ui;
|
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
|
} // namespace OCC
|
||||||
|
|
|
@ -29,6 +29,7 @@ class QModelIndex;
|
||||||
class QStandardItem;
|
class QStandardItem;
|
||||||
class QNetworkReply;
|
class QNetworkReply;
|
||||||
class QListWidgetItem;
|
class QListWidgetItem;
|
||||||
|
class QLabel;
|
||||||
|
|
||||||
namespace OCC {
|
namespace OCC {
|
||||||
|
|
||||||
|
@ -37,9 +38,10 @@ class AccountSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
class FolderMan;
|
class FolderMan;
|
||||||
class IgnoreListEditor;
|
|
||||||
class Account;
|
class Account;
|
||||||
class AccountState;
|
class AccountState;
|
||||||
|
class FolderStatusModel;
|
||||||
|
|
||||||
class AccountSettings : public QWidget
|
class AccountSettings : public QWidget
|
||||||
{
|
{
|
||||||
|
@ -62,27 +64,22 @@ public slots:
|
||||||
void slotUpdateFolderState( Folder* );
|
void slotUpdateFolderState( Folder* );
|
||||||
void slotDoubleClicked( const QModelIndex& );
|
void slotDoubleClicked( const QModelIndex& );
|
||||||
void slotSetProgress(const QString& folder, const Progress::Info& progress);
|
void slotSetProgress(const QString& folder, const Progress::Info& progress);
|
||||||
void slotButtonsSetEnabled();
|
|
||||||
|
|
||||||
void slotUpdateQuota( qint64,qint64 );
|
void slotUpdateQuota( qint64,qint64 );
|
||||||
void slotIgnoreFilesEditor();
|
|
||||||
void slotAccountStateChanged(int state);
|
void slotAccountStateChanged(int state);
|
||||||
|
|
||||||
void setGeneralErrors( const QStringList& errors );
|
void setGeneralErrors( const QStringList& errors );
|
||||||
void setFolderList( const Folder::Map& );
|
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void slotAddFolder();
|
void slotAddFolder();
|
||||||
void slotAddFolder( Folder* );
|
|
||||||
void slotEnableCurrentFolder();
|
void slotEnableCurrentFolder();
|
||||||
void slotSyncCurrentFolderNow();
|
void slotSyncCurrentFolderNow();
|
||||||
void slotRemoveCurrentFolder();
|
void slotRemoveCurrentFolder();
|
||||||
void slotResetCurrentFolder();
|
void slotResetCurrentFolder();
|
||||||
void slotFolderWizardAccepted();
|
void slotFolderWizardAccepted();
|
||||||
void slotFolderWizardRejected();
|
void slotFolderWizardRejected();
|
||||||
void slotOpenAccountWizard();
|
|
||||||
void slotHideProgress();
|
void slotHideProgress();
|
||||||
void slotSelectiveSync();
|
void refreshSelectiveSyncStatus();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString shortenFilename( const QString& folder, const QString& file ) const;
|
QString shortenFilename( const QString& folder, const QString& file ) const;
|
||||||
|
@ -91,16 +88,18 @@ private:
|
||||||
void showConnectionLabel( const QString& message, const QString& tooltip = QString() );
|
void showConnectionLabel( const QString& message, const QString& tooltip = QString() );
|
||||||
|
|
||||||
Ui::AccountSettings *ui;
|
Ui::AccountSettings *ui;
|
||||||
QPointer<IgnoreListEditor> _ignoreEditor;
|
|
||||||
QStandardItemModel *_model;
|
FolderStatusModel *_model;
|
||||||
QUrl _OCUrl;
|
QUrl _OCUrl;
|
||||||
QHash<QStandardItem*, QTimer*> _hideProgressTimers;
|
QHash<QStandardItem*, QTimer*> _hideProgressTimers;
|
||||||
QStringList _generalErrors;
|
QStringList _generalErrors;
|
||||||
bool _wasDisabledBefore;
|
bool _wasDisabledBefore;
|
||||||
AccountState *_accountState;
|
AccountState *_accountState;
|
||||||
|
QLabel *_quotaLabel;
|
||||||
private slots:
|
private slots:
|
||||||
void slotFolderSyncStateChange();
|
void slotFolderSyncStateChange();
|
||||||
void slotAccountStateChanged(AccountState*);
|
void slotAccountStateChanged(AccountState*);
|
||||||
|
void slotCustomContextMenuRequested(const QPoint&);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace OCC
|
} // namespace OCC
|
||||||
|
|
|
@ -6,21 +6,16 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>615</width>
|
<width>469</width>
|
||||||
<height>422</height>
|
<height>652</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Form</string>
|
<string>Form</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item row="0" column="0" colspan="2">
|
<item>
|
||||||
<widget class="QGroupBox" name="syncStatusGroupBox">
|
<widget class="QWidget" name="accountStatus" native="true">
|
||||||
<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">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="SslButton" name="sslButton">
|
<widget class="SslButton" name="sslButton">
|
||||||
|
@ -37,70 +32,45 @@
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="connectLabel">
|
<widget class="QLabel" name="connectLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Connected with <server> as <user></string>
|
<string>Connected with <server> as <user></string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QListView" name="_folderList"/>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="_buttonAdd">
|
<widget class="QPushButton" name="pushButton">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Add Folder...</string>
|
<string>Delete</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</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>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item>
|
||||||
<widget class="QGroupBox" name="storageGroupBox">
|
<widget class="QGroupBox" name="storageGroupBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Storage Usage</string>
|
<string>Storage Usage</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QProgressBar" name="quotaProgressBar">
|
<widget class="QProgressBar" name="quotaProgressBar">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
|
@ -117,17 +87,16 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="quotaLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>Retrieving usage information...</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="quotaInfoLabel">
|
<widget class="QLabel" name="quotaInfoLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<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>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
@ -137,26 +106,76 @@
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QGroupBox" name="maintenanceGroupBox">
|
|
||||||
<property name="title">
|
|
||||||
<string>Account Maintenance</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="ignoredFilesButton">
|
<widget class="QTreeView" name="_folderList">
|
||||||
<property name="enabled">
|
<property name="sizePolicy">
|
||||||
<bool>true</bool>
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>5</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="contextMenuPolicy">
|
||||||
<string>Edit Ignored Files</string>
|
<enum>Qt::CustomContextMenu</enum>
|
||||||
|
</property>
|
||||||
|
<property name="editTriggers">
|
||||||
|
<set>QAbstractItemView::NoEditTriggers</set>
|
||||||
|
</property>
|
||||||
|
<property name="animated">
|
||||||
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="modifyAccountButton">
|
<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">
|
<property name="text">
|
||||||
<string>Modify Account</string>
|
<string>Cancel</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<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>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>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
@ -13,7 +13,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "folderstatusmodel.h"
|
#include "folderstatusmodel.h"
|
||||||
|
#include "folderman.h"
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
|
#include <theme.h>
|
||||||
|
#include <account.h>
|
||||||
|
|
||||||
#include <QtCore>
|
#include <QtCore>
|
||||||
#include <QtGui>
|
#include <QtGui>
|
||||||
|
@ -21,17 +24,42 @@
|
||||||
#include <QtWidgets>
|
#include <QtWidgets>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(QPersistentModelIndex)
|
||||||
|
|
||||||
namespace OCC {
|
namespace OCC {
|
||||||
|
|
||||||
FolderStatusModel::FolderStatusModel()
|
static const char propertyParentIndexC[] = "oc_parentIndex";
|
||||||
:QStandardItemModel()
|
|
||||||
{
|
|
||||||
|
|
||||||
|
FolderStatusModel::FolderStatusModel(QObject *parent)
|
||||||
|
:QAbstractItemModel(parent)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Qt::ItemFlags FolderStatusModel::flags ( const QModelIndex& ) const
|
FolderStatusModel::~FolderStatusModel()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
void FolderStatusModel::setAccount(const AccountPtr& account)
|
||||||
{
|
{
|
||||||
|
beginResetModel();
|
||||||
|
_dirty = false;
|
||||||
|
_folders.clear();
|
||||||
|
_account = account;
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Qt::ItemFlags FolderStatusModel::flags ( const QModelIndex &index ) const
|
||||||
|
{
|
||||||
|
switch (classify(index)) {
|
||||||
|
case AddButton:
|
||||||
|
return Qt::ItemIsEnabled;
|
||||||
|
case RootFolder:
|
||||||
return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
|
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
|
QVariant FolderStatusModel::data(const QModelIndex &index, int role) const
|
||||||
|
@ -41,9 +69,432 @@ QVariant FolderStatusModel::data(const QModelIndex &index, int role) const
|
||||||
|
|
||||||
if (role == Qt::EditRole)
|
if (role == Qt::EditRole)
|
||||||
return QVariant();
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ====================================================================================
|
// ====================================================================================
|
||||||
|
|
||||||
|
@ -62,6 +513,12 @@ FolderStatusDelegate::~FolderStatusDelegate()
|
||||||
QSize FolderStatusDelegate::sizeHint(const QStyleOptionViewItem & option ,
|
QSize FolderStatusDelegate::sizeHint(const QStyleOptionViewItem & option ,
|
||||||
const QModelIndex & index) const
|
const QModelIndex & index) const
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (static_cast<const FolderStatusModel *>(index.model())->classify(index) != FolderStatusModel::RootFolder) {
|
||||||
|
return QStyledItemDelegate::sizeHint(option, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Q_UNUSED(option)
|
Q_UNUSED(option)
|
||||||
QFont aliasFont = option.font;
|
QFont aliasFont = option.font;
|
||||||
QFont font = option.font;
|
QFont font = option.font;
|
||||||
|
@ -101,8 +558,17 @@ QSize FolderStatusDelegate::sizeHint(const QStyleOptionViewItem & option ,
|
||||||
void FolderStatusDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
|
void FolderStatusDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
|
||||||
const QModelIndex &index) const
|
const QModelIndex &index) const
|
||||||
{
|
{
|
||||||
|
if (qvariant_cast<bool>(index.data(AddButton))) {
|
||||||
|
painter->drawText(option.rect, "[+ Add Folder]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
QStyledItemDelegate::paint(painter,option,index);
|
QStyledItemDelegate::paint(painter,option,index);
|
||||||
|
|
||||||
|
if (static_cast<const FolderStatusModel *>(index.model())->classify(index) != FolderStatusModel::RootFolder) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
painter->save();
|
painter->save();
|
||||||
|
|
||||||
QFont aliasFont = option.font;
|
QFont aliasFont = option.font;
|
||||||
|
@ -141,7 +607,7 @@ void FolderStatusDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
|
||||||
QRect iconRect = option.rect;
|
QRect iconRect = option.rect;
|
||||||
QRect aliasRect = 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);
|
iconRect.setTop( iconRect.top() + aliasMargin ); // (iconRect.height()-iconsize.height())/2);
|
||||||
|
|
||||||
// alias box
|
// alias box
|
||||||
|
@ -313,11 +779,14 @@ void FolderStatusDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
|
||||||
|
|
||||||
painter->restore();
|
painter->restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,16 +17,72 @@
|
||||||
|
|
||||||
#include <QStyledItemDelegate>
|
#include <QStyledItemDelegate>
|
||||||
#include <QStandardItemModel>
|
#include <QStandardItemModel>
|
||||||
|
#include <accountfwd.h>
|
||||||
|
|
||||||
|
#ifndef Q_DECL_OVERRIDE
|
||||||
|
#define Q_DECL_OVERRIDE
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace OCC {
|
namespace OCC {
|
||||||
|
|
||||||
class FolderStatusModel : public QStandardItemModel
|
class Folder;
|
||||||
{
|
|
||||||
public:
|
|
||||||
FolderStatusModel();
|
|
||||||
virtual Qt::ItemFlags flags( const QModelIndex& ) const Q_DECL_OVERRIDE;
|
|
||||||
QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE;
|
|
||||||
|
|
||||||
|
class FolderStatusModel : public QAbstractItemModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
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
|
class FolderStatusDelegate : public QStyledItemDelegate
|
||||||
|
@ -51,7 +107,9 @@ class FolderStatusDelegate : public QStyledItemDelegate
|
||||||
SyncProgressItemString,
|
SyncProgressItemString,
|
||||||
AddProgressSpace,
|
AddProgressSpace,
|
||||||
WarningCount,
|
WarningCount,
|
||||||
SyncRunning
|
SyncRunning,
|
||||||
|
|
||||||
|
AddButton
|
||||||
};
|
};
|
||||||
void paint( QPainter*, const QStyleOptionViewItem&, const QModelIndex& ) const Q_DECL_OVERRIDE;
|
void paint( QPainter*, const QStyleOptionViewItem&, const QModelIndex& ) const Q_DECL_OVERRIDE;
|
||||||
QSize sizeHint( const QStyleOptionViewItem&, const QModelIndex& ) const Q_DECL_OVERRIDE;
|
QSize sizeHint( const QStyleOptionViewItem&, const QModelIndex& ) const Q_DECL_OVERRIDE;
|
||||||
|
|
|
@ -19,9 +19,12 @@
|
||||||
#include "application.h"
|
#include "application.h"
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
#include "configfile.h"
|
#include "configfile.h"
|
||||||
|
#include "owncloudsetupwizard.h"
|
||||||
|
|
||||||
|
|
||||||
#include "updater/updater.h"
|
#include "updater/updater.h"
|
||||||
#include "updater/ocupdater.h"
|
#include "updater/ocupdater.h"
|
||||||
|
#include "ignorelisteditor.h"
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
@ -68,6 +71,9 @@ GeneralSettings::GeneralSettings(QWidget *parent) :
|
||||||
QString themeDir = QString::fromLatin1(":/client/theme/%1/")
|
QString themeDir = QString::fromLatin1(":/client/theme/%1/")
|
||||||
.arg(Theme::instance()->systrayIconFlavor(true));
|
.arg(Theme::instance()->systrayIconFlavor(true));
|
||||||
_ui->monoIconsCheckBox->setVisible(QDir(themeDir).exists());
|
_ui->monoIconsCheckBox->setVisible(QDir(themeDir).exists());
|
||||||
|
|
||||||
|
connect(_ui->ignoredFilesButton, SIGNAL(clicked()), SLOT(slotIgnoreFilesEditor()));
|
||||||
|
connect(_ui->addAccountButton, SIGNAL(clicked()), SLOT(slotOpenAccountWizard()));
|
||||||
}
|
}
|
||||||
|
|
||||||
GeneralSettings::~GeneralSettings()
|
GeneralSettings::~GeneralSettings()
|
||||||
|
@ -119,4 +125,24 @@ void GeneralSettings::slotToggleOptionalDesktopNotifications(bool enable)
|
||||||
cfgFile.setOptionalDesktopNotifications(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
|
} // namespace OCC
|
||||||
|
|
|
@ -15,9 +15,10 @@
|
||||||
#define MIRALL_GENERALSETTINGS_H
|
#define MIRALL_GENERALSETTINGS_H
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
#include <QPointer>
|
||||||
|
|
||||||
namespace OCC {
|
namespace OCC {
|
||||||
|
class IgnoreListEditor;
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class GeneralSettings;
|
class GeneralSettings;
|
||||||
|
@ -36,11 +37,15 @@ private slots:
|
||||||
void slotToggleLaunchOnStartup(bool);
|
void slotToggleLaunchOnStartup(bool);
|
||||||
void slotToggleOptionalDesktopNotifications(bool);
|
void slotToggleOptionalDesktopNotifications(bool);
|
||||||
void slotUpdateInfo();
|
void slotUpdateInfo();
|
||||||
|
void slotIgnoreFilesEditor();
|
||||||
|
void slotOpenAccountWizard();
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void loadMiscSettings();
|
void loadMiscSettings();
|
||||||
|
|
||||||
Ui::GeneralSettings *_ui;
|
Ui::GeneralSettings *_ui;
|
||||||
|
QPointer<IgnoreListEditor> _ignoreEditor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>468</width>
|
<width>599</width>
|
||||||
<height>249</height>
|
<height>429</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
@ -41,13 +41,76 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</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">
|
<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">
|
<widget class="QCheckBox" name="crashreporterCheckBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Show crash reporter</string>
|
<string>Show crash reporter</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</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>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
@ -410,7 +410,5 @@ qint64 SelectiveSyncDialog::estimatedSize()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue