Commit 6575a733 authored by Harald Sitter's avatar Harald Sitter 🌼

substantially refine the path x-platform path displaying

- File::name is now File::decodedName
- new File::displayName which properly applies separators to the name
  (on Windows src/ should be src\)

The motivation behind this change is to force us having to make a decision
if we want the low-overhead name or the high-overhead UI name.

- File::fullPath is now File::displayPath for the same reason as above
- new File::url as a convenience wrapper used by the display* functions
  to construct a full URL out of their tree so we can determine whether
  the path is local or remote (scheme file:// vs. http:// etc.)
- RadialMap::Widget::mouseMoveEvent had its tooltip adjusted to not
  resolve it against the held tree but rather the entities tree. This was
  inconsistent with hover signals emitted and caused remote paths to
  get improperly displayed like local paths in the tooltip while being
  correctly displayed as URLs in the rest of the UI
parent 3d148799
/***********************************************************************
* Copyright 2003-2004 Max Howell <max.howell@methylblue.com>
* Copyright 2008-2009 Martin Sandsmark <martin.sandsmark@kde.org>
* Copyright 2017 Harald Sitter <sitter@kde.org>
*
* 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 <QDir>
#include <QUrl>
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);
}
/***********************************************************************
* Copyright 2003-2004 Max Howell <max.howell@methylblue.com>
* Copyright 2008-2009 Martin Sandsmark <martin.sandsmark@kde.org>
* Copyright 2017 Harald Sitter <sitter@kde.org>
*
* 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 @@ public:
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 @@ public:
{
append(new File(name, size, this));
}
/// removes a file
void remove(const File *f) {
files.removeAll(const_cast<File*>(f));
for (Folder *d = this; d; d = d->parent()) {
d->m_size -= f->size();
}
......
......@@ -212,7 +212,7 @@ LocalLister::scan(const QByteArray &path, const QByteArray &dirname)
{
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();
......
......@@ -197,7 +197,7 @@ void RadialMap::Widget::paintExplodedLabels(QPainter &paint) const
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]);
}
......
......@@ -267,7 +267,7 @@ void RadialMap::Map::colorise()
{
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);
......
......@@ -62,12 +62,12 @@ RadialMap::Widget::~Widget()
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()
......
......@@ -151,7 +151,7 @@ void RadialMap::Widget::mouseMoveEvent(QMouseEvent *e)
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 @@ void RadialMap::Widget::mouseMoveEvent(QMouseEvent *e)
m_tooltip.setText(string);
m_tooltip.show();
emit mouseHover(m_focus->file()->fullPath());
emit mouseHover(m_focus->file()->displayPath());
update();
}
}
......@@ -205,7 +205,7 @@ void RadialMap::Widget::enterEvent(QEvent *)
if (!m_focus) return;
setCursor(Qt::PointingHandCursor);
emit mouseHover(m_focus->file()->fullPath());
emit mouseHover(m_focus->file()->displayPath());
update();
}
......@@ -260,7 +260,7 @@ void RadialMap::Widget::mousePressEvent(QMouseEvent *e)
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"));
......
......@@ -104,7 +104,7 @@ bool ScanManager::start(const QUrl &url)
QMutableListIterator<Folder*> 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 @@ bool ScanManager::start(const QUrl &url)
d = nullptr;
while (it.hasNext()) {
File *subfolder = it.next();
if (s == subfolder->name()) {
if (s == subfolder->decodedName()) {
d = (Folder*)subfolder;
break;
}
......
......@@ -71,7 +71,7 @@ public:
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();
......
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