2 * Copyright (C) 2013-2016 Canonical, Ltd.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
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 General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
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 const QStringList xdgLocations = shellDataDirs();
60 m_fsWatcher.reset(new QFileSystemWatcher(this));
62 Q_FOREACH(const QString& xdgLocation, xdgLocations)
64 const QString indicator_path = QDir::cleanPath(xdgLocation + "/unity/indicators");
65 QDir indicator_dir(indicator_path);
66 if (indicator_dir.exists())
68 // watch folder for changes.
69 m_fsWatcher->addPath(indicator_path);
71 loadDir(indicator_dir);
75 QObject::connect(m_fsWatcher.data(), &QFileSystemWatcher::directoryChanged, this, &IndicatorsManager::onDirectoryChanged);
76 QObject::connect(m_fsWatcher.data(), &QFileSystemWatcher::fileChanged, this, &IndicatorsManager::onFileChanged);
80void IndicatorsManager::onDirectoryChanged(const QString& directory)
82 loadDir(QDir(directory));
85void IndicatorsManager::onFileChanged(const QString& file)
87 QFileInfo file_info(file);
88 if (!file_info.exists())
90 unloadFile(file_info);
95 loadFile(QFileInfo(file));
99void IndicatorsManager::loadDir(const QDir& dir)
101 startVerify(dir.canonicalPath());
103 const QFileInfoList indicator_files = dir.entryInfoList(QStringList(), QDir::Files|QDir::NoDotAndDotDot);
104 Q_FOREACH(const QFileInfo& indicator_file, indicator_files)
106 loadFile(indicator_file);
109 endVerify(dir.canonicalPath());
112void IndicatorsManager::loadFile(const QFileInfo& file_info)
114 QSettings indicator_settings(file_info.absoluteFilePath(), QSettings::IniFormat, this);
115 const QString name = indicator_settings.value(QStringLiteral("Indicator Service/Name")).toString();
117 if (m_platform.isPC() && name == QLatin1String("indicator-keyboard")) {
118 return; // convergence: skip this indicator until it works in Mir
121 auto iter = m_indicatorsData.constFind(name);
122 if (iter != m_indicatorsData.constEnd())
124 const QString newFileInfoDir = QDir::cleanPath(file_info.canonicalPath());
125 IndicatorData* currentData = (*iter);
126 currentData->m_verified = true;
128 int file_info_location = -1;
129 int current_data_location = -1;
131 const QString currentDataDir = QDir::cleanPath(currentData->m_fileInfo.canonicalPath());
133 // if we've already got this indicator, we need to make sure we're not overwriting data which is
134 // from a lower priority standard path
135 QStringList xdgLocations = shellDataDirs();
136 for (int i = 0; i < xdgLocations.size(); i++)
138 const QString indicatorDir = QDir::cleanPath(xdgLocations[i] + "/unity/indicators");
140 if (newFileInfoDir == indicatorDir)
142 file_info_location = i;
144 if (currentDataDir == indicatorDir)
146 current_data_location = i;
149 if (file_info_location != -1 && current_data_location != -1)
155 // file location is higher (or of equal) priority. overwrite.
156 if (file_info_location <= current_data_location &&
157 file_info != currentData->m_fileInfo)
159 currentData->m_fileInfo = file_info;
160 Q_EMIT indicatorLoaded(name);
165 IndicatorData* data = new IndicatorData(name, file_info);
166 data->m_verified = true;
167 m_indicatorsData[name]= data;
168 Q_EMIT indicatorLoaded(name);
172void IndicatorsManager::unload()
174 QHashIterator<QString, IndicatorData*> iter(m_indicatorsData);
175 while(iter.hasNext())
178 Q_EMIT indicatorAboutToBeUnloaded(iter.key());
181 qDeleteAll(m_indicatorsData);
182 m_indicatorsData.clear();
187void IndicatorsManager::unloadFile(const QFileInfo& file)
189 QMutableHashIterator<QString, IndicatorData*> iter(m_indicatorsData);
190 while(iter.hasNext())
193 IndicatorData* data = iter.value();
194 if (data->m_fileInfo.absoluteFilePath() == file.absoluteFilePath())
196 if (!data->m_verified)
198 const QString name = data->m_name;
199 Q_EMIT indicatorAboutToBeUnloaded(name);
207 setLoaded(m_indicatorsData.size() > 0);
210void IndicatorsManager::setLoaded(bool loaded)
212 if (loaded != m_loaded)
215 Q_EMIT loadedChanged(m_loaded);
219QString IndicatorsManager::profile() const
224void IndicatorsManager::setProfile(const QString& profile)
226 if (m_profile != profile) {
228 Q_EMIT profileChanged(m_profile);
232void IndicatorsManager::startVerify(const QString& path)
234 QHashIterator<QString, IndicatorData*> iter(m_indicatorsData);
235 while(iter.hasNext())
238 IndicatorData* data = iter.value();
239 if (data->m_fileInfo.canonicalPath() == path)
241 data->m_verified = false;
246void IndicatorsManager::endVerify(const QString& path)
248 QMutableHashIterator<QString, IndicatorData*> iter(m_indicatorsData);
249 while(iter.hasNext())
252 IndicatorData* data = iter.value();
253 if (data->m_fileInfo.canonicalPath() == path)
255 if (!data->m_verified)
257 const QString name = data->m_name;
258 Q_EMIT indicatorAboutToBeUnloaded(name);
267Indicator::Ptr IndicatorsManager::indicator(const QString& indicator_name)
269 if (!m_indicatorsData.contains(indicator_name))
271 qWarning() << Q_FUNC_INFO << "Invalid indicator name: " << indicator_name;
272 return Indicator::Ptr();
275 IndicatorData *data = m_indicatorsData.value(indicator_name);
276 if (data->m_indicator)
278 return data->m_indicator;
281 Indicator::Ptr new_indicator(new Indicator(this));
282 data->m_indicator = new_indicator;
283 QSettings settings(data->m_fileInfo.absoluteFilePath(), QSettings::IniFormat, this);
284 new_indicator->init(data->m_fileInfo.fileName(), settings);
287 // 1) enable session indicator
288 // 2) on a PC, switch the battery/power indicator to desktop mode,
289 // can't control brightness for now and phone-on-desktop broken (FIXME)
291 // The rest of the indicators respect their default profile (which is "phone", even on desktop PCs)
292 if ((new_indicator->identifier() == QStringLiteral("indicator-session"))
293 || (new_indicator->identifier() == QStringLiteral("indicator-power") && m_platform.isPC())) {
294 new_indicator->setProfile(QStringLiteral("desktop"));
296 new_indicator->setProfile(m_profile);
299 QObject::connect(this, &IndicatorsManager::profileChanged, new_indicator.data(), &Indicator::setProfile);
300 return new_indicator;
303QVector<Indicator::Ptr> IndicatorsManager::indicators()
305 QVector<Indicator::Ptr> list;
306 Q_FOREACH(IndicatorData* data, m_indicatorsData)
308 Indicator::Ptr ret = indicator(data->m_name);
315bool IndicatorsManager::isLoaded() const
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list