From d4816442efa0dacb6a5cec00a9bac6f685a239c3 Mon Sep 17 00:00:00 2001 From: Samir Benmendil Date: Wed, 14 Aug 2019 22:09:19 +0100 Subject: [PATCH] Extract IgnoreListTableWidget to be reused Signed-off-by: Samir Benmendil --- src/gui/CMakeLists.txt | 2 + src/gui/generalsettings.cpp | 2 +- src/gui/ignorelisteditor.cpp | 182 ++++-------------------------- src/gui/ignorelisteditor.h | 10 +- src/gui/ignorelisteditor.ui | 100 ++-------------- src/gui/ignorelisttablewidget.cpp | 167 +++++++++++++++++++++++++++ src/gui/ignorelisttablewidget.h | 38 +++++++ src/gui/ignorelisttablewidget.ui | 112 ++++++++++++++++++ 8 files changed, 351 insertions(+), 262 deletions(-) create mode 100644 src/gui/ignorelisttablewidget.cpp create mode 100644 src/gui/ignorelisttablewidget.h create mode 100644 src/gui/ignorelisttablewidget.ui diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 167d1727fb..ff78ca1bd9 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -22,6 +22,7 @@ set(client_UI_SRCS generalsettings.ui legalnotice.ui ignorelisteditor.ui + ignorelisttablewidget.ui networksettings.ui activitywidget.ui synclogdialog.ui @@ -59,6 +60,7 @@ set(client_SRCS generalsettings.cpp legalnotice.cpp ignorelisteditor.cpp + ignorelisttablewidget.cpp lockwatcher.cpp logbrowser.cpp navigationpanehelper.cpp diff --git a/src/gui/generalsettings.cpp b/src/gui/generalsettings.cpp index 07cf2dc610..dd42358349 100644 --- a/src/gui/generalsettings.cpp +++ b/src/gui/generalsettings.cpp @@ -185,7 +185,7 @@ void GeneralSettings::slotIgnoreFilesEditor() { if (_ignoreEditor.isNull()) { ConfigFile cfgFile; - _ignoreEditor = new IgnoreListEditor(cfgFile.excludeFile(ConfigFile::UserScope), this); + _ignoreEditor = new IgnoreListEditor(this); _ignoreEditor->setAttribute(Qt::WA_DeleteOnClose, true); _ignoreEditor->open(); } else { diff --git a/src/gui/ignorelisteditor.cpp b/src/gui/ignorelisteditor.cpp index df8726a701..22182b5a0e 100644 --- a/src/gui/ignorelisteditor.cpp +++ b/src/gui/ignorelisteditor.cpp @@ -28,45 +28,28 @@ namespace OCC { -static int patternCol = 0; -static int deletableCol = 1; -static int readOnlyRows = 3; - -IgnoreListEditor::IgnoreListEditor(QString ignoreFile, QWidget *parent) +IgnoreListEditor::IgnoreListEditor(QWidget *parent) : QDialog(parent) , ui(new Ui::IgnoreListEditor) - , m_ignoreFile(std::move(ignoreFile)) { setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); ui->setupUi(this); ConfigFile cfgFile; - ui->descriptionLabel->setText(tr("Files or folders matching a pattern will not be synchronized.\n\n" - "Items where deletion is allowed will be deleted if they prevent a " - "directory from being removed. " - "This is useful for meta data.")); //FIXME This is not true. The entries are hardcoded below in setupTableReadOnlyItems readOnlyTooltip = tr("This entry is provided by the system at '%1' " "and cannot be modified in this view.") .arg(QDir::toNativeSeparators(cfgFile.excludeFile(ConfigFile::SystemScope))); - //TODO this is a bit hacky but is an easy way to figure out if this is created from the - //GeneralSettings or not. Until it gets refactored into a separate widged. - if (qobject_cast(parent)) - setupTableReadOnlyItems(); - readIgnoreFile(m_ignoreFile, false); + setupTableReadOnlyItems(); + const auto userConfig = cfgFile.excludeFile(ConfigFile::Scope::UserScope); + ui->ignoreTableWidget->readIgnoreFile(userConfig); - connect(this, &QDialog::accepted, this, &IgnoreListEditor::slotUpdateLocalIgnoreList); - ui->removePushButton->setEnabled(false); - connect(ui->tableWidget, &QTableWidget::itemSelectionChanged, this, &IgnoreListEditor::slotItemSelectionChanged); - connect(ui->removePushButton, &QAbstractButton::clicked, this, &IgnoreListEditor::slotRemoveCurrentItem); - connect(ui->addPushButton, &QAbstractButton::clicked, this, &IgnoreListEditor::slotAddPattern); - connect(ui->removeAllPushButton, &QAbstractButton::clicked, this, &IgnoreListEditor::slotRemoveAllItems); - connect(ui->buttonBox, &QDialogButtonBox::clicked, this, &IgnoreListEditor::slotRestoreDefaults); - - ui->tableWidget->resizeColumnsToContents(); - ui->tableWidget->horizontalHeader()->setSectionResizeMode(patternCol, QHeaderView::Stretch); - ui->tableWidget->verticalHeader()->setVisible(false); + connect(this, &QDialog::accepted, [=]() { + ui->ignoreTableWidget->slotWriteIgnoreFile(userConfig); + }); + connect(ui->buttonBox, &QDialogButtonBox::clicked, + this, &IgnoreListEditor::slotRestoreDefaults); ui->syncHiddenFilesCheckBox->setChecked(!FolderMan::instance()->ignoreHiddenFiles()); } @@ -76,12 +59,11 @@ IgnoreListEditor::~IgnoreListEditor() delete ui; } -void IgnoreListEditor::setupTableReadOnlyItems(){ - ui->tableWidget->setRowCount(0); - addPattern(".csync_journal.db*", /*deletable=*/false, /*readonly=*/true); - addPattern("._sync_*.db*", /*deletable=*/false, /*readonly=*/true); - addPattern(".sync_*.db*", /*deletable=*/false, /*readonly=*/true); - ui->removeAllPushButton->setEnabled(false); +void IgnoreListEditor::setupTableReadOnlyItems() +{ + ui->ignoreTableWidget->addPattern(".csync_journal.db*", /*deletable=*/false, /*readonly=*/true); + ui->ignoreTableWidget->addPattern("._sync_*.db*", /*deletable=*/false, /*readonly=*/true); + ui->ignoreTableWidget->addPattern(".sync_*.db*", /*deletable=*/false, /*readonly=*/true); } bool IgnoreListEditor::ignoreHiddenFiles() @@ -89,140 +71,16 @@ bool IgnoreListEditor::ignoreHiddenFiles() return !ui->syncHiddenFilesCheckBox->isChecked(); } -void IgnoreListEditor::slotItemSelectionChanged() +void IgnoreListEditor::slotRestoreDefaults(QAbstractButton *button) { - QTableWidgetItem *item = ui->tableWidget->currentItem(); - if (!item) { - ui->removePushButton->setEnabled(false); - return; - } - - bool enable = item->flags() & Qt::ItemIsEnabled; - ui->removePushButton->setEnabled(enable); -} - -void IgnoreListEditor::slotRemoveCurrentItem() -{ - ui->tableWidget->removeRow(ui->tableWidget->currentRow()); - if(ui->tableWidget->rowCount() == readOnlyRows) - ui->removeAllPushButton->setEnabled(false); -} - -void IgnoreListEditor::slotRemoveAllItems() -{ - ui->tableWidget->setRowCount(0); - if (qobject_cast(parent())) - setupTableReadOnlyItems(); -} - -void IgnoreListEditor::slotUpdateLocalIgnoreList() -{ - QFile ignores(m_ignoreFile); - if (ignores.open(QIODevice::WriteOnly)) { - // rewrites the whole file since now the user can also remove system patterns - QFile::resize(m_ignoreFile, 0); - for (int row = 0; row < ui->tableWidget->rowCount(); ++row) { - QTableWidgetItem *patternItem = ui->tableWidget->item(row, patternCol); - QTableWidgetItem *deletableItem = ui->tableWidget->item(row, deletableCol); - if (patternItem->flags() & Qt::ItemIsEnabled) { - QByteArray prepend; - if (deletableItem->checkState() == Qt::Checked) { - prepend = "]"; - } else if (patternItem->text().startsWith('#')) { - prepend = "\\"; - } - ignores.write(prepend + patternItem->text().toUtf8() + '\n'); - } - } - } else { - QMessageBox::warning(this, tr("Could not open file"), - tr("Cannot write changes to '%1'.").arg(m_ignoreFile)); - } - ignores.close(); //close the file before reloading stuff. - - FolderMan *folderMan = FolderMan::instance(); - - /* handle the hidden file checkbox */ - - /* the ignoreHiddenFiles flag is a folder specific setting, but for now, it is - * handled globally. Save it to every folder that is defined. - */ - folderMan->setIgnoreHiddenFiles(ignoreHiddenFiles()); - - // We need to force a remote discovery after a change of the ignore list. - // Otherwise we would not download the files/directories that are no longer - // ignored (because the remote etag did not change) (issue #3172) - foreach (Folder *folder, folderMan->map()) { - folder->journalDb()->forceRemoteDiscoveryNextSync(); - folderMan->scheduleFolder(folder); - } -} - -void IgnoreListEditor::slotAddPattern() -{ - bool okClicked; - QString pattern = QInputDialog::getText(this, tr("Add Ignore Pattern"), - tr("Add a new ignore pattern:"), - QLineEdit::Normal, QString(), &okClicked); - - if (!okClicked || pattern.isEmpty()) + if(ui->buttonBox->buttonRole(button) != QDialogButtonBox::ResetRole) return; - addPattern(pattern, false, false); - ui->tableWidget->scrollToBottom(); -} + ui->ignoreTableWidget->slotRemoveAllItems(); -void IgnoreListEditor::slotRestoreDefaults(QAbstractButton *button){ - if(ui->buttonBox->buttonRole(button) == QDialogButtonBox::ResetRole){ - ConfigFile cfgFile; - if (qobject_cast(parent())) - setupTableReadOnlyItems(); - readIgnoreFile(cfgFile.excludeFile(ConfigFile::SystemScope), false); - } -} - -void IgnoreListEditor::readIgnoreFile(const QString &file, bool readOnly) -{ - QFile ignores(file); - if (ignores.open(QIODevice::ReadOnly)) { - while (!ignores.atEnd()) { - QString line = QString::fromUtf8(ignores.readLine()); - line.chop(1); - if (!line.isEmpty() && !line.startsWith("#")) { - bool deletable = false; - if (line.startsWith(']')) { - deletable = true; - line = line.mid(1); - } - addPattern(line, deletable, readOnly); - } - } - } -} - -int IgnoreListEditor::addPattern(const QString &pattern, bool deletable, bool readOnly) -{ - int newRow = ui->tableWidget->rowCount(); - ui->tableWidget->setRowCount(newRow + 1); - - QTableWidgetItem *patternItem = new QTableWidgetItem; - patternItem->setText(pattern); - ui->tableWidget->setItem(newRow, patternCol, patternItem); - - QTableWidgetItem *deletableItem = new QTableWidgetItem; - deletableItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); - deletableItem->setCheckState(deletable ? Qt::Checked : Qt::Unchecked); - ui->tableWidget->setItem(newRow, deletableCol, deletableItem); - - if (readOnly) { - patternItem->setFlags(patternItem->flags() ^ Qt::ItemIsEnabled); - patternItem->setToolTip(readOnlyTooltip); - deletableItem->setFlags(deletableItem->flags() ^ Qt::ItemIsEnabled); - } - - ui->removeAllPushButton->setEnabled(true); - - return newRow; + ConfigFile cfgFile; + setupTableReadOnlyItems(); + ui->ignoreTableWidget->readIgnoreFile(cfgFile.excludeFile(ConfigFile::SystemScope), false); } } // namespace OCC diff --git a/src/gui/ignorelisteditor.h b/src/gui/ignorelisteditor.h index f18709e6d2..39c38d74d4 100644 --- a/src/gui/ignorelisteditor.h +++ b/src/gui/ignorelisteditor.h @@ -35,26 +35,18 @@ class IgnoreListEditor : public QDialog Q_OBJECT public: - IgnoreListEditor(QString ignoreFile, QWidget *parent = nullptr); + IgnoreListEditor(QWidget *parent = nullptr); ~IgnoreListEditor(); bool ignoreHiddenFiles(); private slots: - void slotItemSelectionChanged(); - void slotRemoveCurrentItem(); - void slotUpdateLocalIgnoreList(); - void slotAddPattern(); void slotRestoreDefaults(QAbstractButton *button); - void slotRemoveAllItems(); private: - void readIgnoreFile(const QString &file, bool readOnly); void setupTableReadOnlyItems(); - int addPattern(const QString &pattern, bool deletable, bool readOnly); QString readOnlyTooltip; Ui::IgnoreListEditor *ui; - QString m_ignoreFile; }; } // namespace OCC diff --git a/src/gui/ignorelisteditor.ui b/src/gui/ignorelisteditor.ui index 8e544a9113..891fbc6e9b 100644 --- a/src/gui/ignorelisteditor.ui +++ b/src/gui/ignorelisteditor.ui @@ -36,96 +36,8 @@ Files Ignored by Patterns - - - - true - - - - 0 - 0 - - - - - - - Qt::PlainText - - - true - - - - - - - true - - - Qt::Vertical - - - - 20 - 213 - - - - - - - - true - - - QAbstractItemView::SingleSelection - - - QAbstractItemView::SelectRows - - - 2 - - - - Pattern - - - - - Allow Deletion - - - - - - - - true - - - Remove - - - - - - - true - - - Add - - - - - - - Remove all - - + + @@ -139,6 +51,14 @@ + + + IgnoreListTableWidget + QWidget +
ignorelisttablewidget.h
+ 1 +
+
diff --git a/src/gui/ignorelisttablewidget.cpp b/src/gui/ignorelisttablewidget.cpp new file mode 100644 index 0000000000..67c8ab4f2f --- /dev/null +++ b/src/gui/ignorelisttablewidget.cpp @@ -0,0 +1,167 @@ +#include "ignorelisttablewidget.h" +#include "ui_ignorelisttablewidget.h" + +#include "folderman.h" + +#include +#include +#include +#include + +namespace OCC { + +static constexpr int patternCol = 0; +static constexpr int deletableCol = 1; +static constexpr int readOnlyRows = 3; + +IgnoreListTableWidget::IgnoreListTableWidget(QWidget *parent) + : QWidget(parent) + , ui(new Ui::IgnoreListTableWidget) +{ + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + ui->setupUi(this); + + ui->descriptionLabel->setText(tr("Files or folders matching a pattern will not be synchronized.\n\n" + "Items where deletion is allowed will be deleted if they prevent a " + "directory from being removed. " + "This is useful for meta data.")); + + ui->removePushButton->setEnabled(false); + connect(ui->tableWidget, &QTableWidget::itemSelectionChanged, + this, &IgnoreListTableWidget::slotItemSelectionChanged); + connect(ui->removePushButton, &QAbstractButton::clicked, + this, &IgnoreListTableWidget::slotRemoveCurrentItem); + connect(ui->addPushButton, &QAbstractButton::clicked, + this, &IgnoreListTableWidget::slotAddPattern); + connect(ui->removeAllPushButton, &QAbstractButton::clicked, + this, &IgnoreListTableWidget::slotRemoveAllItems); + + ui->tableWidget->resizeColumnsToContents(); + ui->tableWidget->horizontalHeader()->setSectionResizeMode(patternCol, QHeaderView::Stretch); + ui->tableWidget->verticalHeader()->setVisible(false); +} + +IgnoreListTableWidget::~IgnoreListTableWidget() +{ + delete ui; +} + +void IgnoreListTableWidget::slotItemSelectionChanged() +{ + QTableWidgetItem *item = ui->tableWidget->currentItem(); + if (!item) { + ui->removePushButton->setEnabled(false); + return; + } + + bool enable = item->flags() & Qt::ItemIsEnabled; + ui->removePushButton->setEnabled(enable); +} + +void IgnoreListTableWidget::slotRemoveCurrentItem() +{ + ui->tableWidget->removeRow(ui->tableWidget->currentRow()); + if(ui->tableWidget->rowCount() == readOnlyRows) + ui->removeAllPushButton->setEnabled(false); +} + +void IgnoreListTableWidget::slotRemoveAllItems() +{ + ui->tableWidget->setRowCount(0); +} + +void IgnoreListTableWidget::slotWriteIgnoreFile(const QString & file) +{ + QFile ignores(file); + if (ignores.open(QIODevice::WriteOnly)) { + // rewrites the whole file since now the user can also remove system patterns + QFile::resize(file, 0); + for (int row = 0; row < ui->tableWidget->rowCount(); ++row) { + QTableWidgetItem *patternItem = ui->tableWidget->item(row, patternCol); + QTableWidgetItem *deletableItem = ui->tableWidget->item(row, deletableCol); + if (patternItem->flags() & Qt::ItemIsEnabled) { + QByteArray prepend; + if (deletableItem->checkState() == Qt::Checked) { + prepend = "]"; + } else if (patternItem->text().startsWith('#')) { + prepend = "\\"; + } + ignores.write(prepend + patternItem->text().toUtf8() + '\n'); + } + } + } else { + QMessageBox::warning(this, tr("Could not open file"), + tr("Cannot write changes to '%1'.").arg(file)); + } + ignores.close(); //close the file before reloading stuff. + + FolderMan *folderMan = FolderMan::instance(); + + // We need to force a remote discovery after a change of the ignore list. + // Otherwise we would not download the files/directories that are no longer + // ignored (because the remote etag did not change) (issue #3172) + foreach (Folder *folder, folderMan->map()) { + folder->journalDb()->forceRemoteDiscoveryNextSync(); + folderMan->scheduleFolder(folder); + } +} + +void IgnoreListTableWidget::slotAddPattern() +{ + bool okClicked; + QString pattern = QInputDialog::getText(this, tr("Add Ignore Pattern"), + tr("Add a new ignore pattern:"), + QLineEdit::Normal, QString(), &okClicked); + + if (!okClicked || pattern.isEmpty()) + return; + + addPattern(pattern, false, false); + ui->tableWidget->scrollToBottom(); +} + +void IgnoreListTableWidget::readIgnoreFile(const QString &file, bool readOnly) +{ + QFile ignores(file); + if (ignores.open(QIODevice::ReadOnly)) { + while (!ignores.atEnd()) { + QString line = QString::fromUtf8(ignores.readLine()); + line.chop(1); + if (!line.isEmpty() && !line.startsWith("#")) { + bool deletable = false; + if (line.startsWith(']')) { + deletable = true; + line = line.mid(1); + } + addPattern(line, deletable, readOnly); + } + } + } +} + +int IgnoreListTableWidget::addPattern(const QString &pattern, bool deletable, bool readOnly) +{ + int newRow = ui->tableWidget->rowCount(); + ui->tableWidget->setRowCount(newRow + 1); + + QTableWidgetItem *patternItem = new QTableWidgetItem; + patternItem->setText(pattern); + ui->tableWidget->setItem(newRow, patternCol, patternItem); + + QTableWidgetItem *deletableItem = new QTableWidgetItem; + deletableItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); + deletableItem->setCheckState(deletable ? Qt::Checked : Qt::Unchecked); + ui->tableWidget->setItem(newRow, deletableCol, deletableItem); + + if (readOnly) { + patternItem->setFlags(patternItem->flags() ^ Qt::ItemIsEnabled); + patternItem->setToolTip(readOnlyTooltip); + deletableItem->setFlags(deletableItem->flags() ^ Qt::ItemIsEnabled); + } + + ui->removeAllPushButton->setEnabled(true); + + return newRow; +} + +} // namespace OCC diff --git a/src/gui/ignorelisttablewidget.h b/src/gui/ignorelisttablewidget.h new file mode 100644 index 0000000000..3bded0462a --- /dev/null +++ b/src/gui/ignorelisttablewidget.h @@ -0,0 +1,38 @@ +#pragma once + +#include + +class QAbstractButton; + +namespace OCC { + +namespace Ui { + class IgnoreListTableWidget; +} + +class IgnoreListTableWidget : public QWidget +{ + Q_OBJECT + +public: + IgnoreListTableWidget(QWidget *parent = nullptr); + ~IgnoreListTableWidget(); + + void readIgnoreFile(const QString &file, bool readOnly = false); + int addPattern(const QString &pattern, bool deletable, bool readOnly); + +public slots: + void slotRemoveAllItems(); + void slotWriteIgnoreFile(const QString & file); + +private slots: + void slotItemSelectionChanged(); + void slotRemoveCurrentItem(); + void slotAddPattern(); + +private: + void setupTableReadOnlyItems(); + QString readOnlyTooltip; + Ui::IgnoreListTableWidget *ui; +}; +} // namespace OCC diff --git a/src/gui/ignorelisttablewidget.ui b/src/gui/ignorelisttablewidget.ui new file mode 100644 index 0000000000..2a618395a9 --- /dev/null +++ b/src/gui/ignorelisttablewidget.ui @@ -0,0 +1,112 @@ + + + OCC::IgnoreListTableWidget + + + + 0 + 0 + 342 + 378 + + + + IgnoreListTableWidget + + + + + + true + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + 2 + + + + Pattern + + + + + Allow Deletion + + + + + + + + true + + + Add + + + + + + + true + + + Remove + + + + + + + Remove all + + + + + + + true + + + Qt::Vertical + + + + 20 + 322 + + + + + + + + true + + + + 0 + 0 + + + + + + + Qt::PlainText + + + true + + + + + + + +