Subject: Read .desktop file translations from .mo files if not present
From: Lubos Lunak
Fate: #300461
Patch-upstream: no
Relates: kdelibs3/desktop-translations.diff

---
 kdecore/config/kconfig.cpp         | 11 +++++++++++
 kdecore/config/kconfig_p.h         |  1 +
 kdecore/config/kconfigdata.cpp     | 17 +++++++++++++++++
 kdecore/config/kconfigdata.h       |  3 +++
 kdecore/config/kconfiggroup.cpp    | 10 ++++++++++
 kdecore/config/kconfiggroup.h      |  5 +++++
 kdecore/config/kdesktopfile.cpp    | 34 ++++++++++++++++++++++++++++------
 kdecore/config/kdesktopfile.h      |  2 ++
 kdecore/services/kservicegroup.cpp |  6 +++---
 9 files changed, 80 insertions(+), 9 deletions(-)

diff --git a/kdecore/config/kconfig.cpp b/kdecore/config/kconfig.cpp
index 048605d..230dcd4 100644
--- a/kdecore/config/kconfig.cpp
+++ b/kdecore/config/kconfig.cpp
@@ -882,6 +882,17 @@ QString KConfigPrivate::lookupData(const QByteArray& group, const char* key,
     return entryMap.getEntry(group, key, QString(), flags, expand);
 }

+QByteArray KConfigPrivate::lookupExactData(const QByteArray& group, const char* key,
+                                      KEntryMap::SearchFlags flags) const
+{
+    if (bReadDefaults)
+        flags |= KEntryMap::SearchDefaults;
+    const KEntryMapConstIterator it = entryMap.findExactEntry(group, key, flags);
+    if (it == entryMap.constEnd())
+        return QByteArray();
+    return it->mValue;
+}
+
 void KConfig::virtual_hook(int /*id*/, void* /*data*/)
 {
 	/* nothing */
diff --git a/kdecore/config/kconfig_p.h b/kdecore/config/kconfig_p.h
index 7751242..b2c363f 100644
--- a/kdecore/config/kconfig_p.h
+++ b/kdecore/config/kconfig_p.h
@@ -53,6 +53,7 @@ public:
     QString lookupData(const QByteArray& group, const char* key, KEntryMap::SearchFlags flags,
                        bool* expand) const;
     QByteArray lookupData(const QByteArray& group, const char* key, KEntryMap::SearchFlags flags) const;
+    QByteArray lookupExactData(const QByteArray& group, const char* key, KEntryMap::SearchFlags flags) const;

     void putData(const QByteArray& group, const char* key, const QByteArray& value,
                  KConfigBase::WriteConfigFlags flags, bool expand=false);
diff --git a/kdecore/config/kconfigdata.h b/kdecore/config/kconfigdata.h
index e5dd7da..341e40b 100644
--- a/kdecore/config/kconfigdata.h
+++ b/kdecore/config/kconfigdata.h
@@ -169,6 +169,19 @@ class KEntryMap : public QMap<KEntryKey, KEntry>
         Iterator findExactEntry(const QByteArray& group, const QByteArray& key = QByteArray(),
                            SearchFlags flags = SearchFlags());
 
+        ConstIterator findExactEntry(const QByteArray& group, const QByteArray& key = QByteArray(),
+                           SearchFlags flags = SearchFlags()) const
+        {
+            KEntryKey theKey(group, key, false, bool(flags&SearchDefaults));
+
+            // try the localized key first
+            if (flags&SearchLocalized) {
+                theKey.bLocal = true;
+                return find(theKey);
+            }
+            return find(theKey);
+        }
+
         Iterator findEntry(const QByteArray& group, const QByteArray& key = QByteArray(),
                            SearchFlags flags = SearchFlags());
 
diff --git a/kdecore/config/kconfiggroup.cpp b/kdecore/config/kconfiggroup.cpp
index 9e73eb7..671474f 100644
--- a/kdecore/config/kconfiggroup.cpp
+++ b/kdecore/config/kconfiggroup.cpp
@@ -1156,6 +1156,16 @@ bool KConfigGroup::hasKey(const char *key) const
     return !config()->d_func()->lookupData(d->fullName(), key, flags).isNull();
 }

+bool KConfigGroup::hasTranslatedKey(const char* key) const
+{
+    Q_ASSERT_X(isValid(), "KConfigGroup::hasTranslatedKey", "accessing an invalid group");
+
+    KEntryMap::SearchFlags flags = KEntryMap::SearchLocalized;
+    if ( config()->readDefaults() )
+        flags |= KEntryMap::SearchDefaults;
+    return !config()->d_func()->lookupExactData(d->fullName(), key, flags).isNull();
+}
+
 bool KConfigGroup::hasKey(const QString &key) const
 {
    return hasKey(key.toUtf8().constData());
diff --git a/kdecore/config/kconfiggroup.h b/kdecore/config/kconfiggroup.h
index 8eddfd5..cae528f 100644
--- a/kdecore/config/kconfiggroup.h
+++ b/kdecore/config/kconfiggroup.h
@@ -621,6 +621,11 @@ public:
      */
     QMap<QString, QString> entryMap() const;

+    /**
+     * @internal
+     */
+    bool hasTranslatedKey( const char *pKey ) const;
+
 protected:
     bool hasGroupImpl(const QByteArray &group) const;
     KConfigGroup groupImpl(const QByteArray &b);
diff --git a/kdecore/config/kdesktopfile.cpp b/kdecore/config/kdesktopfile.cpp
index 54e5910..ef11b75 100644
--- a/kdecore/config/kdesktopfile.cpp
+++ b/kdecore/config/kdesktopfile.cpp
@@ -34,6 +34,8 @@
 #include "kstandarddirs.h"
 #include "kconfigini_p.h"
 #include "kde_file.h"
+#include "kcatalog_p.h"
+#include "klocale.h"

 class KDesktopFilePrivate : public KConfigPrivate
 {
@@ -173,6 +175,29 @@ bool KDesktopFile::isAuthorizedDesktopFile(const QString& path)
   return false;
 }

+QString KDesktopFile::translatedEntry(const char* key) const
+{
+  Q_D(const KDesktopFile);
+  if (d->desktopGroup.hasTranslatedKey(key))
+    return d->desktopGroup.readEntry(key);
+
+  if (d->desktopGroup.hasKey(key)) {
+    QString value = d->desktopGroup.readEntryUntranslated(key);
+    QString fName = fileName();
+    fName = fName.mid(fName.lastIndexOf(QLatin1Char('/'))+1);
+    QString po_lookup_key = QString::fromLatin1(key) + QString::fromLatin1("(") + fName + QString::fromLatin1("): ") + value;
+    QString po_value;
+    KGlobal::locale()->translateRaw(po_lookup_key.toUtf8().data(), NULL, &po_value);
+
+    if (po_value == po_lookup_key)
+      return value;
+
+    return po_value;
+  }
+
+  return QString::null;
+}
+
 QString KDesktopFile::readType() const
 {
   Q_D(const KDesktopFile);
@@ -187,20 +212,17 @@ QString KDesktopFile::readIcon() const

 QString KDesktopFile::readName() const
 {
-  Q_D(const KDesktopFile);
-  return d->desktopGroup.readEntry("Name", QString());
+  return translatedEntry("Name");
 }

 QString KDesktopFile::readComment() const
 {
-  Q_D(const KDesktopFile);
-  return d->desktopGroup.readEntry("Comment", QString());
+  return translatedEntry("Comment");
 }

 QString KDesktopFile::readGenericName() const
 {
-  Q_D(const KDesktopFile);
-  return d->desktopGroup.readEntry("GenericName", QString());
+  return translatedEntry("GenericName");
 }

 QString KDesktopFile::readPath() const
diff --git a/kdecore/config/kdesktopfile.h b/kdecore/config/kdesktopfile.h
index 1c4eae6..f8a5d87 100644
--- a/kdecore/config/kdesktopfile.h
+++ b/kdecore/config/kdesktopfile.h
@@ -250,6 +250,8 @@ protected:
 //  virtual void virtual_hook( int id, void* data );
 private:

+  QString translatedEntry(const char*) const;
+
   Q_DISABLE_COPY(KDesktopFile)

   Q_DECLARE_PRIVATE(KDesktopFile)
diff --git a/kdecore/services/kservicegroup.cpp b/kdecore/services/kservicegroup.cpp
index 70f4ab3..f590632 100644
--- a/kdecore/services/kservicegroup.cpp
+++ b/kdecore/services/kservicegroup.cpp
@@ -56,9 +56,9 @@ void KServiceGroupPrivate::load(const QString &cfg)

   const KConfigGroup config = desktopFile.desktopGroup();

-  m_strCaption = config.readEntry( "Name" );
-  m_strIcon = config.readEntry( "Icon" );
-  m_strComment = config.readEntry( "Comment" );
+  m_strCaption = desktopFile.readName();
+  m_strIcon = desktopFile.readIcon();
+  m_strComment = desktopFile.readComment();
   deleted = config.readEntry("Hidden", false );
   m_bNoDisplay = desktopFile.noDisplay();
   if (directoryEntryPath.startsWith(QDir::homePath()))
--
1.8.2.2
