diff --git a/src/fileTree.h b/src/fileTree.h --- a/src/fileTree.h +++ b/src/fileTree.h @@ -1,6 +1,7 @@ /*********************************************************************** * Copyright 2003-2004 Max Howell * Copyright 2008-2009 Martin Sandsmark +* Copyright 2017 Harald Sitter * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -49,25 +50,41 @@ Folder *parent() const { return m_parent; } + + /** Do not use for user visible strings. Use name instead. */ const char *name8Bit() const { return m_name; } + /** Decoded name. Use when you need a QString. */ + QString decodedName() const { + return QFile::decodeName(m_name); + } + /** + * Humand readable name (including native seperators where applicable). + * Only use for display. + */ + QString displayName() const; + FileSize size() const { return m_size; } - QString name() const { - return QFile::decodeName(m_name); - } virtual bool isFolder() const { return false; } - QString fullPath(const Folder* = nullptr) const; + /** + * Human readable path for display (including native separators where applicable. + * Only use for display. + */ + QString displayPath(const Folder * = nullptr) const; QString humanReadableSize() const { return KFormat().formatByteSize(m_size); } + /** Builds a complete QUrl by walking up to root. */ + QUrl url(const Folder *root = nullptr) const; + protected: File(const char *name, FileSize size, Folder *parent) : m_parent(parent), m_name(qstrdup(name)), m_size(size) {} @@ -111,11 +128,11 @@ { append(new File(name, size, this)); } - + /// removes a file void remove(const File *f) { files.removeAll(const_cast(f)); - + for (Folder *d = this; d; d = d->parent()) { d->m_size -= f->size(); } diff --git a/src/fileTree.cpp b/src/fileTree.cpp --- a/src/fileTree.cpp +++ b/src/fileTree.cpp @@ -1,6 +1,7 @@ /*********************************************************************** * Copyright 2003-2004 Max Howell * Copyright 2008-2009 Martin Sandsmark +* Copyright 2017 Harald Sitter * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -24,20 +25,30 @@ #include #include -QString -File::fullPath(const Folder *root /*= 0*/) const +QString File::displayName() const { + const QString decodedName = QFile::decodeName(m_name); + return url().isLocalFile() ? QDir::toNativeSeparators(decodedName) : decodedName; +} + +QString File::displayPath(const Folder *root) const +{ + // Use QUrl to sanitize the path for display and then run it throuh + // QDir to make sure we use native path seprators. + const QUrl url = this->url(root); + const QString cleanPath = url.toDisplayString(QUrl::PreferLocalFile | QUrl::NormalizePathSegments); + return url.isLocalFile() ? QDir::toNativeSeparators(cleanPath) : cleanPath; +} + +QUrl File::url(const Folder *root) const { QString path; if (root == this) root = nullptr; //prevent returning empty string when there is something we could return - for (const Folder *d = (Folder*)this; d != root && d; d = d->parent()) - path.prepend(d->name()); + for (const Folder *d = (Folder*)this; d != root && d; d = d->parent()) { + path.prepend(QFile::decodeName(d->name8Bit())); + } - // Use QUrl to sanitize the path for display and then run it throuh - // QDir to make sure we use native path seprators. - const QUrl url = QUrl::fromLocalFile(path); - const QString cleanPath = url.toDisplayString(QUrl::PreferLocalFile | QUrl::NormalizePathSegments); - return url.isLocalFile() ? QDir::toNativeSeparators(cleanPath) : cleanPath; + return QUrl::fromUserInput(path, QString(), QUrl::AssumeLocalFile); } diff --git a/src/localLister.cpp b/src/localLister.cpp --- a/src/localLister.cpp +++ b/src/localLister.cpp @@ -212,7 +212,7 @@ { if (new_path == folder->name8Bit()) { - qDebug() << "Tree pre-completed: " << folder->name(); + qDebug() << "Tree pre-completed: " << folder->decodedName(); d = folder; m_trees->removeAll(folder); m_parent->m_files += folder->children(); diff --git a/src/radialMap/labels.cpp b/src/radialMap/labels.cpp --- a/src/radialMap/labels.cpp +++ b/src/radialMap/labels.cpp @@ -197,7 +197,7 @@ for (it = list.begin(); it != list.end(); ++it) { Label *label = *it; //** bear in mind that text is drawn with QPoint param as BOTTOM left corner of text box - QString string = label->segment->file()->name(); + QString string = label->segment->file()->displayName(); if (varySizes) { font.setPointSize(sizes[label->level]); } diff --git a/src/radialMap/map.cpp b/src/radialMap/map.cpp --- a/src/radialMap/map.cpp +++ b/src/radialMap/map.cpp @@ -267,7 +267,7 @@ { for (Segment *segment : m_signature[i]) { if (m_summary){ // Summary view has its own colors, special cased. - if (segment->file()->name() == QLatin1String("Used")) { + if (segment->file()->decodedName() == QLatin1String("Used")) { cb = QApplication::palette().highlight().color(); cb.getHsv(&h, &s1, &v1); diff --git a/src/radialMap/widget.cpp b/src/radialMap/widget.cpp --- a/src/radialMap/widget.cpp +++ b/src/radialMap/widget.cpp @@ -62,12 +62,12 @@ QString RadialMap::Widget::path() const { - return m_tree->fullPath(); + return m_tree->displayPath(); } QUrl RadialMap::Widget::url(File const * const file) const { - return QUrl::fromUserInput(file ? file->fullPath() : m_tree->fullPath()); + return file ? file->url() : m_tree->url(); } void RadialMap::Widget::invalidate() diff --git a/src/radialMap/widgetEvents.cpp b/src/radialMap/widgetEvents.cpp --- a/src/radialMap/widgetEvents.cpp +++ b/src/radialMap/widgetEvents.cpp @@ -151,7 +151,7 @@ setCursor(Qt::PointingHandCursor); - QString string = m_focus->file()->fullPath(m_tree) + QString string = m_focus->file()->displayPath() + QLatin1Char('\n') + m_focus->file()->humanReadableSize(); @@ -186,7 +186,7 @@ m_tooltip.setText(string); m_tooltip.show(); - emit mouseHover(m_focus->file()->fullPath()); + emit mouseHover(m_focus->file()->displayPath()); update(); } } @@ -205,7 +205,7 @@ if (!m_focus) return; setCursor(Qt::PointingHandCursor); - emit mouseHover(m_focus->file()->fullPath()); + emit mouseHover(m_focus->file()->displayPath()); update(); } @@ -260,7 +260,7 @@ QAction* deleteItem = nullptr; QMenu popup; - popup.setTitle(m_focus->file()->fullPath(m_tree)); + popup.setTitle(m_focus->file()->displayPath(m_tree)); if (isDir) { openFileManager = popup.addAction(QIcon::fromTheme(QLatin1String("system-file-manager")), i18n("Open &File Manager Here")); diff --git a/src/scan.cpp b/src/scan.cpp --- a/src/scan.cpp +++ b/src/scan.cpp @@ -104,7 +104,7 @@ QMutableListIterator it(m_cache); while (it.hasNext()) { Folder *folder = it.next(); - QString cachePath = folder->name(); + QString cachePath = folder->decodedName(); if (path.startsWith(cachePath)) { //then whole tree already scanned //find a pointer to the requested branch @@ -124,7 +124,7 @@ d = nullptr; while (it.hasNext()) { File *subfolder = it.next(); - if (s == subfolder->name()) { + if (s == subfolder->decodedName()) { d = (Folder*)subfolder; break; } diff --git a/src/summaryWidget.cpp b/src/summaryWidget.cpp --- a/src/summaryWidget.cpp +++ b/src/summaryWidget.cpp @@ -71,7 +71,7 @@ virtual void setCursor(const QCursor &c) { - if (focusSegment() && focusSegment()->file()->name() == QLatin1String( "Used" )) + if (focusSegment() && focusSegment()->file()->decodedName() == QLatin1String( "Used" )) RadialMap::Widget::setCursor(c); else unsetCursor();