1 #include "ignorelisttablewidget.h"
2 #include "ui_ignorelisttablewidget.h"
3
4 #include "folderman.h"
5
6 #include <QFile>
7 #include <QInputDialog>
8 #include <QLineEdit>
9 #include <QMessageBox>
10
11 namespace OCC {
12
13 static constexpr int patternCol = 0;
14 static constexpr int deletableCol = 1;
15 static constexpr int readOnlyRows = 3;
16
IgnoreListTableWidget(QWidget * parent)17 IgnoreListTableWidget::IgnoreListTableWidget(QWidget *parent)
18 : QWidget(parent)
19 , ui(new Ui::IgnoreListTableWidget)
20 {
21 setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
22 ui->setupUi(this);
23
24 ui->descriptionLabel->setText(tr("Files or folders matching a pattern will not be synchronized.\n\n"
25 "Items where deletion is allowed will be deleted if they prevent a "
26 "directory from being removed. "
27 "This is useful for meta data."));
28
29 ui->removePushButton->setEnabled(false);
30 connect(ui->tableWidget, &QTableWidget::itemSelectionChanged,
31 this, &IgnoreListTableWidget::slotItemSelectionChanged);
32 connect(ui->removePushButton, &QAbstractButton::clicked,
33 this, &IgnoreListTableWidget::slotRemoveCurrentItem);
34 connect(ui->addPushButton, &QAbstractButton::clicked,
35 this, &IgnoreListTableWidget::slotAddPattern);
36 connect(ui->removeAllPushButton, &QAbstractButton::clicked,
37 this, &IgnoreListTableWidget::slotRemoveAllItems);
38
39 ui->tableWidget->resizeColumnsToContents();
40 ui->tableWidget->horizontalHeader()->setSectionResizeMode(patternCol, QHeaderView::Stretch);
41 ui->tableWidget->verticalHeader()->setVisible(false);
42 }
43
~IgnoreListTableWidget()44 IgnoreListTableWidget::~IgnoreListTableWidget()
45 {
46 delete ui;
47 }
48
slotItemSelectionChanged()49 void IgnoreListTableWidget::slotItemSelectionChanged()
50 {
51 QTableWidgetItem *item = ui->tableWidget->currentItem();
52 if (!item) {
53 ui->removePushButton->setEnabled(false);
54 return;
55 }
56
57 bool enable = item->flags() & Qt::ItemIsEnabled;
58 ui->removePushButton->setEnabled(enable);
59 }
60
slotRemoveCurrentItem()61 void IgnoreListTableWidget::slotRemoveCurrentItem()
62 {
63 ui->tableWidget->removeRow(ui->tableWidget->currentRow());
64 if(ui->tableWidget->rowCount() == readOnlyRows)
65 ui->removeAllPushButton->setEnabled(false);
66 }
67
slotRemoveAllItems()68 void IgnoreListTableWidget::slotRemoveAllItems()
69 {
70 ui->tableWidget->setRowCount(0);
71 }
72
slotWriteIgnoreFile(const QString & file)73 void IgnoreListTableWidget::slotWriteIgnoreFile(const QString & file)
74 {
75 QFile ignores(file);
76 if (ignores.open(QIODevice::WriteOnly)) {
77 // rewrites the whole file since now the user can also remove system patterns
78 QFile::resize(file, 0);
79 for (int row = 0; row < ui->tableWidget->rowCount(); ++row) {
80 QTableWidgetItem *patternItem = ui->tableWidget->item(row, patternCol);
81 QTableWidgetItem *deletableItem = ui->tableWidget->item(row, deletableCol);
82 if (patternItem->flags() & Qt::ItemIsEnabled) {
83 QByteArray prepend;
84 if (deletableItem->checkState() == Qt::Checked) {
85 prepend = "]";
86 } else if (patternItem->text().startsWith('#')) {
87 prepend = "\\";
88 }
89 ignores.write(prepend + patternItem->text().toUtf8() + '\n');
90 }
91 }
92 } else {
93 QMessageBox::warning(this, tr("Could not open file"),
94 tr("Cannot write changes to \"%1\".").arg(file));
95 }
96 ignores.close(); //close the file before reloading stuff.
97
98 FolderMan *folderMan = FolderMan::instance();
99
100 // We need to force a remote discovery after a change of the ignore list.
101 // Otherwise we would not download the files/directories that are no longer
102 // ignored (because the remote etag did not change) (issue #3172)
103 foreach (Folder *folder, folderMan->map()) {
104 folder->journalDb()->forceRemoteDiscoveryNextSync();
105 folderMan->scheduleFolder(folder);
106 }
107 }
108
slotAddPattern()109 void IgnoreListTableWidget::slotAddPattern()
110 {
111 bool okClicked = false;
112 QString pattern = QInputDialog::getText(this, tr("Add Ignore Pattern"),
113 tr("Add a new ignore pattern:"),
114 QLineEdit::Normal, QString(), &okClicked);
115
116 if (!okClicked || pattern.isEmpty())
117 return;
118
119 addPattern(pattern, false, false);
120 ui->tableWidget->scrollToBottom();
121 }
122
readIgnoreFile(const QString & file,bool readOnly)123 void IgnoreListTableWidget::readIgnoreFile(const QString &file, bool readOnly)
124 {
125 QFile ignores(file);
126 if (ignores.open(QIODevice::ReadOnly)) {
127 while (!ignores.atEnd()) {
128 QString line = QString::fromUtf8(ignores.readLine());
129 line.chop(1);
130 if (!line.isEmpty() && !line.startsWith("#")) {
131 bool deletable = false;
132 if (line.startsWith(']')) {
133 deletable = true;
134 line = line.mid(1);
135 }
136 addPattern(line, deletable, readOnly);
137 }
138 }
139 }
140 }
141
addPattern(const QString & pattern,bool deletable,bool readOnly)142 int IgnoreListTableWidget::addPattern(const QString &pattern, bool deletable, bool readOnly)
143 {
144 int newRow = ui->tableWidget->rowCount();
145 ui->tableWidget->setRowCount(newRow + 1);
146
147 auto *patternItem = new QTableWidgetItem;
148 patternItem->setText(pattern);
149 ui->tableWidget->setItem(newRow, patternCol, patternItem);
150
151 auto *deletableItem = new QTableWidgetItem;
152 deletableItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
153 deletableItem->setCheckState(deletable ? Qt::Checked : Qt::Unchecked);
154 ui->tableWidget->setItem(newRow, deletableCol, deletableItem);
155
156 if (readOnly) {
157 patternItem->setFlags(patternItem->flags() ^ Qt::ItemIsEnabled);
158 patternItem->setToolTip(readOnlyTooltip);
159 deletableItem->setFlags(deletableItem->flags() ^ Qt::ItemIsEnabled);
160 }
161
162 ui->removeAllPushButton->setEnabled(true);
163
164 return newRow;
165 }
166
167 } // namespace OCC
168