Unity 8
desktopfilehandler.cpp
1 /*
2  * Copyright 2014 Canonical Ltd.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation; version 3.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * Authors:
17  * Michael Zanetti <michael.zanetti@canonical.com>
18  */
19 
20 #include "desktopfilehandler.h"
21 
22 #include <QStringList>
23 #include <QStandardPaths>
24 #include <QDir>
25 #include <QSettings>
26 #include <QLocale>
27 
28 #include <libintl.h>
29 
30 DesktopFileHandler::DesktopFileHandler(const QString &appId, QObject *parent):
31  QObject(parent),
32  m_appId(appId)
33 {
34  load();
35 }
36 
37 QString DesktopFileHandler::appId() const
38 {
39  return m_appId;
40 }
41 
42 void DesktopFileHandler::setAppId(const QString &appId)
43 {
44  if (m_appId != appId) {
45  m_appId = appId;
46  load();
47  }
48 }
49 
50 QString DesktopFileHandler::filename() const
51 {
52  return m_filename;
53 }
54 
55 bool DesktopFileHandler::isValid() const
56 {
57  return !m_filename.isEmpty();
58 }
59 
60 void DesktopFileHandler::load()
61 {
62  m_filename.clear();
63 
64  if (m_appId.isEmpty()) {
65  return;
66  }
67 
68  int dashPos = -1;
69  QString helper = m_appId;
70 
71  QStringList searchDirs = QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation);
72 #ifdef LAUNCHER_TESTING
73  searchDirs << QStringLiteral(".");
74 #endif
75 
76  QString path;
77  do {
78  if (dashPos != -1) {
79  helper.replace(dashPos, 1, '/');
80  }
81 
82  if (helper.contains('/')) {
83  path += helper.split('/').at(0) + '/';
84  helper.remove(QRegExp("^" + path));
85  }
86 
87  Q_FOREACH(const QString &searchDirName, searchDirs) {
88  QDir searchDir(searchDirName + "/" + path);
89  const QString desktop = QStringLiteral("*.desktop");
90  Q_FOREACH(const QString &desktopFile, searchDir.entryList(QStringList() << desktop)) {
91  if (desktopFile.startsWith(helper)) {
92  QFileInfo fileInfo(searchDir, desktopFile);
93  m_filename = fileInfo.absoluteFilePath();
94  return;
95  }
96  }
97  }
98 
99  dashPos = helper.indexOf('-');
100  } while (dashPos != -1);
101 }
102 
103 QString DesktopFileHandler::displayName() const
104 {
105  if (!isValid()) {
106  return QString();
107  }
108 
109  QSettings settings(m_filename, QSettings::IniFormat);
110  settings.setIniCodec("UTF-8");
111  settings.beginGroup(QStringLiteral("Desktop Entry"));
112 
113  // First try to find Name[xx_YY] and Name[xx] in .desktop file
114  const QString locale = QLocale().name();
115  const QStringList splitLocale = locale.split(QLatin1Char('_'));
116  const QString shortLocale = splitLocale.first();
117 
118  if (locale != shortLocale && settings.contains(QStringLiteral("Name[%1]").arg(locale))) {
119  return settings.value(QStringLiteral("Name[%1]").arg(locale)).toString();
120  }
121 
122  if (settings.contains(QStringLiteral("Name[%1]").arg(shortLocale))) {
123  return settings.value(QStringLiteral("Name[%1]").arg(shortLocale)).toString();
124  }
125 
126  // No translation found in desktop file. Get the untranslated one and have a go with gettext.
127  QString displayName = settings.value(QStringLiteral("Name")).toString();
128 
129  if (settings.contains(QStringLiteral("X-Ubuntu-Gettext-Domain"))) {
130  const QString domain = settings.value(QStringLiteral("X-Ubuntu-Gettext-Domain")).toString();
131  return dgettext(domain.toUtf8().constData(), displayName.toUtf8().constData());
132  }
133 
134  return displayName;
135 }
136 
137 QString DesktopFileHandler::icon() const
138 {
139  if (!isValid()) {
140  return QString();
141  }
142 
143  QSettings settings(m_filename, QSettings::IniFormat);
144  settings.setIniCodec("UTF-8");
145  settings.beginGroup(QStringLiteral("Desktop Entry"));
146  QString iconString = settings.value(QStringLiteral("Icon")).toString();
147  QString pathString = settings.value(QStringLiteral("Path")).toString();
148 
149  if (QFileInfo(iconString).exists()) {
150  return QFileInfo(iconString).absoluteFilePath();
151  } else if (QFileInfo(pathString + '/' + iconString).exists()) {
152  return pathString + '/' + iconString;
153  }
154  return "image://theme/" + iconString;
155 }