Making paths case insensitive in krunner

Diaa Sami diaasami at gmail.com
Mon Jan 19 18:35:17 CET 2009


On Sat, 17 Jan 2009 10:50 -0700, "Aaron J. Seigo" <aseigo at kde.org> wrote:
> 
> sure; if you can come to the list with some patches, i see no reason
> (assuming the performance is still good =) they couldn't go in...
> 

You can find an initial version of the patch below, it looks like it works fast enough.
Although rare, The behavior of the code in case of multiple matches needs to be determined.
Tell me what you think...

Index: kdelibs/plasma/runnercontext.cpp
===================================================================
--- kdelibs/plasma/runnercontext.cpp	(revision 911086)
+++ kdelibs/plasma/runnercontext.cpp	(working copy)
@@ -47,6 +47,115 @@
 namespace Plasma
 {
 
+/*
+Corrects the case of the last component in a path (e.g. /usr/liB -> /usr/lib)
+path: The path to be processed.
+correctCasePath: The corrected-case path
+mustBeDir: Tells whether the last component is a folder or doesn't matter
+Returns true on success and false on error, in case of error, correctCasePath is not modified
+*/
+bool CorrectLastComponentCase(const QString &path, QString *correctCasePath, const bool mustBeDir)
+    {
+    const QFileInfo pathInfo(path);
+
+    const QDir fileDir = pathInfo.dir();
+    qDebug() << "Directory is" << fileDir;
+
+    const QString filename = pathInfo.fileName();
+    qDebug() << "Filename is" << filename;
+
+    qDebug() << "searching for a" << (mustBeDir ? "directory" : "directory/file");
+
+    const QStringList matchingFilenames = fileDir.entryList(QStringList(filename),
+            mustBeDir ? QDir::Dirs : QDir::NoFilter);
+
+    if (matchingFilenames.empty())
+        {
+        qDebug() << "No matches found!!\n";
+        return false;
+        }
+    else
+        {
+        if (matchingFilenames.size() > 1)
+            {
+            qDebug() << "Found multiple matches!!\n";
+            }
+
+        *correctCasePath = fileDir.path() + QDir::separator() + matchingFilenames[0];        
+        if (correctCasePath->startsWith("//"))
+            {
+            correctCasePath->remove(0, 1);
+            }
+
+        return true;
+        }
+    }
+
+/*
+Corrects the case of a path (e.g. /uSr/loCAL/bIN -> /usr/local/bin)
+path: The path to be processed.
+corrected: The corrected-case path
+Returns true on success and false on error, in case of error, corrected is not modified
+*/
+bool CorrectPathCase(const QString path, QString *corrected)
+    {
+  // early exit check
+        if (QFile::exists(path))
+            {
+            *corrected = path;
+            return true;
+            }
+
+  // path components
+    QStringList components = QString(path).split(QDir::separator());
+
+    const bool mustBeDir = components.back() == "";
+
+    qDebug() << "Components are" << components;
+
+    QString correctPath;
+
+    if (components.back() == "")
+        {
+        components.pop_back();
+        }
+
+    Q_ASSERT(components.size() > 1);
+
+        if (components.size() == 1)
+            return false;
+ 
+    const unsigned initialComponents = components.size();
+    for (unsigned i = 0; i < initialComponents - 1; i ++)
+        {
+        const QString tmp = components[0] + QDir::separator() + components[1];
+
+        qDebug() << "Correcting " << tmp;
+
+        // If the file already exists then no need to search for it
+        if (QFile::exists(tmp))
+            {
+            correctPath = tmp; 
+            }
+        else
+            {
+            if (CorrectLastComponentCase(tmp, &correctPath, components.size() > 2 || mustBeDir) == false)
+                {
+                qDebug() << "search was not successfull";
+                return false;
+                }
+            }
+
+        components.removeFirst();
+        components[0] = correctPath;
+
+        qDebug() << "Correct path is" << correctPath;
+        }
+
+    *corrected = correctPath;
+        return true;
+    }
+
 class RunnerContextPrivate : public QSharedData
 {
     public:
@@ -88,9 +197,11 @@
                                      RunnerContext::Executable;
             } else {
                 KUrl url(term);
+                QString correctCasePath;
                 if (!url.protocol().isEmpty() && !url.isLocalFile()) {
                     type = RunnerContext::NetworkLocation;
-                } else if (QFile::exists(path)) {
+                } else if (CorrectPathCase(path, &correctCasePath)) {
+		    path = correctCasePath;
                     QFileInfo info(path);
                     if (info.isSymLink()) {
                         path = info.canonicalFilePath();


More information about the Plasma-devel mailing list