17#include "indicatorsmanager.h"
25class IndicatorsManager::IndicatorData
28 IndicatorData(
const QString& name,
const QFileInfo& fileInfo)
30 , m_fileInfo(fileInfo)
39 Indicator::Ptr m_indicator;
42IndicatorsManager::IndicatorsManager(QObject* parent)
45 , m_profile(QStringLiteral(
"phone"))
49IndicatorsManager::~IndicatorsManager()
54void IndicatorsManager::load()
58 m_fsWatcher.reset(
new QFileSystemWatcher(
this));
60 for (
const auto &xdgPath : shellDataDirs()) {
62 const auto unityPath = QDir::cleanPath(xdgPath +
"/unity/indicators");
63 if (QFile::exists(unityPath)) {
65 m_fsWatcher->addPath(unityPath);
69 const auto ayatanaPath = QDir::cleanPath(xdgPath +
"/ayatana/indicators");
70 if (QFile::exists(ayatanaPath)) {
72 m_fsWatcher->addPath(ayatanaPath);
77 QObject::connect(m_fsWatcher.data(), &QFileSystemWatcher::directoryChanged,
this, &IndicatorsManager::onDirectoryChanged);
78 QObject::connect(m_fsWatcher.data(), &QFileSystemWatcher::fileChanged,
this, &IndicatorsManager::onFileChanged);
82void IndicatorsManager::onDirectoryChanged(
const QString& directory)
84 loadDir(QDir(directory));
87void IndicatorsManager::onFileChanged(
const QString& file)
89 QFileInfo file_info(file);
90 if (!file_info.exists())
92 unloadFile(file_info);
97 loadFile(QFileInfo(file));
101void IndicatorsManager::loadDir(
const QDir& dir)
103 startVerify(dir.canonicalPath());
105 const QFileInfoList indicator_files = dir.entryInfoList(QStringList(), QDir::Files|QDir::NoDotAndDotDot);
106 Q_FOREACH(
const QFileInfo& indicator_file, indicator_files)
108 loadFile(indicator_file);
111 endVerify(dir.canonicalPath());
114void IndicatorsManager::loadFile(
const QFileInfo& file_info)
116 QSettings indicator_settings(file_info.absoluteFilePath(), QSettings::IniFormat,
this);
117 const QString name = indicator_settings.value(QStringLiteral(
"Indicator Service/Name")).toString();
119 auto iter = m_indicatorsData.constFind(name);
120 if (iter != m_indicatorsData.constEnd())
122 const QString newFileInfoDir = QDir::cleanPath(file_info.canonicalPath());
123 IndicatorData* currentData = (*iter);
124 currentData->m_verified =
true;
126 int file_info_location = -1;
127 int current_data_location = -1;
129 const QString currentDataDir = QDir::cleanPath(currentData->m_fileInfo.canonicalPath());
133 QStringList xdgLocations = shellDataDirs();
134 for (
int i = 0; i < xdgLocations.size(); i++)
136 const QString xdgLocation = QDir::cleanPath(xdgLocations[i]);
138 if (newFileInfoDir.startsWith(xdgLocation))
140 file_info_location = i;
142 if (currentDataDir.startsWith(xdgLocation))
144 current_data_location = i;
147 if (file_info_location != -1 && current_data_location != -1)
154 if (file_info_location <= current_data_location &&
155 file_info != currentData->m_fileInfo)
157 currentData->m_fileInfo = file_info;
158 Q_EMIT indicatorLoaded(name);
163 IndicatorData* data =
new IndicatorData(name, file_info);
164 data->m_verified =
true;
165 m_indicatorsData[name]= data;
166 Q_EMIT indicatorLoaded(name);
170void IndicatorsManager::unload()
172 QHashIterator<QString, IndicatorData*> iter(m_indicatorsData);
173 while(iter.hasNext())
176 Q_EMIT indicatorAboutToBeUnloaded(iter.key());
179 qDeleteAll(m_indicatorsData);
180 m_indicatorsData.clear();
185void IndicatorsManager::unloadFile(
const QFileInfo& file)
187 QMutableHashIterator<QString, IndicatorData*> iter(m_indicatorsData);
188 while(iter.hasNext())
191 IndicatorData* data = iter.value();
192 if (data->m_fileInfo.absoluteFilePath() == file.absoluteFilePath())
194 if (!data->m_verified)
196 const QString name = data->m_name;
197 Q_EMIT indicatorAboutToBeUnloaded(name);
205 setLoaded(m_indicatorsData.size() > 0);
208void IndicatorsManager::setLoaded(
bool loaded)
210 if (loaded != m_loaded)
213 Q_EMIT loadedChanged(m_loaded);
217QString IndicatorsManager::profile()
const
222void IndicatorsManager::setProfile(
const QString& profile)
224 if (m_profile != profile) {
226 Q_EMIT profileChanged(m_profile);
230void IndicatorsManager::startVerify(
const QString& path)
232 QHashIterator<QString, IndicatorData*> iter(m_indicatorsData);
233 while(iter.hasNext())
236 IndicatorData* data = iter.value();
237 if (data->m_fileInfo.canonicalPath() == path)
239 data->m_verified =
false;
244void IndicatorsManager::endVerify(
const QString& path)
246 QMutableHashIterator<QString, IndicatorData*> iter(m_indicatorsData);
247 while(iter.hasNext())
250 IndicatorData* data = iter.value();
251 if (data->m_fileInfo.canonicalPath() == path)
253 if (!data->m_verified)
255 const QString name = data->m_name;
256 Q_EMIT indicatorAboutToBeUnloaded(name);
265Indicator::Ptr IndicatorsManager::indicator(
const QString& indicator_name)
267 if (!m_indicatorsData.contains(indicator_name))
269 qWarning() << Q_FUNC_INFO <<
"Invalid indicator name: " << indicator_name;
270 return Indicator::Ptr();
273 IndicatorData *data = m_indicatorsData.value(indicator_name);
274 if (data->m_indicator)
276 return data->m_indicator;
279 Indicator::Ptr new_indicator(
new Indicator(
this));
280 data->m_indicator = new_indicator;
281 QSettings settings(data->m_fileInfo.absoluteFilePath(), QSettings::IniFormat,
this);
282 new_indicator->init(data->m_fileInfo.fileName(), settings);
289 if ((new_indicator->identifier() == QStringLiteral(
"ayatana-indicator-session"))
290 || new_indicator->identifier() == QStringLiteral(
"ayatana-indicator-keyboard")) {
291 new_indicator->setProfile(QString(m_profile).replace(QStringLiteral(
"phone"), QStringLiteral(
"desktop")));
293 new_indicator->setProfile(m_profile);
296 QObject::connect(
this, &IndicatorsManager::profileChanged, new_indicator.data(), &Indicator::setProfile);
297 return new_indicator;
300QVector<Indicator::Ptr> IndicatorsManager::indicators()
302 QVector<Indicator::Ptr> list;
303 Q_FOREACH(IndicatorData* data, m_indicatorsData)
305 Indicator::Ptr ret = indicator(data->m_name);
312bool IndicatorsManager::isLoaded()
const