1 #include "backuplistwidget.h"
2 #include "backuplistwidgetitem.h"
3 #include "debug.h"
4 #include "utils.h"
5
6 #include <QDropEvent>
7 #include <QFileInfo>
8 #include <QMessageBox>
9 #include <QMimeData>
10 #include <QSettings>
11
BackupListWidget(QWidget * parent)12 BackupListWidget::BackupListWidget(QWidget *parent) : QListWidget(parent)
13 {
14 QSettings settings;
15 QStringList urls = settings.value("app/backup_list").toStringList();
16 if(!urls.isEmpty())
17 {
18 QList<QUrl> urllist;
19 foreach(QString url, urls)
20 urllist << QUrl::fromUserInput(url);
21 if(!urllist.isEmpty())
22 QMetaObject::invokeMethod(this, "addItemsWithUrls", QUEUED,
23 Q_ARG(QList<QUrl>, urllist));
24 }
25 connect(this, &QListWidget::itemActivated, [&](QListWidgetItem *item) {
26 static_cast<BackupListWidgetItem *>(item)->browseUrl();
27 });
28 }
29
~BackupListWidget()30 BackupListWidget::~BackupListWidget()
31 {
32 QStringList urls;
33 for(int i = 0; i < count(); ++i)
34 {
35 BackupListWidgetItem *backupItem =
36 static_cast<BackupListWidgetItem *>(item(i));
37 urls << backupItem->url().toString(QUrl::FullyEncoded);
38 }
39 QSettings settings;
40 settings.setValue("app/backup_list", urls);
41 settings.sync();
42 clear();
43 }
44
addItemWithUrl(QUrl url)45 void BackupListWidget::addItemWithUrl(QUrl url)
46 {
47 if(url.isEmpty())
48 return;
49
50 QString fileUrl = url.toLocalFile();
51 if(fileUrl.isEmpty())
52 return;
53 QFileInfo file(fileUrl);
54 if(!file.exists())
55 return;
56
57 QList<QUrl> urls = itemUrls();
58 bool matches = false;
59 foreach(QUrl existingUrl, urls)
60 {
61 if(url == existingUrl)
62 {
63 matches = true;
64 break;
65 }
66 QFileInfo existingFile(existingUrl.toLocalFile());
67 if(existingFile.isDir()
68 && fileUrl.startsWith(existingFile.absoluteFilePath()))
69 {
70 matches = true;
71 break;
72 }
73 }
74
75 if(matches)
76 {
77 auto confirm =
78 QMessageBox::question(this, tr("Confirm action"),
79 tr("The file or directory:\n %1\n"
80 "was already in the backup list;"
81 " adding it again will have no effect.\n"
82 "Add anyway?")
83 .arg(url.toLocalFile()));
84 if(confirm == QMessageBox::No)
85 return;
86 }
87
88 BackupListWidgetItem *item = new BackupListWidgetItem(url);
89 connect(item, &BackupListWidgetItem::requestDelete, this,
90 &BackupListWidget::removeItems);
91 connect(item, &BackupListWidgetItem::requestUpdate, this,
92 &BackupListWidget::recomputeListTotals);
93 insertItem(count(), item);
94 setItemWidget(item, item->widget());
95 emit itemWithUrlAdded(url);
96 }
97
addItemsWithUrls(QList<QUrl> urls)98 void BackupListWidget::addItemsWithUrls(QList<QUrl> urls)
99 {
100 setUpdatesEnabled(false);
101 foreach(QUrl url, urls)
102 addItemWithUrl(url);
103 recomputeListTotals();
104 setUpdatesEnabled(true);
105 }
106
setItemsWithUrls(QList<QUrl> urls)107 void BackupListWidget::setItemsWithUrls(QList<QUrl> urls)
108 {
109 setUpdatesEnabled(false);
110 clear();
111 setUpdatesEnabled(true);
112 addItemsWithUrls(urls);
113 }
114
itemUrls()115 QList<QUrl> BackupListWidget::itemUrls()
116 {
117 QList<QUrl> urls;
118 for(int i = 0; i < count(); ++i)
119 {
120 BackupListWidgetItem *backupItem =
121 static_cast<BackupListWidgetItem *>(item(i));
122 urls << backupItem->url().toString(QUrl::FullyEncoded);
123 }
124 return urls;
125 }
126
removeItems()127 void BackupListWidget::removeItems()
128 {
129 setUpdatesEnabled(false);
130 if(selectedItems().count() == 0)
131 {
132 // attempt to remove the sender
133 BackupListWidgetItem *backupItem =
134 qobject_cast<BackupListWidgetItem *>(sender());
135 if(backupItem)
136 delete backupItem;
137 }
138 else
139 {
140 foreach(QListWidgetItem *item, selectedItems())
141 {
142 if(item && item->isSelected())
143 delete item;
144 }
145 }
146 setUpdatesEnabled(true);
147 recomputeListTotals();
148 }
149
recomputeListTotals()150 void BackupListWidget::recomputeListTotals()
151 {
152 quint64 items = 0;
153 quint64 size = 0;
154 for(int i = 0; i < count(); ++i)
155 {
156 BackupListWidgetItem *backupItem =
157 static_cast<BackupListWidgetItem *>(item(i));
158 if(backupItem && (backupItem->count() != 0))
159 {
160 items += backupItem->count();
161 size += backupItem->size();
162 }
163 }
164 emit itemTotals(items, size);
165 }
166
dragMoveEvent(QDragMoveEvent * event)167 void BackupListWidget::dragMoveEvent(QDragMoveEvent *event)
168 {
169 if(!event->mimeData()->hasUrls())
170 {
171 event->ignore();
172 return;
173 }
174 event->accept();
175 }
176
dragEnterEvent(QDragEnterEvent * event)177 void BackupListWidget::dragEnterEvent(QDragEnterEvent *event)
178 {
179 if(event->mimeData()->hasUrls())
180 event->acceptProposedAction();
181 }
182
dropEvent(QDropEvent * event)183 void BackupListWidget::dropEvent(QDropEvent *event)
184 {
185 QList<QUrl> urls = event->mimeData()->urls();
186 if(!urls.isEmpty())
187 addItemsWithUrls(urls);
188
189 event->acceptProposedAction();
190 }
191
keyPressEvent(QKeyEvent * event)192 void BackupListWidget::keyPressEvent(QKeyEvent *event)
193 {
194 switch(event->key())
195 {
196 case Qt::Key_Delete:
197 case Qt::Key_Backspace:
198 removeItems();
199 break;
200 case Qt::Key_Escape:
201 if(!selectedItems().isEmpty())
202 clearSelection();
203 else
204 QListWidget::keyPressEvent(event);
205 break;
206 default:
207 QListWidget::keyPressEvent(event);
208 }
209 }
210
changeEvent(QEvent * event)211 void BackupListWidget::changeEvent(QEvent *event)
212 {
213 if(event->type() == QEvent::LanguageChange)
214 recomputeListTotals();
215 QWidget::changeEvent(event);
216 }
217