Commit 4107a196 authored by Martin Tobias Holmedahl Sandsmark's avatar Martin Tobias Holmedahl Sandsmark
Browse files

add support for re-scanning a single subfolder

parent dbae6894
......@@ -39,6 +39,10 @@ public:
const char *name8Bit() const {
return m_name;
}
void setName(const QByteArray &newName) {
delete [] m_name;
m_name = qstrdup(newName.constData());
}
/** Decoded name. Use when you need a QString. */
QString decodedName() const {
return QFile::decodeName(m_name);
......@@ -99,6 +103,19 @@ public:
return true;
}
Folder *duplicate() const
{
Folder *ret = new Folder(m_name);
for (const File *child : files) {
if (child->isFolder()) {
ret->append(((Folder*)child)->duplicate());
} else {
ret->append(child->name8Bit(), child->size());
}
}
return ret;
}
///appends a Folder
void append(Folder *d, const char *name=nullptr)
{
......@@ -130,6 +147,18 @@ public:
}
}
// Removes a file, but does not delete
const File *take(const File *f) {
files.removeAll(const_cast<File*>(f));
const FileSize childSize = f->size();
for (Folder *d = this; d; d = d->parent()) {
d->m_size -= childSize;
d->m_children--;
}
return f;
}
QList<File *> files;
private:
......
......@@ -87,6 +87,7 @@ MainWindow::MainWindow()
// TODO make better system
connect(m_map, &RadialMap::Widget::giveMeTreeFor, this, &MainWindow::updateURL);
connect(m_map, &RadialMap::Widget::giveMeTreeFor, this, &MainWindow::openUrl);
connect(m_map, &RadialMap::Widget::rescanRequested, this, &MainWindow::rescanSingleDir);
connect(m_manager, &ScanManager::completed, this, &MainWindow::folderScanCompleted);
connect(m_manager, &ScanManager::aboutToEmptyCache, m_map, &RadialMap::Widget::invalidate);
......@@ -400,7 +401,11 @@ bool MainWindow::openUrl(const QUrl &u)
m_stateWidget->show();
m_layout->addWidget(m_stateWidget);
return start(uri);
const bool success = start(uri);
if (success) {
setUrl(uri);
}
return success;
}
return false;
......@@ -429,12 +434,24 @@ void MainWindow::updateURL(const QUrl &u)
m_manager->abort();
if (u == url())
m_manager->invalidateCacheFor(u); //same as rescan()
m_manager->emptyCache(); //same as rescan()
//do this last, or it breaks Konqi location bar
setUrl(u);
}
void MainWindow::rescanSingleDir(const QUrl &dirUrl)
{
if (m_manager->running()) {
m_manager->abort();
}
m_manager->invalidateCacheFor(dirUrl);
m_map->hide();
m_stateWidget->show();
start(url());
}
QUrl MainWindow::url() const
{
return m_url;
......@@ -474,8 +491,6 @@ bool MainWindow::start(const QUrl &url)
m_numberOfFiles->setText(QString());
if (m_manager->start(url)) {
setUrl(url);
const QString s = i18n("Scanning: %1", prettyUrl());
stateChanged(QStringLiteral("scan_started"));
Q_EMIT started(); //as a MainWindow, we have to do this
......
......@@ -75,6 +75,7 @@ private Q_SLOTS:
void folderScanCompleted(Folder*);
void mapChanged(const Folder*);
void updateURL(const QUrl &);
void rescanSingleDir(const QUrl &);
protected:
void saveProperties(KConfigGroup&) override;
......
......@@ -74,6 +74,7 @@ Q_SIGNALS:
void folderCreated(const Folder*);
void mouseHover(const QString&);
void giveMeTreeFor(const QUrl&);
void rescanRequested(const QUrl&);
protected:
void changeEvent(QEvent*) override;
......
......@@ -296,6 +296,7 @@ void RadialMap::Widget::mousePressEvent(QMouseEvent *e)
QAction* copyClipboard = nullptr;
QAction* deleteItem = nullptr;
QAction* doNotScanItem = nullptr;
QAction* rescanAction = nullptr;
QMenu popup;
popup.setTitle(m_focus->file()->displayPath(m_tree));
......@@ -314,6 +315,7 @@ void RadialMap::Widget::mousePressEvent(QMouseEvent *e)
popup.addSeparator();
doNotScanItem = popup.addAction(QIcon::fromTheme(QStringLiteral("list-remove")), i18n("Add to Do &Not Scan List"));
rescanAction = popup.addAction(QIcon::fromTheme(QStringLiteral("view-refresh")), i18n("&Rescan"));
} else {
openFile = popup.addAction(QIcon::fromTheme(QStringLiteral("document-open")), i18nc("Scan/open the path of the selected element", "&Open"));
}
......@@ -332,6 +334,8 @@ void RadialMap::Widget::mousePressEvent(QMouseEvent *e)
KIO::OpenUrlJob *job = new KIO::OpenUrlJob(url, QStringLiteral("inode/directory"), this);
job->setUiDelegate(new KIO::JobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, window()));
job->start();
} else if (rescanAction && clicked == rescanAction) {
Q_EMIT rescanRequested(url);
} else if (openTerminal && clicked == openTerminal) {
KToolInvocation::invokeTerminal(QString(), QStringList(), url.path());
} else if (centerMap && clicked == centerMap) {
......
......@@ -182,35 +182,45 @@ void ScanManager::invalidateCacheFor(const QUrl &url)
Q_EMIT aboutToEmptyCache();
QMutableListIterator<Folder*> it(m_cache);
while (it.hasNext()) {
Folder *folder = it.next();
QMutableListIterator<Folder*> cacheIterator(m_cache);
QList<Folder*> subCaches;
QList<Folder*> oldCache = m_cache;
while (cacheIterator.hasNext()) {
Folder *folder = cacheIterator.next();
cacheIterator.remove();
QString cachePath = folder->decodedName();
if (!path.startsWith(cachePath)) {
continue;
}
QVector<QStringRef> split = path.midRef(cachePath.length()).split(QLatin1Char('/'));
QVector<QStringRef> splitPath = path.midRef(cachePath.length()).split(QLatin1Char('/'));
Folder *d = folder;
while (!split.isEmpty() && d != nullptr) { //if NULL we have got lost so abort!!
if (split.first().isEmpty()) { //found the dir
while (!splitPath.isEmpty() && d != nullptr) { //if NULL we have got lost so abort!!
if (splitPath.first().isEmpty()) { //found the dir
break;
}
QString s = split.first() % QLatin1Char('/'); // % is the string concatenation operator for QStringBuilder
QString wantedName = splitPath.takeFirst() % QLatin1Char('/'); // % is the string concatenation operator for QStringBuilder
QListIterator<File*> it(d->files);
d = nullptr;
while (it.hasNext()) {
File *subfolder = it.next();
if (s == subfolder->decodedName()) {
d = (Folder*)subfolder;
break;
if (subfolder->decodedName() == wantedName) {
// This is the one we want to remove
continue;
}
if (!subfolder->isFolder()) {
continue;
}
}
split.pop_front();
Folder *newFolder = ((Folder*)subfolder)->duplicate();
newFolder->setName((cachePath.toLocal8Bit() + subfolder->name8Bit()));
subCaches.append(newFolder);
d = nullptr;
}
}
if (!d || !d->parent()) {
......@@ -218,6 +228,11 @@ void ScanManager::invalidateCacheFor(const QUrl &url)
}
d->parent()->remove(d);
}
qDeleteAll(oldCache);
for (Folder *folder : subCaches) {
m_cache.append(folder);
}
}
void ScanManager::emptyCache()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment