[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [lokalize] src: CHANGELOG: handle source file links found in po files nicely: either open lxr.kde.or
From:       Nick Shaforostoff <shafff () ukr ! net>
Date:       2016-02-21 23:11:51
Message-ID: E1aXdAN-0006Pg-Tb () scm ! kde ! org
[Download RAW message or body]

Git commit 70c340bfb316767e81ce6058bd19305913e924d7 by Nick Shaforostoff.
Committed on 21/02/2016 at 23:07.
Pushed by shaforo into branch 'master'.

CHANGELOG: handle source file links found in po files nicely: either open lxr.kde.org \
                lookup or search files locally
FEATURE: 244686
BUG: 204276

M  +86   -3    src/editortab.cpp
M  +4    -0    src/lokalize.notifyrc
M  +115  -0    src/project/project.cpp
M  +9    -0    src/project/project.h
M  +3    -0    src/project/projectlocal.kcfg
M  +1    -1    src/tm/jobs.cpp

http://commits.kde.org/lokalize/70c340bfb316767e81ce6058bd19305913e924d7

diff --git a/src/editortab.cpp b/src/editortab.cpp
index 3e5d2b5..d1f35a5 100644
--- a/src/editortab.cpp
+++ b/src/editortab.cpp
@@ -1463,11 +1463,18 @@ void EditorTab::reloadFile()
         mergeOpen(mergeFilePath);
 }
 
-void EditorTab::dispatchSrcFileOpenRequest(const QString& srcPath, int line)
+static void openLxrSearch(const QString& srcFileRelPath)
+{
+    QDesktopServices::openUrl(QUrl(QStringLiteral("https://lxr.kde.org/search?_filestring=")
 +                                   + \
QString::fromLatin1(QUrl::toPercentEncoding(srcFileRelPath)))); +}
+
+
+void EditorTab::dispatchSrcFileOpenRequest(const QString& srcFileRelPath, int line)
 {
     // Try project scripts first.
     m_srcFileOpenRequestAccepted = false;
-    emit srcFileOpenRequested(srcPath, line);
+    emit srcFileOpenRequested(srcFileRelPath, line);
     if (m_srcFileOpenRequestAccepted)
         return;
 
@@ -1475,12 +1482,88 @@ void EditorTab::dispatchSrcFileOpenRequest(const QString& \
srcPath, int line)  // path exists relative to the current translation file path.
     QDir relativePath(currentFilePath());
     relativePath.cdUp();
-    QString srcAbsolutePath(relativePath.absoluteFilePath(srcPath));
+    QString srcAbsolutePath(relativePath.absoluteFilePath(srcFileRelPath));
     if (QFile::exists(srcAbsolutePath)) {
         QDesktopServices::openUrl(QUrl::fromLocalFile(srcAbsolutePath));
         return;
     }
 
+    QString dir = Project::instance()->local()->sourceDir();
+    if (dir.isEmpty())
+    {
+        switch (KMessageBox::questionYesNoCancel(SettingsController::instance()->mainWindowPtr(),
 +                                       i18nc("@info","Would you like to search for \
the source file locally or via lxr.kde.org?"),i18nc("@title:window","Source file \
lookup"), +                                             KGuiItem(i18n("Locally")), \
KGuiItem("lxr.kde.org") +                                            ))
+        {
+            case KMessageBox::Yes: break;
+            case KMessageBox::No: openLxrSearch(srcFileRelPath);
+            case KMessageBox::Cancel:
+            default:
+                return;
+        }
+    }
+
+    //hard fallback
+    if (dir.isEmpty())
+    {
+        dir = QFileDialog::getExistingDirectory(this, i18n("Select project's base \
folder for source file lookup"), QDir::homePath()); +        if (dir.length())
+            Project::instance()->local()->setSourceDir(dir);
+    }
+    if (dir.length())
+    {
+        auto doOpen = [srcFileRelPath]()
+        {
+            auto sourceFilePaths = Project::instance()->sourceFilePaths();
+            bool found = false;
+            QByteArray fn = \
srcFileRelPath.midRef(srcFileRelPath.lastIndexOf('/')+1).toUtf8(); +            auto \
it=sourceFilePaths.constFind(fn); +            while (it!=sourceFilePaths.constEnd() \
&& it.key() == fn) +            {
+                const QString absFilePath = QString::fromUtf8(it.value()+'/'+fn);
+                if (!absFilePath.endsWith(srcFileRelPath) || \
!QFileInfo::exists(absFilePath) ) //for the case when link contained also folders +   \
{ +                    it++;
+                    continue;
+                }
+                found = true;
+                QDesktopServices::openUrl(QUrl::fromLocalFile(absFilePath));
+                it++;
+            }
+            if (!found)
+            {
+                switch \
(KMessageBox::warningYesNoCancel(SettingsController::instance()->mainWindowPtr(), +   \
i18nc("@info","Could not find source file in the folder specified,\n" +               \
"Do you want to change source files folder?"),i18nc("@title:window","Source file \
lookup"), +                                                      \
KStandardGuiItem::yes(), KStandardGuiItem::no(), KGuiItem(i18n("lxr.kde.org")))) +    \
{ +                    case KMessageBox::Cancel:
+                        Project::instance()->local()->setSourceDir(QString());
+                        Project::instance()->resetSourceFilePaths();
+                        openLxrSearch(srcFileRelPath);
+                    case KMessageBox::No:
+                        return;
+                    default: ; //fall through to dir selection
+                }
+
+                QString dir = QFileDialog::getExistingDirectory(0, i18n("Select \
project's base folder for source file lookup"), \
Project::instance()->local()->sourceDir()); +                if (dir.length())
+                {
+                    Project::instance()->local()->setSourceDir(dir);
+                    Project::instance()->resetSourceFilePaths();
+                }
+
+            }
+        };
+        if (!Project::instance()->sourceFilePaths().isEmpty())
+            doOpen();
+        else
+            connect(Project::instance(), &Project::sourceFilePathsAreReady, doOpen);
+        return;
+    }
+
+
     // Otherwise, let the user know how to create a project script to handle
     // opening source file paths that are not relative to translation files.
     KMessageBox::information(this, i18nc("@info",
diff --git a/src/lokalize.notifyrc b/src/lokalize.notifyrc
index 5991c81..aae9efd 100644
--- a/src/lokalize.notifyrc
+++ b/src/lokalize.notifyrc
@@ -232,3 +232,7 @@ Name[x-test]=xxNo Qt Sql modules were foundxx
 Name[zh_CN]=未找到 Qt SQL 模块
 Name[zh_TW]=找不到 Qt Sql 模組
 Action=Popup
+
+[Event/SourceFileScan]
+Name=Scanning folders with source files...
+Action=Popup
diff --git a/src/project/project.cpp b/src/project/project.cpp
index ff5bc50..f59fd62 100644
--- a/src/project/project.cpp
+++ b/src/project/project.cpp
@@ -37,6 +37,7 @@
 
 #include <klocalizedstring.h>
 #include <kmessagebox.h>
+#include <knotification.h>
 
 #include <QLocale>
 #include <QTimer>
@@ -50,6 +51,10 @@
 #include "projectmodel.h"
 #include "webquerycontroller.h"
 
+#include <kio/global.h>
+#include <kjob.h>
+#include <kjobtrackerinterface.h>
+
 #include <kross/core/action.h>
 #include <kross/core/actioncollection.h>
 #include <kross/core/manager.h>
@@ -195,6 +200,8 @@ void Project::load(const QString &newProjectPath, const QString& \
forcedTargetLan  //QTimer::singleShot(0,this,SLOT(populateGlossary()));
     populateGlossary();//we cant postpone it because project load can be called from \
define new term function  
+    m_sourceFilePaths.clear();
+
     if (newProjectPath.isEmpty())
         return;
 
@@ -347,7 +354,115 @@ void Project::init(const QString& path, const QString& kind, \
const QString& id,  
 
 
+static void fillFilePathsRecursive(const QDir& dir, QMultiMap<QByteArray, \
QByteArray>& sourceFilePaths) +{
+    QStringList subDirs(dir.entryList(QDir::Dirs|QDir::NoDotAndDotDot|QDir::Readable));
 +    int i=subDirs.size();
+    while(--i>=0)
+        fillFilePathsRecursive(QDir(dir.filePath(subDirs.at(i))),sourceFilePaths);
+
+    static QStringList filters = QStringList(QStringLiteral("*.cpp"))
+                                           <<QStringLiteral("*.c")
+                                           <<QStringLiteral("*.cc")
+                                           <<QStringLiteral("*.mm")
+                                           <<QStringLiteral("*.ui")
+                                           <<QStringLiteral("*rc");
+    QStringList files(dir.entryList(filters, \
QDir::Files|QDir::NoDotAndDotDot|QDir::Readable)); +    i=files.size();
+
+    QByteArray absDirPath=dir.absolutePath().toUtf8(); absDirPath.squeeze();
+    while(--i>=0)
+    {
+        //qDebug()<<files.at(i)<<absDirPath;
+        QByteArray fn=files.at(i).toUtf8(); fn.squeeze();
+        auto it=sourceFilePaths.constFind(fn);
+        if (it!=sourceFilePaths.constEnd())
+            sourceFilePaths.insert(it.key(), absDirPath); //avoid having identical \
qbytearray objects to save memory +        else
+            sourceFilePaths.insert(fn, absDirPath);
+    }
+}
+
+
+#ifndef NOKDE
+class SourceFilesSearchJob: public KJob
+{
+public:
+    SourceFilesSearchJob(const QString& folderName, QObject* parent=0);
+    void start();
+    void finish(){emitResult(); emit \
Project::instance()->sourceFilePathsAreReady();} +protected:
+    bool doKill();
+
+private:
+    QString m_folderName;
+};
+
+SourceFilesSearchJob::SourceFilesSearchJob(const QString& folderName, QObject* \
parent) +    : KJob(parent)
+    , m_folderName(folderName)
+{
+    setCapabilities(KJob::Killable);
+}
+
+bool SourceFilesSearchJob::doKill()
+{
+    //TODO
+    return true;
+}
+
+class FillSourceFilePathsJob: public QRunnable
+{
+public:
+    explicit FillSourceFilePathsJob(const QDir& dir, SourceFilesSearchJob* \
j):startingDir(dir),kj(j){} +
+protected:
+    void run()
+    {
+        QMultiMap<QByteArray, QByteArray> sourceFilePaths;
+        fillFilePathsRecursive(startingDir, sourceFilePaths);
+        Project::instance()->m_sourceFilePaths = sourceFilePaths;
+        QTimer::singleShot(0, kj, &SourceFilesSearchJob::finish);
+    }
+public:
+    QDir startingDir;
+    SourceFilesSearchJob* kj;
+};
+
+
+void SourceFilesSearchJob::start()
+{
+    QThreadPool::globalInstance()->start(new \
FillSourceFilePathsJob(QDir(m_folderName), this)); +    emit description(this,
+                i18n("Scanning folders with source files"),
+                qMakePair(i18n("Editor"), m_folderName));
+}
+#endif
+
+const QMultiMap<QByteArray, QByteArray>& Project::sourceFilePaths()
+{
+    if (m_sourceFilePaths.isEmpty())
+    {
+        QDir dir(local()->sourceDir());
+        if (dir.exists())
+        {
+#ifndef NOKDE
+            SourceFilesSearchJob* metaJob = new \
SourceFilesSearchJob(local()->sourceDir()); +            \
KIO::getJobTracker()->registerJob(metaJob); +            metaJob->start();
 
+            //KNotification* notification=new KNotification("SourceFileScan", 0);
+            //notification->setText( i18nc("@info","Please wait while %1 is being \
scanned for source files.", local()->sourceDir()) ); +            \
//notification->sendEvent(); +#else
+            QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
+            fillFilePathsRecursive(dir, m_sourceFilePaths);
+            QApplication::restoreOverrideCursor();
+#endif
+        }
+    }
+    return m_sourceFilePaths;
+}
 
 
 
diff --git a/src/project/project.h b/src/project/project.h
index c64f4bf..05e1d48 100644
--- a/src/project/project.h
+++ b/src/project/project.h
@@ -121,6 +121,13 @@ public:
     static Project* instance();
     static ProjectLocal* local(){return instance()->m_localConfig;}
 
+    const QMultiMap<QByteArray, QByteArray>& sourceFilePaths();
+    void resetSourceFilePaths(){m_sourceFilePaths.clear();}
+
+    friend class FillSourceFilePathsJob;
+signals:
+    void sourceFilePathsAreReady();
+
 private:
     QString m_path;
     QString m_desirablePath;
@@ -130,6 +137,8 @@ private:
     GlossaryNS::GlossaryWindow* m_glossaryWindow;
     TM::TMManagerWin* m_tmManagerWindow;
 
+    QMultiMap<QByteArray, QByteArray> m_sourceFilePaths;
+
     //cache
     QString m_projectDir;
  };
diff --git a/src/project/projectlocal.kcfg b/src/project/projectlocal.kcfg
index 03107ba..f7461ca 100644
--- a/src/project/projectlocal.kcfg
+++ b/src/project/projectlocal.kcfg
@@ -4,6 +4,9 @@
       xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
                           http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
   <kcfgfile arg="true"/>
+  <group name="General">
+    <entry name="SourceDir"  type="String"></entry>
+  </group>
   <group name="Personal">
     <entry name="Role" type="Enum">
       <choices name="PersonRole">
diff --git a/src/tm/jobs.cpp b/src/tm/jobs.cpp
index d0b1848..f8b8051 100644
--- a/src/tm/jobs.cpp
+++ b/src/tm/jobs.cpp
@@ -1238,7 +1238,7 @@ bool SelectJob::doSelect(QSqlDatabase& db,
         return false;
     bool seen85=false;
     int limit=200;
-    QMap<uint,qlonglong>::const_iterator clit=concordanceLevelToIds.constEnd();
+    auto clit=concordanceLevelToIds.constEnd();
     if (concordanceLevelToIds.size()) --clit;
     if (concordanceLevelToIds.size()) while (--limit>=0)
     {


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic